mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-18 22:41:33 +00:00
Implement multi device removal sheet
This commit is contained in:
parent
5e9dd8d286
commit
f56e3be1d4
@ -57,6 +57,7 @@
|
|||||||
android:layout_height="@dimen/onboarding_button_bottom_offset"
|
android:layout_height="@dimen/onboarding_button_bottom_offset"
|
||||||
android:layout_marginLeft="@dimen/massive_spacing"
|
android:layout_marginLeft="@dimen/massive_spacing"
|
||||||
android:layout_marginRight="@dimen/massive_spacing"
|
android:layout_marginRight="@dimen/massive_spacing"
|
||||||
|
android:visibility="invisible"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:background="@color/transparent"
|
android:background="@color/transparent"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
android:layout_height="@dimen/onboarding_button_bottom_offset"
|
android:layout_height="@dimen/onboarding_button_bottom_offset"
|
||||||
android:layout_marginLeft="@dimen/massive_spacing"
|
android:layout_marginLeft="@dimen/massive_spacing"
|
||||||
android:layout_marginRight="@dimen/massive_spacing"
|
android:layout_marginRight="@dimen/massive_spacing"
|
||||||
|
android:visibility="invisible"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:background="@color/transparent"
|
android:background="@color/transparent"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
|
42
res/layout/fragment_multi_device_removal_bottom_sheet.xml
Normal file
42
res/layout/fragment_multi_device_removal_bottom_sheet.xml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:paddingLeft="@dimen/very_large_spacing"
|
||||||
|
android:paddingTop="@dimen/large_spacing"
|
||||||
|
android:paddingRight="@dimen/very_large_spacing"
|
||||||
|
android:paddingBottom="@dimen/very_large_spacing"
|
||||||
|
app:behavior_hideable="true"
|
||||||
|
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
|
||||||
|
android:background="@drawable/default_bottom_sheet_background_inset">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Changes to Multi-Device"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="@dimen/large_font_size" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/explanationTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:text="You’re seeing this because you have a secondary device linked to your Session ID. To improve reliability and stability, we’ve decided to temporarily disable Session’s multi-device functionality. Device linking has been disabled, and existing secondary clients will be erased on %s.\n\nTo read more about this change, visit the Session FAQ at getsession.org/faq"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/small_font_size" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/MediumProminentOutlineButton"
|
||||||
|
android:id="@+id/okButton"
|
||||||
|
android:layout_width="240dp"
|
||||||
|
android:layout_height="@dimen/medium_button_height"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:text="@string/ok" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -7,6 +7,7 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
|
import android.net.Uri
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
@ -30,7 +31,9 @@ import org.thoughtcrime.securesms.database.DatabaseFactory
|
|||||||
import org.thoughtcrime.securesms.database.ThreadDatabase
|
import org.thoughtcrime.securesms.database.ThreadDatabase
|
||||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob
|
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob
|
||||||
|
import org.thoughtcrime.securesms.loki.database.LokiAPIDatabase
|
||||||
import org.thoughtcrime.securesms.loki.dialogs.ConversationOptionsBottomSheet
|
import org.thoughtcrime.securesms.loki.dialogs.ConversationOptionsBottomSheet
|
||||||
|
import org.thoughtcrime.securesms.loki.dialogs.MultiDeviceRemovalBottomSheet
|
||||||
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol
|
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol
|
||||||
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation
|
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation
|
||||||
import org.thoughtcrime.securesms.loki.utilities.*
|
import org.thoughtcrime.securesms.loki.utilities.*
|
||||||
@ -189,6 +192,25 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
|||||||
if (hasViewedSeed || !isMasterDevice) {
|
if (hasViewedSeed || !isMasterDevice) {
|
||||||
seedReminderView.visibility = View.GONE
|
seedReminderView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
val hasSeenMultiDeviceRemovalSheet = TextSecurePreferences.getHasSeenMultiDeviceRemovalSheet(this)
|
||||||
|
if (!hasSeenMultiDeviceRemovalSheet) {
|
||||||
|
TextSecurePreferences.setHasSeenMultiDeviceRemovalSheet(this)
|
||||||
|
val userPublicKey = TextSecurePreferences.getLocalNumber(this)
|
||||||
|
val deviceLinks = DatabaseFactory.getLokiAPIDatabase(this).getDeviceLinks(userPublicKey)
|
||||||
|
if (deviceLinks.isNotEmpty()) {
|
||||||
|
val bottomSheet = MultiDeviceRemovalBottomSheet()
|
||||||
|
bottomSheet.onOKTapped = {
|
||||||
|
bottomSheet.dismiss()
|
||||||
|
}
|
||||||
|
bottomSheet.onLinkTapped = {
|
||||||
|
bottomSheet.dismiss()
|
||||||
|
val url = "https://getsession.org/faq"
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
bottomSheet.show(supportFragmentManager, bottomSheet.tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
@ -44,7 +44,7 @@ class LandingActivity : BaseActionBarActivity(), LinkDeviceSlaveModeDialogDelega
|
|||||||
fakeChatView.startAnimating()
|
fakeChatView.startAnimating()
|
||||||
registerButton.setOnClickListener { register() }
|
registerButton.setOnClickListener { register() }
|
||||||
restoreButton.setOnClickListener { restore() }
|
restoreButton.setOnClickListener { restore() }
|
||||||
linkButton.setOnClickListener { linkDevice() }
|
// linkButton.setOnClickListener { linkDevice() }
|
||||||
if (TextSecurePreferences.getWasUnlinked(this)) {
|
if (TextSecurePreferences.getWasUnlinked(this)) {
|
||||||
Toast.makeText(this, R.string.activity_landing_device_unlinked_dialog_title, Toast.LENGTH_LONG).show()
|
Toast.makeText(this, R.string.activity_landing_device_unlinked_dialog_title, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ class PNModeActivity : BaseActionBarActivity() {
|
|||||||
TextSecurePreferences.setHasSeenWelcomeScreen(this, true)
|
TextSecurePreferences.setHasSeenWelcomeScreen(this, true)
|
||||||
TextSecurePreferences.setPromptedPushRegistration(this, true)
|
TextSecurePreferences.setPromptedPushRegistration(this, true)
|
||||||
TextSecurePreferences.setIsUsingFCM(this, (selectedOptionView == fcmOptionView))
|
TextSecurePreferences.setIsUsingFCM(this, (selectedOptionView == fcmOptionView))
|
||||||
TextSecurePreferences.setHasSeenPNModeSheet(this, true) // Shouldn't be shown to users who've done the new onboarding
|
TextSecurePreferences.setHasSeenMultiDeviceRemovalSheet(this)
|
||||||
val application = ApplicationContext.getInstance(this)
|
val application = ApplicationContext.getInstance(this)
|
||||||
application.setUpStorageAPIIfNeeded()
|
application.setUpStorageAPIIfNeeded()
|
||||||
application.setUpP2PAPIIfNeeded()
|
application.setUpP2PAPIIfNeeded()
|
||||||
|
@ -83,16 +83,16 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
copyButton.setOnClickListener { copyPublicKey() }
|
copyButton.setOnClickListener { copyPublicKey() }
|
||||||
shareButton.setOnClickListener { sharePublicKey() }
|
shareButton.setOnClickListener { sharePublicKey() }
|
||||||
val isMasterDevice = (TextSecurePreferences.getMasterHexEncodedPublicKey(this) == null)
|
val isMasterDevice = (TextSecurePreferences.getMasterHexEncodedPublicKey(this) == null)
|
||||||
|
linkedDevicesButtonTopSeparator.visibility = View.GONE
|
||||||
|
linkedDevicesButton.visibility = View.GONE
|
||||||
if (!isMasterDevice) {
|
if (!isMasterDevice) {
|
||||||
linkedDevicesButtonTopSeparator.visibility = View.GONE
|
|
||||||
linkedDevicesButton.visibility = View.GONE
|
|
||||||
seedButtonTopSeparator.visibility = View.GONE
|
seedButtonTopSeparator.visibility = View.GONE
|
||||||
seedButton.visibility = View.GONE
|
seedButton.visibility = View.GONE
|
||||||
}
|
}
|
||||||
privacyButton.setOnClickListener { showPrivacySettings() }
|
privacyButton.setOnClickListener { showPrivacySettings() }
|
||||||
notificationsButton.setOnClickListener { showNotificationSettings() }
|
notificationsButton.setOnClickListener { showNotificationSettings() }
|
||||||
chatsButton.setOnClickListener { showChatSettings() }
|
chatsButton.setOnClickListener { showChatSettings() }
|
||||||
linkedDevicesButton.setOnClickListener { showLinkedDevices() }
|
// linkedDevicesButton.setOnClickListener { showLinkedDevices() }
|
||||||
seedButton.setOnClickListener { showSeed() }
|
seedButton.setOnClickListener { showSeed() }
|
||||||
clearAllDataButton.setOnClickListener { clearAllData() }
|
clearAllDataButton.setOnClickListener { clearAllData() }
|
||||||
versionTextView.text = String.format(getString(R.string.version_s), BuildConfig.VERSION_NAME)
|
versionTextView.text = String.format(getString(R.string.version_s), BuildConfig.VERSION_NAME)
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
package org.thoughtcrime.securesms.loki.dialogs
|
||||||
|
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.design.widget.BottomSheetDialogFragment
|
||||||
|
import android.text.Spannable
|
||||||
|
import android.text.SpannableStringBuilder
|
||||||
|
import android.text.method.LinkMovementMethod
|
||||||
|
import android.text.style.ClickableSpan
|
||||||
|
import android.text.style.ForegroundColorSpan
|
||||||
|
import android.text.style.StyleSpan
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
|
import kotlinx.android.synthetic.main.fragment_multi_device_removal_bottom_sheet.*
|
||||||
|
import network.loki.messenger.R
|
||||||
|
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class MultiDeviceRemovalBottomSheet : BottomSheetDialogFragment() {
|
||||||
|
var onOKTapped: (() -> Unit)? = null
|
||||||
|
var onLinkTapped: (() -> Unit)? = null
|
||||||
|
|
||||||
|
private val removalDate by lazy {
|
||||||
|
val timeZone = TimeZone.getTimeZone("Australia/Melbourne")
|
||||||
|
val calendar = GregorianCalendar.getInstance(timeZone)
|
||||||
|
calendar.set(2020, 8 - 1, 6, 17, 0, 0)
|
||||||
|
calendar.time
|
||||||
|
}
|
||||||
|
|
||||||
|
private val removalDateDescription by lazy {
|
||||||
|
val formatter = SimpleDateFormat("MMMM d", Locale.getDefault())
|
||||||
|
formatter.format(removalDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val explanation by lazy {
|
||||||
|
if (TextSecurePreferences.getMasterHexEncodedPublicKey(context!!) != null) {
|
||||||
|
"You’re seeing this because this is a secondary device in a multi-device setup. To improve reliability and stability, we’ve decided to temporarily disable Session’s multi-device functionality. Device linking has been disabled, and existing secondary clients will be erased on $removalDateDescription.\n\nTo read more about this change, visit the Session FAQ at getsession.org/faq."
|
||||||
|
} else {
|
||||||
|
"You’re seeing this because you have a secondary device linked to your Session ID. To improve reliability and stability, we’ve decided to temporarily disable Session’s multi-device functionality. Device linking has been disabled, and existing secondary clients will be erased on $removalDateDescription.\n\nTo read more about this change, visit the Session FAQ at getsession.org/faq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val decoratedExplanation by lazy {
|
||||||
|
val result = SpannableStringBuilder(explanation)
|
||||||
|
val removalDateStartIndex = explanation.indexOf(removalDateDescription)
|
||||||
|
val removalDateEndIndex = removalDateStartIndex + removalDateDescription.count()
|
||||||
|
result.setSpan(StyleSpan(Typeface.BOLD), removalDateStartIndex, removalDateEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
result.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, context!!.theme)), removalDateStartIndex, removalDateEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
val link = "getsession.org/faq"
|
||||||
|
val linkStartIndex = explanation.indexOf(link)
|
||||||
|
val linkEndIndex = linkStartIndex + link.count()
|
||||||
|
result.setSpan(object : ClickableSpan() {
|
||||||
|
|
||||||
|
override fun onClick(widget: View) {
|
||||||
|
try {
|
||||||
|
onLinkTapped?.invoke()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Toast.makeText(context!!, R.string.invalid_url, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, linkStartIndex, linkEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
result.setSpan(StyleSpan(Typeface.BOLD), linkStartIndex, linkEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
result.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, context!!.theme)), linkStartIndex, linkEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setStyle(STYLE_NORMAL, R.style.SessionBottomSheetDialogTheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
return inflater.inflate(R.layout.fragment_multi_device_removal_bottom_sheet, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
explanationTextView.movementMethod = LinkMovementMethod.getInstance()
|
||||||
|
explanationTextView.text = decoratedExplanation
|
||||||
|
okButton.setOnClickListener { onOKTapped?.invoke() }
|
||||||
|
}
|
||||||
|
}
|
@ -214,14 +214,6 @@ public class TextSecurePreferences {
|
|||||||
public static void setLastFCMUploadTime(Context context, long value) {
|
public static void setLastFCMUploadTime(Context context, long value) {
|
||||||
setLongPreference(context, LAST_FCM_TOKEN_UPLOAD_TIME, value);
|
setLongPreference(context, LAST_FCM_TOKEN_UPLOAD_TIME, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasSeenPNModeSheet(Context context) {
|
|
||||||
return getBooleanPreference(context, HAS_SEEN_PN_MODE_SHEET, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setHasSeenPNModeSheet(Context context, boolean value) {
|
|
||||||
setBooleanPreference(context, HAS_SEEN_PN_MODE_SHEET, value);
|
|
||||||
}
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
public static boolean isScreenLockEnabled(@NonNull Context context) {
|
public static boolean isScreenLockEnabled(@NonNull Context context) {
|
||||||
@ -1316,5 +1308,13 @@ public class TextSecurePreferences {
|
|||||||
public static void clearAll(Context context) {
|
public static void clearAll(Context context) {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit().clear().commit();
|
PreferenceManager.getDefaultSharedPreferences(context).edit().clear().commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean getHasSeenMultiDeviceRemovalSheet(Context context) {
|
||||||
|
return getBooleanPreference(context, "has_seen_multi_device_removal_sheet", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setHasSeenMultiDeviceRemovalSheet(Context context) {
|
||||||
|
setBooleanPreference(context, "has_seen_multi_device_removal_sheet", true);
|
||||||
|
}
|
||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user