Re-added favorite community functionality

This commit re-adds the ability to mark communities as 'favorites'. This function only works locally as Lemmy does not have an API/functionality for this.
This commit is contained in:
Balazs Toldi 2023-07-20 15:58:52 +02:00
parent c9e6a0bc2e
commit 267570d7b4
No known key found for this signature in database
GPG Key ID: 6C7D440036F99D58
12 changed files with 144 additions and 29 deletions

View File

@ -111,7 +111,7 @@ class ParseSubscribedThing {
int instanceId = community.getInt("instance_id");
int subscribers = data.getJSONObject("counts").getInt("subscribers");
boolean isBlocked = data.getBoolean("blocked");
newSubscribedSubredditData.add(new SubscribedSubredditData(id, title, LemmyUtils.actorID2FullName(actorId), iconUrl, accountName));
newSubscribedSubredditData.add(new SubscribedSubredditData(id, title, LemmyUtils.actorID2FullName(actorId), iconUrl, accountName, false));
newSubredditData.add(new SubredditData(id, name, title, description, removed, published, updated, deleted, nsfw, actorId, local, iconUrl, bannerImageUrl, hidden, postingRestrictedToMods, instanceId, subscribers, isBlocked));
}

View File

@ -42,7 +42,7 @@ import eu.toldi.infinityforlemmy.user.UserData;
@Database(entities = {Account.class, SubredditData.class, SubscribedSubredditData.class, UserData.class,
SubscribedUserData.class, MultiReddit.class, CustomTheme.class, RecentSearchQuery.class,
ReadPost.class, PostFilter.class, PostFilterUsage.class, AnonymousMultiredditSubreddit.class, BlockedUserData.class, BlockedCommunityData.class}, version = 26)
ReadPost.class, PostFilter.class, PostFilterUsage.class, AnonymousMultiredditSubreddit.class, BlockedUserData.class, BlockedCommunityData.class}, version = 27)
public abstract class RedditDataRoomDatabase extends RoomDatabase {
public static RedditDataRoomDatabase create(final Context context) {
@ -53,7 +53,7 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase {
MIGRATION_9_10, MIGRATION_10_11, MIGRATION_11_12, MIGRATION_12_13,
MIGRATION_13_14, MIGRATION_14_15, MIGRATION_15_16, MIGRATION_16_17,
MIGRATION_17_18, MIGRATION_18_19, MIGRATION_19_20, MIGRATION_20_21,
MIGRATION_21_22, MIGRATION_22_23, MIGRATION_23_24, MIGRATION_24_25, MIGRATION_25_26)
MIGRATION_21_22, MIGRATION_22_23, MIGRATION_23_24, MIGRATION_24_25, MIGRATION_25_26, MIGRATION_26_27)
.build();
}
@ -416,4 +416,12 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase {
}
};
private static final Migration MIGRATION_26_27 = new Migration(26, 27) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE subscribed_subreddits"
+ " ADD COLUMN is_favorite INTEGER DEFAULT 0 NOT NULL");
}
};
}

View File

@ -1011,12 +1011,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
sectionsPagerAdapter.setSubscribedSubreddits(subscribedSubredditData);
}
});
/*subscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(this, subscribedSubredditData -> {
subscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(this, subscribedSubredditData -> {
adapter.setFavoriteSubscribedSubreddits(subscribedSubredditData);
if (mShowFavoriteSubscribedSubreddits && sectionsPagerAdapter != null) {
sectionsPagerAdapter.setFavoriteSubscribedSubreddits(subscribedSubredditData);
}
});*/
});
accountViewModel = new ViewModelProvider(this,
new AccountViewModel.Factory(mRedditDataRoomDatabase)).get(AccountViewModel.class);

View File

@ -1,9 +1,11 @@
package eu.toldi.infinityforlemmy.adapters;
import android.content.Intent;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
@ -22,6 +24,7 @@ import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.activities.BaseActivity;
import eu.toldi.infinityforlemmy.activities.ViewSubredditDetailActivity;
import eu.toldi.infinityforlemmy.asynctasks.InsertSubscribedThings;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.subscribedsubreddit.SubscribedSubredditData;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
@ -158,11 +161,31 @@ public class SubscribedSubredditsRecyclerViewAdapter extends RecyclerView.Adapte
fullname = mSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).getQualified_name();
iconUrl = mSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).getIconUrl();
if (mSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).isFavorite()) {
((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp);
} else {
((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp);
}
((SubredditViewHolder) viewHolder).favoriteImageView.setOnClickListener(view -> {
if (mSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).isFavorite()) {
((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp);
mSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).setFavorite(false);
} else {
((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp);
mSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).setFavorite(true);
}
InsertSubscribedThings.insertSubscribedThings(mExecutor, new Handler(), mRedditDataRoomDatabase, mSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset),
() -> {
});
});
if (itemClickListener != null) {
viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(communityData));
}
}
if (itemClickListener == null) {
String finalFullname = fullname;
viewHolder.itemView.setOnClickListener(view -> {
@ -201,12 +224,33 @@ public class SubscribedSubredditsRecyclerViewAdapter extends RecyclerView.Adapte
String name = mFavoriteSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).getName();
String iconUrl = mFavoriteSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).getIconUrl();
if (mFavoriteSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).isFavorite()) {
((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp);
} else {
((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp);
}
((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setOnClickListener(view -> {
if (mFavoriteSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).isFavorite()) {
((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp);
mFavoriteSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).setFavorite(false);
} else {
((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp);
mFavoriteSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).setFavorite(true);
}
InsertSubscribedThings.insertSubscribedThings(mExecutor, new Handler(), mRedditDataRoomDatabase, mFavoriteSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset),
() -> {
});
});
if (itemClickListener != null) {
viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(communityData));
} else {
viewHolder.itemView.setOnClickListener(view -> {
Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, name);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY,
mFavoriteSubscribedSubredditData.get(viewHolder.getBindingAdapterPosition() - offset).getQualified_name());
mActivity.startActivity(intent);
});
}
@ -243,6 +287,7 @@ public class SubscribedSubredditsRecyclerViewAdapter extends RecyclerView.Adapte
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
if(holder instanceof SubredditViewHolder) {
glide.clear(((SubredditViewHolder) holder).iconGifImageView);
((SubredditViewHolder) holder).favoriteImageView.setVisibility(View.VISIBLE);
} else if (holder instanceof FavoriteSubredditViewHolder) {
glide.clear(((FavoriteSubredditViewHolder) holder).iconGifImageView);
}
@ -317,6 +362,8 @@ public class SubscribedSubredditsRecyclerViewAdapter extends RecyclerView.Adapte
GifImageView iconGifImageView;
@BindView(R.id.thing_name_text_view_item_subscribed_thing)
TextView subredditNameTextView;
@BindView(R.id.favorite_image_view_item_subscribed_thing)
ImageView favoriteImageView;
SubredditViewHolder(View itemView) {
super(itemView);
@ -333,6 +380,9 @@ public class SubscribedSubredditsRecyclerViewAdapter extends RecyclerView.Adapte
GifImageView iconGifImageView;
@BindView(R.id.thing_name_text_view_item_subscribed_thing)
TextView subredditNameTextView;
@BindView(R.id.favorite_image_view_item_subscribed_thing)
ImageView favoriteImageView;
FavoriteSubredditViewHolder(View itemView) {
super(itemView);

View File

@ -38,7 +38,7 @@ public class InsertSubscribedThings {
if (subscribedSubredditDataList != null) {
List<SubscribedSubredditData> existingSubscribedSubredditDataList =
subscribedSubredditDao.getAllSubscribedSubredditsList(accountName);
Collections.sort(subscribedSubredditDataList, (subscribedSubredditData, t1) -> subscribedSubredditData.getName().compareToIgnoreCase(t1.getName()));
Collections.sort(subscribedSubredditDataList, (subscribedSubredditData, t1) -> subscribedSubredditData.getQualified_name().compareToIgnoreCase(t1.getQualified_name()));
List<String> unsubscribedSubreddits = new ArrayList<>();
compareTwoSubscribedSubredditList(subscribedSubredditDataList, existingSubscribedSubredditDataList,
unsubscribedSubreddits);
@ -48,6 +48,9 @@ public class InsertSubscribedThings {
}
for (SubscribedSubredditData s : subscribedSubredditDataList) {
if (existingSubscribedSubredditDataList.contains(s)) {
continue;
}
subscribedSubredditDao.insert(s);
}
}
@ -79,7 +82,8 @@ public class InsertSubscribedThings {
});
}
public static void insertSubscribedThings(Executor executor, Handler handler, RedditDataRoomDatabase redditDataRoomDatabase,
public static void insertSubscribedThings(Executor executor, Handler
handler, RedditDataRoomDatabase redditDataRoomDatabase,
SubscribedSubredditData singleSubscribedSubredditData,
InsertSubscribedThingListener insertSubscribedThingListener) {
executor.execute(() -> {
@ -94,7 +98,8 @@ public class InsertSubscribedThings {
});
}
public static void insertSubscribedThings(Executor executor, Handler handler, RedditDataRoomDatabase redditDataRoomDatabase,
public static void insertSubscribedThings(Executor executor, Handler
handler, RedditDataRoomDatabase redditDataRoomDatabase,
SubscribedUserData mSingleSubscribedUserData,
InsertSubscribedThingListener insertSubscribedThingListener) {
executor.execute(() -> {
@ -109,35 +114,37 @@ public class InsertSubscribedThings {
});
}
private static void compareTwoSubscribedSubredditList(List<SubscribedSubredditData> newSubscribedSubreddits,
List<SubscribedSubredditData> oldSubscribedSubreddits,
List<String> unsubscribedSubredditNames) {
private static void compareTwoSubscribedSubredditList
(List<SubscribedSubredditData> newSubscribedSubreddits,
List<SubscribedSubredditData> oldSubscribedSubreddits,
List<String> unsubscribedSubredditNames) {
int newIndex = 0;
for (int oldIndex = 0; oldIndex < oldSubscribedSubreddits.size(); oldIndex++) {
if (newIndex >= newSubscribedSubreddits.size()) {
for (; oldIndex < oldSubscribedSubreddits.size(); oldIndex++) {
unsubscribedSubredditNames.add(oldSubscribedSubreddits.get(oldIndex).getName());
unsubscribedSubredditNames.add(oldSubscribedSubreddits.get(oldIndex).getQualified_name());
}
return;
}
SubscribedSubredditData old = oldSubscribedSubreddits.get(oldIndex);
for (; newIndex < newSubscribedSubreddits.size(); newIndex++) {
if (newSubscribedSubreddits.get(newIndex).getName().compareToIgnoreCase(old.getName()) == 0) {
if (newSubscribedSubreddits.get(newIndex).getQualified_name().compareToIgnoreCase(old.getQualified_name()) == 0) {
newIndex++;
break;
}
if (newSubscribedSubreddits.get(newIndex).getName().compareToIgnoreCase(old.getName()) > 0) {
unsubscribedSubredditNames.add(old.getName());
if (newSubscribedSubreddits.get(newIndex).getQualified_name().compareToIgnoreCase(old.getQualified_name()) > 0) {
unsubscribedSubredditNames.add(old.getQualified_name());
break;
}
}
}
}
private static void compareTwoSubscribedUserList(List<SubscribedUserData> newSubscribedUsers,
List<SubscribedUserData> oldSubscribedUsers,
List<String> unsubscribedUserNames) {
private static void compareTwoSubscribedUserList
(List<SubscribedUserData> newSubscribedUsers,
List<SubscribedUserData> oldSubscribedUsers,
List<String> unsubscribedUserNames) {
int newIndex = 0;
for (int oldIndex = 0; oldIndex < oldSubscribedUsers.size(); oldIndex++) {
if (newIndex >= newSubscribedUsers.size()) {

View File

@ -157,16 +157,16 @@ public class SubscribedSubredditsListingFragment extends Fragment implements Fra
adapter.setSubscribedSubreddits(subscribedSubredditData);
});
/* mSubscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(getViewLifecycleOwner(), favoriteSubscribedSubredditData -> {
mSwipeRefreshLayout.setRefreshing(false);
if (favoriteSubscribedSubredditData != null && favoriteSubscribedSubredditData.size() > 0) {
mLinearLayout.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
mGlide.clear(mImageView);
}
mSubscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(getViewLifecycleOwner(), favoriteSubscribedSubredditData -> {
mSwipeRefreshLayout.setRefreshing(false);
if (favoriteSubscribedSubredditData != null && favoriteSubscribedSubredditData.size() > 0) {
mLinearLayout.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
mGlide.clear(mImageView);
}
adapter.setFavoriteSubscribedSubreddits(favoriteSubscribedSubredditData);
});*/
adapter.setFavoriteSubscribedSubreddits(favoriteSubscribedSubredditData);
});
return rootView;
}

View File

@ -112,7 +112,7 @@ public class CommunitySubscription {
SubredditSubscriptionListener subredditSubscriptionListener) {
executor.execute(() -> {
SubscribedSubredditData subscribedSubredditData = new SubscribedSubredditData(subredditData.getId(), subredditData.getName(), LemmyUtils.actorID2FullName(subredditData.getActorId()),
subredditData.getIconUrl(), accountName);
subredditData.getIconUrl(), accountName, false);
if (accountName.equals("-")) {
if (!redditDataRoomDatabase.accountDao().isAnonymousAccountInserted()) {
redditDataRoomDatabase.accountDao().insert(Account.getAnonymousAccount());

View File

@ -33,4 +33,7 @@ public interface SubscribedSubredditDao {
@Query("DELETE FROM subscribed_subreddits WHERE name = :subredditName COLLATE NOCASE AND username = :accountName COLLATE NOCASE")
void deleteSubscribedSubreddit(String subredditName, String accountName);
@Query("SELECT * from subscribed_subreddits WHERE username = :qualified_name AND name LIKE '%' || :searchQuery || '%' COLLATE NOCASE AND is_favorite = 1 ORDER BY name COLLATE NOCASE ASC")
LiveData<List<SubscribedSubredditData>> getAllFavoriteSubscribedSubredditsWithSearchQuery(String qualified_name, String searchQuery);
}

View File

@ -4,6 +4,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
@ -30,12 +31,16 @@ public class SubscribedSubredditData implements Parcelable {
@ColumnInfo(name = "username")
private String username;
public SubscribedSubredditData(@NonNull int id, String name, @NonNull String qualified_name, String iconUrl, @NonNull String username) {
@ColumnInfo(name = "is_favorite")
private boolean favorite;
public SubscribedSubredditData(@NonNull int id, String name, @NonNull String qualified_name, String iconUrl, @NonNull String username, boolean favorite) {
this.id = id;
this.name = name;
this.iconUrl = iconUrl;
this.username = username;
this.qualified_name = qualified_name;
this.favorite = favorite;
}
public SubscribedSubredditData(@NonNull SubredditData communityData) {
@ -44,6 +49,7 @@ public class SubscribedSubredditData implements Parcelable {
this.iconUrl = communityData.getIconUrl();
this.username = "-";
this.qualified_name = LemmyUtils.actorID2FullName(communityData.getActorId());
this.favorite = false;
}
@NonNull
@ -89,6 +95,7 @@ public class SubscribedSubredditData implements Parcelable {
parcel.writeString(iconUrl);
parcel.writeString(username);
parcel.writeString(qualified_name);
parcel.writeByte((byte) (favorite ? 1 : 0));
}
public SubscribedSubredditData(Parcel in) {
@ -97,6 +104,7 @@ public class SubscribedSubredditData implements Parcelable {
iconUrl = in.readString();
username = in.readString();
qualified_name = in.readString();
favorite = in.readByte() != 0;
}
public static final Creator<SubscribedSubredditData> CREATOR = new Creator<>() {
@ -110,4 +118,25 @@ public class SubscribedSubredditData implements Parcelable {
return new SubscribedSubredditData[size];
}
};
public boolean isFavorite() {
return favorite;
}
public void setFavorite(boolean favorite) {
this.favorite = favorite;
}
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(@Nullable Object obj) {
if (obj instanceof SubscribedSubredditData) {
return id == ((SubscribedSubredditData) obj).getId();
}
return false;
}
}

View File

@ -21,6 +21,10 @@ public class SubscribedSubredditRepository {
return mSubscribedSubredditDao.getAllSubscribedSubredditsWithSearchQuery(mAccountName, searchQuery);
}
public LiveData<List<SubscribedSubredditData>> getAllFavoriteSubscribedSubredditsWithSearchQuery(String searchQuery) {
return mSubscribedSubredditDao.getAllFavoriteSubscribedSubredditsWithSearchQuery(mAccountName, searchQuery);
}
public void insert(SubscribedSubredditData subscribedSubredditData) {
new insertAsyncTask(mSubscribedSubredditDao).execute(subscribedSubredditData);
}

View File

@ -17,6 +17,7 @@ import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
public class SubscribedSubredditViewModel extends AndroidViewModel {
private SubscribedSubredditRepository mSubscribedSubredditRepository;
private LiveData<List<SubscribedSubredditData>> mAllSubscribedSubreddits;
private LiveData<List<SubscribedSubredditData>> mAllFavoriteSubscribedSubreddits;
private MutableLiveData<String> searchQueryLiveData;
public SubscribedSubredditViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) {
@ -26,12 +27,17 @@ public class SubscribedSubredditViewModel extends AndroidViewModel {
searchQueryLiveData.postValue("");
mAllSubscribedSubreddits = Transformations.switchMap(searchQueryLiveData, searchQuery -> mSubscribedSubredditRepository.getAllSubscribedSubredditsWithSearchQuery(searchQuery));
mAllFavoriteSubscribedSubreddits = Transformations.switchMap(searchQueryLiveData, searchQuery -> mSubscribedSubredditRepository.getAllFavoriteSubscribedSubredditsWithSearchQuery(searchQuery));
}
public LiveData<List<SubscribedSubredditData>> getAllSubscribedSubreddits() {
return mAllSubscribedSubreddits;
}
public LiveData<List<SubscribedSubredditData>> getAllFavoriteSubscribedSubreddits() {
return mAllFavoriteSubscribedSubreddits;
}
public void insert(SubscribedSubredditData subscribedSubredditData) {
mSubscribedSubredditRepository.insert(subscribedSubredditData);
}

View File

@ -24,4 +24,12 @@
android:fontFamily="?attr/font_family"
android:layout_gravity="center_vertical" />
<ImageView
android:id="@+id/favorite_image_view_item_subscribed_thing"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="end|center_vertical"
android:layout_marginStart="32dp" />
</LinearLayout>