Finalize wallpaper UX.

Co-authored-by: Greyson Parrelli <greyson@signal.org>
Co-authored-by: Alan Evans <alan@signal.org>
This commit is contained in:
Alex Hart
2021-01-20 17:09:36 -04:00
committed by Greyson Parrelli
parent a8ad1e718e
commit c244a98962
29 changed files with 455 additions and 90 deletions

View File

@@ -0,0 +1,43 @@
package org.thoughtcrime.securesms.wallpaper;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
class ChatWallpaperAlignmentDecoration extends RecyclerView.ItemDecoration {
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
int itemPosition = parent.getChildAdapterPosition(view);
int itemCount = state.getItemCount();
if (itemCount > 0 && itemPosition == itemCount - 1) {
outRect.set(0, 0, 0, 0);
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
int viewWidth = view.getMeasuredWidth() + params.rightMargin + params.leftMargin;
int availableWidth = (parent.getRight() - parent.getPaddingRight()) - (parent.getLeft() + parent.getPaddingLeft());
int itemsPerRow = availableWidth / viewWidth;
if (itemsPerRow == 1 || (itemPosition + 1) % itemsPerRow == 0) {
return;
}
int extraCellsNeeded = itemsPerRow - ((itemPosition + 1) % itemsPerRow);
setEnd(outRect, view.getLayoutDirection(), extraCellsNeeded * viewWidth);
} else {
super.getItemOffsets(outRect, view, parent, state);
}
}
private void setEnd(@NonNull Rect outRect, int layoutDirection, int end) {
if (layoutDirection == View.LAYOUT_DIRECTION_LTR) {
outRect.right = end;
} else {
outRect.left = end;
}
}
}

View File

@@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.wallpaper;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -8,6 +9,7 @@ import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
@@ -18,6 +20,12 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.ThemeUtil;
public class ChatWallpaperFragment extends Fragment {
private boolean isSettingDimFromViewModel;
private View clearWallpaper;
private View resetAllWallpaper;
private View divider;
@Override
public @NonNull View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.chat_wallpaper_fragment, container, false);
@@ -30,8 +38,10 @@ public class ChatWallpaperFragment extends Fragment {
View setWallpaper = view.findViewById(R.id.chat_wallpaper_set_wallpaper);
SwitchCompat dimInNightMode = view.findViewById(R.id.chat_wallpaper_dark_theme_dims_wallpaper);
View chatWallpaperDim = view.findViewById(R.id.chat_wallpaper_dim);
View clearWallpaper = view.findViewById(R.id.chat_wallpaper_clear_wallpaper);
View resetAllWallpaper = view.findViewById(R.id.chat_wallpaper_reset_all_wallpapers);
clearWallpaper = view.findViewById(R.id.chat_wallpaper_clear_wallpaper);
resetAllWallpaper = view.findViewById(R.id.chat_wallpaper_reset_all_wallpapers);
divider = view.findViewById(R.id.chat_wallpaper_divider);
viewModel.getCurrentWallpaper().observe(getViewLifecycleOwner(), wallpaper -> {
if (wallpaper.isPresent()) {
@@ -40,36 +50,78 @@ public class ChatWallpaperFragment extends Fragment {
chatWallpaperPreview.setImageDrawable(null);
chatWallpaperPreview.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.signal_background_primary));
}
dimInNightMode.setEnabled(wallpaper.isPresent());
});
viewModel.getDimInDarkTheme().observe(getViewLifecycleOwner(), shouldDimInNightMode -> {
if (shouldDimInNightMode != dimInNightMode.isChecked()) {
isSettingDimFromViewModel = true;
dimInNightMode.setChecked(shouldDimInNightMode);
isSettingDimFromViewModel = false;
}
chatWallpaperDim.setAlpha(ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME);
chatWallpaperDim.setVisibility(shouldDimInNightMode && ThemeUtil.isDarkTheme(requireContext()) ? View.VISIBLE : View.GONE);
});
viewModel.getEnableWallpaperControls().observe(getViewLifecycleOwner(), enableWallpaperControls -> {
dimInNightMode.setEnabled(enableWallpaperControls);
clearWallpaper.setVisibility(enableWallpaperControls ? View.VISIBLE : View.GONE);
updateDividerVisibility();
});
chatWallpaperPreview.setOnClickListener(unused -> setWallpaper.performClick());
setWallpaper.setOnClickListener(unused -> Navigation.findNavController(view)
.navigate(R.id.action_chatWallpaperFragment_to_chatWallpaperSelectionFragment));
clearWallpaper.setOnClickListener(unused -> {
viewModel.setWallpaper(null);
viewModel.setDimInDarkTheme(false);
viewModel.saveWallpaperSelection();
});
resetAllWallpaper.setVisibility(viewModel.isGlobal() ? View.VISIBLE : View.GONE);
updateDividerVisibility();
clearWallpaper.setOnClickListener(unused -> {
confirmAction(R.string.ChatWallpaperFragment__clear_wallpaper_question_mark,
R.string.ChatWallpaperFragment__clear,
() -> {
viewModel.setWallpaper(null);
viewModel.setDimInDarkTheme(false);
viewModel.saveWallpaperSelection();
});
});
resetAllWallpaper.setOnClickListener(unused -> {
viewModel.setWallpaper(null);
viewModel.setDimInDarkTheme(false);
viewModel.resetAllWallpaper();
confirmAction(R.string.ChatWallpaperFragment__reset_all_wallpapers_question_mark,
R.string.ChatWallpaperFragment__reset,
() -> {
viewModel.setWallpaper(null);
viewModel.setDimInDarkTheme(false);
viewModel.resetAllWallpaper();
});
});
dimInNightMode.setOnCheckedChangeListener((buttonView, isChecked) -> viewModel.setDimInDarkTheme(isChecked));
dimInNightMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (!isSettingDimFromViewModel) {
viewModel.setDimInDarkTheme(isChecked);
}
});
}
private void updateDividerVisibility() {
if (clearWallpaper.getVisibility() == View.VISIBLE || resetAllWallpaper.getVisibility() == View.VISIBLE) {
divider.setVisibility(View.VISIBLE);
} else {
divider.setVisibility(View.GONE);
}
}
private void confirmAction(@StringRes int title, @StringRes int positiveActionLabel, @NonNull Runnable onPositiveAction) {
new AlertDialog.Builder(requireContext())
.setMessage(title)
.setPositiveButton(positiveActionLabel, (dialog, which) -> {
onPositiveAction.run();
dialog.dismiss();
})
.setNegativeButton(android.R.string.cancel, (dialog, which) -> {
dialog.dismiss();
})
.setCancelable(true)
.show();
}
}

View File

@@ -2,24 +2,30 @@ package org.thoughtcrime.securesms.wallpaper;
import android.content.Context;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.view.ViewCompat;
import androidx.viewpager2.widget.ViewPager2;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.PassphraseRequiredActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.ActivityTransitionUtil;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.FullscreenHelper;
import org.thoughtcrime.securesms.util.MappingModel;
import org.thoughtcrime.securesms.util.WindowUtil;
import java.util.Collections;
@@ -27,14 +33,16 @@ public class ChatWallpaperPreviewActivity extends PassphraseRequiredActivity {
public static final String EXTRA_CHAT_WALLPAPER = "extra.chat.wallpaper";
private static final String EXTRA_DIM_IN_DARK_MODE = "extra.dim.in.dark.mode";
private static final String EXTRA_RECIPIENT_ID = "extra.recipient.id";
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
public static @NonNull Intent create(@NonNull Context context, @NonNull ChatWallpaper selection, boolean dimInDarkMode) {
public static @NonNull Intent create(@NonNull Context context, @NonNull ChatWallpaper selection, @NonNull RecipientId recipientId, boolean dimInDarkMode) {
Intent intent = new Intent(context, ChatWallpaperPreviewActivity.class);
intent.putExtra(EXTRA_CHAT_WALLPAPER, selection);
intent.putExtra(EXTRA_DIM_IN_DARK_MODE, dimInDarkMode);
intent.putExtra(EXTRA_RECIPIENT_ID, recipientId);
return intent;
}
@@ -52,6 +60,8 @@ public class ChatWallpaperPreviewActivity extends PassphraseRequiredActivity {
ChatWallpaper selected = getIntent().getParcelableExtra(EXTRA_CHAT_WALLPAPER);
boolean dim = getIntent().getBooleanExtra(EXTRA_DIM_IN_DARK_MODE, false);
Toolbar toolbar = findViewById(R.id.toolbar);
View bubble1 = findViewById(R.id.preview_bubble_1);
TextView bubble2 = findViewById(R.id.preview_bubble_2_text);
toolbar.setNavigationOnClickListener(unused -> {
finish();
@@ -62,7 +72,7 @@ public class ChatWallpaperPreviewActivity extends PassphraseRequiredActivity {
adapter.submitList(Collections.singletonList(new ChatWallpaperSelectionMappingModel(selected)));
repository.getAllWallpaper(wallpapers -> adapter.submitList(Stream.of(wallpapers)
.map(wallpaper -> ChatWallpaperFactory.updateWithDimming(wallpaper, dim ? 1f : 0f))
.map(wallpaper -> ChatWallpaperFactory.updateWithDimming(wallpaper, dim ? ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME : 0f))
.<MappingModel<?>>map(ChatWallpaperSelectionMappingModel::new)
.toList()));
@@ -73,7 +83,16 @@ public class ChatWallpaperPreviewActivity extends PassphraseRequiredActivity {
finish();
});
RecipientId recipientId = getIntent().getParcelableExtra(EXTRA_RECIPIENT_ID);
if (recipientId != null) {
Recipient recipient = Recipient.live(recipientId).get();
bubble1.getBackground().setColorFilter(recipient.getColor().toConversationColor(this), PorterDuff.Mode.SRC_IN);
bubble2.setText(getString(R.string.ChatWallpaperPreviewActivity__set_wallpaper_for_s, recipient.getDisplayName(this)));
}
new FullscreenHelper(this).showSystemUI();
WindowUtil.setLightStatusBarFromTheme(this);
WindowUtil.setLightNavigationBarFromTheme(this);
}
@Override

View File

@@ -14,6 +14,8 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.concurrent.SerialExecutor;
import org.whispersystems.libsignal.util.guava.Optional;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executor;
@@ -24,14 +26,19 @@ class ChatWallpaperRepository {
@MainThread
@Nullable ChatWallpaper getCurrentWallpaper(@Nullable RecipientId recipientId) {
if (recipientId != null) {
return Recipient.resolved(recipientId).getWallpaper();
return Recipient.live(recipientId).get().getWallpaper();
} else {
return SignalStore.wallpaper().getWallpaper();
}
}
void getAllWallpaper(@NonNull Consumer<List<ChatWallpaper>> consumer) {
consumer.accept(ChatWallpaper.BUILTINS);
EXECUTOR.execute(() -> {
List<ChatWallpaper> wallpapers = new ArrayList<>(ChatWallpaper.BUILTINS);
wallpapers.addAll(WallpaperStorage.getAll(ApplicationDependencies.getApplication()));
consumer.accept(wallpapers);
});
}
void saveWallpaper(@Nullable RecipientId recipientId, @Nullable ChatWallpaper chatWallpaper) {
@@ -52,10 +59,21 @@ class ChatWallpaperRepository {
});
}
void setDimInDarkTheme(@NonNull RecipientId recipientId, boolean dimInDarkTheme) {
void setDimInDarkTheme(@Nullable RecipientId recipientId, boolean dimInDarkTheme) {
if (recipientId != null) {
EXECUTOR.execute(() -> {
DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).setDimWallpaperInDarkTheme(recipientId, dimInDarkTheme);
Recipient recipient = Recipient.resolved(recipientId);
if (recipient.hasOwnWallpaper()) {
DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).setDimWallpaperInDarkTheme(recipientId, dimInDarkTheme);
} else if (recipient.hasWallpaper()) {
DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication())
.setWallpaper(recipientId,
ChatWallpaperFactory.updateWithDimming(recipient.getWallpaper(),
dimInDarkTheme ? ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME
: 0f));
} else {
throw new IllegalStateException("Unexpected call to setDimInDarkTheme, no wallpaper has been set on the given recipient or globally.");
}
});
} else {
SignalStore.wallpaper().setDimInDarkTheme(dimInDarkTheme);

View File

@@ -1,11 +1,13 @@
package org.thoughtcrime.securesms.wallpaper;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -14,10 +16,12 @@ import androidx.lifecycle.ViewModelProviders;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.flexbox.AlignContent;
import com.google.android.flexbox.FlexboxLayoutManager;
import com.google.android.flexbox.JustifyContent;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.util.ActivityTransitionUtil;
import org.thoughtcrime.securesms.wallpaper.crop.WallpaperImageSelectionActivity;
@@ -39,23 +43,30 @@ public class ChatWallpaperSelectionFragment extends Fragment {
FlexboxLayoutManager flexboxLayoutManager = new FlexboxLayoutManager(requireContext());
chooseFromPhotos.setOnClickListener(unused -> {
startActivityForResult(WallpaperImageSelectionActivity.getIntent(requireContext(), viewModel.getRecipientId()), CHOOSE_WALLPAPER);
askForPermissionIfNeededAndLaunchPhotoSelection();
});
@SuppressWarnings("CodeBlock2Expr")
ChatWallpaperSelectionAdapter adapter = new ChatWallpaperSelectionAdapter(chatWallpaper -> {
startActivityForResult(ChatWallpaperPreviewActivity.create(requireActivity(), chatWallpaper, viewModel.getDimInDarkTheme().getValue()), CHOOSE_WALLPAPER);
startActivityForResult(ChatWallpaperPreviewActivity.create(requireActivity(), chatWallpaper, viewModel.getRecipientId(), viewModel.getDimInDarkTheme().getValue()), CHOOSE_WALLPAPER);
ActivityTransitionUtil.setSlideInTransition(requireActivity());
});
flexboxLayoutManager.setJustifyContent(JustifyContent.SPACE_AROUND);
flexboxLayoutManager.setJustifyContent(JustifyContent.CENTER);
recyclerView.setLayoutManager(flexboxLayoutManager);
recyclerView.setAdapter(adapter);
recyclerView.addItemDecoration(new ChatWallpaperAlignmentDecoration());
viewModel = ViewModelProviders.of(requireActivity()).get(ChatWallpaperViewModel.class);
viewModel.getWallpapers().observe(getViewLifecycleOwner(), adapter::submitList);
}
@Override
public void onResume() {
super.onResume();
viewModel.refreshWallpaper();
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == CHOOSE_WALLPAPER && resultCode == Activity.RESULT_OK && data != null) {
@@ -67,4 +78,17 @@ public class ChatWallpaperSelectionFragment extends Fragment {
super.onActivityResult(requestCode, resultCode, data);
}
}
private void askForPermissionIfNeededAndLaunchPhotoSelection() {
Permissions.with(this)
.request(Manifest.permission.READ_EXTERNAL_STORAGE)
.ifNecessary()
.onAllGranted(() -> {
startActivityForResult(WallpaperImageSelectionActivity.getIntent(requireContext(), viewModel.getRecipientId()), CHOOSE_WALLPAPER);
ActivityTransitionUtil.setSlideInTransition(requireActivity());
})
.onAnyDenied(() -> Toast.makeText(requireContext(), R.string.ChatWallpaperPreviewActivity__viewing_your_gallery_requires_the_storage_permission, Toast.LENGTH_SHORT)
.show())
.execute();
}
}

View File

@@ -9,6 +9,8 @@ import androidx.lifecycle.ViewModelProvider;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.MappingModel;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
@@ -19,10 +21,11 @@ import java.util.Objects;
public class ChatWallpaperViewModel extends ViewModel {
private final ChatWallpaperRepository repository = new ChatWallpaperRepository();
private final MutableLiveData<Optional<ChatWallpaper>> wallpaper = new MutableLiveData<>();
private final MutableLiveData<List<ChatWallpaper>> builtins = new MutableLiveData<>();
private final MutableLiveData<Boolean> dimInDarkTheme = new MutableLiveData<>();
private final ChatWallpaperRepository repository = new ChatWallpaperRepository();
private final MutableLiveData<Optional<ChatWallpaper>> wallpaper = new MutableLiveData<>();
private final MutableLiveData<List<ChatWallpaper>> builtins = new MutableLiveData<>();
private final MutableLiveData<Boolean> dimInDarkTheme = new MutableLiveData<>();
private final MutableLiveData<Boolean> enableWallpaperControls = new MutableLiveData<>();
private final RecipientId recipientId;
private ChatWallpaperViewModel(@Nullable RecipientId recipientId) {
@@ -30,7 +33,11 @@ public class ChatWallpaperViewModel extends ViewModel {
ChatWallpaper currentWallpaper = repository.getCurrentWallpaper(recipientId);
dimInDarkTheme.setValue(currentWallpaper != null && currentWallpaper.getDimLevelForDarkTheme() > 0f);
enableWallpaperControls.setValue(hasClearableWallpaper());
wallpaper.setValue(Optional.fromNullable(currentWallpaper));
}
void refreshWallpaper() {
repository.getAllWallpaper(builtins::postValue);
}
@@ -53,7 +60,18 @@ public class ChatWallpaperViewModel extends ViewModel {
if (!wallpaper.isPresent()) {
repository.saveWallpaper(recipientId, null);
if (recipientId != null) {
ChatWallpaper globalWallpaper = SignalStore.wallpaper().getWallpaper();
this.wallpaper.setValue(Optional.fromNullable(globalWallpaper));
this.dimInDarkTheme.setValue(globalWallpaper != null && globalWallpaper.getDimLevelForDarkTheme() > 0);
}
enableWallpaperControls.setValue(false);
return;
} else {
enableWallpaperControls.setValue(true);
}
Optional<ChatWallpaper> updated = wallpaper.transform(paper -> ChatWallpaperFactory.updateWithDimming(paper, dimInDarkTheme ? ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME : 0f));
@@ -67,30 +85,39 @@ public class ChatWallpaperViewModel extends ViewModel {
repository.resetAllWallpaper();
}
public @Nullable RecipientId getRecipientId() {
@Nullable RecipientId getRecipientId() {
return recipientId;
}
LiveData<Optional<ChatWallpaper>> getCurrentWallpaper() {
@NonNull LiveData<Optional<ChatWallpaper>> getCurrentWallpaper() {
return wallpaper;
}
LiveData<List<MappingModel<?>>> getWallpapers() {
@NonNull LiveData<List<MappingModel<?>>> getWallpapers() {
return LiveDataUtil.combineLatest(builtins, dimInDarkTheme, (wallpapers, dimInDarkMode) ->
Stream.of(wallpapers)
.map(paper -> ChatWallpaperFactory.updateWithDimming(paper, dimInDarkMode ? 1f : 0f))
.map(paper -> ChatWallpaperFactory.updateWithDimming(paper, dimInDarkMode ? ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME : 0f))
.<MappingModel<?>>map(ChatWallpaperSelectionMappingModel::new).toList()
);
}
LiveData<Boolean> getDimInDarkTheme() {
@NonNull LiveData<Boolean> getDimInDarkTheme() {
return dimInDarkTheme;
}
@NonNull LiveData<Boolean> getEnableWallpaperControls() {
return enableWallpaperControls;
}
boolean isGlobal() {
return recipientId == null;
}
private boolean hasClearableWallpaper() {
return (isGlobal() && SignalStore.wallpaper().hasWallpaperSet()) ||
(recipientId != null && Recipient.live(recipientId).get().hasOwnWallpaper());
}
public static class Factory implements ViewModelProvider.Factory {
private final RecipientId recipientId;

View File

@@ -22,6 +22,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -39,9 +40,9 @@ public final class WallpaperStorage {
* Saves the provided input stream as a new wallpaper file.
*/
@WorkerThread
public static @NonNull ChatWallpaper save(@NonNull Context context, @NonNull InputStream wallpaperStream) throws IOException {
public static @NonNull ChatWallpaper save(@NonNull Context context, @NonNull InputStream wallpaperStream, @NonNull String extension) throws IOException {
File directory = context.getDir(DIRECTORY, Context.MODE_PRIVATE);
File file = File.createTempFile(FILENAME_BASE, "", directory);
File file = File.createTempFile(FILENAME_BASE, "." + extension, directory);
StreamUtil.copy(wallpaperStream, getOutputStream(context, file));
@@ -61,11 +62,15 @@ public final class WallpaperStorage {
File directory = context.getDir(DIRECTORY, Context.MODE_PRIVATE);
File[] allFiles = directory.listFiles(pathname -> pathname.getName().contains(FILENAME_BASE));
return Stream.of(allFiles)
.map(File::getName)
.map(PartAuthority::getWallpaperUri)
.map(ChatWallpaperFactory::create)
.toList();
if (allFiles != null) {
return Stream.of(allFiles)
.map(File::getName)
.map(PartAuthority::getWallpaperUri)
.map(ChatWallpaperFactory::create)
.toList();
} else {
return Collections.emptyList();
}
}
/**

View File

@@ -17,6 +17,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.SwitchCompat;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
@@ -62,6 +63,12 @@ public final class WallpaperCropActivity extends BaseActivity {
return intent;
}
@Override
protected void attachBaseContext(@NonNull Context newBase) {
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
super.attachBaseContext(newBase);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

View File

@@ -33,7 +33,7 @@ final class WallpaperCropRepository {
@WorkerThread
@NonNull ChatWallpaper setWallPaper(byte[] bytes) throws IOException {
try (InputStream inputStream = new ByteArrayInputStream(bytes)) {
ChatWallpaper wallpaper = WallpaperStorage.save(context, inputStream);
ChatWallpaper wallpaper = WallpaperStorage.save(context, inputStream, "webp");
if (recipientId != null) {
Log.i(TAG, "Setting image wallpaper for " + recipientId);

View File

@@ -1,11 +1,13 @@
package org.thoughtcrime.securesms.wallpaper.crop;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresPermission;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
@@ -23,6 +25,7 @@ public final class WallpaperImageSelectionActivity extends AppCompatActivity
private static final String EXTRA_RECIPIENT_ID = "RECIPIENT_ID";
private static final int CROP = 901;
@RequiresPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
public static Intent getIntent(@NonNull Context context,
@Nullable RecipientId recipientId)
{