Commit 701430de authored by Yusuke Iwaki's avatar Yusuke Iwaki

unread message indicator

parent 1e2a248d
...@@ -6,6 +6,7 @@ import android.content.Intent; ...@@ -6,6 +6,7 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.view.GravityCompat; import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.SlidingPaneLayout; import android.support.v4.widget.SlidingPaneLayout;
...@@ -32,6 +33,7 @@ import chat.rocket.android.helper.RecyclerViewScrolledToBottomListener; ...@@ -32,6 +33,7 @@ import chat.rocket.android.helper.RecyclerViewScrolledToBottomListener;
import chat.rocket.android.helper.TextUtils; import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.chatroom.MessageFormManager; import chat.rocket.android.layouthelper.chatroom.MessageFormManager;
import chat.rocket.android.layouthelper.chatroom.MessageListAdapter; import chat.rocket.android.layouthelper.chatroom.MessageListAdapter;
import chat.rocket.android.layouthelper.chatroom.NewMessageIndicatorManager;
import chat.rocket.android.layouthelper.chatroom.PairedMessage; import chat.rocket.android.layouthelper.chatroom.PairedMessage;
import chat.rocket.android.layouthelper.extra_action.MessageExtraActionBehavior; import chat.rocket.android.layouthelper.extra_action.MessageExtraActionBehavior;
import chat.rocket.android.layouthelper.extra_action.upload.AbstractUploadActionItem; import chat.rocket.android.layouthelper.extra_action.upload.AbstractUploadActionItem;
...@@ -73,6 +75,9 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -73,6 +75,9 @@ public class RoomFragment extends AbstractChatRoomFragment
private RealmObjectObserver<LoadMessageProcedure> procedureObserver; private RealmObjectObserver<LoadMessageProcedure> procedureObserver;
private MessageFormManager messageFormManager; private MessageFormManager messageFormManager;
private RecyclerViewAutoScrollManager autoScrollManager; private RecyclerViewAutoScrollManager autoScrollManager;
private NewMessageIndicatorManager newMessageIndicatorManager;
private Snackbar unreadIndicator;
private boolean previousUnreadMessageExists;
public RoomFragment() { public RoomFragment() {
} }
...@@ -148,7 +153,14 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -148,7 +153,14 @@ public class RoomFragment extends AbstractChatRoomFragment
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(),
LinearLayoutManager.VERTICAL, true); LinearLayoutManager.VERTICAL, true);
listView.setLayoutManager(layoutManager); listView.setLayoutManager(layoutManager);
autoScrollManager = new RecyclerViewAutoScrollManager(layoutManager); autoScrollManager = new RecyclerViewAutoScrollManager(layoutManager) {
@Override
protected void onAutoScrollMissed() {
if (newMessageIndicatorManager != null) {
newMessageIndicatorManager.updateNewMessageCount(getUnreadMessageCount());
}
}
};
adapter.registerAdapterDataObserver(autoScrollManager); adapter.registerAdapterDataObserver(autoScrollManager);
scrollListener = new LoadMoreScrollListener(layoutManager, 40) { scrollListener = new LoadMoreScrollListener(layoutManager, 40) {
...@@ -161,10 +173,59 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -161,10 +173,59 @@ public class RoomFragment extends AbstractChatRoomFragment
listView.addOnScrollListener( listView.addOnScrollListener(
new RecyclerViewScrolledToBottomListener(layoutManager, 1, this::markAsReadIfNeeded)); new RecyclerViewScrolledToBottomListener(layoutManager, 1, this::markAsReadIfNeeded));
newMessageIndicatorManager = new NewMessageIndicatorManager() {
@Override
protected void onShowIndicator(int count, boolean onlyAlreadyShown) {
if ((onlyAlreadyShown && unreadIndicator != null && unreadIndicator.isShown())
|| !onlyAlreadyShown) {
unreadIndicator = getUnreadCountIndicatorView(count);
unreadIndicator.show();
}
}
@Override
protected void onHideIndicator() {
if (unreadIndicator != null && unreadIndicator.isShown()) {
unreadIndicator.dismiss();
}
}
};
setupSideMenu(); setupSideMenu();
setupMessageComposer(); setupMessageComposer();
} }
private void scrollToLatestMessage() {
RecyclerView listView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
if (listView != null) {
listView.smoothScrollToPosition(0);
}
}
private Snackbar getUnreadCountIndicatorView(int count) {
// TODO: replace with another custom View widget, not to hide message composer.
final String caption = getResources().getString(
R.string.fmt_dialog_view_latest_message_title, count);
return Snackbar.make(rootView, caption, Snackbar.LENGTH_LONG)
.setAction(R.string.dialog_view_latest_message_action, view -> scrollToLatestMessage());
}
private int getUnreadMessageCount() {
RoomSubscription room = realmHelper.executeTransactionForRead(realm ->
realm.where(RoomSubscription.class).equalTo(RoomSubscription.ROOM_ID, roomId).findFirst());
if (room != null) {
return realmHelper.executeTransactionForReadResults(realm ->
realm.where(Message.class)
.equalTo(Message.ROOM_ID, roomId)
.greaterThanOrEqualTo(Message.TIMESTAMP, room.getLastSeen())
.notEqualTo(Message.USER_ID, userId)
.findAll()).size();
} else {
return 0;
}
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
RecyclerView listView = (RecyclerView) rootView.findViewById(R.id.recyclerview); RecyclerView listView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
...@@ -244,7 +305,11 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -244,7 +305,11 @@ public class RoomFragment extends AbstractChatRoomFragment
.put(Message.SYNC_STATE, SyncState.NOT_SYNCED) .put(Message.SYNC_STATE, SyncState.NOT_SYNCED)
.put(Message.TIMESTAMP, System.currentTimeMillis()) .put(Message.TIMESTAMP, System.currentTimeMillis())
.put(Message.ROOM_ID, roomId) .put(Message.ROOM_ID, roomId)
.put(Message.MESSAGE, messageText)))); .put(Message.MESSAGE, messageText)))
.onSuccess(_task -> {
scrollToLatestMessage();
return null;
}));
messageFormManager.registerExtraActionItem(new ImageUploadActionItem()); messageFormManager.registerExtraActionItem(new ImageUploadActionItem());
messageFormManager.registerExtraActionItem(new AudioUploadActionItem()); messageFormManager.registerExtraActionItem(new AudioUploadActionItem());
messageFormManager.registerExtraActionItem(new VideoUploadActionItem()); messageFormManager.registerExtraActionItem(new VideoUploadActionItem());
...@@ -289,6 +354,12 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -289,6 +354,12 @@ public class RoomFragment extends AbstractChatRoomFragment
setToolbarRoomIcon(0); setToolbarRoomIcon(0);
} }
setToolbarTitle(roomSubscription.getName()); setToolbarTitle(roomSubscription.getName());
boolean unreadMessageExists = roomSubscription.isAlert();
if (newMessageIndicatorManager != null && previousUnreadMessageExists && !unreadMessageExists) {
newMessageIndicatorManager.reset();
}
previousUnreadMessageExists = unreadMessageExists;
} }
private void onUpdateLoadMessageProcedure(LoadMessageProcedure procedure) { private void onUpdateLoadMessageProcedure(LoadMessageProcedure procedure) {
...@@ -360,7 +431,6 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -360,7 +431,6 @@ public class RoomFragment extends AbstractChatRoomFragment
roomObserver.sub(); roomObserver.sub();
procedureObserver.sub(); procedureObserver.sub();
closeSideMenuIfNeeded(); closeSideMenuIfNeeded();
markAsReadIfNeeded();
} }
@Override @Override
......
...@@ -20,6 +20,12 @@ public class RecyclerViewAutoScrollManager extends RecyclerView.AdapterDataObser ...@@ -20,6 +20,12 @@ public class RecyclerViewAutoScrollManager extends RecyclerView.AdapterDataObser
if (linearLayoutManager.findFirstVisibleItemPosition() <= positionStart) { if (linearLayoutManager.findFirstVisibleItemPosition() <= positionStart) {
linearLayoutManager.scrollToPosition(positionStart); linearLayoutManager.scrollToPosition(positionStart);
} else {
onAutoScrollMissed();
} }
} }
protected void onAutoScrollMissed() {
//do nothing by default.
}
} }
package chat.rocket.android.layouthelper.chatroom;
/**
* manager class for showing "You have XX messages" indicator.
*/
public abstract class NewMessageIndicatorManager {
private int count;
private boolean onlyAlreadyShown;
/**
* update the number of unread message.
*/
public void updateNewMessageCount(int count) {
if (count > 0) {
this.count = count;
update();
onlyAlreadyShown = true;
} else {
reset();
}
}
/**
* Should call this method when user checked new message.
*/
public void reset() {
count = 0;
onlyAlreadyShown = false;
update();
}
private void update() {
if (count > 0) {
onShowIndicator(count, onlyAlreadyShown);
} else {
onHideIndicator();
}
}
protected abstract void onShowIndicator(int count, boolean onlyAlreadyShown);
protected abstract void onHideIndicator();
}
...@@ -25,6 +25,7 @@ public class Message extends RealmObject { ...@@ -25,6 +25,7 @@ public class Message extends RealmObject {
@SuppressWarnings({"PMD.AvoidFieldNameMatchingTypeName"}) @SuppressWarnings({"PMD.AvoidFieldNameMatchingTypeName"})
public static final String MESSAGE = "msg"; public static final String MESSAGE = "msg";
public static final String USER = "u"; public static final String USER = "u";
public static final String USER_ID = "u._id";
public static final String GROUPABLE = "groupable"; public static final String GROUPABLE = "groupable";
public static final String ATTACHMENTS = "attachments"; public static final String ATTACHMENTS = "attachments";
public static final String URLS = "urls"; public static final String URLS = "urls";
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
<string name="resend">Resend</string> <string name="resend">Resend</string>
<string name="discard">Discard</string> <string name="discard">Discard</string>
<string name="fmt_dialog_view_latest_message_title">New %d messages</string>
<string name="dialog_view_latest_message_action">View</string>
<string name="file_uploading_title">Uploading…</string> <string name="file_uploading_title">Uploading…</string>
<string name="dialog_user_registration_email">Email</string> <string name="dialog_user_registration_email">Email</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment