refactor: replacing the media loader calls to no longer bucket them by dates

This commit is contained in:
0x330a
2022-11-24 09:18:35 +11:00
parent 75a10f71c3
commit 9d8ccc765e
6 changed files with 66 additions and 192 deletions

View File

@@ -1,173 +0,0 @@
/*
* Copyright (C) 2015 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import android.content.Context;
import androidx.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.codewaves.stickyheadergrid.StickyHeaderGridAdapter;
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView;
import org.thoughtcrime.securesms.database.MediaDatabase.MediaRecord;
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.util.MediaUtil;
import java.util.Collection;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import network.loki.messenger.R;
class MediaGalleryAdapter extends StickyHeaderGridAdapter {
@SuppressWarnings("unused")
private static final String TAG = MediaGalleryAdapter.class.getSimpleName();
private final Context context;
private final GlideRequests glideRequests;
private final Locale locale;
private final ItemClickListener itemClickListener;
private final Set<MediaRecord> selected;
private BucketedThreadMedia media;
private static class ViewHolder extends StickyHeaderGridAdapter.ItemViewHolder {
ThumbnailView imageView;
View selectedIndicator;
ViewHolder(View v) {
super(v);
imageView = v.findViewById(R.id.image);
selectedIndicator = v.findViewById(R.id.selected_indicator);
}
}
private static class HeaderHolder extends StickyHeaderGridAdapter.HeaderViewHolder {
TextView textView;
HeaderHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text);
}
}
MediaGalleryAdapter(@NonNull Context context,
@NonNull GlideRequests glideRequests,
BucketedThreadMedia media,
Locale locale,
ItemClickListener clickListener)
{
this.context = context;
this.glideRequests = glideRequests;
this.locale = locale;
this.media = media;
this.itemClickListener = clickListener;
this.selected = new HashSet<>();
}
public void setMedia(BucketedThreadMedia media) {
this.media = media;
}
@Override
public StickyHeaderGridAdapter.HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent, int headerType) {
return new HeaderHolder(LayoutInflater.from(context).inflate(R.layout.media_overview_gallery_item_header, parent, false));
}
@Override
public ItemViewHolder onCreateItemViewHolder(ViewGroup parent, int itemType) {
return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.media_overview_gallery_item, parent, false));
}
@Override
public void onBindHeaderViewHolder(StickyHeaderGridAdapter.HeaderViewHolder viewHolder, int section) {
((HeaderHolder)viewHolder).textView.setText(media.getName(section, locale));
}
@Override
public void onBindItemViewHolder(ItemViewHolder viewHolder, int section, int offset) {
MediaRecord mediaRecord = media.get(section, offset);
ThumbnailView thumbnailView = ((ViewHolder)viewHolder).imageView;
View selectedIndicator = ((ViewHolder)viewHolder).selectedIndicator;
Slide slide = MediaUtil.getSlideForAttachment(context, mediaRecord.getAttachment());
if (slide != null) {
thumbnailView.setImageResource(glideRequests, slide, false, false);
}
thumbnailView.setOnClickListener(view -> itemClickListener.onMediaClicked(mediaRecord));
thumbnailView.setOnLongClickListener(view -> {
itemClickListener.onMediaLongClicked(mediaRecord);
return true;
});
selectedIndicator.setVisibility(selected.contains(mediaRecord) ? View.VISIBLE : View.GONE);
}
@Override
public int getSectionCount() {
return media.getSectionCount();
}
@Override
public int getSectionItemCount(int section) {
return media.getSectionItemCount(section);
}
public void toggleSelection(@NonNull MediaRecord mediaRecord) {
if (!selected.remove(mediaRecord)) {
selected.add(mediaRecord);
}
notifyDataSetChanged();
}
public int getSelectedMediaCount() {
return selected.size();
}
@NonNull
public Collection<MediaRecord> getSelectedMedia() {
return new HashSet<>(selected);
}
public void clearSelection() {
selected.clear();
notifyDataSetChanged();
}
void selectAllMedia() {
for (int section = 0; section < media.getSectionCount(); section++) {
for (int item = 0; item < media.getSectionItemCount(section); item++) {
selected.add(media.get(section, item));
}
}
this.notifyDataSetChanged();
}
interface ItemClickListener {
void onMediaClicked(@NonNull MediaRecord mediaRecord);
void onMediaLongClicked(MediaRecord mediaRecord);
}
}

View File

@@ -0,0 +1,53 @@
package org.thoughtcrime.securesms
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import network.loki.messenger.R
import network.loki.messenger.databinding.MediaOverviewGalleryItemBinding
import org.thoughtcrime.securesms.database.MediaDatabase.MediaRecord
class MediaGalleryAdapter(private val itemClickListener: ItemClickListener): RecyclerView.Adapter<MediaGalleryAdapter.ViewHolder>() {
private val items: MutableList<MediaRecord> = mutableListOf()
private val selectedItems: MutableList<MediaRecord> = mutableListOf()
fun setItems(newItems: List<MediaRecord>) {
items.clear()
items += newItems
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.media_overview_gallery_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = items[position]
holder.bind(item, selectedItems.contains(item), itemClickListener)
}
override fun getItemCount(): Int = items.size
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
private val binding = MediaOverviewGalleryItemBinding.bind(itemView)
fun bind(item: MediaRecord, isSelected: Boolean, itemClickListener: ItemClickListener) {
binding.image.setOnClickListener { itemClickListener.onMediaClicked(item) }
binding.image.setOnLongClickListener {
itemClickListener.onMediaLongClicked(item)
true
}
binding.selectedIndicator.isVisible = isSelected
}
}
interface ItemClickListener {
fun onMediaClicked(mediaRecord: MediaRecord)
fun onMediaLongClicked(mediaRecord: MediaRecord?)
}
}

View File

@@ -75,7 +75,9 @@ import org.thoughtcrime.securesms.util.AttachmentUtil;
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
@@ -244,7 +246,7 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity i
}
public static class MediaOverviewGalleryFragment
extends MediaOverviewFragment<BucketedThreadMedia>
extends MediaOverviewFragment<ThreadMediaLoader>
implements MediaGalleryAdapter.ItemClickListener
{
@@ -260,11 +262,7 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity i
this.noMedia = ViewUtil.findById(view, R.id.no_images);
this.gridManager = new StickyHeaderGridLayoutManager(getResources().getInteger(R.integer.media_overview_cols));
this.recyclerView.setAdapter(new MediaGalleryAdapter(getContext(),
GlideApp.with(this),
new BucketedThreadMedia(getContext()),
locale,
this));
this.recyclerView.setAdapter(new MediaGalleryAdapter(this));
this.recyclerView.setLayoutManager(gridManager);
this.recyclerView.setHasFixedSize(true);
@@ -281,22 +279,21 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity i
}
@Override
public @NonNull Loader<BucketedThreadMedia> onCreateLoader(int i, Bundle bundle) {
return new BucketedThreadMediaLoader(getContext(), recipient.getAddress());
public @NonNull Loader<ThreadMediaLoader> onCreateLoader(int i, Bundle bundle) {
return new ThreadMediaLoader(getContext(), recipient.getAddress(), true);
}
@Override
public void onLoadFinished(@NonNull Loader<BucketedThreadMedia> loader, BucketedThreadMedia bucketedThreadMedia) {
((MediaGalleryAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
((MediaGalleryAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
public void onLoadFinished(@NonNull Loader<ThreadMediaLoader> loader, ThreadMediaLoader threadMedia) {
((MediaGalleryAdapter) recyclerView.getAdapter()).setItems(threadMedia.);
noMedia.setVisibility(recyclerView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
getActivity().invalidateOptionsMenu();
}
@Override
public void onLoaderReset(@NonNull Loader<BucketedThreadMedia> cursorLoader) {
((MediaGalleryAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMedia(getContext()));
public void onLoaderReset(@NonNull Loader<ThreadMediaLoader> cursorLoader) {
((MediaGalleryAdapter) recyclerView.getAdapter()).setItems(new ArrayList<>());
}
@Override

View File

@@ -103,7 +103,7 @@
<dimen name="quote_corner_radius_bottom">2dp</dimen>
<dimen name="quote_corner_radius_preview">16dp</dimen>
<integer name="media_overview_cols">3</integer>
<integer name="media_overview_cols">4</integer>
<dimen name="contact_selection_actions_tap_area">10dp</dimen>

View File

@@ -55,9 +55,8 @@ public class DatabaseAttachment extends Attachment {
@Override
public boolean equals(Object other) {
return other != null &&
other instanceof DatabaseAttachment &&
((DatabaseAttachment) other).attachmentId.equals(this.attachmentId);
return other instanceof DatabaseAttachment &&
((DatabaseAttachment) other).attachmentId.equals(this.attachmentId);
}
@Override

View File

@@ -103,8 +103,6 @@
<dimen name="quote_corner_radius_bottom">2dp</dimen>
<dimen name="quote_corner_radius_preview">16dp</dimen>
<integer name="media_overview_cols">3</integer>
<dimen name="contact_selection_actions_tap_area">10dp</dimen>
<dimen name="unread_count_bubble_radius">13sp</dimen>