make unread status and notifications presistent across restarts
This commit is contained in:
parent
0587ba2ad2
commit
5f9476448f
|
@ -111,6 +111,16 @@ public class Conversation extends AbstractEntity implements Blockable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void findUnreadMessages(OnMessageFound onMessageFound) {
|
||||||
|
synchronized (this.messages) {
|
||||||
|
for(Message message : this.messages) {
|
||||||
|
if (!message.isRead()) {
|
||||||
|
onMessageFound.onMessageFound(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void findMessagesWithFiles(final OnMessageFound onMessageFound) {
|
public void findMessagesWithFiles(final OnMessageFound onMessageFound) {
|
||||||
synchronized (this.messages) {
|
synchronized (this.messages) {
|
||||||
for (final Message message : this.messages) {
|
for (final Message message : this.messages) {
|
||||||
|
@ -266,9 +276,8 @@ public class Conversation extends AbstractEntity implements Blockable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public interface OnMessageFound {
|
public interface OnMessageFound {
|
||||||
public void onMessageFound(final Message message);
|
void onMessageFound(final Message message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Conversation(final String name, final Account account, final Jid contactJid,
|
public Conversation(final String name, final Account account, final Jid contactJid,
|
||||||
|
@ -301,14 +310,19 @@ public class Conversation extends AbstractEntity implements Blockable {
|
||||||
return (this.messages.size() == 0) || this.messages.get(this.messages.size() - 1).isRead();
|
return (this.messages.size() == 0) || this.messages.get(this.messages.size() - 1).isRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markRead() {
|
public List<Message> markRead() {
|
||||||
|
final List<Message> unread = new ArrayList<>();
|
||||||
|
synchronized (this.messages) {
|
||||||
for (int i = this.messages.size() - 1; i >= 0; --i) {
|
for (int i = this.messages.size() - 1; i >= 0; --i) {
|
||||||
if (messages.get(i).isRead()) {
|
if (this.messages.get(i).isRead()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.messages.get(i).markRead();
|
this.messages.get(i).markRead();
|
||||||
|
unread.add(this.messages.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return unread;
|
||||||
|
}
|
||||||
|
|
||||||
public Message getLatestMarkableMessage() {
|
public Message getLatestMarkableMessage() {
|
||||||
for (int i = this.messages.size() - 1; i >= 0; --i) {
|
for (int i = this.messages.size() - 1; i >= 0; --i) {
|
||||||
|
|
|
@ -56,6 +56,7 @@ public class Message extends AbstractEntity {
|
||||||
public static final String SERVER_MSG_ID = "serverMsgId";
|
public static final String SERVER_MSG_ID = "serverMsgId";
|
||||||
public static final String RELATIVE_FILE_PATH = "relativeFilePath";
|
public static final String RELATIVE_FILE_PATH = "relativeFilePath";
|
||||||
public static final String FINGERPRINT = "axolotl_fingerprint";
|
public static final String FINGERPRINT = "axolotl_fingerprint";
|
||||||
|
public static final String READ = "read";
|
||||||
public static final String ME_COMMAND = "/me ";
|
public static final String ME_COMMAND = "/me ";
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,11 +88,8 @@ public class Message extends AbstractEntity {
|
||||||
public Message(Conversation conversation, String body, int encryption) {
|
public Message(Conversation conversation, String body, int encryption) {
|
||||||
this(conversation, body, encryption, STATUS_UNSEND);
|
this(conversation, body, encryption, STATUS_UNSEND);
|
||||||
}
|
}
|
||||||
public Message(Conversation conversation, String body, int encryption, int status) {
|
|
||||||
this(conversation, body, encryption, status, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Message(Conversation conversation, String body, int encryption, int status, boolean carbon) {
|
public Message(Conversation conversation, String body, int encryption, int status) {
|
||||||
this(java.util.UUID.randomUUID().toString(),
|
this(java.util.UUID.randomUUID().toString(),
|
||||||
conversation.getUuid(),
|
conversation.getUuid(),
|
||||||
conversation.getJid() == null ? null : conversation.getJid().toBareJid(),
|
conversation.getJid() == null ? null : conversation.getJid().toBareJid(),
|
||||||
|
@ -105,7 +103,8 @@ public class Message extends AbstractEntity {
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null);
|
null,
|
||||||
|
true);
|
||||||
this.conversation = conversation;
|
this.conversation = conversation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +112,7 @@ public class Message extends AbstractEntity {
|
||||||
final Jid trueCounterpart, final String body, final long timeSent,
|
final Jid trueCounterpart, final String body, final long timeSent,
|
||||||
final int encryption, final int status, final int type, final boolean carbon,
|
final int encryption, final int status, final int type, final boolean carbon,
|
||||||
final String remoteMsgId, final String relativeFilePath,
|
final String remoteMsgId, final String relativeFilePath,
|
||||||
final String serverMsgId, final String fingerprint) {
|
final String serverMsgId, final String fingerprint, final boolean read) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.conversationUuid = conversationUUid;
|
this.conversationUuid = conversationUUid;
|
||||||
this.counterpart = counterpart;
|
this.counterpart = counterpart;
|
||||||
|
@ -128,6 +127,7 @@ public class Message extends AbstractEntity {
|
||||||
this.relativeFilePath = relativeFilePath;
|
this.relativeFilePath = relativeFilePath;
|
||||||
this.serverMsgId = serverMsgId;
|
this.serverMsgId = serverMsgId;
|
||||||
this.axolotlFingerprint = fingerprint;
|
this.axolotlFingerprint = fingerprint;
|
||||||
|
this.read = read;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Message fromCursor(Cursor cursor) {
|
public static Message fromCursor(Cursor cursor) {
|
||||||
|
@ -166,7 +166,8 @@ public class Message extends AbstractEntity {
|
||||||
cursor.getString(cursor.getColumnIndex(REMOTE_MSG_ID)),
|
cursor.getString(cursor.getColumnIndex(REMOTE_MSG_ID)),
|
||||||
cursor.getString(cursor.getColumnIndex(RELATIVE_FILE_PATH)),
|
cursor.getString(cursor.getColumnIndex(RELATIVE_FILE_PATH)),
|
||||||
cursor.getString(cursor.getColumnIndex(SERVER_MSG_ID)),
|
cursor.getString(cursor.getColumnIndex(SERVER_MSG_ID)),
|
||||||
cursor.getString(cursor.getColumnIndex(FINGERPRINT)));
|
cursor.getString(cursor.getColumnIndex(FINGERPRINT)),
|
||||||
|
cursor.getInt(cursor.getColumnIndex(READ)) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Message createStatusMessage(Conversation conversation, String body) {
|
public static Message createStatusMessage(Conversation conversation, String body) {
|
||||||
|
@ -202,6 +203,7 @@ public class Message extends AbstractEntity {
|
||||||
values.put(RELATIVE_FILE_PATH, relativeFilePath);
|
values.put(RELATIVE_FILE_PATH, relativeFilePath);
|
||||||
values.put(SERVER_MSG_ID, serverMsgId);
|
values.put(SERVER_MSG_ID, serverMsgId);
|
||||||
values.put(FINGERPRINT, axolotlFingerprint);
|
values.put(FINGERPRINT, axolotlFingerprint);
|
||||||
|
values.put(READ,read);
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
private static DatabaseBackend instance = null;
|
private static DatabaseBackend instance = null;
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "history";
|
private static final String DATABASE_NAME = "history";
|
||||||
private static final int DATABASE_VERSION = 17;
|
private static final int DATABASE_VERSION = 18;
|
||||||
|
|
||||||
private static String CREATE_CONTATCS_STATEMENT = "create table "
|
private static String CREATE_CONTATCS_STATEMENT = "create table "
|
||||||
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
|
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
|
||||||
|
@ -143,6 +143,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
+ Message.SERVER_MSG_ID + " TEXT, "
|
+ Message.SERVER_MSG_ID + " TEXT, "
|
||||||
+ Message.FINGERPRINT + " TEXT, "
|
+ Message.FINGERPRINT + " TEXT, "
|
||||||
+ Message.CARBON + " INTEGER, "
|
+ Message.CARBON + " INTEGER, "
|
||||||
|
+ Message.READ + " NUMBER DEFAULT 1, "
|
||||||
+ Message.REMOTE_MSG_ID + " TEXT, FOREIGN KEY("
|
+ Message.REMOTE_MSG_ID + " TEXT, FOREIGN KEY("
|
||||||
+ Message.CONVERSATION + ") REFERENCES "
|
+ Message.CONVERSATION + ") REFERENCES "
|
||||||
+ Conversation.TABLENAME + "(" + Conversation.UUID
|
+ Conversation.TABLENAME + "(" + Conversation.UUID
|
||||||
|
@ -320,6 +321,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (oldVersion < 18 && newVersion >= 18) {
|
||||||
|
db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "+ Message.READ+ " NUMBER DEFAULT 1");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized DatabaseBackend getInstance(Context context) {
|
public static synchronized DatabaseBackend getInstance(Context context) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package eu.siacs.conversations.services;
|
package eu.siacs.conversations.services;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
@ -10,7 +9,6 @@ import android.content.SharedPreferences;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.PowerManager;
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.NotificationCompat.BigPictureStyle;
|
import android.support.v4.app.NotificationCompat.BigPictureStyle;
|
||||||
|
@ -115,19 +113,20 @@ public class NotificationService {
|
||||||
return mXmppConnectionService.getPreferences().getBoolean("always_notify_in_conference", false);
|
return mXmppConnectionService.getPreferences().getBoolean("always_notify_in_conference", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void push(final Message message) {
|
public void pushFromBacklog(final Message message) {
|
||||||
mXmppConnectionService.updateUnreadCountBadge();
|
if (notify(message)) {
|
||||||
if (!notify(message)) {
|
pushToStack(message);
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
final boolean isScreenOn = mXmppConnectionService.isInteractive();
|
|
||||||
|
|
||||||
if (this.mIsInForeground && isScreenOn && this.mOpenConversation == message.getConversation()) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void finishBacklog() {
|
||||||
synchronized (notifications) {
|
synchronized (notifications) {
|
||||||
|
mXmppConnectionService.updateUnreadCountBadge();
|
||||||
|
updateNotification(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pushToStack(final Message message) {
|
||||||
final String conversationUuid = message.getConversationUuid();
|
final String conversationUuid = message.getConversationUuid();
|
||||||
if (notifications.containsKey(conversationUuid)) {
|
if (notifications.containsKey(conversationUuid)) {
|
||||||
notifications.get(conversationUuid).add(message);
|
notifications.get(conversationUuid).add(message);
|
||||||
|
@ -136,6 +135,19 @@ public class NotificationService {
|
||||||
mList.add(message);
|
mList.add(message);
|
||||||
notifications.put(conversationUuid, mList);
|
notifications.put(conversationUuid, mList);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void push(final Message message) {
|
||||||
|
mXmppConnectionService.updateUnreadCountBadge();
|
||||||
|
if (!notify(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final boolean isScreenOn = mXmppConnectionService.isInteractive();
|
||||||
|
if (this.mIsInForeground && isScreenOn && this.mOpenConversation == message.getConversation()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronized (notifications) {
|
||||||
|
pushToStack(message);
|
||||||
final Account account = message.getConversation().getAccount();
|
final Account account = message.getConversation().getAccount();
|
||||||
final boolean doNotify = (!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn)
|
final boolean doNotify = (!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn)
|
||||||
&& !account.inGracePeriod()
|
&& !account.inGracePeriod()
|
||||||
|
|
|
@ -1072,7 +1072,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
for (Conversation conversation : conversations) {
|
for (Conversation conversation : conversations) {
|
||||||
conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
|
conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
|
||||||
checkDeletedFiles(conversation);
|
checkDeletedFiles(conversation);
|
||||||
|
conversation.findUnreadMessages(new Conversation.OnMessageFound() {
|
||||||
|
@Override
|
||||||
|
public void onMessageFound(Message message) {
|
||||||
|
mNotificationService.pushFromBacklog(message);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
mNotificationService.finishBacklog();
|
||||||
mRestoredFromDatabase = true;
|
mRestoredFromDatabase = true;
|
||||||
Log.d(Config.LOGTAG,"restored all messages");
|
Log.d(Config.LOGTAG,"restored all messages");
|
||||||
updateConversationUi();
|
updateConversationUi();
|
||||||
|
@ -1330,7 +1337,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateKeyInAccount(final Account account, final String alias) {
|
public void updateKeyInAccount(final Account account, final String alias) {
|
||||||
Log.d(Config.LOGTAG,"update key in account "+alias);
|
Log.d(Config.LOGTAG, "update key in account " + alias);
|
||||||
try {
|
try {
|
||||||
X509Certificate[] chain = KeyChain.getCertificateChain(XmppConnectionService.this, alias);
|
X509Certificate[] chain = KeyChain.getCertificateChain(XmppConnectionService.this, alias);
|
||||||
Pair<Jid, String> info = CryptoHelper.extractJidAndName(chain[0]);
|
Pair<Jid, String> info = CryptoHelper.extractJidAndName(chain[0]);
|
||||||
|
@ -2566,7 +2573,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
|
|
||||||
public void markRead(final Conversation conversation) {
|
public void markRead(final Conversation conversation) {
|
||||||
mNotificationService.clear(conversation);
|
mNotificationService.clear(conversation);
|
||||||
conversation.markRead();
|
for(Message message : conversation.markRead()) {
|
||||||
|
databaseBackend.updateMessage(message);
|
||||||
|
}
|
||||||
updateUnreadCountBadge();
|
updateUnreadCountBadge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,8 +216,7 @@ public class ConversationActivity extends XmppActivity
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
listAdapter.remove(swipedConversation);
|
listAdapter.remove(swipedConversation);
|
||||||
swipedConversation.markRead();
|
xmppConnectionService.markRead(swipedConversation);
|
||||||
xmppConnectionService.getNotificationService().clear(swipedConversation);
|
|
||||||
|
|
||||||
final boolean formerlySelected = (getSelectedConversation() == swipedConversation);
|
final boolean formerlySelected = (getSelectedConversation() == swipedConversation);
|
||||||
if (position == 0 && listAdapter.getCount() == 0) {
|
if (position == 0 && listAdapter.getCount() == 0) {
|
||||||
|
|
Loading…
Reference in a new issue