mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-11 12:47:25 +00:00
Strings updates
Latest strings Removed the LEGACY disappearing messages New title for Share activity (also formatted the lines)
This commit is contained in:
@@ -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<Uri, Void, Uri> {
|
||||
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<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
)
|
||||
|
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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),
|
||||
|
@@ -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 ->
|
||||
|
@@ -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"
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user