mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-03 07:42:27 +00:00
Merge branch 'dev' of github.com:loki-project/loki-messenger-android into dev
This commit is contained in:
@@ -16,17 +16,18 @@
|
||||
*/
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.ProcessLifecycleOwner;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.multidex.MultiDexApplication;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.ProcessLifecycleOwner;
|
||||
|
||||
import com.google.firebase.iid.FirebaseInstanceId;
|
||||
|
||||
@@ -72,6 +73,7 @@ import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol;
|
||||
import org.thoughtcrime.securesms.loki.protocol.SessionRequestMessageSendJob;
|
||||
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation;
|
||||
import org.thoughtcrime.securesms.loki.utilities.Broadcaster;
|
||||
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities;
|
||||
import org.thoughtcrime.securesms.notifications.DefaultMessageNotifier;
|
||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
@@ -114,10 +116,10 @@ import org.whispersystems.signalservice.loki.protocol.closedgroups.SharedSenderK
|
||||
import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager;
|
||||
import org.whispersystems.signalservice.loki.protocol.meta.SessionMetaProtocol;
|
||||
import org.whispersystems.signalservice.loki.protocol.meta.TTLUtilities;
|
||||
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.DeviceLink;
|
||||
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.MultiDeviceProtocol;
|
||||
import org.whispersystems.signalservice.loki.protocol.sessionmanagement.SessionManagementProtocol;
|
||||
import org.whispersystems.signalservice.loki.protocol.sessionmanagement.SessionManagementProtocolDelegate;
|
||||
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.DeviceLink;
|
||||
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.MultiDeviceProtocol;
|
||||
import org.whispersystems.signalservice.loki.protocol.shelved.syncmessages.SyncMessagesProtocol;
|
||||
|
||||
import java.io.File;
|
||||
@@ -143,11 +145,10 @@ import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant;
|
||||
*
|
||||
* @author Moxie Marlinspike
|
||||
*/
|
||||
public class ApplicationContext extends MultiDexApplication implements DependencyInjector, DefaultLifecycleObserver, LokiP2PAPIDelegate,
|
||||
public class ApplicationContext extends Application implements DependencyInjector, DefaultLifecycleObserver, LokiP2PAPIDelegate,
|
||||
SessionManagementProtocolDelegate, SharedSenderKeysImplementationDelegate {
|
||||
|
||||
private static final String TAG = ApplicationContext.class.getSimpleName();
|
||||
private final static int OK_HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||
|
||||
private ExpiringMessageManager expiringMessageManager;
|
||||
private TypingStatusRepository typingStatusRepository;
|
||||
@@ -215,6 +216,8 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
||||
publicChatManager = new PublicChatManager(this);
|
||||
updateOpenGroupProfilePicturesIfNeeded();
|
||||
registerForFCMIfNeeded(false);
|
||||
// Set application UI mode (day/night theme) to the user selected one.
|
||||
UiModeUtilities.setupUiModeToUserSelected(this);
|
||||
// ========
|
||||
initializeJobManager();
|
||||
initializeMessageRetrieval();
|
||||
|
||||
@@ -247,7 +247,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
|
||||
Drawable devices = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.ic_laptop_white_24dp));
|
||||
Drawable advanced = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.ic_advanced_white_24dp));
|
||||
Drawable publicKey = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.ic_textsms_24dp));
|
||||
Drawable qrCode = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.icon_qr_code));
|
||||
Drawable qrCode = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.ic_qr_code_24));
|
||||
Drawable linkDevice = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.icon_link));
|
||||
Drawable seed = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.icon_seedling));
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ import java.util.Date;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
|
||||
public abstract class BaseActionBarActivity extends AppCompatActivity {
|
||||
private static final String TAG = BaseActionBarActivity.class.getSimpleName();
|
||||
private BroadcastReceiver broadcastReceiver;
|
||||
@@ -122,6 +121,9 @@ public abstract class BaseActionBarActivity extends AppCompatActivity {
|
||||
ActivityCompat.startActivity(this, intent, bundle);
|
||||
}
|
||||
|
||||
//TODO AC: I don't think we need this method,
|
||||
// setting any colors directly will most likely clash with the current theme.
|
||||
@Deprecated
|
||||
@TargetApi(VERSION_CODES.LOLLIPOP)
|
||||
protected void setStatusBarColor(int color) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
|
||||
@@ -455,7 +455,7 @@ public class ConversationListFragment extends Fragment
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_select_all: handleSelectAllThreads(); return true;
|
||||
case R.id.menu_delete_selected: handleDeleteAllSelected(); return true;
|
||||
case R.id.menu_archive_selected: handleArchiveAllSelected(); return true;
|
||||
// case R.id.menu_archive_selected: handleArchiveAllSelected(); return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -48,8 +48,6 @@ import org.thoughtcrime.securesms.profiles.SystemProfileUtil;
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicRegistrationTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
@@ -85,7 +83,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
||||
public static final String NEXT_INTENT = "next_intent";
|
||||
public static final String EXCLUDE_SYSTEM = "exclude_system";
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicRegistrationTheme();
|
||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
|
||||
@Inject SignalServiceAccountManager accountManager;
|
||||
@@ -107,7 +104,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
||||
public void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
|
||||
dynamicTheme.onCreate(this);
|
||||
dynamicLanguage.onCreate(this);
|
||||
|
||||
setContentView(R.layout.profile_create_activity);
|
||||
@@ -125,7 +121,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
dynamicLanguage.onResume(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,21 +25,6 @@ import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.Loader;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
@@ -49,7 +34,23 @@ import android.view.Window;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.Loader;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.codewaves.stickyheadergrid.StickyHeaderGridLayoutManager;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
|
||||
@@ -62,8 +63,6 @@ import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.AttachmentUtil;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@@ -87,7 +86,6 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
|
||||
|
||||
public static final String ADDRESS_EXTRA = "address";
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
|
||||
private Toolbar toolbar;
|
||||
@@ -97,14 +95,12 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme.onCreate(this);
|
||||
dynamicLanguage.onCreate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle, boolean ready) {
|
||||
setContentView(R.layout.media_overview_activity);
|
||||
getWindow().setNavigationBarColor(getResources().getColor(R.color.navigation_bar_background));
|
||||
|
||||
initializeResources();
|
||||
initializeToolbar();
|
||||
@@ -116,7 +112,6 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
dynamicLanguage.onResume(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.thoughtcrime.securesms;
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -150,7 +152,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
|
||||
@Override
|
||||
public void onModified(Recipient recipient) {
|
||||
Util.runOnMain(this::initializeActionBar);
|
||||
Util.runOnMain(this::updateActionBar);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,7 +166,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void initializeActionBar() {
|
||||
private void updateActionBar() {
|
||||
MediaItem mediaItem = getCurrentMediaItem();
|
||||
|
||||
if (mediaItem != null) {
|
||||
@@ -222,6 +224,9 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
caption = findViewById(R.id.media_preview_caption);
|
||||
captionContainer = findViewById(R.id.media_preview_caption_container);
|
||||
playbackControlsContainer = findViewById(R.id.media_preview_playback_controls_container);
|
||||
|
||||
|
||||
setSupportActionBar(findViewById(R.id.toolbar));
|
||||
}
|
||||
|
||||
private void initializeResources() {
|
||||
@@ -476,7 +481,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
MediaItem item = adapter.getMediaItemFor(position);
|
||||
if (item.recipient != null) item.recipient.addListener(MediaPreviewActivity.this);
|
||||
viewModel.setActiveAlbumRailItem(MediaPreviewActivity.this, position);
|
||||
initializeActionBar();
|
||||
updateActionBar();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ import org.thoughtcrime.securesms.crypto.InvalidPassphraseException;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.util.DynamicIntroTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
@@ -70,7 +69,6 @@ public class PassphrasePromptActivity extends PassphraseActivity {
|
||||
|
||||
private static final String TAG = PassphrasePromptActivity.class.getSimpleName();
|
||||
|
||||
private DynamicIntroTheme dynamicTheme = new DynamicIntroTheme();
|
||||
private DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
|
||||
private View passphraseAuthContainer;
|
||||
@@ -92,7 +90,6 @@ public class PassphrasePromptActivity extends PassphraseActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
Log.i(TAG, "onCreate()");
|
||||
dynamicTheme.onCreate(this);
|
||||
dynamicLanguage.onCreate(this);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
|
||||
@@ -105,7 +102,6 @@ public class PassphrasePromptActivity extends PassphraseActivity {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
dynamicLanguage.onResume(this);
|
||||
|
||||
setLockTypeVisibility();
|
||||
|
||||
@@ -74,7 +74,6 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
|
||||
public static final String EXTRA_ADDRESS_MARSHALLED = "address_marshalled";
|
||||
public static final String EXTRA_DISTRIBUTION_TYPE = "distribution_type";
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
|
||||
private ContactSelectionListFragment contactsFragment;
|
||||
@@ -87,7 +86,6 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme.onCreate(this);
|
||||
dynamicLanguage.onCreate(this);
|
||||
}
|
||||
|
||||
@@ -121,7 +119,6 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
|
||||
public void onResume() {
|
||||
Log.i(TAG, "onResume()");
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
dynamicLanguage.onResume(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
|
||||
@@ -19,8 +18,6 @@ public class TransportOption implements Parcelable {
|
||||
TEXTSECURE
|
||||
}
|
||||
|
||||
private final int drawable;
|
||||
private final int backgroundColor;
|
||||
private final @NonNull String text;
|
||||
private final @NonNull Type type;
|
||||
private final @NonNull String composeHint;
|
||||
@@ -29,19 +26,15 @@ public class TransportOption implements Parcelable {
|
||||
private final @NonNull Optional<Integer> simSubscriptionId;
|
||||
|
||||
public TransportOption(@NonNull Type type,
|
||||
@DrawableRes int drawable,
|
||||
int backgroundColor,
|
||||
@NonNull String text,
|
||||
@NonNull String composeHint,
|
||||
@NonNull CharacterCalculator characterCalculator)
|
||||
{
|
||||
this(type, drawable, backgroundColor, text, composeHint, characterCalculator,
|
||||
this(type, text, composeHint, characterCalculator,
|
||||
Optional.<CharSequence>absent(), Optional.<Integer>absent());
|
||||
}
|
||||
|
||||
public TransportOption(@NonNull Type type,
|
||||
@DrawableRes int drawable,
|
||||
int backgroundColor,
|
||||
@NonNull String text,
|
||||
@NonNull String composeHint,
|
||||
@NonNull CharacterCalculator characterCalculator,
|
||||
@@ -49,8 +42,6 @@ public class TransportOption implements Parcelable {
|
||||
@NonNull Optional<Integer> simSubscriptionId)
|
||||
{
|
||||
this.type = type;
|
||||
this.drawable = drawable;
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.text = text;
|
||||
this.composeHint = composeHint;
|
||||
this.characterCalculator = characterCalculator;
|
||||
@@ -60,8 +51,6 @@ public class TransportOption implements Parcelable {
|
||||
|
||||
TransportOption(Parcel in) {
|
||||
this(Type.valueOf(in.readString()),
|
||||
in.readInt(),
|
||||
in.readInt(),
|
||||
in.readString(),
|
||||
in.readString(),
|
||||
CharacterCalculator.readFromParcel(in),
|
||||
@@ -85,14 +74,6 @@ public class TransportOption implements Parcelable {
|
||||
return characterCalculator.calculateCharacters(messageBody);
|
||||
}
|
||||
|
||||
public @DrawableRes int getDrawable() {
|
||||
return R.drawable.ic_arrow_up;
|
||||
}
|
||||
|
||||
public int getBackgroundColor() {
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
public @NonNull String getComposeHint() {
|
||||
return composeHint;
|
||||
}
|
||||
@@ -119,8 +100,6 @@ public class TransportOption implements Parcelable {
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(type.name());
|
||||
dest.writeInt(drawable);
|
||||
dest.writeInt(backgroundColor);
|
||||
dest.writeString(text);
|
||||
dest.writeString(composeHint);
|
||||
CharacterCalculator.writeToParcel(dest, characterCalculator);
|
||||
|
||||
@@ -2,6 +2,10 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -147,8 +151,7 @@ public class TransportOptions {
|
||||
private List<TransportOption> initializeAvailableTransports(boolean isMediaMessage) {
|
||||
List<TransportOption> results = new LinkedList<>();
|
||||
|
||||
results.add(new TransportOption(Type.TEXTSECURE, R.drawable.ic_send_push_white_24dp,
|
||||
context.getResources().getColor(R.color.textsecure_primary),
|
||||
results.add(new TransportOption(Type.TEXTSECURE,
|
||||
context.getString(R.string.ConversationActivity_transport_signal),
|
||||
context.getString(R.string.conversation_activity__type_message_push),
|
||||
new PushCharacterCalculator()));
|
||||
@@ -171,13 +174,11 @@ public class TransportOptions {
|
||||
}
|
||||
|
||||
if (subscriptions.size() < 2) {
|
||||
results.add(new TransportOption(Type.SMS, R.drawable.ic_send_sms_white_24dp,
|
||||
context.getResources().getColor(R.color.grey_600),
|
||||
results.add(new TransportOption(Type.SMS,
|
||||
text, composeHint, characterCalculator));
|
||||
} else {
|
||||
for (SubscriptionInfoCompat subscriptionInfo : subscriptions) {
|
||||
results.add(new TransportOption(Type.SMS, R.drawable.ic_send_sms_white_24dp,
|
||||
context.getResources().getColor(R.color.grey_600),
|
||||
results.add(new TransportOption(Type.SMS,
|
||||
text, composeHint, characterCalculator,
|
||||
Optional.of(subscriptionInfo.getDisplayName()),
|
||||
Optional.of(subscriptionInfo.getSubscriptionId())));
|
||||
@@ -202,6 +203,6 @@ public class TransportOptions {
|
||||
}
|
||||
|
||||
public interface OnTransportChangedListener {
|
||||
public void onChange(TransportOption newTransport, boolean manuallySelected);
|
||||
void onChange(TransportOption newTransport, boolean manuallySelected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -10,6 +8,8 @@ import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.util.List;
|
||||
@@ -60,8 +60,7 @@ public class TransportOptionsAdapter extends BaseAdapter {
|
||||
TextView textView = ViewUtil.findById(convertView, R.id.text);
|
||||
TextView subtextView = ViewUtil.findById(convertView, R.id.subtext);
|
||||
|
||||
imageView.getBackground().setColorFilter(transport.getBackgroundColor(), Mode.MULTIPLY);
|
||||
imageView.setImageResource(transport.getDrawable());
|
||||
imageView.setImageResource(R.drawable.ic_arrow_up_circle_24);
|
||||
textView.setText(transport.getDescription());
|
||||
|
||||
if (transport.getSimName().isPresent()) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.widget.LinearLayout;
|
||||
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -41,7 +42,10 @@ public class ConversationTypingView extends LinearLayout {
|
||||
}
|
||||
|
||||
Recipient typist = typists.get(0);
|
||||
bubble.getBackground().setColorFilter(getResources().getColor(R.color.received_message_background), PorterDuff.Mode.MULTIPLY);
|
||||
|
||||
bubble.getBackground().setColorFilter(
|
||||
ThemeUtil.getThemedColor(getContext(), R.attr.message_received_background_color),
|
||||
PorterDuff.Mode.MULTIPLY);
|
||||
|
||||
if (isGroupThread) {
|
||||
avatar.setAvatar(glideRequests, typist, false);
|
||||
|
||||
@@ -210,7 +210,8 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
||||
|
||||
// We use the raw color resource because Android 4.x was struggling with tints here
|
||||
quoteBarView.setImageResource(R.color.accent);
|
||||
mainView.setBackgroundColor(getResources().getColor(outgoing ? R.color.received_message_background : R.color.sent_message_background));
|
||||
mainView.setBackgroundColor(ThemeUtil.getThemedColor(getContext(),
|
||||
outgoing ? R.attr.message_received_background_color : R.attr.message_sent_background_color));
|
||||
}
|
||||
|
||||
private void setQuoteText(@Nullable String body, @NonNull SlideDeck attachments) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.thoughtcrime.securesms.components;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.AppCompatImageButton;
|
||||
import android.util.AttributeSet;
|
||||
@@ -10,14 +12,16 @@ import org.thoughtcrime.securesms.TransportOption;
|
||||
import org.thoughtcrime.securesms.TransportOptions;
|
||||
import org.thoughtcrime.securesms.TransportOptions.OnTransportChangedListener;
|
||||
import org.thoughtcrime.securesms.TransportOptionsPopup;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class SendButton extends AppCompatImageButton
|
||||
implements TransportOptions.OnTransportChangedListener,
|
||||
TransportOptionsPopup.SelectedListener,
|
||||
View.OnLongClickListener
|
||||
{
|
||||
View.OnLongClickListener {
|
||||
|
||||
private final TransportOptions transportOptions;
|
||||
|
||||
@@ -102,7 +106,19 @@ public class SendButton extends AppCompatImageButton
|
||||
|
||||
@Override
|
||||
public void onChange(TransportOption newTransport, boolean isManualSelection) {
|
||||
setImageResource(newTransport.getDrawable());
|
||||
// Map send icon drawable resource from a transport type.
|
||||
//TODO These values should come from XML layout as view's attributes and not be resolved in code like this.
|
||||
@DrawableRes final int sendDrawable;
|
||||
switch (newTransport.getType()) {
|
||||
case SMS:
|
||||
case TEXTSECURE:
|
||||
default: {
|
||||
sendDrawable = ThemeUtil.getThemedDrawableResId(
|
||||
getContext(), R.attr.conversation_transport_sms_indicator);
|
||||
}
|
||||
}
|
||||
|
||||
setImageResource(sendDrawable);
|
||||
setContentDescription(newTransport.getDescription());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package org.thoughtcrime.securesms.components.emoji;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.AppCompatImageButton;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import org.thoughtcrime.securesms.stickers.StickerKeyboardProvider;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
@@ -46,18 +46,16 @@ public class EmojiToggle extends AppCompatImageButton implements MediaKeyboard.M
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
int attributes[] = new int[] {R.attr.conversation_emoji_toggle,
|
||||
R.attr.conversation_sticker_toggle,
|
||||
R.attr.conversation_keyboard_toggle};
|
||||
TypedArray drawables = getContext().obtainStyledAttributes(new int[] {
|
||||
R.attr.conversation_emoji_toggle,
|
||||
R.attr.conversation_sticker_toggle,
|
||||
R.attr.conversation_keyboard_toggle});
|
||||
|
||||
TypedArray drawables = getContext().obtainStyledAttributes(attributes);
|
||||
this.emojiToggle = drawables.getDrawable(0);
|
||||
this.stickerToggle = drawables.getDrawable(1);
|
||||
this.imeToggle = drawables.getDrawable(2);
|
||||
this.mediaToggle = emojiToggle;
|
||||
|
||||
setImageTintList(ColorStateList.valueOf(getResources().getColor(R.color.text)));
|
||||
|
||||
drawables.recycle();
|
||||
setToMedia();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.thoughtcrime.securesms.conversation;
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ClipData;
|
||||
@@ -29,12 +28,8 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.hardware.Camera;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
@@ -44,17 +39,6 @@ import android.os.Handler;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Browser;
|
||||
import android.provider.Telephony;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.core.content.pm.ShortcutInfoCompat;
|
||||
import androidx.core.content.pm.ShortcutManagerCompat;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
@@ -77,6 +61,20 @@ import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.pm.ShortcutInfoCompat;
|
||||
import androidx.core.content.pm.ShortcutManagerCompat;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
@@ -147,7 +145,6 @@ import org.thoughtcrime.securesms.database.model.StickerRecord;
|
||||
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
||||
import org.thoughtcrime.securesms.giph.ui.GiphyActivity;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.RetrieveProfileJob;
|
||||
import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
|
||||
@@ -210,7 +207,6 @@ import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.Dialogs;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.ExpirationUtil;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
@@ -348,7 +344,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private int keyboardHeight = 0;
|
||||
|
||||
private final IdentityRecordList identityRecords = new IdentityRecordList();
|
||||
private final DynamicNoActionBarTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
|
||||
// Message status bar
|
||||
@@ -367,7 +362,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme.onCreate(this);
|
||||
dynamicLanguage.onCreate(this);
|
||||
}
|
||||
|
||||
@@ -377,12 +371,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
setContentView(R.layout.conversation_activity);
|
||||
|
||||
TypedArray typedArray = obtainStyledAttributes(new int[] {R.attr.conversation_background});
|
||||
int color = typedArray.getColor(0, Color.WHITE);
|
||||
typedArray.recycle();
|
||||
|
||||
getWindow().getDecorView().setBackgroundColor(color);
|
||||
|
||||
fragment = initFragment(R.id.fragment_content, new ConversationFragment(), dynamicLanguage.getCurrentLocale());
|
||||
|
||||
registerMessageStatusObserver("calculatingPoW");
|
||||
@@ -530,7 +518,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
dynamicLanguage.onResume(this);
|
||||
|
||||
EventBus.getDefault().register(this);
|
||||
@@ -866,17 +853,17 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_call_secure: handleDial(getRecipient(), true); return true;
|
||||
case R.id.menu_call_insecure: handleDial(getRecipient(), false); return true;
|
||||
// case R.id.menu_call_secure: handleDial(getRecipient(), true); return true;
|
||||
// case R.id.menu_call_insecure: handleDial(getRecipient(), false); return true;
|
||||
case R.id.menu_unblock: handleUnblock(); return true;
|
||||
case R.id.menu_block: handleBlock(); return true;
|
||||
case R.id.menu_copy_session_id: handleCopySessionID(); return true;
|
||||
case R.id.menu_view_media: handleViewMedia(); return true;
|
||||
case R.id.menu_add_shortcut: handleAddShortcut(); return true;
|
||||
case R.id.menu_search: handleSearch(); return true;
|
||||
case R.id.menu_add_to_contacts: handleAddToContacts(); return true;
|
||||
// case R.id.menu_add_to_contacts: handleAddToContacts(); return true;
|
||||
case R.id.menu_reset_secure_session: handleResetSecureSession(); return true;
|
||||
case R.id.menu_group_recipients: handleDisplayGroupRecipients(); return true;
|
||||
// case R.id.menu_group_recipients: handleDisplayGroupRecipients(); return true;
|
||||
case R.id.menu_distribution_broadcast: handleDistributionBroadcastEnabled(item); return true;
|
||||
case R.id.menu_distribution_conversation: handleDistributionConversationEnabled(item); return true;
|
||||
case R.id.menu_edit_group: handleEditPushGroup(); return true;
|
||||
@@ -1295,9 +1282,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private void handleAddAttachment() {
|
||||
if (this.isMmsEnabled || isSecureText) {
|
||||
if (attachmentTypeSelector == null) {
|
||||
attachmentTypeSelector = new AttachmentTypeSelector(this, getSupportLoaderManager(), new AttachmentTypeListener(), keyboardHeight);
|
||||
attachmentTypeSelector = new AttachmentTypeSelector(
|
||||
this,
|
||||
LoaderManager.getInstance(this),
|
||||
new AttachmentTypeListener(),
|
||||
keyboardHeight);
|
||||
}
|
||||
attachmentTypeSelector.keyboardHeight = keyboardHeight;
|
||||
attachmentTypeSelector.show(this, attachButton);
|
||||
} else {
|
||||
handleManualMmsRequired();
|
||||
@@ -1746,7 +1736,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
protected void initializeActionBar() {
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
toolbar.getOverflowIcon().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ActionBar supportActionBar = getSupportActionBar();
|
||||
@@ -2093,13 +2082,14 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
|
||||
private void setActionBarColor(MaterialColor color) {
|
||||
ActionBar supportActionBar = getSupportActionBar();
|
||||
if (supportActionBar == null) throw new AssertionError();
|
||||
supportActionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.action_bar_background)));
|
||||
setStatusBarColor(getResources().getColor(R.color.action_bar_background));
|
||||
//TODO AC: As we're trying to theme everything properly this method seems a bit broken
|
||||
// and it's not used anyway so it's a subject to be deleted.
|
||||
// ActionBar supportActionBar = getSupportActionBar();
|
||||
// if (supportActionBar == null) throw new AssertionError();
|
||||
// supportActionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.action_bar_background)));
|
||||
// setStatusBarColor(getResources().getColor(R.color.action_bar_background));
|
||||
}
|
||||
|
||||
// FIXME: This name is confusing because we also have updateInputPanel and setInputPanelEnabled
|
||||
private void updateInputUI(Recipient recipient, boolean isSecureText, boolean isDefaultSms) {
|
||||
if (recipient.isGroupRecipient() && !isActiveGroup()) {
|
||||
unblockButton.setVisibility(View.GONE);
|
||||
@@ -2562,7 +2552,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
Permissions.with(this)
|
||||
.request(Manifest.permission.RECORD_AUDIO)
|
||||
.ifNecessary()
|
||||
.withRationaleDialog(getString(R.string.ConversationActivity_to_send_audio_messages_allow_signal_access_to_your_microphone), R.drawable.ic_mic_white_48dp)
|
||||
.withRationaleDialog(getString(R.string.ConversationActivity_to_send_audio_messages_allow_signal_access_to_your_microphone), R.drawable.ic_baseline_mic_48)
|
||||
.withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_requires_the_microphone_permission_in_order_to_send_audio_messages))
|
||||
.execute();
|
||||
}
|
||||
@@ -2763,7 +2753,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
Permissions.with(ConversationActivity.this)
|
||||
.request(Manifest.permission.CAMERA)
|
||||
.ifNecessary()
|
||||
.withRationaleDialog(getString(R.string.ConversationActivity_to_capture_photos_and_video_allow_signal_access_to_the_camera), R.drawable.ic_photo_camera_white_48dp)
|
||||
.withRationaleDialog(getString(R.string.ConversationActivity_to_capture_photos_and_video_allow_signal_access_to_the_camera), R.drawable.ic_baseline_photo_camera_48)
|
||||
.withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_needs_the_camera_permission_to_take_photos_or_video))
|
||||
.onAllGranted(() -> {
|
||||
composeText.clearFocus();
|
||||
|
||||
@@ -352,11 +352,10 @@ public class ConversationItem extends LinearLayout
|
||||
/// MessageRecord Attribute Parsers
|
||||
|
||||
private void setBubbleState(MessageRecord messageRecord) {
|
||||
if (messageRecord.isOutgoing()) {
|
||||
bodyBubble.getBackground().setColorFilter(getResources().getColor(R.color.sent_message_background), PorterDuff.Mode.MULTIPLY);
|
||||
} else {
|
||||
bodyBubble.getBackground().setColorFilter(getResources().getColor(R.color.received_message_background), PorterDuff.Mode.MULTIPLY);
|
||||
}
|
||||
int bubbleColor = ThemeUtil.getThemedColor(getContext(), messageRecord.isOutgoing() ?
|
||||
R.attr.message_sent_background_color :
|
||||
R.attr.message_received_background_color);
|
||||
bodyBubble.getBackground().setColorFilter(bubbleColor, PorterDuff.Mode.MULTIPLY);
|
||||
|
||||
if (audioViewStub.resolved()) {
|
||||
setAudioViewTint(messageRecord, this.conversationRecipient);
|
||||
@@ -364,7 +363,7 @@ public class ConversationItem extends LinearLayout
|
||||
}
|
||||
|
||||
private void setAudioViewTint(MessageRecord messageRecord, Recipient recipient) {
|
||||
audioViewStub.get().setTint(Color.WHITE, getResources().getColor(R.color.action_bar_background));
|
||||
// audioViewStub.get().setTint(Color.WHITE, getResources().getColor(R.color.action_bar_background));
|
||||
}
|
||||
|
||||
private void setInteractionState(MessageRecord messageRecord, boolean pulseHighlight) {
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
package org.thoughtcrime.securesms.giph.ui;
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||
import network.loki.messenger.R;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.providers.BlobProvider;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class GiphyActivity extends PassphraseRequiredActionBarActivity
|
||||
implements GiphyActivityToolbar.OnLayoutChangedListener,
|
||||
GiphyActivityToolbar.OnFilterChangedListener,
|
||||
@@ -42,7 +42,6 @@ public class GiphyActivity extends PassphraseRequiredActionBarActivity
|
||||
public static final String EXTRA_WIDTH = "extra_width";
|
||||
public static final String EXTRA_HEIGHT = "extra_height";
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
|
||||
private GiphyGifFragment gifFragment;
|
||||
@@ -53,7 +52,6 @@ public class GiphyActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
@Override
|
||||
public void onPreCreate() {
|
||||
dynamicTheme.onCreate(this);
|
||||
dynamicLanguage.onCreate(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public class RegistrationLockDialog {
|
||||
if (!RegistrationLockReminders.needsReminder(context)) return;
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
|
||||
|
||||
AlertDialog dialog = new AlertDialog.Builder(context, R.style.RationaleDialog)
|
||||
AlertDialog dialog = new AlertDialog.Builder(context, R.style.Theme_TextSecure_Dialog_Rationale)
|
||||
.setView(R.layout.registration_lock_reminder_view)
|
||||
.setCancelable(true)
|
||||
.setOnCancelListener(d -> RegistrationLockReminders.scheduleReminder(context, false))
|
||||
|
||||
@@ -110,8 +110,8 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() {
|
||||
})
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_apply, menu)
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_edit_closed_group, menu)
|
||||
return members.isNotEmpty()
|
||||
}
|
||||
// endregion
|
||||
@@ -163,7 +163,7 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() {
|
||||
// region Interaction
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when(item.itemId) {
|
||||
R.id.applyButton -> commitChanges()
|
||||
R.id.action_apply -> commitChanges()
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ class EditClosedGroupMembersAdapter(
|
||||
private val glide: GlideRequests,
|
||||
private val memberClickListener: ((String) -> Unit)? = null
|
||||
) : RecyclerView.Adapter<EditClosedGroupMembersAdapter.ViewHolder>() {
|
||||
|
||||
private val members = ArrayList<String>()
|
||||
private val lockedMembers = HashSet<String>()
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.thoughtcrime.securesms.database.ThreadDatabase
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob
|
||||
import org.thoughtcrime.securesms.loki.dialogs.ConversationOptionsBottomSheet
|
||||
import org.thoughtcrime.securesms.loki.dialogs.LightThemeFeatureIntroBottomSheet
|
||||
import org.thoughtcrime.securesms.loki.dialogs.MultiDeviceRemovalBottomSheet
|
||||
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol
|
||||
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation
|
||||
@@ -200,8 +201,9 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
||||
if (hasViewedSeed || !isMasterDevice) {
|
||||
seedReminderView.visibility = View.GONE
|
||||
}
|
||||
val hasSeenMultiDeviceRemovalSheet = TextSecurePreferences.getHasSeenMultiDeviceRemovalSheet(this)
|
||||
if (!hasSeenMultiDeviceRemovalSheet) {
|
||||
|
||||
// Multiple device removal notification
|
||||
if (!TextSecurePreferences.getHasSeenMultiDeviceRemovalSheet(this)) {
|
||||
TextSecurePreferences.setHasSeenMultiDeviceRemovalSheet(this)
|
||||
val userPublicKey = TextSecurePreferences.getLocalNumber(this)
|
||||
val deviceLinks = DatabaseFactory.getLokiAPIDatabase(this).getDeviceLinks(userPublicKey)
|
||||
@@ -217,8 +219,18 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
||||
startActivity(intent)
|
||||
}
|
||||
bottomSheet.show(supportFragmentManager, bottomSheet.tag)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Light theme introduction
|
||||
if (!TextSecurePreferences.hasSeenLightThemeIntroSheet(this) &&
|
||||
UiModeUtilities.isDayUiMode(this)) {
|
||||
TextSecurePreferences.setHasSeenLightThemeIntroSheet(this)
|
||||
val bottomSheet = LightThemeFeatureIntroBottomSheet()
|
||||
bottomSheet.show(supportFragmentManager, bottomSheet.tag)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
@@ -259,12 +271,16 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
||||
val thread = view.thread ?: return
|
||||
val bottomSheet = ConversationOptionsBottomSheet()
|
||||
bottomSheet.recipient = thread.recipient
|
||||
bottomSheet.onBlockOrUnblockTapped = {
|
||||
bottomSheet.onBlockTapped = {
|
||||
bottomSheet.dismiss()
|
||||
if (!thread.recipient.isBlocked) {
|
||||
blockConversation(thread)
|
||||
}
|
||||
}
|
||||
bottomSheet.onUnblockTapped = {
|
||||
bottomSheet.dismiss()
|
||||
if (thread.recipient.isBlocked) {
|
||||
unblockConversation(thread)
|
||||
} else {
|
||||
blockConversation(thread)
|
||||
}
|
||||
}
|
||||
bottomSheet.onDeleteTapped = {
|
||||
|
||||
@@ -116,6 +116,7 @@ class PNModeActivity : BaseActionBarActivity() {
|
||||
TextSecurePreferences.setPromptedPushRegistration(this, true)
|
||||
TextSecurePreferences.setIsUsingFCM(this, (selectedOptionView == fcmOptionView))
|
||||
TextSecurePreferences.setHasSeenMultiDeviceRemovalSheet(this)
|
||||
TextSecurePreferences.setHasSeenLightThemeIntroSheet(this)
|
||||
val application = ApplicationContext.getInstance(this)
|
||||
application.setUpStorageAPIIfNeeded()
|
||||
application.setUpP2PAPIIfNeeded()
|
||||
|
||||
@@ -10,7 +10,6 @@ class PrivacySettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
|
||||
super.onCreate(savedInstanceState, isReady)
|
||||
setContentView(R.layout.activity_fragment_wrapper)
|
||||
supportActionBar!!.title = resources.getString(R.string.activity_privacy_settings_title)
|
||||
val fragment = AppProtectionPreferenceFragment()
|
||||
val transaction = supportFragmentManager.beginTransaction()
|
||||
transaction.replace(R.id.fragmentContainer, fragment)
|
||||
|
||||
@@ -10,9 +10,11 @@ import android.os.AsyncTask
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.ActionMode
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Toast
|
||||
import kotlinx.android.synthetic.main.activity_settings.*
|
||||
import network.loki.messenger.BuildConfig
|
||||
@@ -27,12 +29,13 @@ import org.thoughtcrime.securesms.avatar.AvatarSelection
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
|
||||
import org.thoughtcrime.securesms.database.Address
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.loki.dialogs.ChangeUiModeDialog
|
||||
import org.thoughtcrime.securesms.loki.dialogs.ClearAllDataDialog
|
||||
import org.thoughtcrime.securesms.loki.dialogs.SeedDialog
|
||||
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities
|
||||
import org.thoughtcrime.securesms.loki.utilities.fadeIn
|
||||
import org.thoughtcrime.securesms.loki.utilities.fadeOut
|
||||
import org.thoughtcrime.securesms.loki.utilities.push
|
||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper
|
||||
@@ -49,9 +52,11 @@ import java.security.SecureRandom
|
||||
import java.util.*
|
||||
|
||||
class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
|
||||
private var displayNameEditActionMode: ActionMode? = null
|
||||
set(value) { field = value; handleDisplayNameEditActionModeChanged() }
|
||||
|
||||
private lateinit var glide: GlideRequests
|
||||
private var isEditingDisplayName = false
|
||||
set(value) { field = value; handleIsEditingDisplayNameChanged() }
|
||||
private var displayNameToBeUploaded: String? = null
|
||||
private var profilePictureToBeUploaded: ByteArray? = null
|
||||
private var tempFile: File? = null
|
||||
@@ -66,18 +71,16 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
// region Lifecycle
|
||||
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
|
||||
super.onCreate(savedInstanceState, isReady)
|
||||
|
||||
setContentView(R.layout.activity_settings)
|
||||
setSupportActionBar(toolbar)
|
||||
cancelButton.setOnClickListener { cancelEditingDisplayName() }
|
||||
saveButton.setOnClickListener { saveDisplayName() }
|
||||
showQRCodeButton.setOnClickListener { showQRCode() }
|
||||
|
||||
glide = GlideApp.with(this)
|
||||
profilePictureView.glide = glide
|
||||
profilePictureView.publicKey = hexEncodedPublicKey
|
||||
profilePictureView.isLarge = true
|
||||
profilePictureView.update()
|
||||
profilePictureView.setOnClickListener { showEditProfilePictureUI() }
|
||||
ctnGroupNameSection.setOnClickListener { showEditDisplayNameUI() }
|
||||
ctnGroupNameSection.setOnClickListener { startActionMode(DisplayNameEditActionModeCallback()) }
|
||||
btnGroupNameDisplay.text = DatabaseFactory.getLokiUserDatabase(this).getDisplayName(hexEncodedPublicKey)
|
||||
publicKeyTextView.text = hexEncodedPublicKey
|
||||
copyButton.setOnClickListener { copyPublicKey() }
|
||||
@@ -98,7 +101,32 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
versionTextView.text = String.format(getString(R.string.version_s), "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})")
|
||||
}
|
||||
|
||||
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.settings_general, menu)
|
||||
|
||||
// Update UI mode menu icon.
|
||||
// It uses three-level selector where each level corresponds to the related UiMode ordinal value.
|
||||
val uiMode = UiModeUtilities.getUserSelectedUiMode(this)
|
||||
menu.findItem(R.id.action_change_theme).icon!!.level = uiMode.ordinal
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_qr_code -> {
|
||||
showQRCode()
|
||||
true
|
||||
}
|
||||
R.id.action_change_theme -> {
|
||||
ChangeUiModeDialog().show(supportFragmentManager, ChangeUiModeDialog.TAG)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
when (requestCode) {
|
||||
AvatarSelection.REQUEST_CODE_AVATAR -> {
|
||||
@@ -128,17 +156,16 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
// endregion
|
||||
|
||||
// region Updating
|
||||
private fun handleIsEditingDisplayNameChanged() {
|
||||
cancelButton.visibility = if (isEditingDisplayName) View.VISIBLE else View.GONE
|
||||
showQRCodeButton.visibility = if (isEditingDisplayName) View.GONE else View.VISIBLE
|
||||
saveButton.visibility = if (isEditingDisplayName) View.VISIBLE else View.GONE
|
||||
private fun handleDisplayNameEditActionModeChanged() {
|
||||
val isEditingDisplayName = this.displayNameEditActionMode !== null
|
||||
|
||||
btnGroupNameDisplay.visibility = if (isEditingDisplayName) View.INVISIBLE else View.VISIBLE
|
||||
displayNameEditText.visibility = if (isEditingDisplayName) View.VISIBLE else View.INVISIBLE
|
||||
val titleTextViewLayoutParams = titleTextView.layoutParams as LinearLayout.LayoutParams
|
||||
titleTextViewLayoutParams.leftMargin = if (isEditingDisplayName) toPx(16, resources) else 0
|
||||
titleTextView.layoutParams = titleTextViewLayoutParams
|
||||
|
||||
val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
if (isEditingDisplayName) {
|
||||
displayNameEditText.setText(btnGroupNameDisplay.text)
|
||||
displayNameEditText.selectAll()
|
||||
displayNameEditText.requestFocus()
|
||||
inputMethodManager.showSoftInput(displayNameEditText, 0)
|
||||
} else {
|
||||
@@ -193,21 +220,24 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
// endregion
|
||||
|
||||
// region Interaction
|
||||
private fun cancelEditingDisplayName() {
|
||||
isEditingDisplayName = false
|
||||
}
|
||||
|
||||
private fun saveDisplayName() {
|
||||
/**
|
||||
* @return true if the update was successful.
|
||||
*/
|
||||
private fun saveDisplayName(): Boolean {
|
||||
val displayName = displayNameEditText.text.toString().trim()
|
||||
if (displayName.isEmpty()) {
|
||||
return Toast.makeText(this, R.string.activity_settings_display_name_missing_error, Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.activity_settings_display_name_missing_error, Toast.LENGTH_SHORT).show()
|
||||
return false
|
||||
}
|
||||
if (displayName.toByteArray().size > ProfileCipher.NAME_PADDED_LENGTH) {
|
||||
return Toast.makeText(this, R.string.activity_settings_display_name_too_long_error, Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.activity_settings_display_name_too_long_error, Toast.LENGTH_SHORT).show()
|
||||
return false
|
||||
}
|
||||
isEditingDisplayName = false
|
||||
// isEditingDisplayName = false
|
||||
displayNameToBeUploaded = displayName
|
||||
updateProfile(false)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun showQRCode() {
|
||||
@@ -219,10 +249,6 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
tempFile = AvatarSelection.startAvatarSelection(this, false, true)
|
||||
}
|
||||
|
||||
private fun showEditDisplayNameUI() {
|
||||
isEditingDisplayName = true
|
||||
}
|
||||
|
||||
private fun copyPublicKey() {
|
||||
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText("Session ID", hexEncodedPublicKey)
|
||||
@@ -266,4 +292,34 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
ClearAllDataDialog().show(supportFragmentManager, "Clear All Data Dialog")
|
||||
}
|
||||
// endregion
|
||||
|
||||
private inner class DisplayNameEditActionModeCallback: ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
mode.title = getString(R.string.activity_settings_display_name_edit_text_hint)
|
||||
mode.menuInflater.inflate(R.menu.menu_apply, menu)
|
||||
this@SettingsActivity.displayNameEditActionMode = mode
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode) {
|
||||
this@SettingsActivity.displayNameEditActionMode = null
|
||||
}
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.applyButton -> {
|
||||
if (this@SettingsActivity.saveDisplayName()) {
|
||||
mode.finish()
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.thoughtcrime.securesms.loki.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.loki.utilities.UiMode
|
||||
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities
|
||||
|
||||
class ChangeUiModeDialog : DialogFragment() {
|
||||
|
||||
companion object {
|
||||
const val TAG = "ChangeUiModeDialog"
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val context = requireContext()
|
||||
|
||||
val displayNameList = UiMode.values().map { getString(it.displayNameRes) }.toTypedArray()
|
||||
val activeUiMode = UiModeUtilities.getUserSelectedUiMode(context)
|
||||
|
||||
return AlertDialog.Builder(context)
|
||||
.setSingleChoiceItems(displayNameList, activeUiMode.ordinal) { _, selectedItemIdx: Int ->
|
||||
val uiMode = UiMode.values()[selectedItemIdx]
|
||||
UiModeUtilities.setUserSelectedUiMode(context, uiMode)
|
||||
dismiss()
|
||||
requireActivity().recreate()
|
||||
}
|
||||
.setTitle(R.string.dialog_ui_mode_title)
|
||||
.setNegativeButton(R.string.cancel) { _, _ -> dismiss() }
|
||||
.create()
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,23 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.view.ContextThemeWrapper
|
||||
import kotlinx.android.synthetic.main.fragment_closed_group_edit_bottom_sheet.*
|
||||
import kotlinx.android.synthetic.main.fragment_conversation_bottom_sheet.*
|
||||
import kotlinx.android.synthetic.main.fragment_device_list_bottom_sheet.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
||||
public class ConversationOptionsBottomSheet : BottomSheetDialogFragment() {
|
||||
|
||||
//FIXME AC: Supplying a recipient directly into the field from an activity
|
||||
// is not the best idea. It doesn't survive configuration change.
|
||||
// We should be dealing with IDs and all sorts of serializable data instead
|
||||
// if we want to use dialog fragments properly.
|
||||
lateinit var recipient: Recipient
|
||||
var onBlockOrUnblockTapped: (() -> Unit)? = null
|
||||
|
||||
var onBlockTapped: (() -> Unit)? = null
|
||||
var onUnblockTapped: (() -> Unit)? = null
|
||||
var onDeleteTapped: (() -> Unit)? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
@@ -21,15 +30,18 @@ public class ConversationOptionsBottomSheet : BottomSheetDialogFragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
if (!this::recipient.isInitialized) {
|
||||
dismiss()
|
||||
return
|
||||
}
|
||||
|
||||
if (!recipient.isGroupRecipient && !recipient.isLocalNumber) {
|
||||
val textID = if (recipient.isBlocked) R.string.RecipientPreferenceActivity_unblock else R.string.RecipientPreferenceActivity_block
|
||||
blockOrUnblockTextView.setText(textID)
|
||||
val iconID = if (recipient.isBlocked) R.drawable.ic_check_white_24dp else R.drawable.ic_block_white_24dp
|
||||
val icon = context!!.resources.getDrawable(iconID, context!!.theme)
|
||||
blockOrUnblockTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null)
|
||||
blockOrUnblockTextView.setOnClickListener { onBlockOrUnblockTapped?.invoke() }
|
||||
} else {
|
||||
blockOrUnblockTextView.visibility = View.GONE
|
||||
unblockTextView.visibility = if (recipient.isBlocked) View.VISIBLE else View.GONE
|
||||
blockTextView.visibility = if (recipient.isBlocked) View.GONE else View.VISIBLE
|
||||
|
||||
blockTextView.setOnClickListener { onBlockTapped?.invoke() }
|
||||
unblockTextView.setOnClickListener { onUnblockTapped?.invoke() }
|
||||
}
|
||||
deleteTextView.setOnClickListener { onDeleteTapped?.invoke() }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.thoughtcrime.securesms.loki.dialogs
|
||||
|
||||
import android.os.Bundle
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import kotlinx.android.synthetic.main.fragment_light_theme_feature_intro_bottom_sheet.*
|
||||
import kotlinx.android.synthetic.main.fragment_open_group_suggestion_bottom_sheet.*
|
||||
import network.loki.messenger.R
|
||||
|
||||
class LightThemeFeatureIntroBottomSheet : BottomSheetDialogFragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(
|
||||
R.layout.fragment_light_theme_feature_intro_bottom_sheet,
|
||||
container,
|
||||
false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
okButton.setOnClickListener { dismiss() }
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ class MultiDeviceRemovalBottomSheet : BottomSheetDialogFragment() {
|
||||
}
|
||||
|
||||
private val explanation by lazy {
|
||||
if (TextSecurePreferences.getMasterHexEncodedPublicKey(context!!) != null) {
|
||||
if (TextSecurePreferences.getMasterHexEncodedPublicKey(requireContext()) != null) {
|
||||
"You’re seeing this because this is a secondary device in a multi-device setup. To improve reliability and stability, we’ve decided to temporarily disable Session’s multi-device functionality. Device linking has been disabled, and existing secondary clients will be erased on $removalDateDescription.\n\nTo read more about this change, visit the Session FAQ at getsession.org/faq."
|
||||
} else {
|
||||
"You’re seeing this because you have a secondary device linked to your Session ID. To improve reliability and stability, we’ve decided to temporarily disable Session’s multi-device functionality. Device linking has been disabled, and existing secondary clients will be erased on $removalDateDescription.\n\nTo read more about this change, visit the Session FAQ at getsession.org/faq"
|
||||
@@ -49,7 +49,7 @@ class MultiDeviceRemovalBottomSheet : BottomSheetDialogFragment() {
|
||||
val removalDateStartIndex = explanation.indexOf(removalDateDescription)
|
||||
val removalDateEndIndex = removalDateStartIndex + removalDateDescription.count()
|
||||
result.setSpan(StyleSpan(Typeface.BOLD), removalDateStartIndex, removalDateEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
result.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, context!!.theme)), removalDateStartIndex, removalDateEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
result.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, requireContext().theme)), removalDateStartIndex, removalDateEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
val link = "getsession.org/faq"
|
||||
val linkStartIndex = explanation.indexOf(link)
|
||||
val linkEndIndex = linkStartIndex + link.count()
|
||||
@@ -59,20 +59,15 @@ class MultiDeviceRemovalBottomSheet : BottomSheetDialogFragment() {
|
||||
try {
|
||||
onLinkTapped?.invoke()
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(context!!, R.string.invalid_url, Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(requireContext(), R.string.invalid_url, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}, linkStartIndex, linkEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
result.setSpan(StyleSpan(Typeface.BOLD), linkStartIndex, linkEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
result.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, context!!.theme)), linkStartIndex, linkEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
result.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, requireContext().theme)), linkStartIndex, linkEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
result
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setStyle(STYLE_NORMAL, R.style.SessionBottomSheetDialogTheme)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_multi_device_removal_bottom_sheet, container, false)
|
||||
}
|
||||
|
||||
@@ -12,11 +12,6 @@ class OpenGroupSuggestionBottomSheet : BottomSheetDialogFragment() {
|
||||
var onJoinTapped: (() -> Unit)? = null
|
||||
var onDismissTapped: (() -> Unit)? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setStyle(STYLE_NORMAL, R.style.SessionBottomSheetDialogTheme)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_open_group_suggestion_bottom_sheet, container, false)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import kotlinx.android.synthetic.main.fragment_scan_qr_code_v2.*
|
||||
import kotlinx.android.synthetic.main.fragment_scan_qr_code.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.qr.ScanListener
|
||||
import org.thoughtcrime.securesms.qr.ScanningThread
|
||||
@@ -19,7 +19,7 @@ class ScanQRCodeFragment : Fragment() {
|
||||
var message: CharSequence = ""
|
||||
|
||||
override fun onCreateView(layoutInflater: LayoutInflater, viewGroup: ViewGroup?, bundle: Bundle?): View? {
|
||||
return layoutInflater.inflate(R.layout.fragment_scan_qr_code_v2, viewGroup, false)
|
||||
return layoutInflater.inflate(R.layout.fragment_scan_qr_code, viewGroup, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, bundle: Bundle?) {
|
||||
|
||||
@@ -27,7 +27,7 @@ class ScanQRCodeWrapperFragment : Fragment(), ScanQRCodePlaceholderFragmentDeleg
|
||||
|
||||
private fun update() {
|
||||
val fragment: Fragment
|
||||
if (ContextCompat.checkSelfPermission(activity!!, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
|
||||
if (ContextCompat.checkSelfPermission(requireActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
|
||||
val scanQRCodeFragment = ScanQRCodeFragment()
|
||||
scanQRCodeFragment.scanListener = this
|
||||
scanQRCodeFragment.message = message
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.thoughtcrime.securesms.loki.utilities
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.preference.PreferenceManager
|
||||
import network.loki.messenger.R
|
||||
|
||||
/**
|
||||
* Day/night UI mode related utilities.
|
||||
* @see <a href="https://developer.android.com/guide/topics/ui/look-and-feel/darktheme">Official Documentation</a>
|
||||
*/
|
||||
object UiModeUtilities {
|
||||
private const val PREF_KEY_SELECTED_UI_MODE = "SELECTED_UI_MODE"
|
||||
|
||||
@JvmStatic
|
||||
fun setUserSelectedUiMode(context: Context, uiMode: UiMode) {
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
prefs.edit()
|
||||
.putString(PREF_KEY_SELECTED_UI_MODE, uiMode.name)
|
||||
.apply()
|
||||
AppCompatDelegate.setDefaultNightMode(uiMode.nightModeValue)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUserSelectedUiMode(context: Context): UiMode {
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val selectedUiModeName = prefs.getString(PREF_KEY_SELECTED_UI_MODE, UiMode.SYSTEM_DEFAULT.name)!!
|
||||
var selectedUiMode: UiMode
|
||||
try {
|
||||
selectedUiMode = UiMode.valueOf(selectedUiModeName)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// Cannot recognize UiMode constant from the given string.
|
||||
selectedUiMode = UiMode.SYSTEM_DEFAULT
|
||||
}
|
||||
return selectedUiMode
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setupUiModeToUserSelected(context: Context) {
|
||||
val selectedUiMode = getUserSelectedUiMode(context)
|
||||
setUserSelectedUiMode(context, selectedUiMode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the application UI is in the light mode
|
||||
* (do not confuse with the user selected UiMode).
|
||||
*/
|
||||
@JvmStatic
|
||||
fun isDayUiMode(context: Context): Boolean {
|
||||
val uiModeNightBit = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
|
||||
return uiModeNightBit == Configuration.UI_MODE_NIGHT_NO
|
||||
}
|
||||
}
|
||||
|
||||
enum class UiMode(
|
||||
@StringRes
|
||||
val displayNameRes: Int,
|
||||
val nightModeValue: Int) {
|
||||
|
||||
DAY(R.string.dialog_ui_mode_option_day, AppCompatDelegate.MODE_NIGHT_NO),
|
||||
NIGHT(R.string.dialog_ui_mode_option_night, AppCompatDelegate.MODE_NIGHT_YES),
|
||||
SYSTEM_DEFAULT(R.string.dialog_ui_mode_option_system_default, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class ConversationView : LinearLayout {
|
||||
}
|
||||
|
||||
private fun setUpViewHierarchy() {
|
||||
val inflater = context.applicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val contentView = inflater.inflate(R.layout.view_conversation, null)
|
||||
addView(contentView)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ class DeviceView : LinearLayout {
|
||||
}
|
||||
|
||||
private fun setUpViewHierarchy() {
|
||||
val inflater = context.applicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val contentView = inflater.inflate(R.layout.view_device, null)
|
||||
addView(contentView)
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class FakeChatView : ScrollView {
|
||||
}
|
||||
|
||||
private fun setUpViewHierarchy() {
|
||||
val inflater = context.applicationContext.getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val inflater = context.getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val contentView = inflater.inflate(R.layout.view_fake_chat, null)
|
||||
addView(contentView)
|
||||
isVerticalScrollBarEnabled = false
|
||||
|
||||
@@ -9,21 +9,21 @@ import android.view.LayoutInflater
|
||||
import android.widget.RelativeLayout
|
||||
import kotlinx.android.synthetic.main.view_separator.view.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil
|
||||
|
||||
class LabeledSeparatorView : RelativeLayout {
|
||||
|
||||
private val path = Path()
|
||||
|
||||
private val paint: Paint = {
|
||||
private val paint: Paint by lazy{
|
||||
val result = Paint()
|
||||
result.style = Paint.Style.STROKE
|
||||
result.color = resources.getColorWithID(R.color.separator, context.theme)
|
||||
result.color = ThemeUtil.getThemedColor(context, R.attr.dividerHorizontal)
|
||||
result.strokeWidth = toPx(1, resources).toFloat()
|
||||
result.isAntiAlias = true
|
||||
result
|
||||
}()
|
||||
}
|
||||
|
||||
// region Lifecycle
|
||||
constructor(context: Context) : super(context) {
|
||||
@@ -43,7 +43,7 @@ class LabeledSeparatorView : RelativeLayout {
|
||||
}
|
||||
|
||||
private fun setUpViewHierarchy() {
|
||||
val inflater = context.applicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val contentView = inflater.inflate(R.layout.view_separator, null)
|
||||
val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
||||
addView(contentView, layoutParams)
|
||||
@@ -56,7 +56,7 @@ class LabeledSeparatorView : RelativeLayout {
|
||||
super.onDraw(c)
|
||||
val w = width.toFloat()
|
||||
val h = height.toFloat()
|
||||
val hMargin = toPx(10, resources).toFloat()
|
||||
val hMargin = toPx(16, resources).toFloat()
|
||||
path.reset()
|
||||
path.moveTo(0.0f, h / 2)
|
||||
path.lineTo(titleTextView.left - hMargin, h / 2)
|
||||
|
||||
@@ -7,19 +7,20 @@ import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.content.Context.VIBRATOR_SERVICE
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.PointF
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Build
|
||||
import android.os.VibrationEffect
|
||||
import android.os.VibrationEffect.DEFAULT_AMPLITUDE
|
||||
import android.os.Vibrator
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.MotionEvent
|
||||
import android.widget.ImageView
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.loki.utilities.*
|
||||
|
||||
@@ -70,10 +71,19 @@ class NewConversationButtonSetView : RelativeLayout {
|
||||
result.layoutParams = LayoutParams(size, size)
|
||||
result.setBackgroundResource(R.drawable.new_conversation_button_background)
|
||||
val background = result.background as GradientDrawable
|
||||
val colorID = if (isMain) R.color.accent else R.color.new_conversation_button_collapsed_background
|
||||
background.color = ColorStateList.valueOf(resources.getColorWithID(colorID, context.theme))
|
||||
@ColorRes val backgroundColorID = if (isMain)
|
||||
R.color.accent else
|
||||
R.color.new_conversation_button_collapsed_background
|
||||
background.color = ColorStateList.valueOf(resources.getColorWithID(backgroundColorID, context.theme))
|
||||
result.scaleType = ImageView.ScaleType.CENTER
|
||||
result.setImageResource(iconID)
|
||||
|
||||
result.imageTintList = if (isMain)
|
||||
// Always use white icon for the main button.
|
||||
ColorStateList.valueOf(resources.getColorWithID(android.R.color.white, context.theme))
|
||||
else
|
||||
ColorStateList.valueOf(resources.getColorWithID(R.color.text, context.theme))
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class ProfilePictureView : RelativeLayout {
|
||||
}
|
||||
|
||||
private fun setUpViewHierarchy() {
|
||||
val inflater = context.applicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val contentView = inflater.inflate(R.layout.view_profile_picture, null)
|
||||
addView(contentView)
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class SeedReminderView : FrameLayout {
|
||||
}
|
||||
|
||||
private fun setUpViewHierarchy() {
|
||||
val inflater = context.applicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val contentView = inflater.inflate(R.layout.view_seed_reminder, null)
|
||||
addView(contentView)
|
||||
button.setOnClickListener { delegate?.handleSeedReminderViewContinueButtonTapped() }
|
||||
|
||||
@@ -39,7 +39,7 @@ class UserView : LinearLayout {
|
||||
}
|
||||
|
||||
private fun setUpViewHierarchy() {
|
||||
val inflater = context.applicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val contentView = inflater.inflate(R.layout.view_user, null)
|
||||
addView(contentView)
|
||||
}
|
||||
@@ -66,7 +66,7 @@ class UserView : LinearLayout {
|
||||
profilePictureView.additionalPublicKey = null
|
||||
profilePictureView.isRSSFeed = false
|
||||
}
|
||||
actionIndicatorImageView.setImageResource(R.drawable.ic_edit_white_24dp)
|
||||
actionIndicatorImageView.setImageResource(R.drawable.ic_baseline_edit_24)
|
||||
profilePictureView.glide = glide
|
||||
profilePictureView.update()
|
||||
nameTextView.text = user.name ?: "Unknown Contact"
|
||||
|
||||
@@ -376,7 +376,7 @@ public class MediaSendActivity extends PassphraseRequiredActionBarActivity imple
|
||||
Permissions.with(this)
|
||||
.request(Manifest.permission.CAMERA)
|
||||
.ifNecessary()
|
||||
.withRationaleDialog(getString(R.string.ConversationActivity_to_capture_photos_and_video_allow_signal_access_to_the_camera), R.drawable.ic_photo_camera_white_48dp)
|
||||
.withRationaleDialog(getString(R.string.ConversationActivity_to_capture_photos_and_video_allow_signal_access_to_the_camera), R.drawable.ic_baseline_photo_camera_48)
|
||||
.withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_needs_the_camera_permission_to_take_photos_or_video))
|
||||
.onAllGranted(() -> {
|
||||
Camera1Fragment fragment = getOrCreateCameraFragment();
|
||||
|
||||
@@ -49,7 +49,6 @@ import org.thoughtcrime.securesms.util.CharacterCalculator.CharacterState;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
|
||||
@@ -129,8 +128,7 @@ public class MediaSendFragment extends Fragment implements ViewTreeObserver.OnGl
|
||||
|
||||
@Override
|
||||
public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return ThemeUtil.getThemedInflater(requireActivity(), inflater, R.style.TextSecure_DarkTheme)
|
||||
.inflate(R.layout.mediasend_fragment, container, false);
|
||||
return inflater.inflate(R.layout.mediasend_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -449,7 +447,7 @@ public class MediaSendFragment extends Fragment implements ViewTreeObserver.OnGl
|
||||
protected void onPreExecute() {
|
||||
renderTimer = new Stopwatch("ProcessMedia");
|
||||
progressTimer = () -> {
|
||||
dialog = new AlertDialog.Builder(new ContextThemeWrapper(requireContext(), R.style.TextSecure_MediaSendProgressDialog))
|
||||
dialog = new AlertDialog.Builder(new ContextThemeWrapper(requireContext(), R.style.Theme_TextSecure_Dialog_MediaSendProgress))
|
||||
.setView(R.layout.progress_dialog)
|
||||
.setCancelable(false)
|
||||
.create();
|
||||
|
||||
@@ -47,7 +47,7 @@ public class RationaleDialog {
|
||||
|
||||
text.setText(message);
|
||||
|
||||
return new AlertDialog.Builder(context, R.style.RationaleDialog).setView(view);
|
||||
return new AlertDialog.Builder(context, R.style.Theme_TextSecure_Dialog_Rationale).setView(view);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class WelcomeActivity extends BaseActionBarActivity {
|
||||
Permissions.with(this)
|
||||
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
.ifNecessary()
|
||||
.withRationaleDialog(getString(R.string.activity_landing_permission_dialog_message), R.drawable.ic_folder_white_48dp)
|
||||
.withRationaleDialog(getString(R.string.activity_landing_permission_dialog_message), R.drawable.ic_baseline_folder_48)
|
||||
.onAnyResult(() -> {
|
||||
Intent nextIntent = getIntent().getParcelableExtra("next_intent");
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class DynamicIntroTheme extends DynamicTheme {
|
||||
@Override
|
||||
protected int getSelectedTheme(Activity activity) {
|
||||
String theme = TextSecurePreferences.getTheme(activity);
|
||||
|
||||
if (theme.equals("dark")) return R.style.TextSecure_DarkIntroTheme;
|
||||
|
||||
return R.style.TextSecure_LightIntroTheme;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,6 @@ import network.loki.messenger.R;
|
||||
public class DynamicNoActionBarTheme extends DynamicTheme {
|
||||
@Override
|
||||
protected int getSelectedTheme(Activity activity) {
|
||||
return R.style.TextSecure_DarkNoActionBar;
|
||||
return R.style.Theme_TextSecure_DayNight_NoActionBar;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class DynamicRegistrationTheme extends DynamicTheme {
|
||||
@Override
|
||||
protected int getSelectedTheme(Activity activity) {
|
||||
return R.style.TextSecure_DarkRegistrationTheme;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,12 @@ import android.content.Intent;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
/**
|
||||
* @deprecated Use one of the Theme.Session.DayNight.*
|
||||
* (or Theme.TextSecure.DayNight.* for old Signal activities)
|
||||
* app themes to support dark/light modes.
|
||||
*/
|
||||
@Deprecated
|
||||
public class DynamicTheme {
|
||||
|
||||
public static final String DARK = "dark";
|
||||
@@ -28,7 +34,8 @@ public class DynamicTheme {
|
||||
}
|
||||
|
||||
protected int getSelectedTheme(Activity activity) {
|
||||
return R.style.TextSecure_DarkTheme;
|
||||
// For all legacy (Signal) activities we lock on to the Signal dedicated theme.
|
||||
return R.style.Theme_TextSecure_DayNight;
|
||||
}
|
||||
|
||||
private static final class OverridePendingTransition {
|
||||
|
||||
@@ -1316,5 +1316,13 @@ public class TextSecurePreferences {
|
||||
public static void setHasSeenMultiDeviceRemovalSheet(Context context) {
|
||||
setBooleanPreference(context, "has_seen_multi_device_removal_sheet", true);
|
||||
}
|
||||
|
||||
public static boolean hasSeenLightThemeIntroSheet(Context context) {
|
||||
return getBooleanPreference(context, "has_seen_light_theme_intro_sheet", false);
|
||||
}
|
||||
|
||||
public static void setHasSeenLightThemeIntroSheet(Context context) {
|
||||
setBooleanPreference(context, "has_seen_light_theme_intro_sheet", true);
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
||||
@@ -4,28 +4,49 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StyleRes;
|
||||
import androidx.appcompat.view.ContextThemeWrapper;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class ThemeUtil {
|
||||
private static final String TAG = ThemeUtil.class.getSimpleName();
|
||||
|
||||
public static boolean isDarkTheme(@NonNull Context context) {
|
||||
return getAttribute(context, R.attr.theme_type, "light").equals("dark");
|
||||
return getAttributeText(context, R.attr.theme_type, "light").equals("dark");
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public static int getThemedColor(@NonNull Context context, @AttrRes int attr) {
|
||||
TypedValue typedValue = new TypedValue();
|
||||
Resources.Theme theme = context.getTheme();
|
||||
|
||||
if (theme.resolveAttribute(attr, typedValue, true)) {
|
||||
return typedValue.data;
|
||||
} else {
|
||||
Log.e(TAG, "Couldn't find a color attribute with id: " + attr);
|
||||
return Color.RED;
|
||||
}
|
||||
}
|
||||
|
||||
@DrawableRes
|
||||
public static int getThemedDrawableResId(@NonNull Context context, @AttrRes int attr) {
|
||||
TypedValue typedValue = new TypedValue();
|
||||
Resources.Theme theme = context.getTheme();
|
||||
|
||||
if (theme.resolveAttribute(attr, typedValue, true)) {
|
||||
return typedValue.resourceId;
|
||||
} else {
|
||||
Log.e(TAG, "Couldn't find a drawable attribute with id: " + attr);
|
||||
return 0;
|
||||
}
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
public static LayoutInflater getThemedInflater(@NonNull Context context, @NonNull LayoutInflater inflater, @StyleRes int theme) {
|
||||
@@ -33,7 +54,7 @@ public class ThemeUtil {
|
||||
return inflater.cloneInContext(contextThemeWrapper);
|
||||
}
|
||||
|
||||
private static String getAttribute(Context context, int attribute, String defaultValue) {
|
||||
private static String getAttributeText(Context context, int attribute, String defaultValue) {
|
||||
TypedValue outValue = new TypedValue();
|
||||
|
||||
if (context.getTheme().resolveAttribute(attribute, outValue, true)) {
|
||||
|
||||
Reference in New Issue
Block a user