From 4759b45fd10cd6c314a6af94a40c1ae1be620a99 Mon Sep 17 00:00:00 2001 From: Denys Nykyforov Date: Tue, 23 Feb 2021 19:51:33 +0800 Subject: [PATCH] Implement Notification list --- .../api/methods/GetNotifications.java | 22 +++ .../houseclub/api/model/Notification.java | 16 ++ .../houseclub/fragments/HomeFragment.java | 9 +- .../fragments/NotificationListFragment.java | 158 ++++++++++++++++++ .../main/res/drawable/ic_notifications.xml | 10 ++ .../main/res/layout/notification_list_row.xml | 53 ++++++ Houseclub/src/main/res/values/strings.xml | 1 + 7 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 Houseclub/src/main/java/me/grishka/houseclub/api/methods/GetNotifications.java create mode 100644 Houseclub/src/main/java/me/grishka/houseclub/api/model/Notification.java create mode 100644 Houseclub/src/main/java/me/grishka/houseclub/fragments/NotificationListFragment.java create mode 100644 Houseclub/src/main/res/drawable/ic_notifications.xml create mode 100644 Houseclub/src/main/res/layout/notification_list_row.xml diff --git a/Houseclub/src/main/java/me/grishka/houseclub/api/methods/GetNotifications.java b/Houseclub/src/main/java/me/grishka/houseclub/api/methods/GetNotifications.java new file mode 100644 index 00000000..d520c484 --- /dev/null +++ b/Houseclub/src/main/java/me/grishka/houseclub/api/methods/GetNotifications.java @@ -0,0 +1,22 @@ +package me.grishka.houseclub.api.methods; + +import java.util.HashMap; +import java.util.List; + +import me.grishka.houseclub.api.ClubhouseAPIRequest; +import me.grishka.houseclub.api.model.Notification; + +public class GetNotifications extends ClubhouseAPIRequest{ + public GetNotifications(int userID, int pageSize, int page){ + super("GET", "get_notifications", Response.class); + queryParams=new HashMap<>(); + queryParams.put("user_id", userID+""); + queryParams.put("page_size", pageSize+""); + queryParams.put("page", page+""); + } + + public static class Response{ + public List notifications; + public int count; + } +} diff --git a/Houseclub/src/main/java/me/grishka/houseclub/api/model/Notification.java b/Houseclub/src/main/java/me/grishka/houseclub/api/model/Notification.java new file mode 100644 index 00000000..f576bb35 --- /dev/null +++ b/Houseclub/src/main/java/me/grishka/houseclub/api/model/Notification.java @@ -0,0 +1,16 @@ +package me.grishka.houseclub.api.model; + +import java.util.Date; + +public class Notification { + public int notificationId; + public boolean inUnread; + public User userProfile; + public int eventId; + public int type; + public Date timeCreated; + public String message; + + public static final int NOTIFICATION_TYPE_USER=1; + public static final int NOTIFICATION_TYPE_EVENT=16; +} diff --git a/Houseclub/src/main/java/me/grishka/houseclub/fragments/HomeFragment.java b/Houseclub/src/main/java/me/grishka/houseclub/fragments/HomeFragment.java index d0587495..c402653f 100644 --- a/Houseclub/src/main/java/me/grishka/houseclub/fragments/HomeFragment.java +++ b/Houseclub/src/main/java/me/grishka/houseclub/fragments/HomeFragment.java @@ -113,14 +113,19 @@ public boolean wantsLightStatusBar(){ @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){ - menu.add("").setIcon(R.drawable.ic_baseline_person_24).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + menu.add(0,0,0,"").setIcon(R.drawable.ic_notifications).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + menu.add(0,1,0,"").setIcon(R.drawable.ic_baseline_person_24).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); } @Override public boolean onOptionsItemSelected(MenuItem item){ Bundle args=new Bundle(); args.putInt("id", Integer.parseInt(ClubhouseSession.userID)); - Nav.go(getActivity(), ProfileFragment.class, args); + if(item.getItemId()==0) { + Nav.go(getActivity(), NotificationListFragment.class, args); + } else if(item.getItemId()==1){ + Nav.go(getActivity(), ProfileFragment.class, args); + } return true; } diff --git a/Houseclub/src/main/java/me/grishka/houseclub/fragments/NotificationListFragment.java b/Houseclub/src/main/java/me/grishka/houseclub/fragments/NotificationListFragment.java new file mode 100644 index 00000000..49bda8e9 --- /dev/null +++ b/Houseclub/src/main/java/me/grishka/houseclub/fragments/NotificationListFragment.java @@ -0,0 +1,158 @@ +package me.grishka.houseclub.fragments; + +import android.app.Activity; +import android.content.res.Configuration; +import android.graphics.Bitmap; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.text.TextUtils; +import android.text.format.DateUtils; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; + +import me.grishka.appkit.Nav; +import me.grishka.appkit.fragments.BaseRecyclerFragment; +import me.grishka.appkit.imageloader.ImageLoaderRecyclerAdapter; +import me.grishka.appkit.imageloader.ImageLoaderViewHolder; +import me.grishka.appkit.utils.BindableViewHolder; +import me.grishka.appkit.views.UsableRecyclerView; +import me.grishka.houseclub.R; +import me.grishka.appkit.api.SimpleCallback; +import me.grishka.houseclub.api.ClubhouseSession; +import me.grishka.houseclub.api.methods.GetNotifications; +import me.grishka.houseclub.api.model.FullUser; +import me.grishka.houseclub.api.model.Notification; + +public class NotificationListFragment extends BaseRecyclerFragment{ + private NotificationListAdapter adapter; + + public NotificationListFragment(){ + super(50); + } + + @Override + public void onAttach(Activity activity){ + super.onAttach(activity); + loadData(); + setTitle(R.string.notifications_title); + } + + @Override + protected RecyclerView.Adapter getAdapter(){ + if(adapter==null){ + adapter=new NotificationListAdapter(); + } + return adapter; + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState){ + super.onViewCreated(view, savedInstanceState); + getToolbar().setElevation(0); + } + + @Override + public void onConfigurationChanged(Configuration newConfig){ + super.onConfigurationChanged(newConfig); + getToolbar().setElevation(0); + } + + @Override + protected void doLoadData(int offset, int count){ + currentRequest=new GetNotifications(getArguments().getInt("id"), 50, offset/50+1) + .setCallback(new SimpleCallback(this){ + @Override + public void onSuccess(GetNotifications.Response result){ + currentRequest=null; + onDataLoaded(result.notifications, data.size()+preloadedData.size()+result.notifications.size() implements ImageLoaderRecyclerAdapter{ + + @NonNull + @Override + public NotificationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){ + return new NotificationViewHolder(); + } + + @Override + public void onBindViewHolder(@NonNull NotificationViewHolder holder, int position){ + holder.bind(data.get(position)); + } + + @Override + public int getItemCount(){ + return data.size(); + } + + @Override + public int getImageCountForItem(int position){ + return data.get(position).userProfile.photoUrl!=null ? 1 : 0; + } + + @Override + public String getImageURL(int position, int image){ + return data.get(position).userProfile.photoUrl; + } + } + + private class NotificationViewHolder extends BindableViewHolder implements ImageLoaderViewHolder, UsableRecyclerView.Clickable{ + + public TextView name, message, time; + public Button followBtn; + public ImageView photo; + private Drawable placeholder=new ColorDrawable(0xFF808080); + + public NotificationViewHolder(){ + super(getActivity(), R.layout.notification_list_row); + + name=findViewById(R.id.name); + message=findViewById(R.id.message); + time=findViewById(R.id.time); + photo=findViewById(R.id.photo); + } + + @Override + public void onBind(Notification item){ + itemView.setAlpha(item.inUnread?1F:0.5F); + name.setText(item.userProfile.name); + message.setText(item.message); + time.setText(DateUtils.getRelativeTimeSpanString(item.timeCreated.getTime())); + + if(item.userProfile.photoUrl!=null) + imgLoader.bindViewHolder(adapter, this, getAdapterPosition()); + else + photo.setImageDrawable(placeholder); + } + + @Override + public void setImage(int index, Bitmap bitmap){ + photo.setImageBitmap(bitmap); + } + + @Override + public void clearImage(int index){ + photo.setImageDrawable(placeholder); + } + + @Override + public void onClick(){ + Bundle args=new Bundle(); + args.putInt("id", item.userProfile.userId); + Nav.go(getActivity(), ProfileFragment.class, args); + } + } +} diff --git a/Houseclub/src/main/res/drawable/ic_notifications.xml b/Houseclub/src/main/res/drawable/ic_notifications.xml new file mode 100644 index 00000000..c375cde2 --- /dev/null +++ b/Houseclub/src/main/res/drawable/ic_notifications.xml @@ -0,0 +1,10 @@ + + + diff --git a/Houseclub/src/main/res/layout/notification_list_row.xml b/Houseclub/src/main/res/layout/notification_list_row.xml new file mode 100644 index 00000000..2b8f2cfb --- /dev/null +++ b/Houseclub/src/main/res/layout/notification_list_row.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Houseclub/src/main/res/values/strings.xml b/Houseclub/src/main/res/values/strings.xml index 87046b75..5d4b63ce 100644 --- a/Houseclub/src/main/res/values/strings.xml +++ b/Houseclub/src/main/res/values/strings.xml @@ -45,6 +45,7 @@ Following Followers Following + Notifications Unfollow %s? Yes No