mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-09 13:08:33 +00:00
Tap avatar in chat preferences or group management to see full screen.
This commit is contained in:
parent
0711a22188
commit
69adcd1d69
@ -353,6 +353,11 @@
|
|||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
|
||||||
|
<activity android:name=".AvatarPreviewActivity"
|
||||||
|
android:label="@string/AndroidManifest__media_preview"
|
||||||
|
android:windowSoftInputMode="stateHidden"
|
||||||
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
|
||||||
<activity android:name=".mediaoverview.MediaOverviewActivity"
|
<activity android:name=".mediaoverview.MediaOverviewActivity"
|
||||||
android:theme="@style/TextSecure.LightNoActionBar"
|
android:theme="@style/TextSecure.LightNoActionBar"
|
||||||
android:windowSoftInputMode="stateHidden"
|
android:windowSoftInputMode="stateHidden"
|
||||||
|
@ -0,0 +1,152 @@
|
|||||||
|
package org.thoughtcrime.securesms;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.core.app.ActivityOptionsCompat;
|
||||||
|
|
||||||
|
import com.bumptech.glide.load.DataSource;
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
|
import com.bumptech.glide.load.engine.GlideException;
|
||||||
|
import com.bumptech.glide.request.RequestListener;
|
||||||
|
import com.bumptech.glide.request.target.Target;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||||
|
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
|
||||||
|
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
|
||||||
|
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
||||||
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
|
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activity for displaying avatars full screen.
|
||||||
|
*/
|
||||||
|
public final class AvatarPreviewActivity extends PassphraseRequiredActionBarActivity {
|
||||||
|
|
||||||
|
private static final String TAG = Log.tag(AvatarPreviewActivity.class);
|
||||||
|
|
||||||
|
private static final String RECIPIENT_ID_EXTRA = "recipient_id";
|
||||||
|
|
||||||
|
public static @NonNull Intent intentFromRecipientId(@NonNull Context context,
|
||||||
|
@NonNull RecipientId recipientId)
|
||||||
|
{
|
||||||
|
Intent intent = new Intent(context, AvatarPreviewActivity.class);
|
||||||
|
intent.putExtra(RECIPIENT_ID_EXTRA, recipientId.serialize());
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bundle createTransitionBundle(@NonNull Activity activity, @NonNull View from) {
|
||||||
|
return ActivityOptionsCompat.makeSceneTransitionAnimation(activity, from, "avatar").toBundle();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState, boolean ready) {
|
||||||
|
super.onCreate(savedInstanceState, ready);
|
||||||
|
|
||||||
|
setTheme(R.style.TextSecure_MediaPreview);
|
||||||
|
setContentView(R.layout.contact_photo_preview_activity);
|
||||||
|
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
ImageView avatar = findViewById(R.id.avatar);
|
||||||
|
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||||
|
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
|
showSystemUI();
|
||||||
|
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
||||||
|
Context context = getApplicationContext();
|
||||||
|
RecipientId recipientId = RecipientId.from(getIntent().getStringExtra(RECIPIENT_ID_EXTRA));
|
||||||
|
|
||||||
|
Recipient.live(recipientId).observe(this, recipient -> {
|
||||||
|
ContactPhoto contactPhoto = recipient.isLocalNumber() ? new ProfileContactPhoto(recipient, recipient.getProfileAvatar())
|
||||||
|
: recipient.getContactPhoto();
|
||||||
|
FallbackContactPhoto fallbackPhoto = recipient.isLocalNumber() ? new ResourceContactPhoto(R.drawable.ic_profile_outline_40, R.drawable.ic_profile_outline_20, R.drawable.ic_person_large)
|
||||||
|
: recipient.getFallbackContactPhoto();
|
||||||
|
|
||||||
|
GlideApp.with(this).load(contactPhoto)
|
||||||
|
.fallback(fallbackPhoto.asCallCard(this))
|
||||||
|
.error(fallbackPhoto.asCallCard(this))
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.addListener(new RequestListener<Drawable>() {
|
||||||
|
@Override
|
||||||
|
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
|
||||||
|
Log.w(TAG, "Unable to load avatar, or avatar removed, closing");
|
||||||
|
finish();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into(avatar);
|
||||||
|
|
||||||
|
toolbar.setTitle(recipient.toShortString(context));
|
||||||
|
});
|
||||||
|
|
||||||
|
avatar.setOnClickListener(v -> toggleUiVisibility());
|
||||||
|
|
||||||
|
showAndHideWithSystemUI(getWindow(), findViewById(R.id.toolbar_layout));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showAndHideWithSystemUI(@NonNull Window window, @NonNull View... views) {
|
||||||
|
window.getDecorView().setOnSystemUiVisibilityChangeListener(visibility -> {
|
||||||
|
boolean hide = (visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
|
||||||
|
|
||||||
|
for (View view : views) {
|
||||||
|
view.animate()
|
||||||
|
.alpha(hide ? 0 : 1)
|
||||||
|
.start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleUiVisibility() {
|
||||||
|
int systemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
|
||||||
|
if ((systemUiVisibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0) {
|
||||||
|
showSystemUI();
|
||||||
|
} else {
|
||||||
|
hideSystemUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideSystemUI() {
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(
|
||||||
|
View.SYSTEM_UI_FLAG_IMMERSIVE |
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
||||||
|
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||||
|
View.SYSTEM_UI_FLAG_FULLSCREEN );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showSystemUI() {
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSupportNavigateUp() {
|
||||||
|
onBackPressed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.media.Ringtone;
|
import android.media.Ringtone;
|
||||||
import android.media.RingtoneManager;
|
import android.media.RingtoneManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -35,7 +36,11 @@ import androidx.preference.Preference;
|
|||||||
import androidx.preference.PreferenceCategory;
|
import androidx.preference.PreferenceCategory;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.load.DataSource;
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
|
import com.bumptech.glide.load.engine.GlideException;
|
||||||
|
import com.bumptech.glide.request.RequestListener;
|
||||||
|
import com.bumptech.glide.request.target.Target;
|
||||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||||
@ -69,7 +74,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
|||||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||||
import org.thoughtcrime.securesms.util.DynamicDarkToolbarTheme;
|
import org.thoughtcrime.securesms.util.DynamicDarkToolbarTheme;
|
||||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||||
@ -101,7 +105,6 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
private static final String PREFERENCE_CUSTOM_NOTIFICATIONS = "pref_key_recipient_custom_notifications";
|
private static final String PREFERENCE_CUSTOM_NOTIFICATIONS = "pref_key_recipient_custom_notifications";
|
||||||
|
|
||||||
private final DynamicTheme dynamicTheme = new DynamicDarkToolbarTheme();
|
private final DynamicTheme dynamicTheme = new DynamicDarkToolbarTheme();
|
||||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
|
||||||
|
|
||||||
private ImageView avatar;
|
private ImageView avatar;
|
||||||
private GlideRequests glideRequests;
|
private GlideRequests glideRequests;
|
||||||
@ -120,7 +123,6 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
@Override
|
@Override
|
||||||
public void onPreCreate() {
|
public void onPreCreate() {
|
||||||
dynamicTheme.onCreate(this);
|
dynamicTheme.onCreate(this);
|
||||||
dynamicLanguage.onCreate(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -135,14 +137,13 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
setHeader(recipient.get());
|
setHeader(recipient.get());
|
||||||
recipient.observe(this, this::setHeader);
|
recipient.observe(this, this::setHeader);
|
||||||
|
|
||||||
getSupportLoaderManager().initLoader(0, null, this);
|
LoaderManager.getInstance(this).initLoader(0, null, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
dynamicTheme.onResume(this);
|
dynamicTheme.onResume(this);
|
||||||
dynamicLanguage.onResume(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -165,10 +166,10 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeToolbar() {
|
private void initializeToolbar() {
|
||||||
this.toolbarLayout = ViewUtil.findById(this, R.id.collapsing_toolbar);
|
this.toolbarLayout = findViewById(R.id.collapsing_toolbar);
|
||||||
this.avatar = ViewUtil.findById(this, R.id.avatar);
|
this.avatar = findViewById(R.id.avatar);
|
||||||
this.threadPhotoRailView = ViewUtil.findById(this, R.id.recent_photos);
|
this.threadPhotoRailView = findViewById(R.id.recent_photos);
|
||||||
this.threadPhotoRailLabel = ViewUtil.findById(this, R.id.rail_label);
|
this.threadPhotoRailLabel = findViewById(R.id.rail_label);
|
||||||
|
|
||||||
this.toolbarLayout.setExpandedTitleColor(ThemeUtil.getThemedColor(this, R.attr.conversation_title_color));
|
this.toolbarLayout.setExpandedTitleColor(ThemeUtil.getThemedColor(this, R.attr.conversation_title_color));
|
||||||
this.toolbarLayout.setCollapsedTitleTextColor(ThemeUtil.getThemedColor(this, R.attr.conversation_title_color));
|
this.toolbarLayout.setCollapsedTitleTextColor(ThemeUtil.getThemedColor(this, R.attr.conversation_title_color));
|
||||||
@ -189,7 +190,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
Toolbar toolbar = ViewUtil.findById(this, R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
getSupportActionBar().setLogo(null);
|
getSupportActionBar().setLogo(null);
|
||||||
@ -215,6 +216,20 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
.fallback(fallbackPhoto.asCallCard(this))
|
.fallback(fallbackPhoto.asCallCard(this))
|
||||||
.error(fallbackPhoto.asCallCard(this))
|
.error(fallbackPhoto.asCallCard(this))
|
||||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.addListener(new RequestListener<Drawable>() {
|
||||||
|
@Override
|
||||||
|
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
|
||||||
|
avatar.setOnClickListener(null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
|
||||||
|
avatar.setOnClickListener(v -> startActivity(AvatarPreviewActivity.intentFromRecipientId(RecipientPreferenceActivity.this, recipient.getId()),
|
||||||
|
AvatarPreviewActivity.createTransitionBundle(RecipientPreferenceActivity.this, avatar)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
.into(this.avatar);
|
.into(this.avatar);
|
||||||
|
|
||||||
if (contactPhoto == null) this.avatar.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
if (contactPhoto == null) this.avatar.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||||
|
@ -22,6 +22,7 @@ import androidx.fragment.app.Fragment;
|
|||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.lifecycle.ViewModelProviders;
|
import androidx.lifecycle.ViewModelProviders;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.AvatarPreviewActivity;
|
||||||
import org.thoughtcrime.securesms.ContactSelectionListFragment;
|
import org.thoughtcrime.securesms.ContactSelectionListFragment;
|
||||||
import org.thoughtcrime.securesms.MediaPreviewActivity;
|
import org.thoughtcrime.securesms.MediaPreviewActivity;
|
||||||
import org.thoughtcrime.securesms.MuteDialog;
|
import org.thoughtcrime.securesms.MuteDialog;
|
||||||
@ -189,7 +190,14 @@ public class ManageGroupFragment extends Fragment {
|
|||||||
viewModel.getTitle().observe(getViewLifecycleOwner(), toolbar::setTitle);
|
viewModel.getTitle().observe(getViewLifecycleOwner(), toolbar::setTitle);
|
||||||
viewModel.getMemberCountSummary().observe(getViewLifecycleOwner(), memberCountUnderAvatar::setText);
|
viewModel.getMemberCountSummary().observe(getViewLifecycleOwner(), memberCountUnderAvatar::setText);
|
||||||
viewModel.getFullMemberCountSummary().observe(getViewLifecycleOwner(), memberCountAboveList::setText);
|
viewModel.getFullMemberCountSummary().observe(getViewLifecycleOwner(), memberCountAboveList::setText);
|
||||||
viewModel.getGroupRecipient().observe(getViewLifecycleOwner(), avatar::setRecipient);
|
viewModel.getGroupRecipient().observe(getViewLifecycleOwner(), groupRecipient -> {
|
||||||
|
avatar.setRecipient(groupRecipient);
|
||||||
|
avatar.setOnClickListener(v -> {
|
||||||
|
FragmentActivity activity = requireActivity();
|
||||||
|
activity.startActivity(AvatarPreviewActivity.intentFromRecipientId(activity, groupRecipient.getId()),
|
||||||
|
AvatarPreviewActivity.createTransitionBundle(activity, avatar));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
viewModel.getGroupViewState().observe(getViewLifecycleOwner(), vs -> {
|
viewModel.getGroupViewState().observe(getViewLifecycleOwner(), vs -> {
|
||||||
if (vs == null) return;
|
if (vs == null) return;
|
||||||
|
29
app/src/main/res/layout/contact_photo_preview_activity.xml
Normal file
29
app/src/main/res/layout/contact_photo_preview_activity.xml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/core_grey_95">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/avatar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:transitionName="avatar" />
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/toolbar_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/media_preview_bar_background"
|
||||||
|
app:elevation="0dp">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:background="@android:color/transparent" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
Loading…
x
Reference in New Issue
Block a user