From 2f4c605613e54cefb3c4672ce409e0346f099587 Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Wed, 4 Sep 2024 10:15:58 +1000 Subject: [PATCH] Strings updates Latest strings Removed the LEGACY disappearing messages New title for Share activity (also formatted the lines) --- .../thoughtcrime/securesms/ShareActivity.java | 487 +++++++++--------- .../DisappearingMessagesViewModel.kt | 8 +- .../disappearingmessages/State.kt | 20 +- .../disappearingmessages/ui/Adapter.kt | 8 +- .../ui/DisappearingMessages.kt | 19 +- .../ui/DisappearingMessagesPreview.kt | 5 +- .../v2/messages/VisibleMessageView.kt | 2 +- app/src/main/res/layout/share_activity.xml | 6 +- .../DisappearingMessagesViewModelTest.kt | 86 ---- .../src/main/res/values/strings.xml | 4 - .../libsession_util/util/ExpiryMode.kt | 1 - .../utilities/UpdateMessageBuilder.kt | 4 +- libsession/src/main/res/values/strings.xml | 68 ++- 13 files changed, 306 insertions(+), 412 deletions(-) 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(); + 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"; + 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; + 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); - } - - 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(); - } - } - }); - } + getIntent().putExtra(ContactSelectionListFragment.REFRESHABLE, false); - private void initializeMedia() { - final Context context = this; - isPassingAlongMedia = false; + setContentView(R.layout.share_activity); - 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); - } - } - - 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(); - } - - boolean hasResolvedDestination = threadId != -1 && address != null && distributionType != -1; - - 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); - } - } - - 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); - - 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"); - } - - return intent; - } - - 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()); - } - - @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 { - private final Context context; - - ResolveMediaTask(Context context) { - this.context = context; + initializeToolbar(); + initializeResources(); + initializeSearch(); + initializeMedia(); } @Override - protected Uri doInBackground(Uri... uris) { - try { - if (uris.length != 1 || uris[0] == null) { - return null; - } + protected void onNewIntent(Intent intent) { + Log.i(TAG, "onNewIntent()"); + super.onNewIntent(intent); + setIntent(intent); + initializeMedia(); + } - InputStream inputStream; + @Override + public void onPause() { + super.onPause(); + if (!isPassingAlongMedia && resolvedExtra != null) { + BlobProvider.getInstance().delete(this, resolvedExtra); - 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); + if (!isFinishing()) { + finish(); } - } - } 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); + 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() { + 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() + ); + } + + 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 + 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); + } + } + + 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(); + } + + boolean hasResolvedDestination = threadId != -1 && address != null && distributionType != -1; + + 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); + } + } + + 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); + + 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"); + } + + return intent; + } + + 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()); + } + + @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 { + 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? = 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? { // 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? { } 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 = - 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 { - 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"> - Expand Media message - - - Original version of disappearing messages. - \ 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 @@ Session + Notifications - Muted About Accept Copy Account ID @@ -156,7 +157,7 @@ Voice and Video Calls Voice and Video Calls (Beta) Your IP is visible to your call partner and an Oxen Foundation server while using beta calls. - Enables voice and video calls to and from other users + Enables voice and video calls to and from other users. You called {name} You missed a call from {name} because you haven\'t enabled Voice and Video Calls in Privacy Settings. No camera found @@ -192,8 +193,9 @@ Are you sure you want to clear all Note to Self messages from your device? Close Close Window - This will ban the selected user from this Community. Are you sure you want to continue? + Commit Hash: {hash} This will ban the selected user from this Community and delete all their messages. Are you sure you want to continue? + This will ban the selected user from this Community. Are you sure you want to continue? Enter Community URL Invalid URL Please check the Community URL and try again. @@ -228,7 +230,7 @@ Added to home screen Audio Messages Autoplay Audio Messages - Autoplay consecutively sent audio messages + Autoplay consecutively sent audio messages. Blocked Contacts Communities Delete Conversation @@ -249,7 +251,7 @@ Tapping the Enter Key will send message instead of starting a new line. All Media Spell Check - Enable spell check when typing messages + Enable spell check when typing messages. Start Conversation Copied Copy @@ -328,6 +330,7 @@ {name} has turned disappearing messages off. Messages they send will no longer disappear. {name} has turned disappearing messages off. You turned off disappearing messages. Messages you send will no longer disappear. + You turned off disappearing messages. read sent {admin_name} updated disappearing message settings. @@ -363,6 +366,12 @@ And %1$d other has reacted %2$s to this message. And %1$d others have reacted %2$s to this message. + {name} reacted with {emoji_name} + {name} and {other_name} reacted with {emoji_name} + {name} and {count} others reacted with {emoji_name} + You reacted with {emoji_name} + You and {count} others reacted with {emoji_name} + You and {name} reacted with {emoji_name} Reacted to your message {emoji} Enable Please check your internet connection and try again. @@ -375,6 +384,7 @@ Follow system settings From: Toggle Full Screen + GIF Giphy {app_name} will connect to Giphy to provide search results. You will not have full metadata protection when sending GIFs. Groups have a maximum of 100 members @@ -409,23 +419,15 @@ {name} left the group. {name} and {count} others left the group. {name} and {other_name} left the group. - {name} and {count} others joined the group. - {name} joined the group. + {name} was invited to join the group. {name} was invited to join the group. Chat history was shared. {name} and {count} others were invited to join the group. Chat history was shared. {name} and {other_name} were invited to join the group. Chat history was shared. - {name} and {count} others joined the group. + {name} and {count} others were invited to join the group. {name} and {other_name} were invited to join the group. - {name} was invited to join the group. Chat history was shared. You and {count} others were invited to join the group. Chat history was shared. You and {name} were invited to join the group. Chat history was shared. - You and {count} others were invited to join the group. - You and {name} were invited to join the group. - You and {count} others joined the group. - You and {other_name} joined the group. - {name} and {other_name} joined the group. You left the group. - You joined the group. Group Members There are no other members in this group. Group Name @@ -440,9 +442,8 @@ You and {count} others were promoted to Admin. You and {name} were promoted to Admin. Would you like to remove {name} from {group_name}? - Would you like to remove {name} and {other_name} from {group_name}? - Remove user and their messages Would you like to remove {name} and {count} others from {group_name}? + Would you like to remove {name} and {other_name} from {group_name}? Remove user and their messages Remove users and their messages @@ -504,6 +505,7 @@ Loading... Lock App Require fingerprint, PIN, pattern or password to unlock {app_name}. + Require Touch ID, Face ID or your passcode to unlock {app_name}. You must enable a passcode in your iOS Settings in order to use Screen Lock. {app_name} is locked Quick response unavailable when {app_name} is locked! @@ -602,6 +604,8 @@ You\'ll be notified of new messages reliably and immediately using Google\'s notification Servers. You\'ll be notified of new messages reliably and immediately using Apple\'s notification Servers. Go to device notification settings + Notifications - All + Notifications - Mentions Only {name} to {conversation_name} You may have received messages while your {device} was restarting. LED color @@ -657,7 +661,7 @@ Your current password is incorrect. Require password to unlock {app_name}. Enter password - Please enter your current password. + Please enter your current password Please enter your new password Password must only contain letters, numbers and symbols Password must be between 6 and 64 characters long @@ -672,14 +676,16 @@ Paste {app_name} needs to use Apple Music to play media attachments. Auto Update - Automatically check for updates on startup + Automatically check for updates on startup. The screen lock feature on {app_name} uses Face ID. Keep in System Tray {app_name} continues running in the background when you close the window {app_name} needs photo library access to continue. You can enable access in the iOS settings. Microphone {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\". - Allow access to microphone + You can enable microphone access in {app_name}\'s privacy settings + {app_name} needs microphone access to make calls and record audio messages. + Allow access to microphone. Permission required {app_name} needs storage access so you can send and save attachments. Tap Settings -> Permissions, and turn \"Files and media\" on. {app_name} needs storage access so you can send and save attachments. Tap Settings -> Permissions, and turn \"Storage\" on. @@ -722,10 +728,10 @@ Incorrect Recovery Password To load your account, enter your recovery password. Hide Recovery Password Permanently - 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. + 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. Are you sure you want to permanently hide your recovery password on this device? This cannot be undone. Hide Recovery Password - Permanently hide your recover password on this device. + Permanently hide your recovery password on this device. Enter your recovery password to load your account. If you haven\'t saved it, you can find it in your app settings. View Password This is your recovery password. If you send it to someone they\'ll have full access to your account. @@ -770,7 +776,6 @@ Help Invite a Friend Message Requests - {token_name_long} ({{token_name_short}) Notifications Permissions Privacy @@ -782,18 +787,19 @@ Invite your friend to chat with you on {app_name} by sharing your Account ID with them. Share with your friends wherever you usually speak with them — then move the conversation here. There is an issue opening the database. Please restart the app and try again. - Share to {app_Name} + Share to {app_name} Show Show All Show Less Stickers Go to Support Page + System Information: {information} Continue Default Error Try Again Typing Indicators - See and share typing indicators + See and share typing indicators. Undo Unknown App updates @@ -821,18 +827,4 @@ Window Yes You - - - Legacy - - - Uploading - \ No newline at end of file