Skip to content
This repository was archived by the owner on Jul 25, 2024. It is now read-only.

Commit 900c472

Browse files
kunall17timabbott
authored andcommitted
Fixes #153: Show in-app new messages notifications snackbar
1 parent 9ff0975 commit 900c472

File tree

5 files changed

+134
-1
lines changed

5 files changed

+134
-1
lines changed

app/src/main/java/com/zulip/android/activities/MessageListFragment.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public class MessageListFragment extends Fragment implements MessageListener {
6868
private boolean paused = false;
6969
private boolean initialized = false;
7070
private List<Message> messageList;
71+
7172
public MessageListFragment() {
7273
app = ZulipApp.get();
7374
mMutedTopics = MutedTopics.get();
@@ -475,6 +476,35 @@ public void onTaskFailure(String result) {
475476
});
476477
}
477478

479+
private void loadMessageId(int id) {
480+
if (lastMessageId > id) {
481+
int index = adapter.getItemIndex(id);
482+
if (index != -1) {
483+
recyclerView.scrollToPosition(adapter.getItemIndex(id));
484+
return;
485+
}
486+
}
487+
AsyncGetOldMessages oldMessagesReq = new AsyncGetOldMessages(this);
488+
oldMessagesReq.setCallback(new ZulipAsyncPushTask.AsyncTaskCompleteListener() {
489+
@Override
490+
public void onTaskComplete(String result, JSONObject jsonObject) {
491+
adapter.setFooterShowing(false);
492+
loadingMessages = false;
493+
}
494+
495+
@Override
496+
public void onTaskFailure(String result) {
497+
Toast.makeText(getActivity(), R.string.no_message, Toast.LENGTH_SHORT).show();
498+
adapter.setFooterShowing(false);
499+
loadingMessages = false;
500+
}
501+
});
502+
adapter.clear();
503+
adapter.setFooterShowing(true);
504+
loadingMessages = true;
505+
oldMessagesReq.execute(id, LoadPosition.BELOW, 0, 100, filter);
506+
}
507+
478508
private Boolean listHasMostRecent() {
479509
return lastMessageId == app.getMaxMessageId();
480510
}
@@ -503,4 +533,13 @@ public interface Listener {
503533

504534
void clearChatBox();
505535
}
506-
}
536+
537+
public void showLatestMessages() {
538+
if (listHasMostRecent()) {
539+
recyclerView.scrollToPosition(adapter.getItemCount() - 1);
540+
} else {
541+
loadMessageId(app.getMaxMessageId());
542+
}
543+
}
544+
545+
}

app/src/main/java/com/zulip/android/activities/RecyclerMessageAdapter.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,15 @@ public int getItemIndex(Message message) {
549549
return items.indexOf(message);
550550
}
551551

552+
public int getItemIndex(int id) {
553+
for (int i = 0; i < items.size(); i++) {
554+
if (items.get(i) instanceof Message && ((Message) items.get(i)).getId() == id) {
555+
return i;
556+
}
557+
}
558+
return -1;
559+
}
560+
552561
public Object getItem(int position) {
553562
return items.get(position);
554563
}

app/src/main/java/com/zulip/android/activities/ZulipActivity.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
package com.zulip.android.activities;
22

33
import android.Manifest;
4+
import java.sql.SQLException;
5+
import java.util.Arrays;
6+
import java.util.HashMap;
7+
import java.util.List;
8+
import java.util.Locale;
9+
import java.util.concurrent.Callable;
10+
import java.util.ArrayList;
11+
import java.util.concurrent.TimeUnit;
12+
413
import android.animation.Animator;
514
import android.annotation.SuppressLint;
615
import android.annotation.TargetApi;
@@ -29,7 +38,9 @@
2938
import android.os.Handler;
3039
import android.provider.MediaStore;
3140
import android.support.design.widget.AppBarLayout;
41+
import android.support.design.widget.CoordinatorLayout;
3242
import android.support.design.widget.FloatingActionButton;
43+
import android.support.design.widget.Snackbar;
3344
import android.support.v4.app.ActionBarDrawerToggle;
3445
import android.support.v4.app.ActivityCompat;
3546
import android.support.v4.app.FragmentManager;
@@ -47,6 +58,7 @@
4758
import android.text.TextUtils;
4859
import android.text.TextWatcher;
4960
import android.util.Log;
61+
import android.view.Gravity;
5062
import android.view.Menu;
5163
import android.view.MenuItem;
5264
import android.view.View;
@@ -539,6 +551,7 @@ public Cursor runQuery(CharSequence charSequence) {
539551
}
540552
handleOnFragmentChange();
541553
calendar = Calendar.getInstance();
554+
setupSnackBar();
542555
}
543556

544557
/**
@@ -2040,6 +2053,66 @@ public void onNewMessages(Message[] messages) {
20402053
if (narrowedList != null) {
20412054
narrowedList.onNewMessages(messages);
20422055
}
2056+
showSnackbarNotification(messages); //Show notification
2057+
}
2058+
2059+
Snackbar snackbar;
2060+
2061+
private void setupSnackBar() {
2062+
final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);
2063+
snackbar = Snackbar.make(coordinatorLayout, "", Snackbar.LENGTH_LONG);
2064+
View v = snackbar.getView();
2065+
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) v.getLayoutParams();
2066+
params.gravity = Gravity.TOP;
2067+
v.setLayoutParams(params);
2068+
}
2069+
2070+
NarrowFilter narrowFilter;
2071+
2072+
private void showSnackbarNotification(Message[] messages) {
2073+
MutedTopics mutedTopics = MutedTopics.get();
2074+
String prevId = null;
2075+
int nonMutedMessagesCount = 0;
2076+
Message tempMessage = null; //Stores a temporary message which is non-muted, later used for retrieving Stream/Topic
2077+
for (Message message : messages) { //Check if all messages from same topic/private and remove all the muted messages
2078+
if (message.getType() == MessageType.STREAM_MESSAGE && mutedTopics.isTopicMute(message))
2079+
continue;
2080+
nonMutedMessagesCount++;
2081+
if (prevId != null && !prevId.equals(message.getIdForHolder())) {
2082+
prevId = null;
2083+
tempMessage = null;
2084+
break;
2085+
}
2086+
prevId = message.getIdForHolder();
2087+
if (tempMessage == null) tempMessage = message;
2088+
}
2089+
if (nonMutedMessagesCount == 0) return;
2090+
if (prevId == null) {
2091+
snackbar.setText(getResources().getQuantityString(R.plurals.new_message_mul_sender, nonMutedMessagesCount, nonMutedMessagesCount));
2092+
narrowFilter = null;
2093+
if (narrowedList != null) {
2094+
narrowedList = null;
2095+
getSupportFragmentManager().popBackStack(NARROW,
2096+
FragmentManager.POP_BACK_STACK_INCLUSIVE);
2097+
}
2098+
snackbar.setAction(R.string.SHOW, new View.OnClickListener() {
2099+
@Override
2100+
public void onClick(View view) {
2101+
homeList.showLatestMessages();
2102+
}
2103+
});
2104+
} else {
2105+
String name = (tempMessage.getType() == MessageType.PRIVATE_MESSAGE) ? getString(R.string.notify_private, tempMessage.getSenderFullName()) : getString(R.string.notify_stream, tempMessage.getStream().getName() , tempMessage.getSubject());
2106+
snackbar.setText(getResources().getQuantityString(R.plurals.new_message, nonMutedMessagesCount, nonMutedMessagesCount, name));
2107+
narrowFilter = (tempMessage.getType() == MessageType.PRIVATE_MESSAGE) ? new NarrowFilterPM(Arrays.asList(tempMessage.getRecipients(app))) : new NarrowFilterStream(tempMessage.getStream(), tempMessage.getSubject());
2108+
snackbar.setAction(R.string.SHOW, new View.OnClickListener() {
2109+
@Override
2110+
public void onClick(View view) {
2111+
doNarrow(narrowFilter);
2112+
}
2113+
});
2114+
}
2115+
snackbar.show();
20432116
}
20442117

20452118
// Intent Extra constants

app/src/main/res/layout/main.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<android.support.design.widget.CoordinatorLayout
1010
android:layout_width="match_parent"
1111
android:layout_height="match_parent"
12+
android:id="@+id/coordinatorLayout"
1213
android:fitsSystemWindows="true">
1314

1415
<FrameLayout

app/src/main/res/values/strings.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,15 @@
118118
<string name="enter_date">Enter Date</string>
119119
<string name="message_not_subscribed">Not subscribed to</string>
120120
<string name="keyword_stream">stream</string>
121+
<plurals name="new_message" formatted="false">
122+
<item quantity="one">%1$d new message %2$s</item>
123+
<item quantity="other">%1$d new messages %2$s</item>
124+
</plurals>
125+
<string name="SHOW">SHOW</string>
126+
<string name="notify_stream" formatted="false">" in %1$s/%2$s"</string>
127+
<string name="notify_private" formatted="false">from %1$s</string>
128+
<plurals name="new_message_mul_sender">
129+
<item quantity="one">%d new message</item>
130+
<item quantity="other">%d new messages</item>
131+
</plurals>
121132
</resources>

0 commit comments

Comments
 (0)