mirror of
https://codeberg.org/tom79/Fedilab.git
synced 2024-12-22 16:50:04 +02:00
comment #77 - Start for grouping similar notifications
This commit is contained in:
parent
c2d3ae8e40
commit
658685b2c7
6 changed files with 105 additions and 3 deletions
|
@ -17,6 +17,7 @@ package app.fedilab.android.client.mastodon.entities;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Notification {
|
public class Notification {
|
||||||
|
|
||||||
|
@ -30,4 +31,6 @@ public class Notification {
|
||||||
public Account account;
|
public Account account;
|
||||||
@SerializedName("status")
|
@SerializedName("status")
|
||||||
public Status status;
|
public Status status;
|
||||||
|
|
||||||
|
public transient List<Notification> relatedNotifications;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ import app.fedilab.android.client.entities.Timeline;
|
||||||
import app.fedilab.android.client.mastodon.entities.Notification;
|
import app.fedilab.android.client.mastodon.entities.Notification;
|
||||||
import app.fedilab.android.databinding.DrawerFollowBinding;
|
import app.fedilab.android.databinding.DrawerFollowBinding;
|
||||||
import app.fedilab.android.databinding.DrawerStatusNotificationBinding;
|
import app.fedilab.android.databinding.DrawerStatusNotificationBinding;
|
||||||
|
import app.fedilab.android.databinding.NotificationsRelatedAccountsBinding;
|
||||||
import app.fedilab.android.helper.Helper;
|
import app.fedilab.android.helper.Helper;
|
||||||
import app.fedilab.android.helper.MastodonHelper;
|
import app.fedilab.android.helper.MastodonHelper;
|
||||||
import app.fedilab.android.viewmodel.mastodon.SearchVM;
|
import app.fedilab.android.viewmodel.mastodon.SearchVM;
|
||||||
|
@ -165,6 +166,28 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
||||||
} else if (getItemViewType(position) == TYPE_POLL) {
|
} else if (getItemViewType(position) == TYPE_POLL) {
|
||||||
title = context.getString(R.string.notif_poll);
|
title = context.getString(R.string.notif_poll);
|
||||||
}
|
}
|
||||||
|
if (notification.relatedNotifications != null && notification.relatedNotifications.size() > 0) {
|
||||||
|
holderStatus.bindingNotification.otherAccounts.removeAllViews();
|
||||||
|
for (Notification relativeNotif : notification.relatedNotifications) {
|
||||||
|
NotificationsRelatedAccountsBinding notificationsRelatedAccountsBinding = NotificationsRelatedAccountsBinding.inflate(LayoutInflater.from(context));
|
||||||
|
MastodonHelper.loadPPMastodon(notificationsRelatedAccountsBinding.profilePicture, relativeNotif.account);
|
||||||
|
notificationsRelatedAccountsBinding.acc.setText(relativeNotif.account.acct);
|
||||||
|
notificationsRelatedAccountsBinding.relatedAccountContainer.setOnClickListener(v -> {
|
||||||
|
Intent intent = new Intent(context, ProfileActivity.class);
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
b.putSerializable(Helper.ARG_ACCOUNT, relativeNotif.account);
|
||||||
|
intent.putExtras(b);
|
||||||
|
ActivityOptionsCompat options = ActivityOptionsCompat
|
||||||
|
.makeSceneTransitionAnimation((Activity) context, notificationsRelatedAccountsBinding.profilePicture, context.getString(R.string.activity_porfile_pp));
|
||||||
|
// start the new activity
|
||||||
|
context.startActivity(intent, options.toBundle());
|
||||||
|
});
|
||||||
|
holderStatus.bindingNotification.otherAccounts.addView(notificationsRelatedAccountsBinding.getRoot());
|
||||||
|
}
|
||||||
|
holderStatus.bindingNotification.otherAccounts.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
holderStatus.bindingNotification.otherAccounts.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
holderStatus.bindingNotification.status.avatar.setOnClickListener(v -> {
|
holderStatus.bindingNotification.status.avatar.setOnClickListener(v -> {
|
||||||
Intent intent = new Intent(context, ProfileActivity.class);
|
Intent intent = new Intent(context, ProfileActivity.class);
|
||||||
Bundle b = new Bundle();
|
Bundle b = new Bundle();
|
||||||
|
|
|
@ -63,6 +63,7 @@ public class FragmentMastodonNotification extends Fragment {
|
||||||
private NotificationAdapter notificationAdapter;
|
private NotificationAdapter notificationAdapter;
|
||||||
private NotificationTypeEnum notificationType;
|
private NotificationTypeEnum notificationType;
|
||||||
private List<String> excludeType;
|
private List<String> excludeType;
|
||||||
|
private boolean aggregateNotification;
|
||||||
|
|
||||||
private final BroadcastReceiver receive_action = new BroadcastReceiver() {
|
private final BroadcastReceiver receive_action = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -114,6 +115,7 @@ public class FragmentMastodonNotification extends Fragment {
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
notificationType = (NotificationTypeEnum) getArguments().get(Helper.ARG_NOTIFICATION_TYPE);
|
notificationType = (NotificationTypeEnum) getArguments().get(Helper.ARG_NOTIFICATION_TYPE);
|
||||||
}
|
}
|
||||||
|
aggregateNotification = false;
|
||||||
binding.getRoot().setBackgroundColor(ThemeHelper.getBackgroundColor(requireActivity()));
|
binding.getRoot().setBackgroundColor(ThemeHelper.getBackgroundColor(requireActivity()));
|
||||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
|
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
|
||||||
String excludedCategories = sharedpreferences.getString(getString(R.string.SET_EXCLUDED_NOTIFICATIONS_TYPE) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, null);
|
String excludedCategories = sharedpreferences.getString(getString(R.string.SET_EXCLUDED_NOTIFICATIONS_TYPE) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, null);
|
||||||
|
@ -136,6 +138,7 @@ public class FragmentMastodonNotification extends Fragment {
|
||||||
excludeType.add("update");
|
excludeType.add("update");
|
||||||
excludeType.add("status");
|
excludeType.add("status");
|
||||||
if (notificationType == NotificationTypeEnum.ALL) {
|
if (notificationType == NotificationTypeEnum.ALL) {
|
||||||
|
aggregateNotification = sharedpreferences.getBoolean(getString(R.string.SET_AGGREGATE_NOTIFICATION), true);
|
||||||
if (excludedCategories != null) {
|
if (excludedCategories != null) {
|
||||||
excludeType = new ArrayList<>();
|
excludeType = new ArrayList<>();
|
||||||
String[] categoriesArray = excludedCategories.split("\\|");
|
String[] categoriesArray = excludedCategories.split("\\|");
|
||||||
|
@ -172,6 +175,7 @@ public class FragmentMastodonNotification extends Fragment {
|
||||||
|
|
||||||
binding.loader.setVisibility(View.GONE);
|
binding.loader.setVisibility(View.GONE);
|
||||||
binding.swipeContainer.setRefreshing(false);
|
binding.swipeContainer.setRefreshing(false);
|
||||||
|
|
||||||
if (notifications == null || notifications.notifications == null) {
|
if (notifications == null || notifications.notifications == null) {
|
||||||
binding.noActionText.setText(R.string.no_notifications);
|
binding.noActionText.setText(R.string.no_notifications);
|
||||||
binding.noAction.setVisibility(View.VISIBLE);
|
binding.noAction.setVisibility(View.VISIBLE);
|
||||||
|
@ -181,6 +185,9 @@ public class FragmentMastodonNotification extends Fragment {
|
||||||
binding.noAction.setVisibility(View.GONE);
|
binding.noAction.setVisibility(View.GONE);
|
||||||
binding.recyclerView.setVisibility(View.VISIBLE);
|
binding.recyclerView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
if (aggregateNotification) {
|
||||||
|
notifications.notifications = aggregateNotifications(notifications.notifications);
|
||||||
|
}
|
||||||
if (notificationAdapter != null && this.notifications != null) {
|
if (notificationAdapter != null && this.notifications != null) {
|
||||||
int size = this.notifications.size();
|
int size = this.notifications.size();
|
||||||
this.notifications.clear();
|
this.notifications.clear();
|
||||||
|
@ -227,6 +234,27 @@ public class FragmentMastodonNotification extends Fragment {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Notification> aggregateNotifications(List<Notification> notifications) {
|
||||||
|
List<Notification> notificationList = new ArrayList<>();
|
||||||
|
int refPosition = 0;
|
||||||
|
for (int i = 0; i < notifications.size(); i++) {
|
||||||
|
if (i != refPosition) {
|
||||||
|
if (notifications.get(i).type.equals(notifications.get(refPosition).type) && (notifications.get(i).type.equals("favourite") || notifications.get(i).type.equals("reblog"))) {
|
||||||
|
if (notificationList.size() > 0) {
|
||||||
|
if (notificationList.get(notificationList.size() - 1).relatedNotifications == null) {
|
||||||
|
notificationList.get(notificationList.size() - 1).relatedNotifications = new ArrayList<>();
|
||||||
|
}
|
||||||
|
notificationList.get(notificationList.size() - 1).relatedNotifications.add(notifications.get(i));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
notificationList.add(notifications.get(i));
|
||||||
|
refPosition = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return notificationList;
|
||||||
|
}
|
||||||
|
|
||||||
public void scrollToTop() {
|
public void scrollToTop() {
|
||||||
binding.recyclerView.scrollToPosition(0);
|
binding.recyclerView.scrollToPosition(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,20 +14,48 @@
|
||||||
You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||||
see <http://www.gnu.org/licenses>
|
see <http://www.gnu.org/licenses>
|
||||||
-->
|
-->
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/card_status_container"
|
android:id="@+id/card_status_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include
|
<include
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:id="@+id/status"
|
android:id="@+id/status"
|
||||||
layout="@layout/drawer_status" />
|
layout="@layout/drawer_status" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:id="@+id/other_accounts"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignBottom="@+id/status"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/status">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/type_of_concat"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<HorizontalScrollView
|
||||||
|
android:id="@+id/related_accounts"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:id="@+id/container_transparent"
|
android:id="@+id/container_transparent"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/black"
|
android:background="@color/black"
|
||||||
android:elevation="5dp"
|
android:elevation="5dp"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
</FrameLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
18
app/src/main/res/layout/notifications_related_accounts.xml
Normal file
18
app/src/main/res/layout/notifications_related_accounts.xml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/related_account_container"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/profile_picture"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/acc"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
|
@ -1367,6 +1367,8 @@
|
||||||
<string name="SET_ENABLE_TIME_SLOT" translatable="false">SET_ENABLE_TIME_SLOT</string>
|
<string name="SET_ENABLE_TIME_SLOT" translatable="false">SET_ENABLE_TIME_SLOT</string>
|
||||||
<string name="SET_CLEAR_CACHE_EXIT" translatable="false">SET_CLEAR_CACHE_EXIT</string>
|
<string name="SET_CLEAR_CACHE_EXIT" translatable="false">SET_CLEAR_CACHE_EXIT</string>
|
||||||
<string name="SET_DISPLAY_EMOJI" translatable="false">SET_DISPLAY_EMOJI</string>
|
<string name="SET_DISPLAY_EMOJI" translatable="false">SET_DISPLAY_EMOJI</string>
|
||||||
|
<string name="SET_AGGREGATE_NOTIFICATION" translatable="false">SET_AGGREGATE_NOTIFICATION</string>
|
||||||
|
|
||||||
<string name="SET_DISPLAY_CARD" translatable="false">SET_DISPLAY_CARD</string>
|
<string name="SET_DISPLAY_CARD" translatable="false">SET_DISPLAY_CARD</string>
|
||||||
<string name="SET_DISPLAY_VIDEO_PREVIEWS" translatable="false">SET_DISPLAY_VIDEO_PREVIEWS</string>
|
<string name="SET_DISPLAY_VIDEO_PREVIEWS" translatable="false">SET_DISPLAY_VIDEO_PREVIEWS</string>
|
||||||
<string name="SET_NOTIFICATION_ACTION" translatable="false">SET_NOTIFICATION_ACTION</string>
|
<string name="SET_NOTIFICATION_ACTION" translatable="false">SET_NOTIFICATION_ACTION</string>
|
||||||
|
|
Loading…
Reference in a new issue