diff --git a/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java b/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java index 284a0e929a..3b939bf647 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java @@ -17,6 +17,8 @@ package org.thoughtcrime.securesms; +import static org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY; + import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; @@ -29,14 +31,21 @@ import android.provider.OpenableColumns; import android.view.MenuItem; import android.view.View; import android.widget.ImageView; +import android.widget.TextView; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.widget.Toolbar; + +import com.squareup.phrase.Phrase; + import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; + import network.loki.messenger.R; + import org.session.libsession.utilities.Address; import org.session.libsession.utilities.DistributionTypes; import org.session.libsession.utilities.ViewUtil; @@ -57,261 +66,261 @@ import org.thoughtcrime.securesms.util.MediaUtil; * @author Jake McGinty */ public class ShareActivity extends PassphraseRequiredActionBarActivity - implements ContactSelectionListFragment.OnContactSelectedListener -{ - private static final String TAG = ShareActivity.class.getSimpleName(); - - public static final String EXTRA_THREAD_ID = "thread_id"; - public static final String EXTRA_ADDRESS_MARSHALLED = "address_marshalled"; - public static final String EXTRA_DISTRIBUTION_TYPE = "distribution_type"; - - private ContactSelectionListFragment contactsFragment; - private SearchToolbar searchToolbar; - private ImageView searchAction; - private View progressWheel; - private Uri resolvedExtra; - private CharSequence resolvedPlaintext; - private String mimeType; - private boolean isPassingAlongMedia; - - @Override - protected void onCreate(Bundle icicle, boolean ready) { - if (!getIntent().hasExtra(ContactSelectionListFragment.DISPLAY_MODE)) { - getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, DisplayMode.FLAG_ALL); - } + implements ContactSelectionListFragment.OnContactSelectedListener { + private static final String TAG = ShareActivity.class.getSimpleName(); + + public static final String EXTRA_THREAD_ID = "thread_id"; + public static final String EXTRA_ADDRESS_MARSHALLED = "address_marshalled"; + public static final String EXTRA_DISTRIBUTION_TYPE = "distribution_type"; + + private ContactSelectionListFragment contactsFragment; + private SearchToolbar searchToolbar; + private ImageView searchAction; + private View progressWheel; + private Uri resolvedExtra; + private CharSequence resolvedPlaintext; + private String mimeType; + private boolean isPassingAlongMedia; - getIntent().putExtra(ContactSelectionListFragment.REFRESHABLE, false); - - setContentView(R.layout.share_activity); - - // initializeToolbar(); - initializeResources(); - initializeSearch(); - initializeMedia(); - } - - @Override - protected void onNewIntent(Intent intent) { - Log.i(TAG, "onNewIntent()"); - super.onNewIntent(intent); - setIntent(intent); - initializeMedia(); - } - - @Override - public void onPause() { - super.onPause(); - if (!isPassingAlongMedia && resolvedExtra != null) { - BlobProvider.getInstance().delete(this, resolvedExtra); - - if (!isFinishing()) { - finish(); - } - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - onBackPressed(); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public void onBackPressed() { - if (searchToolbar.isVisible()) searchToolbar.collapse(); - else super.onBackPressed(); - } - - /* private void initializeToolbar() { - SearchToolbar toolbar = findViewById(R.id.search_toolbar); - setSupportActionBar(toolbar); - ActionBar actionBar = getSupportActionBar(); - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setHomeButtonEnabled(true); - }*/ - - private void initializeResources() { - progressWheel = findViewById(R.id.progress_wheel); - searchToolbar = findViewById(R.id.search_toolbar); - searchAction = findViewById(R.id.search_action); - contactsFragment = (ContactSelectionListFragment) getSupportFragmentManager().findFragmentById(R.id.contact_selection_list_fragment); - contactsFragment.setOnContactSelectedListener(this); - } - - private void initializeSearch() { - searchAction.setOnClickListener(v -> searchToolbar.display(searchAction.getX() + (searchAction.getWidth() / 2), - searchAction.getY() + (searchAction.getHeight() / 2))); - - searchToolbar.setListener(new SearchToolbar.SearchListener() { - @Override - public void onSearchTextChange(String text) { - if (contactsFragment != null) { - contactsFragment.setQueryFilter(text); + @Override + protected void onCreate(Bundle icicle, boolean ready) { + if (!getIntent().hasExtra(ContactSelectionListFragment.DISPLAY_MODE)) { + getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, DisplayMode.FLAG_ALL); } - } - @Override - public void onSearchClosed() { - if (contactsFragment != null) { - contactsFragment.resetQueryFilter(); - } - } - }); - } - - private void initializeMedia() { - final Context context = this; - isPassingAlongMedia = false; - - Uri streamExtra = getIntent().getParcelableExtra(Intent.EXTRA_STREAM); - CharSequence charSequenceExtra = getIntent().getCharSequenceExtra(Intent.EXTRA_TEXT); - mimeType = getMimeType(streamExtra); - - if (streamExtra != null && PartAuthority.isLocalUri(streamExtra)) { - isPassingAlongMedia = true; - resolvedExtra = streamExtra; - handleResolvedMedia(getIntent(), false); - } else if (charSequenceExtra != null && mimeType != null && mimeType.startsWith("text/")) { - resolvedPlaintext = charSequenceExtra; - handleResolvedMedia(getIntent(), false); - } else { - contactsFragment.getView().setVisibility(View.GONE); - progressWheel.setVisibility(View.VISIBLE); - new ResolveMediaTask(context).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, streamExtra); + getIntent().putExtra(ContactSelectionListFragment.REFRESHABLE, false); + + setContentView(R.layout.share_activity); + + initializeToolbar(); + initializeResources(); + initializeSearch(); + initializeMedia(); } - } - - private void handleResolvedMedia(Intent intent, boolean animate) { - long threadId = intent.getLongExtra(EXTRA_THREAD_ID, -1); - int distributionType = intent.getIntExtra(EXTRA_DISTRIBUTION_TYPE, -1); - Address address = null; - - if (intent.hasExtra(EXTRA_ADDRESS_MARSHALLED)) { - Parcel parcel = Parcel.obtain(); - byte[] marshalled = intent.getByteArrayExtra(EXTRA_ADDRESS_MARSHALLED); - parcel.unmarshall(marshalled, 0, marshalled.length); - parcel.setDataPosition(0); - address = parcel.readParcelable(getClassLoader()); - parcel.recycle(); + + @Override + protected void onNewIntent(Intent intent) { + Log.i(TAG, "onNewIntent()"); + super.onNewIntent(intent); + setIntent(intent); + initializeMedia(); } - boolean hasResolvedDestination = threadId != -1 && address != null && distributionType != -1; + @Override + public void onPause() { + super.onPause(); + if (!isPassingAlongMedia && resolvedExtra != null) { + BlobProvider.getInstance().delete(this, resolvedExtra); - if (!hasResolvedDestination && animate) { - ViewUtil.fadeIn(contactsFragment.getView(), 300); - ViewUtil.fadeOut(progressWheel, 300); - } else if (!hasResolvedDestination) { - contactsFragment.getView().setVisibility(View.VISIBLE); - progressWheel.setVisibility(View.GONE); - } else { - createConversation(threadId, address, distributionType); + if (!isFinishing()) { + finish(); + } + } } - } - private void createConversation(long threadId, Address address, int distributionType) { - final Intent intent = getBaseShareIntent(ConversationActivityV2.class); - intent.putExtra(ConversationActivityV2.ADDRESS, address); - intent.putExtra(ConversationActivityV2.THREAD_ID, threadId); + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + } + return super.onOptionsItemSelected(item); + } - isPassingAlongMedia = true; - startActivity(intent); - } + @Override + public void onBackPressed() { + if (searchToolbar.isVisible()) searchToolbar.collapse(); + else super.onBackPressed(); + } - private Intent getBaseShareIntent(final @NonNull Class<?> target) { - final Intent intent = new Intent(this, target); + private void initializeToolbar() { + TextView tootlbarTitle = findViewById(R.id.title); + tootlbarTitle.setText( + Phrase.from(getApplicationContext(), R.string.shareToSession) + .put(APP_NAME_KEY, getString(R.string.app_name)) + .format().toString() + ); + } - if (resolvedExtra != null) { - intent.setDataAndType(resolvedExtra, mimeType); - } else if (resolvedPlaintext != null) { - intent.putExtra(Intent.EXTRA_TEXT, resolvedPlaintext); - intent.setType("text/plain"); + private void initializeResources() { + progressWheel = findViewById(R.id.progress_wheel); + searchToolbar = findViewById(R.id.search_toolbar); + searchAction = findViewById(R.id.search_action); + contactsFragment = (ContactSelectionListFragment) getSupportFragmentManager().findFragmentById(R.id.contact_selection_list_fragment); + contactsFragment.setOnContactSelectedListener(this); } - return intent; - } + private void initializeSearch() { + searchAction.setOnClickListener(v -> searchToolbar.display(searchAction.getX() + (searchAction.getWidth() / 2), + searchAction.getY() + (searchAction.getHeight() / 2))); + + searchToolbar.setListener(new SearchToolbar.SearchListener() { + @Override + public void onSearchTextChange(String text) { + if (contactsFragment != null) { + contactsFragment.setQueryFilter(text); + } + } - private String getMimeType(@Nullable Uri uri) { - if (uri != null) { - final String mimeType = MediaUtil.getMimeType(getApplicationContext(), uri); - if (mimeType != null) return mimeType; + @Override + public void onSearchClosed() { + if (contactsFragment != null) { + contactsFragment.resetQueryFilter(); + } + } + }); } - return MediaUtil.getCorrectedMimeType(getIntent().getType()); - } - - @Override - public void onContactSelected(String number) { - Recipient recipient = Recipient.from(this, Address.fromExternal(this, number), true); - long existingThread = DatabaseComponent.get(this).threadDatabase().getThreadIdIfExistsFor(recipient); - createConversation(existingThread, recipient.getAddress(), DistributionTypes.DEFAULT); - } - - @Override - public void onContactDeselected(String number) { - } - - @SuppressLint("StaticFieldLeak") - private class ResolveMediaTask extends AsyncTask<Uri, Void, Uri> { - private final Context context; - - ResolveMediaTask(Context context) { - this.context = context; + + private void initializeMedia() { + final Context context = this; + isPassingAlongMedia = false; + + Uri streamExtra = getIntent().getParcelableExtra(Intent.EXTRA_STREAM); + CharSequence charSequenceExtra = getIntent().getCharSequenceExtra(Intent.EXTRA_TEXT); + mimeType = getMimeType(streamExtra); + + if (streamExtra != null && PartAuthority.isLocalUri(streamExtra)) { + isPassingAlongMedia = true; + resolvedExtra = streamExtra; + handleResolvedMedia(getIntent(), false); + } else if (charSequenceExtra != null && mimeType != null && mimeType.startsWith("text/")) { + resolvedPlaintext = charSequenceExtra; + handleResolvedMedia(getIntent(), false); + } else { + contactsFragment.getView().setVisibility(View.GONE); + progressWheel.setVisibility(View.VISIBLE); + new ResolveMediaTask(context).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, streamExtra); + } } - @Override - protected Uri doInBackground(Uri... uris) { - try { - if (uris.length != 1 || uris[0] == null) { - return null; + private void handleResolvedMedia(Intent intent, boolean animate) { + long threadId = intent.getLongExtra(EXTRA_THREAD_ID, -1); + int distributionType = intent.getIntExtra(EXTRA_DISTRIBUTION_TYPE, -1); + Address address = null; + + if (intent.hasExtra(EXTRA_ADDRESS_MARSHALLED)) { + Parcel parcel = Parcel.obtain(); + byte[] marshalled = intent.getByteArrayExtra(EXTRA_ADDRESS_MARSHALLED); + parcel.unmarshall(marshalled, 0, marshalled.length); + parcel.setDataPosition(0); + address = parcel.readParcelable(getClassLoader()); + parcel.recycle(); } - InputStream inputStream; + boolean hasResolvedDestination = threadId != -1 && address != null && distributionType != -1; - if ("file".equals(uris[0].getScheme())) { - inputStream = new FileInputStream(uris[0].getPath()); + if (!hasResolvedDestination && animate) { + ViewUtil.fadeIn(contactsFragment.getView(), 300); + ViewUtil.fadeOut(progressWheel, 300); + } else if (!hasResolvedDestination) { + contactsFragment.getView().setVisibility(View.VISIBLE); + progressWheel.setVisibility(View.GONE); } else { - inputStream = context.getContentResolver().openInputStream(uris[0]); + createConversation(threadId, address, distributionType); } + } + + private void createConversation(long threadId, Address address, int distributionType) { + final Intent intent = getBaseShareIntent(ConversationActivityV2.class); + intent.putExtra(ConversationActivityV2.ADDRESS, address); + intent.putExtra(ConversationActivityV2.THREAD_ID, threadId); - if (inputStream == null) { - return null; + isPassingAlongMedia = true; + startActivity(intent); + } + + private Intent getBaseShareIntent(final @NonNull Class<?> target) { + final Intent intent = new Intent(this, target); + + if (resolvedExtra != null) { + intent.setDataAndType(resolvedExtra, mimeType); + } else if (resolvedPlaintext != null) { + intent.putExtra(Intent.EXTRA_TEXT, resolvedPlaintext); + intent.setType("text/plain"); } - Cursor cursor = getContentResolver().query(uris[0], new String[] {OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}, null, null, null); - String fileName = null; - Long fileSize = null; + return intent; + } - try { - if (cursor != null && cursor.moveToFirst()) { - try { - fileName = cursor.getString(cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME)); - fileSize = cursor.getLong(cursor.getColumnIndexOrThrow(OpenableColumns.SIZE)); - } catch (IllegalArgumentException e) { - Log.w(TAG, e); - } - } - } finally { - if (cursor != null) cursor.close(); + private String getMimeType(@Nullable Uri uri) { + if (uri != null) { + final String mimeType = MediaUtil.getMimeType(getApplicationContext(), uri); + if (mimeType != null) return mimeType; } + return MediaUtil.getCorrectedMimeType(getIntent().getType()); + } - return BlobProvider.getInstance() - .forData(inputStream, fileSize == null ? 0 : fileSize) - .withMimeType(mimeType) - .withFileName(fileName) - .createForMultipleSessionsOnDisk(context, e -> Log.w(TAG, "Failed to write to disk.", e)); - } catch (IOException ioe) { - Log.w(TAG, ioe); - return null; - } + @Override + public void onContactSelected(String number) { + Recipient recipient = Recipient.from(this, Address.fromExternal(this, number), true); + long existingThread = DatabaseComponent.get(this).threadDatabase().getThreadIdIfExistsFor(recipient); + createConversation(existingThread, recipient.getAddress(), DistributionTypes.DEFAULT); } @Override - protected void onPostExecute(Uri uri) { - resolvedExtra = uri; - handleResolvedMedia(getIntent(), true); + public void onContactDeselected(String number) { + } + + @SuppressLint("StaticFieldLeak") + private class ResolveMediaTask extends AsyncTask<Uri, Void, Uri> { + private final Context context; + + ResolveMediaTask(Context context) { + this.context = context; + } + + @Override + protected Uri doInBackground(Uri... uris) { + try { + if (uris.length != 1 || uris[0] == null) { + return null; + } + + InputStream inputStream; + + if ("file".equals(uris[0].getScheme())) { + inputStream = new FileInputStream(uris[0].getPath()); + } else { + inputStream = context.getContentResolver().openInputStream(uris[0]); + } + + if (inputStream == null) { + return null; + } + + Cursor cursor = getContentResolver().query(uris[0], new String[]{OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}, null, null, null); + String fileName = null; + Long fileSize = null; + + try { + if (cursor != null && cursor.moveToFirst()) { + try { + fileName = cursor.getString(cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME)); + fileSize = cursor.getLong(cursor.getColumnIndexOrThrow(OpenableColumns.SIZE)); + } catch (IllegalArgumentException e) { + Log.w(TAG, e); + } + } + } finally { + if (cursor != null) cursor.close(); + } + + return BlobProvider.getInstance() + .forData(inputStream, fileSize == null ? 0 : fileSize) + .withMimeType(mimeType) + .withFileName(fileName) + .createForMultipleSessionsOnDisk(context, e -> Log.w(TAG, "Failed to write to disk.", e)); + } catch (IOException ioe) { + Log.w(TAG, ioe); + return null; + } + } + + @Override + protected void onPostExecute(Uri uri) { + resolvedExtra = uri; + handleResolvedMedia(getIntent(), true); + } } - } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModel.kt index 32e20b73d9..915ff66971 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModel.kt @@ -58,7 +58,7 @@ class DisappearingMessagesViewModel( init { viewModelScope.launch { - val expiryMode = storage.getExpirationConfiguration(threadId)?.expiryMode?.maybeConvertToLegacy(isNewConfigEnabled) ?: ExpiryMode.NONE + val expiryMode = storage.getExpirationConfiguration(threadId)?.expiryMode ?: ExpiryMode.NONE val recipient = threadDb.getRecipientForThreadId(threadId) val groupRecord = recipient?.takeIf { it.isClosedGroupRecipient } ?.run { groupDb.getGroup(address.toGroupString()).orNull() } @@ -80,7 +80,7 @@ class DisappearingMessagesViewModel( override fun onSetClick() = viewModelScope.launch { val state = _state.value - val mode = state.expiryMode?.coerceLegacyToAfterSend() + val mode = state.expiryMode val address = state.address if (address == null || mode == null) { _event.send(Event.FAIL) @@ -92,8 +92,6 @@ class DisappearingMessagesViewModel( _event.send(Event.SUCCESS) } - private fun ExpiryMode.coerceLegacyToAfterSend() = takeUnless { it is ExpiryMode.Legacy } ?: ExpiryMode.AfterSend(expirySeconds) - @dagger.assisted.AssistedFactory interface AssistedFactory { fun create(threadId: Long): Factory @@ -125,5 +123,3 @@ class DisappearingMessagesViewModel( ) as T } } - -private fun ExpiryMode.maybeConvertToLegacy(isNewConfigEnabled: Boolean): ExpiryMode = takeIf { isNewConfigEnabled } ?: ExpiryMode.Legacy(expirySeconds) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/State.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/State.kt index 739d7d6c9f..f7c5a38e9d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/State.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/State.kt @@ -18,7 +18,7 @@ data class State( val isSelfAdmin: Boolean = true, val address: Address? = null, val isNoteToSelf: Boolean = false, - val expiryMode: ExpiryMode? = null, + val expiryMode: ExpiryMode = ExpiryMode.NONE, val isNewConfigEnabled: Boolean = true, val persistedMode: ExpiryMode? = null, val showDebugOptions: Boolean = false @@ -30,16 +30,10 @@ data class State( val typeOptionsHidden get() = isNoteToSelf || (isGroup && isNewConfigEnabled) - val nextType get() = when { - expiryType == ExpiryType.AFTER_READ -> ExpiryType.AFTER_READ - isNewConfigEnabled -> ExpiryType.AFTER_SEND - else -> ExpiryType.LEGACY - } - - val duration get() = expiryMode?.duration - val expiryType get() = expiryMode?.type + val duration get() = expiryMode.duration + val expiryType get() = expiryMode.type - val isTimeOptionsEnabled = isNoteToSelf || isSelfAdmin && (isNewConfigEnabled || expiryType == ExpiryType.LEGACY) + val isTimeOptionsEnabled = isNoteToSelf || isSelfAdmin && isNewConfigEnabled } @@ -54,11 +48,6 @@ enum class ExpiryType( R.string.off, contentDescription = R.string.AccessibilityId_disappearingMessagesOff, ), - LEGACY( - ExpiryMode::Legacy, - R.string.expiration_type_disappear_legacy, - contentDescription = R.string.AccessibilityId_disappearingMessagesLegacy - ), AFTER_READ( ExpiryMode::AfterRead, R.string.disappearingMessagesDisappearAfterRead, @@ -83,7 +72,6 @@ enum class ExpiryType( } val ExpiryMode.type: ExpiryType get() = when(this) { - is ExpiryMode.Legacy -> ExpiryType.LEGACY is ExpiryMode.AfterSend -> ExpiryType.AFTER_SEND is ExpiryMode.AfterRead -> ExpiryType.AFTER_READ else -> ExpiryType.NONE diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/Adapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/Adapter.kt index dbd40354a2..3900c06bcf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/Adapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/Adapter.kt @@ -23,7 +23,6 @@ fun State.toUiState() = UiState( private fun State.typeOptions(): List<ExpiryRadioOption>? = if (typeOptionsHidden) null else { buildList { add(offTypeOption()) - if (!isNewConfigEnabled) add(legacyTypeOption()) if (!isGroup) add(afterReadTypeOption()) add(afterSendTypeOption()) } @@ -33,7 +32,7 @@ private fun State.timeOptions(): List<ExpiryRadioOption>? { // Don't show times card if we have a types card, and type is off. if (!typeOptionsHidden && expiryType == ExpiryType.NONE) return null - return nextType.let { type -> + return expiryType.let { type -> when (type) { ExpiryType.AFTER_READ -> afterReadTimes else -> afterSendTimes @@ -48,7 +47,6 @@ private fun State.timeOptions(): List<ExpiryRadioOption>? { } private fun State.offTypeOption() = typeOption(ExpiryType.NONE) -private fun State.legacyTypeOption() = typeOption(ExpiryType.LEGACY) private fun State.afterReadTypeOption() = newTypeOption(ExpiryType.AFTER_READ) private fun State.afterSendTypeOption() = newTypeOption(ExpiryType.AFTER_SEND) private fun State.newTypeOption(type: ExpiryType) = typeOption(type, isNewConfigEnabled && isSelfAdmin) @@ -71,7 +69,7 @@ private fun debugModes(isDebug: Boolean, type: ExpiryType) = debugTimes(isDebug).map { type.mode(it.inWholeSeconds) } private fun State.debugOptions(): List<ExpiryRadioOption> = - debugModes(showDebugOptions, nextType).map { timeOption(it, subtitle = GetString("for testing purposes")) } + debugModes(showDebugOptions, expiryType).map { timeOption(it, subtitle = GetString("for testing purposes")) } // Standard list of available disappearing message times private val afterSendTimes = listOf(12.hours, 1.days, 7.days, 14.days) @@ -96,6 +94,6 @@ private fun State.timeOption( title = title, subtitle = subtitle, contentDescription = title, - selected = mode.duration == expiryMode?.duration, + selected = mode.duration == expiryMode.duration, enabled = isTimeOptionsEnabled ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessages.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessages.kt index ace4097c48..b066a96cc7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessages.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessages.kt @@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.ui.Callbacks import org.thoughtcrime.securesms.ui.NoOpCallbacks import org.thoughtcrime.securesms.ui.OptionsCard import org.thoughtcrime.securesms.ui.RadioOption +import org.thoughtcrime.securesms.ui.components.PrimaryOutlineButton import org.thoughtcrime.securesms.ui.components.SlimOutlineButton import org.thoughtcrime.securesms.ui.contentDescription import org.thoughtcrime.securesms.ui.fadingEdges @@ -71,13 +72,15 @@ fun DisappearingMessages( } } - if (state.showSetButton) SlimOutlineButton( - stringResource(R.string.set), - modifier = Modifier - .contentDescription(R.string.AccessibilityId_setButton) - .align(Alignment.CenterHorizontally) - .padding(bottom = LocalDimensions.current.spacing), - onClick = callbacks::onSetClick - ) + if (state.showSetButton){ + PrimaryOutlineButton( + stringResource(R.string.set), + modifier = Modifier + .contentDescription(R.string.AccessibilityId_setButton) + .align(Alignment.CenterHorizontally) + .padding(bottom = LocalDimensions.current.spacing), + onClick = callbacks::onSetClick + ) + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessagesPreview.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessagesPreview.kt index d043cc314f..48d6539d8a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessagesPreview.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessagesPreview.kt @@ -27,21 +27,18 @@ fun PreviewStates( } class StatePreviewParameterProvider : PreviewParameterProvider<State> { - override val values = newConfigValues.filter { it.expiryType != ExpiryType.LEGACY } + newConfigValues.map { it.copy(isNewConfigEnabled = false) } + override val values = newConfigValues + newConfigValues.map { it.copy(isNewConfigEnabled = false) } private val newConfigValues get() = sequenceOf( // new 1-1 State(expiryMode = ExpiryMode.NONE), - State(expiryMode = ExpiryMode.Legacy(43200)), State(expiryMode = ExpiryMode.AfterRead(300)), State(expiryMode = ExpiryMode.AfterSend(43200)), // new group non-admin State(isGroup = true, isSelfAdmin = false), - State(isGroup = true, isSelfAdmin = false, expiryMode = ExpiryMode.Legacy(43200)), State(isGroup = true, isSelfAdmin = false, expiryMode = ExpiryMode.AfterSend(43200)), // new group admin State(isGroup = true), - State(isGroup = true, expiryMode = ExpiryMode.Legacy(43200)), State(isGroup = true, expiryMode = ExpiryMode.AfterSend(43200)), // new note-to-self State(isNoteToSelf = true), diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt index 205f28a078..0fce0036d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt @@ -404,7 +404,7 @@ class VisibleMessageView : FrameLayout { MessageStatusInfo( R.drawable.ic_delivery_status_sending, context.getColorFromAttr(R.attr.message_status_color), - R.string.messageStatusUploading + R.string.uploading ) } message.isSyncing || message.isResyncing -> diff --git a/app/src/main/res/layout/share_activity.xml b/app/src/main/res/layout/share_activity.xml index 4dec894d88..1d7ad6aed9 100644 --- a/app/src/main/res/layout/share_activity.xml +++ b/app/src/main/res/layout/share_activity.xml @@ -21,9 +21,11 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - <TextView android:layout_width="wrap_content" + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/share" + android:text="@string/shareToSession" android:fontFamily="sans-serif-medium" android:textSize="@dimen/very_large_font_size" android:layout_alignParentStart="true" diff --git a/app/src/test/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModelTest.kt index 9566d06c54..0dcab1ec0d 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModelTest.kt @@ -99,45 +99,6 @@ class DisappearingMessagesViewModelTest { ) } - @Test - fun `note to self, off, old config`() = runTest { - mock1on1(ExpiryMode.NONE, LOCAL_ADDRESS) - - val viewModel = createViewModel(isNewConfigEnabled = false) - - advanceUntilIdle() - - assertThat( - viewModel.state.value - ).isEqualTo( - State( - isGroup = false, - isSelfAdmin = true, - address = LOCAL_ADDRESS, - isNoteToSelf = true, - expiryMode = ExpiryMode.Legacy(0), - isNewConfigEnabled = false, - persistedMode = ExpiryMode.Legacy(0), - showDebugOptions = false - ) - ) - - assertThat( - viewModel.uiState.value - ).isEqualTo( - UiState( - OptionsCardData( - R.string.disappearingMessagesTimer, - typeOption(ExpiryMode.NONE, selected = false), - timeOption(ExpiryType.LEGACY, 12.hours), - timeOption(ExpiryType.LEGACY, 1.days), - timeOption(ExpiryType.LEGACY, 7.days), - timeOption(ExpiryType.LEGACY, 14.days) - ) - ) - ) - } - @Test fun `group, off, admin, new config`() = runTest { mockGroup(ExpiryMode.NONE, isAdmin = true) @@ -303,53 +264,6 @@ class DisappearingMessagesViewModelTest { ) } - @Test - fun `1-1 conversation, 12 hours legacy, old config`() = runTest { - val time = 12.hours - val someAddress = Address.fromSerialized("05---SOME---ADDRESS") - mock1on1(ExpiryType.LEGACY.mode(time), someAddress) - - val viewModel = createViewModel(isNewConfigEnabled = false) - - advanceUntilIdle() - - assertThat( - viewModel.state.value - ).isEqualTo( - State( - isGroup = false, - isSelfAdmin = true, - address = someAddress, - isNoteToSelf = false, - expiryMode = ExpiryType.LEGACY.mode(12.hours), - isNewConfigEnabled = false, - persistedMode = ExpiryType.LEGACY.mode(12.hours), - showDebugOptions = false - ) - ) - - assertThat( - viewModel.uiState.value - ).isEqualTo( - UiState( - OptionsCardData( - R.string.disappearingMessagesDeleteType, - typeOption(ExpiryMode.NONE), - typeOption(time, ExpiryType.LEGACY, selected = true), - typeOption(12.hours, ExpiryType.AFTER_READ, enabled = false), - typeOption(1.days, ExpiryType.AFTER_SEND, enabled = false) - ), - OptionsCardData( - R.string.disappearingMessagesTimer, - timeOption(ExpiryType.LEGACY, 12.hours, selected = true), - timeOption(ExpiryType.LEGACY, 1.days), - timeOption(ExpiryType.LEGACY, 7.days), - timeOption(ExpiryType.LEGACY, 14.days) - ) - ) - ) - } - @Test fun `1-1 conversation, 1 day after send, new config`() = runTest { val time = 1.days diff --git a/content-descriptions/src/main/res/values/strings.xml b/content-descriptions/src/main/res/values/strings.xml index 2b636e557c..541e62e29b 100644 --- a/content-descriptions/src/main/res/values/strings.xml +++ b/content-descriptions/src/main/res/values/strings.xml @@ -156,8 +156,4 @@ <string name="AccessibilityId_expand">Expand</string> <string name="AccessibilityId_mediaMessage">Media message</string> - <!-- LEGACY DISAPPEARING MESSAGES WILL BE NO MORE & THIS CAN BE REMOVED AFTER ONBOARDING GOES OUT! -ACL --> - <!-- Also, this is associated with the string: expiration_type_disappear_legacy --> - <string name="AccessibilityId_disappearingMessagesLegacy">Original version of disappearing messages.</string> - </resources> \ No newline at end of file diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/ExpiryMode.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/ExpiryMode.kt index 9761ce5083..9094754564 100644 --- a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/ExpiryMode.kt +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/ExpiryMode.kt @@ -4,7 +4,6 @@ import kotlin.time.Duration.Companion.seconds sealed class ExpiryMode(val expirySeconds: Long) { object NONE: ExpiryMode(0) - data class Legacy(private val seconds: Long = 0L): ExpiryMode(seconds) data class AfterSend(private val seconds: Long = 0L): ExpiryMode(seconds) data class AfterRead(private val seconds: Long = 0L): ExpiryMode(seconds) diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt index c9f91cf11c..51a07ca65d 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt @@ -74,14 +74,14 @@ object UpdateMessageBuilder { .format() } 2 -> { - Phrase.from(context, R.string.groupMemberTwoNew) + Phrase.from(context, R.string.groupMemberNewTwo) .put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0))) .put(OTHER_NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(1))) .format() } else -> { val newMemberCountMinusOne = newMemberCount - 1 - Phrase.from(context, R.string.groupMemberMoreNew) + Phrase.from(context, R.string.groupMemberNewMultiple) .put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0))) .put(COUNT_KEY, newMemberCountMinusOne) .format() diff --git a/libsession/src/main/res/values/strings.xml b/libsession/src/main/res/values/strings.xml index 9db042567c..cacaa32144 100644 --- a/libsession/src/main/res/values/strings.xml +++ b/libsession/src/main/res/values/strings.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name" translatable="false">Session</string> + <string name="notificationsHeaderMute">Notifications - Muted</string> <string name="about">About</string> <string name="accept">Accept</string> <string name="accountIDCopy">Copy Account ID</string> @@ -156,7 +157,7 @@ <string name="callsVoiceAndVideo">Voice and Video Calls</string> <string name="callsVoiceAndVideoBeta">Voice and Video Calls (Beta)</string> <string name="callsVoiceAndVideoModalDescription">Your IP is visible to your call partner and an Oxen Foundation server while using beta calls.</string> - <string name="callsVoiceAndVideoToggleDescription">Enables voice and video calls to and from other users</string> + <string name="callsVoiceAndVideoToggleDescription">Enables voice and video calls to and from other users.</string> <string name="callsYouCalled">You called {name}</string> <string name="callsYouMissedCallPermissions">You missed a call from <b>{name}</b> because you haven\'t enabled <b>Voice and Video Calls</b> in Privacy Settings.</string> <string name="cameraErrorNotFound">No camera found</string> @@ -192,8 +193,9 @@ <string name="clearMessagesNoteToSelfDescription">Are you sure you want to clear all Note to Self messages from your device?</string> <string name="close">Close</string> <string name="closeWindow">Close Window</string> - <string name="communityBanDescription">This will ban the selected user from this Community. Are you sure you want to continue?</string> + <string name="commitHashDesktop">Commit Hash: {hash}</string> <string name="communityBanDeleteDescription">This will ban the selected user from this Community and delete all their messages. Are you sure you want to continue?</string> + <string name="communityBanDescription">This will ban the selected user from this Community. Are you sure you want to continue?</string> <string name="communityEnterUrl">Enter Community URL</string> <string name="communityEnterUrlErrorInvalid">Invalid URL</string> <string name="communityEnterUrlErrorInvalidDescription">Please check the Community URL and try again.</string> @@ -228,7 +230,7 @@ <string name="conversationsAddedToHome">Added to home screen</string> <string name="conversationsAudioMessages">Audio Messages</string> <string name="conversationsAutoplayAudioMessage">Autoplay Audio Messages</string> - <string name="conversationsAutoplayAudioMessageDescription">Autoplay consecutively sent audio messages</string> + <string name="conversationsAutoplayAudioMessageDescription">Autoplay consecutively sent audio messages.</string> <string name="conversationsBlockedContacts">Blocked Contacts</string> <string name="conversationsCommunities">Communities</string> <string name="conversationsDelete">Delete Conversation</string> @@ -249,7 +251,7 @@ <string name="conversationsSendWithEnterKeyDescription">Tapping the Enter Key will send message instead of starting a new line.</string> <string name="conversationsSettingsAllMedia">All Media</string> <string name="conversationsSpellCheck">Spell Check</string> - <string name="conversationsSpellCheckDescription">Enable spell check when typing messages</string> + <string name="conversationsSpellCheckDescription">Enable spell check when typing messages.</string> <string name="conversationsStart">Start Conversation</string> <string name="copied">Copied</string> <string name="copy">Copy</string> @@ -328,6 +330,7 @@ <string name="disappearingMessagesTurnedOff"><b>{name}</b> has turned disappearing messages off. Messages they send will no longer disappear.</string> <string name="disappearingMessagesTurnedOffGroup"><b>{name}</b> has turned disappearing messages <b>off</b>.</string> <string name="disappearingMessagesTurnedOffYou"><b>You</b> turned <b>off</b> disappearing messages. Messages you send will no longer disappear.</string> + <string name="disappearingMessagesTurnedOffYouGroup"><b>You</b> turned <b>off</b> disappearing messages.</string> <string name="disappearingMessagesTypeRead">read</string> <string name="disappearingMessagesTypeSent">sent</string> <string name="disappearingMessagesUpdated"><b>{admin_name}</b> updated disappearing message settings.</string> @@ -363,6 +366,12 @@ <item quantity="one">And %1$d other has reacted %2$s to this message.</item> <item quantity="other">And %1$d others have reacted %2$s to this message.</item> </plurals> + <string name="emojiReactsHoverNameDesktop">{name} reacted with {emoji_name}</string> + <string name="emojiReactsHoverNameTwoDesktop">{name} and {other_name} reacted with {emoji_name}</string> + <string name="emojiReactsHoverTwoNameMultipleDesktop">{name} and <span>{count} others</span> reacted with {emoji_name}</string> + <string name="emojiReactsHoverYouNameDesktop">You reacted with {emoji_name}</string> + <string name="emojiReactsHoverYouNameMultipleDesktop">You and <span>{count} others</span> reacted with {emoji_name}</string> + <string name="emojiReactsHoverYouNameTwoDesktop">You and {name} reacted with {emoji_name}</string> <string name="emojiReactsNotification">Reacted to your message {emoji}</string> <string name="enable">Enable</string> <string name="errorConnection">Please check your internet connection and try again.</string> @@ -375,6 +384,7 @@ <string name="followSystemSettings">Follow system settings</string> <string name="from">From:</string> <string name="fullScreenToggle">Toggle Full Screen</string> + <string name="gif">GIF</string> <string name="giphyWarning">Giphy</string> <string name="giphyWarningDescription">{app_name} will connect to Giphy to provide search results. You will not have full metadata protection when sending GIFs.</string> <string name="groupAddMemberMaximum">Groups have a maximum of 100 members</string> @@ -409,23 +419,15 @@ <string name="groupMemberLeft"><b>{name}</b> left the group.</string> <string name="groupMemberLeftMultiple"><b>{name}</b> and <b>{count} others</b> left the group.</string> <string name="groupMemberLeftTwo"><b>{name}</b> and <b>{other_name}</b> left the group.</string> - <string name="groupMemberMoreNew"><b>{name}</b> and <b>{count} others</b> joined the group.</string> - <string name="groupMemberNew"><b>{name}</b> joined the group.</string> + <string name="groupMemberNew"><b>{name}</b> was invited to join the group.</string> <string name="groupMemberNewHistory"><b>{name}</b> was invited to join the group. Chat history was shared.</string> <string name="groupMemberNewHistoryMultiple"><b>{name}</b> and <b>{count} others</b> were invited to join the group. Chat history was shared.</string> <string name="groupMemberNewHistoryTwo"><b>{name}</b> and <b>{other_name}</b> were invited to join the group. Chat history was shared.</string> - <string name="groupMemberNewMultiple"><b>{name}</b> and <b>{count} others</b> joined the group.</string> + <string name="groupMemberNewMultiple"><b>{name}</b> and <b>{count} others</b> were invited to join the group.</string> <string name="groupMemberNewTwo"><b>{name}</b> and <b>{other_name}</b> were invited to join the group.</string> - <string name="groupMemberNewYouHistory"><b>{name}</b> was invited to join the group. Chat history was shared.</string> <string name="groupMemberNewYouHistoryMultiple"><b>You</b> and <b>{count} others</b> were invited to join the group. Chat history was shared.</string> <string name="groupMemberNewYouHistoryTwo"><b>You</b> and <b>{name}</b> were invited to join the group. Chat history was shared.</string> - <string name="groupMemberNewYouMultiple"><b>You</b> and <b>{count} others</b> were invited to join the group.</string> - <string name="groupMemberNewYouTwo"><b>You</b> and <b>{name}</b> were invited to join the group.</string> - <string name="groupMemberYouAndMoreNew"><b>You</b> and <b>{count} others</b> joined the group.</string> - <string name="groupMemberYouAndOtherNew"><b>You</b> and <b>{other_name}</b> joined the group.</string> - <string name="groupMemberTwoNew"><b>{name}</b> and <b>{other_name}</b> joined the group.</string> <string name="groupMemberYouLeft"><b>You</b> left the group.</string> - <string name="groupMemberYouNew"><b>You</b> joined the group.</string> <string name="groupMembers">Group Members</string> <string name="groupMembersNone">There are no other members in this group.</string> <string name="groupName">Group Name</string> @@ -440,9 +442,8 @@ <string name="groupPromotedYouMultiple"><b>You</b> and <b>{count} others</b> were promoted to Admin.</string> <string name="groupPromotedYouTwo"><b>You</b> and <b>{name}</b> were promoted to Admin.</string> <string name="groupRemoveDescription">Would you like to remove <b>{name}</b> from <b>{group_name}</b>?</string> - <string name="groupRemoveDescriptionTwo">Would you like to remove <b>{name}</b> and <b>{other_name}</b> from <b>{group_name}</b>?</string> - <string name="groupRemoveMessages">Remove user and their messages</string> <string name="groupRemoveDescriptionMultiple">Would you like to remove <b>{name}</b> and <b>{count} others</b> from <b>{group_name}</b>?</string> + <string name="groupRemoveDescriptionTwo">Would you like to remove <b>{name}</b> and <b>{other_name}</b> from <b>{group_name}</b>?</string> <plurals name="groupRemoveMessages"> <item quantity="one">Remove user and their messages</item> <item quantity="other">Remove users and their messages</item> @@ -504,6 +505,7 @@ <string name="loading">Loading...</string> <string name="lockApp">Lock App</string> <string name="lockAppDescription">Require fingerprint, PIN, pattern or password to unlock {app_name}.</string> + <string name="lockAppDescriptionIos">Require Touch ID, Face ID or your passcode to unlock {app_name}.</string> <string name="lockAppEnablePasscode">You must enable a passcode in your iOS Settings in order to use Screen Lock.</string> <string name="lockAppLocked">{app_name} is locked</string> <string name="lockAppQuickResponse">Quick response unavailable when {app_name} is locked!</string> @@ -602,6 +604,8 @@ <string name="notificationsFastModeDescription">You\'ll be notified of new messages reliably and immediately using Google\'s notification Servers.</string> <string name="notificationsFastModeDescriptionIos">You\'ll be notified of new messages reliably and immediately using Apple\'s notification Servers.</string> <string name="notificationsGoToDevice">Go to device notification settings</string> + <string name="notificationsHeaderAllMessages">Notifications - All</string> + <string name="notificationsHeaderMentionsOnly">Notifications - Mentions Only</string> <string name="notificationsIosGroup">{name} to {conversation_name}</string> <string name="notificationsIosRestart">You may have received messages while your {device} was restarting.</string> <string name="notificationsLedColor">LED color</string> @@ -657,7 +661,7 @@ <string name="passwordCurrentIncorrect">Your current password is incorrect.</string> <string name="passwordDescription">Require password to unlock {app_name}.</string> <string name="passwordEnter">Enter password</string> - <string name="passwordEnterCurrent">Please enter your current password.</string> + <string name="passwordEnterCurrent">Please enter your current password</string> <string name="passwordEnterNew">Please enter your new password</string> <string name="passwordError">Password must only contain letters, numbers and symbols</string> <string name="passwordErrorLength">Password must be between 6 and 64 characters long</string> @@ -672,14 +676,16 @@ <string name="paste">Paste</string> <string name="permissionsAppleMusic">{app_name} needs to use Apple Music to play media attachments.</string> <string name="permissionsAutoUpdate">Auto Update</string> - <string name="permissionsAutoUpdateDescription">Automatically check for updates on startup</string> + <string name="permissionsAutoUpdateDescription">Automatically check for updates on startup.</string> <string name="permissionsFaceId">The screen lock feature on {app_name} uses Face ID.</string> <string name="permissionsKeepInSystemTray">Keep in System Tray</string> <string name="permissionsKeepInSystemTrayDescription">{app_name} continues running in the background when you close the window</string> <string name="permissionsLibrary">{app_name} needs photo library access to continue. You can enable access in the iOS settings.</string> <string name="permissionsMicrophone">Microphone</string> <string name="permissionsMicrophoneAccessRequired">{app_name} needs microphone access to send audio messages, but it has been permanently denied. Please continue to app settings, select \"Permissions\", and enable \"Microphone\".</string> - <string name="permissionsMicrophoneDescription">Allow access to microphone</string> + <string name="permissionsMicrophoneAccessRequiredDesktop">You can enable microphone access in {app_name}\'s privacy settings</string> + <string name="permissionsMicrophoneAccessRequiredIos">{app_name} needs microphone access to make calls and record audio messages.</string> + <string name="permissionsMicrophoneDescription">Allow access to microphone.</string> <string name="permissionsRequired">Permission required</string> <string name="permissionsStorageDenied">{app_name} needs storage access so you can send and save attachments. Tap Settings -> Permissions, and turn \"Files and media\" on.</string> <string name="permissionsStorageDeniedLegacy">{app_name} needs storage access so you can send and save attachments. Tap Settings -> Permissions, and turn \"Storage\" on.</string> @@ -722,10 +728,10 @@ <string name="recoveryPasswordErrorTitle">Incorrect Recovery Password</string> <string name="recoveryPasswordExplanation">To load your account, enter your recovery password.</string> <string name="recoveryPasswordHidePermanently">Hide Recovery Password Permanently</string> - <string name="recoveryPasswordHidePermanentlyDescription1">Without your recovery password, you cannot load your account on new devices.\n\nWe strongly recommend you save your recovery password in a safe and secure place before continuing.</string> + <string name="recoveryPasswordHidePermanentlyDescription1">Without your recovery password, you cannot load your account on new devices. \n\nWe strongly recommend you save your recovery password in a safe and secure place before continuing.</string> <string name="recoveryPasswordHidePermanentlyDescription2">Are you sure you want to permanently hide your recovery password on this device? This cannot be undone.</string> <string name="recoveryPasswordHideRecoveryPassword">Hide Recovery Password</string> - <string name="recoveryPasswordHideRecoveryPasswordDescription">Permanently hide your recover password on this device.</string> + <string name="recoveryPasswordHideRecoveryPasswordDescription">Permanently hide your recovery password on this device.</string> <string name="recoveryPasswordRestoreDescription">Enter your recovery password to load your account. If you haven\'t saved it, you can find it in your app settings.</string> <string name="recoveryPasswordView">View Password</string> <string name="recoveryPasswordWarningSendDescription">This is your recovery password. If you send it to someone they\'ll have full access to your account.</string> @@ -770,7 +776,6 @@ <string name="sessionHelp">Help</string> <string name="sessionInviteAFriend">Invite a Friend</string> <string name="sessionMessageRequests">Message Requests</string> - <string name="sessionNetworkSent">{token_name_long} ({<span>{token_name_short}</span>)</string> <string name="sessionNotifications">Notifications</string> <string name="sessionPermissions">Permissions</string> <string name="sessionPrivacy">Privacy</string> @@ -782,18 +787,19 @@ <string name="shareAccountIdDescription">Invite your friend to chat with you on {app_name} by sharing your Account ID with them.</string> <string name="shareAccountIdDescriptionCopied">Share with your friends wherever you usually speak with them — then move the conversation here.</string> <string name="shareExtensionDatabaseError">There is an issue opening the database. Please restart the app and try again.</string> - <string name="shareToSession">Share to {app_Name}</string> + <string name="shareToSession">Share to {app_name}</string> <string name="show">Show</string> <string name="showAll">Show All</string> <string name="showLess">Show Less</string> <string name="stickers">Stickers</string> <string name="supportGoTo">Go to Support Page</string> + <string name="systemInformationDesktop">System Information: {information}</string> <string name="theContinue">Continue</string> <string name="theDefault">Default</string> <string name="theError">Error</string> <string name="tryAgain">Try Again</string> <string name="typingIndicators">Typing Indicators</string> - <string name="typingIndicatorsDescription">See and share typing indicators</string> + <string name="typingIndicatorsDescription">See and share typing indicators.</string> <string name="undo">Undo</string> <string name="unknown">Unknown</string> <string name="updateApp">App updates</string> @@ -821,18 +827,4 @@ <string name="window">Window</string> <string name="yes">Yes</string> <string name="you">You</string> - - <!-- USED as text for the Legacy ExpiryType enum defined in State.kt - however, I don' think - there's any way to set "Legacy" disappearing messages any more, that's gone. Although we - may still need to cater to _seeing_ Legacy disappearing messages from clients which haven't - been updated, perhaps? - Figma: https://www.figma.com/design/tEgZ8ujg76DdtPwEJv8zFp/Disappearing-Messages?t=25H0THKH9VADKm9s-0 - Morgan 2024/07/31: "once the Onboarding release has gone out we can remove the 'Legacy' - disappearing message settings (there is a PR for iOS to do so already)" - --> - <string name="expiration_type_disappear_legacy">Legacy</string> - - <!-- Missing from CrowdIn circa 2024-08-22 --> - <string name="messageStatusUploading">Uploading</string> - </resources> \ No newline at end of file