From 1add11177d01a38a86ffc8894d80ad6c30898c72 Mon Sep 17 00:00:00 2001 From: DrKLO Date: Fri, 31 Oct 2014 22:02:29 +0300 Subject: [PATCH] Messages search (not finished) --- .../main/java/org/telegram/android/Emoji.java | 8 +- .../telegram/android/MessagesController.java | 86 +-- .../org/telegram/android/MessagesStorage.java | 295 ++++------- .../telegram/android/NotificationCenter.java | 1 - .../telegram/android/SendMessagesHelper.java | 6 +- .../Adapters/BaseContactsSearchAdapter.java | 8 +- .../ContactsActivitySearchAdapter.java | 14 +- .../ui/Adapters/MessagesActivityAdapter.java | 155 ++++++ .../MessagesActivitySearchAdapter.java | 499 ++++++++++++++++++ .../org/telegram/ui/Cells/DialogCell.java | 51 +- .../java/org/telegram/ui/ChatActivity.java | 145 ++--- .../org/telegram/ui/ChatProfileActivity.java | 2 +- .../org/telegram/ui/ContactsActivity.java | 12 +- .../telegram/ui/GroupCreateFinalActivity.java | 2 +- .../org/telegram/ui/MessagesActivity.java | 461 ++++------------ .../org/telegram/ui/Views/SlidingTabView.java | 153 ++++++ .../main/res/layout-ar/contacts_layout.xml | 34 -- .../src/main/res/layout-ar/messages_list.xml | 67 --- .../settings_blocked_users_layout.xml | 45 -- .../main/res/layout-ar/settings_layout.xml | 24 - .../src/main/res/layout/messages_list.xml | 42 +- .../src/main/res/values-ar/strings.xml | 2 + .../src/main/res/values-de/strings.xml | 2 + .../src/main/res/values-es/strings.xml | 2 + .../src/main/res/values-it/strings.xml | 2 + .../src/main/res/values-ko/strings.xml | 2 + .../src/main/res/values-nl/strings.xml | 2 + .../src/main/res/values-pt-rBR/strings.xml | 2 + .../src/main/res/values-pt-rPT/strings.xml | 2 + TMessagesProj/src/main/res/values/strings.xml | 2 + 30 files changed, 1254 insertions(+), 874 deletions(-) create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Adapters/MessagesActivityAdapter.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Adapters/MessagesActivitySearchAdapter.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Views/SlidingTabView.java delete mode 100644 TMessagesProj/src/main/res/layout-ar/contacts_layout.xml delete mode 100644 TMessagesProj/src/main/res/layout-ar/messages_list.xml delete mode 100644 TMessagesProj/src/main/res/layout-ar/settings_blocked_users_layout.xml delete mode 100644 TMessagesProj/src/main/res/layout-ar/settings_layout.xml diff --git a/TMessagesProj/src/main/java/org/telegram/android/Emoji.java b/TMessagesProj/src/main/java/org/telegram/android/Emoji.java index 7f9c2bbca..df744fa7b 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/Emoji.java +++ b/TMessagesProj/src/main/java/org/telegram/android/Emoji.java @@ -346,7 +346,13 @@ public class Emoji { canvas.drawRect(getBounds(), placeholderPaint); return; } - Rect b = getDrawRect(); + Rect b; + if (fullSize) { + b = getDrawRect(); + } else { + b = getBounds(); + } + if (!canvas.quickReject(b.left, b.top, b.right, b.bottom, Canvas.EdgeType.AA)) { canvas.drawBitmap(emojiBmp[info.page], info.rect, b, paint); } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java index 06806b770..e9fece9a8 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java @@ -1021,7 +1021,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialog.unread_count = 0; } dialogMessage.remove(dialog.top_message); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.RunOnUIThread(new Runnable() { @@ -1332,10 +1332,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - public void loadMessages(final long dialog_id, final int count, final int max_id, boolean fromCache, int midDate, final int classGuid, boolean from_unread, boolean forward, final Semaphore semaphore) { + public void loadMessages(final long dialog_id, final int count, final int max_id, boolean fromCache, int midDate, final int classGuid, final int load_type) { int lower_part = (int)dialog_id; if (fromCache || lower_part == 0) { - MessagesStorage.getInstance().getMessages(dialog_id, count, max_id, midDate, classGuid, from_unread, forward, semaphore); + MessagesStorage.getInstance().getMessages(dialog_id, count, max_id, midDate, classGuid, load_type); } else { TLRPC.TL_messages_getHistory req = new TLRPC.TL_messages_getHistory(); if (lower_part < 0) { @@ -1360,7 +1360,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter public void run(TLObject response, TLRPC.TL_error error) { if (error == null) { final TLRPC.messages_Messages res = (TLRPC.messages_Messages) response; - processLoadedMessages(res, dialog_id, count, max_id, false, classGuid, 0, 0, 0, 0, false, semaphore); + processLoadedMessages(res, dialog_id, count, max_id, false, classGuid, 0, 0, 0, 0, load_type); } } }); @@ -1368,7 +1368,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - public void processLoadedMessages(final TLRPC.messages_Messages messagesRes, final long dialog_id, final int count, final int max_id, final boolean isCache, final int classGuid, final int first_unread, final int last_unread, final int unread_count, final int last_date, final boolean isForward, final Semaphore semaphore) { + public void processLoadedMessages(final TLRPC.messages_Messages messagesRes, final long dialog_id, final int count, final int max_id, final boolean isCache, final int classGuid, final int first_unread, final int last_message_id, final int unread_count, final int last_date, final int load_type) { Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { @@ -1376,14 +1376,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (!isCache) { MessagesStorage.getInstance().putMessages(messagesRes, dialog_id); } - if (lower_id != 0 && isCache && messagesRes.messages.size() == 0 && !isForward) { - if (semaphore != null) { - semaphore.release(); - } + if (lower_id != 0 && isCache && messagesRes.messages.size() == 0 && (load_type == 0 || load_type == 3)) { AndroidUtilities.RunOnUIThread(new Runnable() { @Override public void run() { - loadMessages(dialog_id, count, max_id, false, 0, classGuid, false, false, null); + loadMessages(dialog_id, count, max_id, false, 0, classGuid, load_type); } }); return; @@ -1397,21 +1394,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter message.dialog_id = dialog_id; objects.add(new MessageObject(message, usersLocal, 2)); } - if (semaphore != null) { - putUsers(messagesRes.users, isCache); - putChats(messagesRes.chats, isCache); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDidLoaded, dialog_id, count, objects, isCache, first_unread, last_unread, unread_count, last_date, isForward); - semaphore.release(); - } else { - AndroidUtilities.RunOnUIThread(new Runnable() { - @Override - public void run() { - putUsers(messagesRes.users, isCache); - putChats(messagesRes.chats, isCache); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDidLoaded, dialog_id, count, objects, isCache, first_unread, last_unread, unread_count, last_date, isForward); - } - }); - } + AndroidUtilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + putUsers(messagesRes.users, isCache); + putChats(messagesRes.chats, isCache); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDidLoaded, dialog_id, count, objects, isCache, first_unread, last_message_id, unread_count, last_date, load_type); + } + }); } }); } @@ -1761,7 +1751,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter req.read_contents = true; if (offset == 0) { MessagesStorage.getInstance().processPendingRead(dialog_id, max_positive_id, max_date, false); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.RunOnUIThread(new Runnable() { @@ -1824,7 +1814,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } MessagesStorage.getInstance().processPendingRead(dialog_id, max_id, max_date, false); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.RunOnUIThread(new Runnable() { @@ -2480,7 +2470,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } }); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { if (!msgUpdates.isEmpty()) { @@ -2572,7 +2562,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); } }); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { if (!pushMessages.isEmpty()) { @@ -2682,7 +2672,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); } }); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.RunOnUIThread(new Runnable() { @@ -2747,7 +2737,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); } }); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.RunOnUIThread(new Runnable() { @@ -3204,7 +3194,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } else { MessagesStorage.getInstance().deleteBlockedUser(finalUpdate.user_id); } - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.RunOnUIThread(new Runnable() { @@ -3215,7 +3205,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter blockedUsers.add(finalUpdate.user_id); } } else { - blockedUsers.remove((Integer)finalUpdate.user_id); + blockedUsers.remove((Integer) finalUpdate.user_id); } NotificationCenter.getInstance().postNotificationName(NotificationCenter.blockedUsersDidLoaded); } @@ -3225,7 +3215,27 @@ public class MessagesController implements NotificationCenter.NotificationCenter } else if (update instanceof TLRPC.TL_updateNotifySettings) { updatesOnMainThread.add(update); } else if (update instanceof TLRPC.TL_updateServiceNotification) { - //TODO + TLRPC.TL_message newMessage = new TLRPC.TL_message(); + newMessage.local_id = newMessage.id = UserConfig.getNewMessageId(); + UserConfig.saveConfig(false); + newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD; + newMessage.date = update.date; + newMessage.from_id = 777000; + newMessage.to_id = new TLRPC.TL_peerUser(); + newMessage.to_id.user_id = UserConfig.getClientUserId(); + newMessage.dialog_id = 777000; + newMessage.media = update.media; + newMessage.message = ((TLRPC.TL_updateServiceNotification)update).message; + + messagesArr.add(newMessage); + MessageObject obj = new MessageObject(newMessage, usersDict); + ArrayList arr = messages.get(newMessage.dialog_id); + if (arr == null) { + arr = new ArrayList(); + messages.put(newMessage.dialog_id, arr); + } + arr.add(obj); + pushMessages.add(obj); } } if (!messages.isEmpty()) { @@ -3251,7 +3261,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter ContactsController.getInstance().processContactsUpdates(contactsIds, usersDict); } - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.RunOnUIThread(new Runnable() { @@ -3374,7 +3384,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } }); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.RunOnUIThread(new Runnable() { @@ -3396,7 +3406,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (!markAsReadEncrypted.isEmpty()) { for (HashMap.Entry entry : markAsReadEncrypted.entrySet()) { NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesReadedEncrypted, entry.getKey(), entry.getValue()); - long dialog_id = (long)(entry.getKey()) << 32; + long dialog_id = (long) (entry.getKey()) << 32; TLRPC.TL_dialog dialog = dialogs_dict.get(dialog_id); if (dialog != null) { MessageObject message = dialogMessage.get(dialog.top_message); @@ -3762,7 +3772,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialog.unread_count = 0; dialogMessage.remove(dialog.top_message); } - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.RunOnUIThread(new Runnable() { diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java index 2648b28af..9bf30b189 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java @@ -10,7 +10,6 @@ package org.telegram.android; import android.content.Context; import android.content.SharedPreferences; -import android.text.Html; import android.text.TextUtils; import android.util.SparseArray; @@ -41,7 +40,7 @@ import java.util.Map; import java.util.concurrent.Semaphore; public class MessagesStorage { - public DispatchQueue storageQueue = new DispatchQueue("storageQueue"); + private DispatchQueue storageQueue = new DispatchQueue("storageQueue"); private SQLiteDatabase database; private File cacheFile; private BuffersStorage buffersStorage = new BuffersStorage(false); @@ -77,6 +76,18 @@ public class MessagesStorage { openDatabase(); } + public SQLiteDatabase getDatabase() { + return database; + } + + public DispatchQueue getStorageQueue() { + return storageQueue; + } + + public BuffersStorage getBuffersStorage() { + return buffersStorage; + } + public void openDatabase() { cacheFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "cache4.db"); @@ -1152,131 +1163,6 @@ public class MessagesStorage { }); } - public void searchDialogs(final Integer token, final String query, final boolean needEncrypted) { - storageQueue.postRunnable(new Runnable() { - @Override - public void run() { - try { - ArrayList encUsers = new ArrayList(); - String q = query.trim().toLowerCase(); - if (q.length() == 0) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadSearchResults, token, new ArrayList(), new ArrayList(), new ArrayList()); - return; - } - ArrayList resultArray = new ArrayList(); - ArrayList resultArrayNames = new ArrayList(); - - SQLiteCursor cursor = database.queryFinalized("SELECT u.data, u.status, u.name FROM users as u INNER JOIN contacts as c ON u.uid = c.uid"); - while (cursor.next()) { - String name = cursor.stringValue(2); - String username = null; - int usernamePos = name.lastIndexOf(";;;"); - if (usernamePos != -1) { - username = name.substring(usernamePos + 3); - } - int found = 0; - if (name.startsWith(q) || name.contains(" " + q)) { - found = 1; - } else if (username != null && username.startsWith(q)) { - found = 2; - } - if (found != 0) { - ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); - if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { - TLRPC.User user = (TLRPC.User)TLClassStore.Instance().TLdeserialize(data, data.readInt32()); - if (user.id != UserConfig.getClientUserId()) { - if (user.status != null) { - user.status.expires = cursor.intValue(1); - } - if (found == 1) { - resultArrayNames.add(Utilities.generateSearchName(user.first_name, user.last_name, q)); - } else { - resultArrayNames.add(Utilities.generateSearchName("@" + user.username, null, "@" + q)); - } - resultArray.add(user); - } - } - buffersStorage.reuseFreeBuffer(data); - } - } - cursor.dispose(); - - if (needEncrypted) { - cursor = database.queryFinalized("SELECT q.data, u.name, q.user, q.g, q.authkey, q.ttl, u.data, u.status, q.layer, q.seq_in, q.seq_out FROM enc_chats as q INNER JOIN dialogs as d ON (q.uid << 32) = d.did INNER JOIN users as u ON q.user = u.uid"); - while (cursor.next()) { - String name = cursor.stringValue(1); - - String username = null; - int usernamePos = name.lastIndexOf(";;;"); - if (usernamePos != -1) { - username = name.substring(usernamePos + 2); - } - int found = 0; - if (name.startsWith(q) || name.contains(" " + q)) { - found = 1; - } else if (username != null && username.startsWith(q)) { - found = 2; - } - - if (found != 0) { - ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); - ByteBufferDesc data2 = buffersStorage.getFreeBuffer(cursor.byteArrayLength(6)); - if (data != null && cursor.byteBufferValue(0, data.buffer) != 0 && cursor.byteBufferValue(6, data2.buffer) != 0) { - TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); - chat.user_id = cursor.intValue(2); - chat.a_or_b = cursor.byteArrayValue(3); - chat.auth_key = cursor.byteArrayValue(4); - chat.ttl = cursor.intValue(5); - chat.layer = cursor.intValue(8); - chat.seq_in = cursor.intValue(9); - chat.seq_out = cursor.intValue(10); - - TLRPC.User user = (TLRPC.User)TLClassStore.Instance().TLdeserialize(data2, data2.readInt32()); - if (user.status != null) { - user.status.expires = cursor.intValue(7); - } - if (found == 1) { - resultArrayNames.add(Html.fromHtml("" + ContactsController.formatName(user.first_name, user.last_name) + "")); - } else { - resultArrayNames.add(Utilities.generateSearchName("@" + user.username, null, "@" + q)); - } - resultArray.add(chat); - encUsers.add(user); - } - buffersStorage.reuseFreeBuffer(data); - buffersStorage.reuseFreeBuffer(data2); - } - } - cursor.dispose(); - } - - cursor = database.queryFinalized("SELECT data, name FROM chats"); - while (cursor.next()) { - String name = cursor.stringValue(1); - String[] args = name.split(" "); - if (name.startsWith(q) || name.contains(" " + q)) { - ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); - if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { - TLRPC.Chat chat = (TLRPC.Chat) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); - if (!needEncrypted && chat.id < 0) { - continue; - } - resultArrayNames.add(Utilities.generateSearchName(chat.title, null, q)); - resultArray.add(chat); - } - buffersStorage.reuseFreeBuffer(data); - } - } - cursor.dispose(); - - NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadSearchResults, token, resultArray, resultArrayNames, encUsers); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - }); - } - public void putContacts(final ArrayList contacts, final boolean deleteAll) { if (contacts.isEmpty()) { return; @@ -1720,7 +1606,7 @@ public class MessagesStorage { }); } - public void getMessages(final long dialog_id, final int count, final int max_id, final int minDate, final int classGuid, final boolean from_unread, final boolean forward, final Semaphore semaphore) { + public void getMessages(final long dialog_id, final int count, final int max_id, final int minDate, final int classGuid, final int load_type) { storageQueue.postRunnable(new Runnable() { @Override public void run() { @@ -1729,7 +1615,7 @@ public class MessagesStorage { int count_query = count; int offset_query = 0; int min_unread_id = 0; - int max_unread_id = 0; + int last_message_id = 0; int max_unread_date = 0; try { ArrayList loadedUsers = new ArrayList(); @@ -1739,7 +1625,16 @@ public class MessagesStorage { int lower_id = (int)dialog_id; if (lower_id != 0) { - if (forward) { + if (load_type == 3) { + cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid) FROM messages WHERE uid = %d AND mid > 0", dialog_id)); + if (cursor.next()) { + last_message_id = cursor.intValue(0); + } + cursor.dispose(); + + cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND mid <= %d ORDER BY date DESC, mid DESC LIMIT %d) UNION " + + "SELECT * FROM (SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND mid > %d ORDER BY date ASC, mid ASC LIMIT %d)", dialog_id, max_id, count_query / 2, dialog_id, max_id, count_query / 2)); + } else if (load_type == 1) { cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND date >= %d AND mid > %d ORDER BY date ASC, mid ASC LIMIT %d", dialog_id, minDate, max_id, count_query)); } else if (minDate != 0) { if (max_id != 0) { @@ -1748,12 +1643,17 @@ public class MessagesStorage { cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND date <= %d ORDER BY date DESC, mid DESC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query)); } } else { - if (from_unread) { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid), max(mid), max(date) FROM messages WHERE uid = %d AND out = 0 AND read_state = 0 AND mid > 0", dialog_id)); + if (load_type == 2) { + cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid) FROM messages WHERE uid = %d AND mid > 0", dialog_id)); + if (cursor.next()) { + last_message_id = cursor.intValue(0); + } + cursor.dispose(); + + cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid), max(date) FROM messages WHERE uid = %d AND out = 0 AND read_state = 0 AND mid > 0", dialog_id)); if (cursor.next()) { min_unread_id = cursor.intValue(0); - max_unread_id = cursor.intValue(1); - max_unread_date = cursor.intValue(2); + max_unread_date = cursor.intValue(1); } cursor.dispose(); if (min_unread_id != 0) { @@ -1770,7 +1670,7 @@ public class MessagesStorage { if (count_unread < 4) { count_unread = 0; min_unread_id = 0; - max_unread_id = 0; + last_message_id = 0; } } else { offset_query = count_unread - count_query; @@ -1779,7 +1679,7 @@ public class MessagesStorage { cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d ORDER BY date DESC, mid DESC LIMIT %d,%d", dialog_id, offset_query, count_query)); } } else { - if (forward) { + if (load_type == 1) { cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid < %d ORDER BY m.mid DESC LIMIT %d", dialog_id, max_id, count_query)); } else if (minDate != 0) { if (max_id != 0) { @@ -1788,12 +1688,17 @@ public class MessagesStorage { cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d ORDER BY m.mid ASC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query)); } } else { - if (from_unread) { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid), min(mid), max(date) FROM messages WHERE uid = %d AND out = 0 AND read_state = 0 AND mid < 0", dialog_id)); + if (load_type == 2) { + cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages WHERE uid = %d AND mid < 0", dialog_id)); + if (cursor.next()) { + last_message_id = cursor.intValue(0); + } + cursor.dispose(); + + cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid), max(date) FROM messages WHERE uid = %d AND out = 0 AND read_state = 0 AND mid < 0", dialog_id)); if (cursor.next()) { min_unread_id = cursor.intValue(0); - max_unread_id = cursor.intValue(1); - max_unread_date = cursor.intValue(2); + max_unread_date = cursor.intValue(1); } cursor.dispose(); if (min_unread_id != 0) { @@ -1810,7 +1715,7 @@ public class MessagesStorage { if (count_unread < 4) { count_unread = 0; min_unread_id = 0; - max_unread_id = 0; + last_message_id = 0; } } else { offset_query = count_unread - count_query; @@ -1822,6 +1727,12 @@ public class MessagesStorage { while (cursor.next()) { ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1)); if (data != null && cursor.byteBufferValue(1, data.buffer) != 0) { + if (load_type == 3 && res.messages.isEmpty()) { + int id = cursor.intValue(3); + if (id > max_id) { + break; + } + } TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32()); MessageObject.setIsUnread(message, cursor.intValue(0) != 1); message.id = cursor.intValue(3); @@ -1861,59 +1772,59 @@ public class MessagesStorage { } } buffersStorage.reuseFreeBuffer(data); - - Collections.sort(res.messages, new Comparator() { - @Override - public int compare(TLRPC.Message lhs, TLRPC.Message rhs) { - if (lhs.id > 0 && rhs.id > 0) { - if (!forward) { - if (lhs.id > rhs.id) { - return -1; - } else if (lhs.id < rhs.id) { - return 1; - } - } else { - if (lhs.id < rhs.id) { - return -1; - } else if (lhs.id > rhs.id) { - return 1; - } - } - } else if (lhs.id < 0 && rhs.id < 0) { - if (!forward) { - if (lhs.id < rhs.id) { - return -1; - } else if (lhs.id > rhs.id) { - return 1; - } - } else { - if (lhs.id > rhs.id) { - return -1; - } else if (lhs.id < rhs.id) { - return 1; - } - } - } else { - if (!forward) { - if (lhs.date > rhs.date) { - return -1; - } else if (lhs.date < rhs.date) { - return 1; - } - } else { - if (lhs.date < rhs.date) { - return -1; - } else if (lhs.date > rhs.date) { - return 1; - } - } - } - return 0; - } - }); } cursor.dispose(); + Collections.sort(res.messages, new Comparator() { + @Override + public int compare(TLRPC.Message lhs, TLRPC.Message rhs) { + if (lhs.id > 0 && rhs.id > 0) { + if (load_type != 1) { + if (lhs.id > rhs.id) { + return -1; + } else if (lhs.id < rhs.id) { + return 1; + } + } else { + if (lhs.id < rhs.id) { + return -1; + } else if (lhs.id > rhs.id) { + return 1; + } + } + } else if (lhs.id < 0 && rhs.id < 0) { + if (load_type != 1) { + if (lhs.id < rhs.id) { + return -1; + } else if (lhs.id > rhs.id) { + return 1; + } + } else { + if (lhs.id > rhs.id) { + return -1; + } else if (lhs.id < rhs.id) { + return 1; + } + } + } else { + if (load_type != 1) { + if (lhs.date > rhs.date) { + return -1; + } else if (lhs.date < rhs.date) { + return 1; + } + } else { + if (lhs.date < rhs.date) { + return -1; + } else if (lhs.date > rhs.date) { + return 1; + } + } + } + return 0; + } + }); + StringBuilder usersToLoad = new StringBuilder(); for (int uid : fromUser) { if (!loadedUsers.contains(uid)) { @@ -1933,7 +1844,7 @@ public class MessagesStorage { res.users.clear(); FileLog.e("tmessages", e); } finally { - MessagesController.getInstance().processLoadedMessages(res, dialog_id, count_query, max_id, true, classGuid, min_unread_id, max_unread_id, count_unread, max_unread_date, forward, semaphore); + MessagesController.getInstance().processLoadedMessages(res, dialog_id, count_query, max_id, true, classGuid, min_unread_id, last_message_id, count_unread, max_unread_date, load_type); } } }); diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java index 1b9896166..612e35be3 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java @@ -23,7 +23,6 @@ public class NotificationCenter { public static final int messageReceivedByAck = 9; public static final int messageReceivedByServer = 10; public static final int messageSendError = 11; - public static final int reloadSearchResults = 12; public static final int contactsDidLoaded = 13; public static final int chatDidCreated = 15; public static final int chatDidFailCreate = 16; diff --git a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java index 2cd6af214..fa1d9eb6e 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java @@ -1064,7 +1064,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } private void stopVideoService(final String path) { - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.RunOnUIThread(new Runnable() { @@ -1110,7 +1110,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, -1); } - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { MessagesStorage.getInstance().updateMessageStateAndId(newMsgObj.random_id, oldId, (isBroadcast ? oldId : newMsgObj.id), 0, false); @@ -1301,7 +1301,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (res.file instanceof TLRPC.TL_encryptedFile) { processSentMessage(newMsgObj, null, res.file, req, originalPath); } - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { if (newMsgObj.action instanceof TLRPC.TL_messageEncryptedAction) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/BaseContactsSearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/BaseContactsSearchAdapter.java index e639fb166..53da9988a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/BaseContactsSearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/BaseContactsSearchAdapter.java @@ -24,11 +24,11 @@ public class BaseContactsSearchAdapter extends BaseFragmentAdapter { protected String lastFoundUsername = null; public void queryServerSearch(final String query) { + if (reqId != 0) { + ConnectionsManager.getInstance().cancelRpc(reqId, true); + reqId = 0; + } if (query == null || query.length() < 5) { - if (reqId != 0) { - ConnectionsManager.getInstance().cancelRpc(reqId, true); - reqId = 0; - } globalSearch.clear(); lastReqId = 0; notifyDataSetChanged(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsActivitySearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsActivitySearchAdapter.java index eacc0cdb6..c0c16fc71 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsActivitySearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsActivitySearchAdapter.java @@ -45,6 +45,13 @@ public class ContactsActivitySearchAdapter extends BaseContactsSearchAdapter { } public void searchDialogs(final String query) { + try { + if (searchTimer != null) { + searchTimer.cancel(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } if (query == null) { searchResult.clear(); searchResultNames.clear(); @@ -53,13 +60,6 @@ public class ContactsActivitySearchAdapter extends BaseContactsSearchAdapter { } notifyDataSetChanged(); } else { - try { - if (searchTimer != null) { - searchTimer.cancel(); - } - } catch (Exception e) { - FileLog.e("tmessages", e); - } searchTimer = new Timer(); searchTimer.schedule(new TimerTask() { @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MessagesActivityAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MessagesActivityAdapter.java new file mode 100644 index 000000000..9533d38c1 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MessagesActivityAdapter.java @@ -0,0 +1,155 @@ +/* + * This is the source code of Telegram for Android v. 1.7.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.ui.Adapters; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.MessageObject; +import org.telegram.android.MessagesController; +import org.telegram.messenger.R; +import org.telegram.messenger.TLRPC; +import org.telegram.ui.Cells.DialogCell; + +public class MessagesActivityAdapter extends BaseFragmentAdapter { + + private Context mContext; + private boolean serverOnly; + private long openedDialogId; + + public MessagesActivityAdapter(Context context, boolean onlyFromServer) { + mContext = context; + serverOnly = onlyFromServer; + } + + public void setOpenedDialogId(long id) { + openedDialogId = id; + } + + @Override + public boolean areAllItemsEnabled() { + return true; + } + + @Override + public boolean isEnabled(int i) { + return true; + } + + @Override + public int getCount() { + int count; + if (serverOnly) { + count = MessagesController.getInstance().dialogsServerOnly.size(); + } else { + count = MessagesController.getInstance().dialogs.size(); + } + if (count == 0 && MessagesController.getInstance().loadingDialogs) { + return 0; + } + if (!MessagesController.getInstance().dialogsEndReached) { + count++; + } + return count; + } + + @Override + public TLRPC.TL_dialog getItem(int i) { + if (serverOnly) { + if (i < 0 || i >= MessagesController.getInstance().dialogsServerOnly.size()) { + return null; + } + return MessagesController.getInstance().dialogsServerOnly.get(i); + } else { + if (i < 0 || i >= MessagesController.getInstance().dialogs.size()) { + return null; + } + return MessagesController.getInstance().dialogs.get(i); + } + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + int type = getItemViewType(i); + if (type == 1) { + if (view == null) { + LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + view = li.inflate(R.layout.loading_more_layout, viewGroup, false); + } + } else if (type == 0) { + if (view == null) { + view = new DialogCell(mContext); + } + ((DialogCell) view).useSeparator = (i != getCount() - 1); + TLRPC.TL_dialog dialog = null; + if (serverOnly) { + dialog = MessagesController.getInstance().dialogsServerOnly.get(i); + } else { + dialog = MessagesController.getInstance().dialogs.get(i); + if (AndroidUtilities.isTablet()) { + if (dialog.id == openedDialogId) { + view.setBackgroundColor(0x0f000000); + } else { + view.setBackgroundColor(0); + } + } + } + MessageObject message = MessagesController.getInstance().dialogMessage.get(dialog.top_message); + ((DialogCell) view).setDialog(dialog.id, message, true, dialog.last_message_date, dialog.unread_count); + } + + return view; + } + + @Override + public int getItemViewType(int i) { + if (serverOnly && i == MessagesController.getInstance().dialogsServerOnly.size() || !serverOnly && i == MessagesController.getInstance().dialogs.size()) { + return 1; + } + return 0; + } + + @Override + public int getViewTypeCount() { + return 2; + } + + @Override + public boolean isEmpty() { + if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { + return false; + } + int count; + if (serverOnly) { + count = MessagesController.getInstance().dialogsServerOnly.size(); + } else { + count = MessagesController.getInstance().dialogs.size(); + } + if (count == 0 && MessagesController.getInstance().loadingDialogs) { + return true; + } + if (!MessagesController.getInstance().dialogsEndReached) { + count++; + } + return count == 0; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MessagesActivitySearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MessagesActivitySearchAdapter.java new file mode 100644 index 000000000..527b85a58 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MessagesActivitySearchAdapter.java @@ -0,0 +1,499 @@ +/* + * This is the source code of Telegram for Android v. 1.7.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.ui.Adapters; + +import android.content.Context; +import android.text.Html; +import android.view.View; +import android.view.ViewGroup; + +import org.telegram.SQLite.SQLiteCursor; +import org.telegram.android.AndroidUtilities; +import org.telegram.android.ContactsController; +import org.telegram.android.LocaleController; +import org.telegram.android.MessageObject; +import org.telegram.android.MessagesController; +import org.telegram.android.MessagesStorage; +import org.telegram.messenger.ByteBufferDesc; +import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; +import org.telegram.messenger.RPCRequest; +import org.telegram.messenger.TLClassStore; +import org.telegram.messenger.TLObject; +import org.telegram.messenger.TLRPC; +import org.telegram.messenger.UserConfig; +import org.telegram.messenger.Utilities; +import org.telegram.ui.Cells.ChatOrUserCell; +import org.telegram.ui.Cells.DialogCell; +import org.telegram.ui.Views.SettingsSectionLayout; + +import java.util.ArrayList; +import java.util.Timer; +import java.util.TimerTask; + +public class MessagesActivitySearchAdapter extends BaseContactsSearchAdapter { + private Context mContext; + private Timer searchTimer; + private ArrayList searchResult = new ArrayList(); + private ArrayList searchResultNames = new ArrayList(); + private ArrayList searchResultMessages = new ArrayList(); + private String lastSearchTextDialogs; + private String lastSearchTextMessages; + private int currentSearchType; + private long reqId = 0; + private int lastReqId; + private MessagesActivitySearchAdapterDelegate delegate; + + public static interface MessagesActivitySearchAdapterDelegate { + public abstract void searchStateChanged(boolean searching); + } + + public MessagesActivitySearchAdapter(Context context) { + mContext = context; + } + + public void setDelegate(MessagesActivitySearchAdapterDelegate delegate) { + this.delegate = delegate; + } + + private void searchMessagesInternal(final String query) { + if (reqId != 0) { + ConnectionsManager.getInstance().cancelRpc(reqId, true); + reqId = 0; + } + if (query == null || query.length() == 0) { + searchResultMessages.clear(); + lastReqId = 0; + notifyDataSetChanged(); + if (delegate != null) { + delegate.searchStateChanged(false); + } + return; + } + TLRPC.TL_messages_search req = new TLRPC.TL_messages_search(); + req.limit = 128; + req.peer = new TLRPC.TL_inputPeerEmpty(); + req.q = query; + req.filter = new TLRPC.TL_inputMessagesFilterEmpty(); + final int currentReqId = ++lastReqId; + if (delegate != null) { + delegate.searchStateChanged(true); + } + reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(final TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + if (currentReqId == lastReqId) { + if (error == null) { + TLRPC.messages_Messages res = (TLRPC.messages_Messages) response; + MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true); + MessagesController.getInstance().putUsers(res.users, false); + MessagesController.getInstance().putChats(res.chats, false); + searchResultMessages.clear(); + for (TLRPC.Message message : res.messages) { + searchResultMessages.add(new MessageObject(message, null, 0)); + } + notifyDataSetChanged(); + } + } + if (delegate != null) { + delegate.searchStateChanged(false); + } + reqId = 0; + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); + } + + private void searchDialogsInternal(final String query, final boolean needEncrypted) { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + try { + ArrayList encUsers = new ArrayList(); + String q = query.trim().toLowerCase(); + if (q.length() == 0) { + updateSearchResults(new ArrayList(), new ArrayList(), new ArrayList()); + return; + } + ArrayList resultArray = new ArrayList(); + ArrayList resultArrayNames = new ArrayList(); + + SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT u.data, u.status, u.name FROM users as u INNER JOIN contacts as c ON u.uid = c.uid"); + while (cursor.next()) { + String name = cursor.stringValue(2); + String username = null; + int usernamePos = name.lastIndexOf(";;;"); + if (usernamePos != -1) { + username = name.substring(usernamePos + 3); + } + int found = 0; + if (name.startsWith(q) || name.contains(" " + q)) { + found = 1; + } else if (username != null && username.startsWith(q)) { + found = 2; + } + if (found != 0) { + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { + TLRPC.User user = (TLRPC.User) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + if (user.id != UserConfig.getClientUserId()) { + if (user.status != null) { + user.status.expires = cursor.intValue(1); + } + if (found == 1) { + resultArrayNames.add(Utilities.generateSearchName(user.first_name, user.last_name, q)); + } else { + resultArrayNames.add(Utilities.generateSearchName("@" + user.username, null, "@" + q)); + } + resultArray.add(user); + } + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + } + } + cursor.dispose(); + + if (needEncrypted) { + cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT q.data, u.name, q.user, q.g, q.authkey, q.ttl, u.data, u.status, q.layer, q.seq_in, q.seq_out FROM enc_chats as q INNER JOIN dialogs as d ON (q.uid << 32) = d.did INNER JOIN users as u ON q.user = u.uid"); + while (cursor.next()) { + String name = cursor.stringValue(1); + + String username = null; + int usernamePos = name.lastIndexOf(";;;"); + if (usernamePos != -1) { + username = name.substring(usernamePos + 2); + } + int found = 0; + if (name.startsWith(q) || name.contains(" " + q)) { + found = 1; + } else if (username != null && username.startsWith(q)) { + found = 2; + } + + if (found != 0) { + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); + ByteBufferDesc data2 = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(6)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0 && cursor.byteBufferValue(6, data2.buffer) != 0) { + TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + chat.user_id = cursor.intValue(2); + chat.a_or_b = cursor.byteArrayValue(3); + chat.auth_key = cursor.byteArrayValue(4); + chat.ttl = cursor.intValue(5); + chat.layer = cursor.intValue(8); + chat.seq_in = cursor.intValue(9); + chat.seq_out = cursor.intValue(10); + + TLRPC.User user = (TLRPC.User)TLClassStore.Instance().TLdeserialize(data2, data2.readInt32()); + if (user.status != null) { + user.status.expires = cursor.intValue(7); + } + if (found == 1) { + resultArrayNames.add(Html.fromHtml("" + ContactsController.formatName(user.first_name, user.last_name) + "")); + } else { + resultArrayNames.add(Utilities.generateSearchName("@" + user.username, null, "@" + q)); + } + resultArray.add(chat); + encUsers.add(user); + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data2); + } + } + cursor.dispose(); + } + + cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, name FROM chats"); + while (cursor.next()) { + String name = cursor.stringValue(1); + String[] args = name.split(" "); + if (name.startsWith(q) || name.contains(" " + q)) { + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { + TLRPC.Chat chat = (TLRPC.Chat) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + if (!needEncrypted && chat.id < 0) { + continue; + } + resultArrayNames.add(Utilities.generateSearchName(chat.title, null, q)); + resultArray.add(chat); + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + } + } + cursor.dispose(); + updateSearchResults(resultArray, resultArrayNames, encUsers); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + private void updateSearchResults(final ArrayList result, final ArrayList names, final ArrayList encUsers) { + AndroidUtilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + for (TLObject obj : result) { + if (obj instanceof TLRPC.User) { + TLRPC.User user = (TLRPC.User) obj; + MessagesController.getInstance().putUser(user, true); + } else if (obj instanceof TLRPC.Chat) { + TLRPC.Chat chat = (TLRPC.Chat) obj; + MessagesController.getInstance().putChat(chat, true); + } else if (obj instanceof TLRPC.EncryptedChat) { + TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) obj; + MessagesController.getInstance().putEncryptedChat(chat, true); + } + } + for (TLRPC.User user : encUsers) { + MessagesController.getInstance().putUser(user, true); + } + searchResult = result; + searchResultNames = names; + notifyDataSetChanged(); + } + }); + } + + public String getLastSearchText() { + if (currentSearchType == 2) { + return lastSearchTextMessages; + } else { + return lastSearchTextDialogs; + } + } + + public boolean isGlobalSearch(int i) { + if (currentSearchType != 2) { + int localCount = searchResult.size(); + int globalCount = globalSearch.size(); + if (i >= 0 && i < localCount) { + return false; + } else if (i > localCount && i <= globalCount + localCount) { + return true; + } + } + return false; + } + + public void searchDialogs(final String query, final int type) { + String lastSearchText; + if (type == 2) { + lastSearchText = lastSearchTextMessages; + } else { + lastSearchText = lastSearchTextDialogs; + } + boolean typeChanged = currentSearchType != type; + currentSearchType = type; + if (query == null && lastSearchText == null || query != null && lastSearchText != null && query.equals(lastSearchText)) { + if (typeChanged) { + notifyDataSetChanged(); + } + return; + } + if (type == 2) { + lastSearchTextMessages = query; + } else { + lastSearchTextDialogs = query; + } + try { + if (searchTimer != null) { + searchTimer.cancel(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + if (query == null || query.length() == 0) { + if (currentSearchType == 2) { + searchMessagesInternal(null); + } else { + searchResult.clear(); + searchResultNames.clear(); + queryServerSearch(null); + } + notifyDataSetChanged(); + } else { + searchTimer = new Timer(); + searchTimer.schedule(new TimerTask() { + @Override + public void run() { + try { + searchTimer.cancel(); + searchTimer = null; + } catch (Exception e) { + FileLog.e("tmessages", e); + } + if (type != 2) { + searchDialogsInternal(query, type == 0); + AndroidUtilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + queryServerSearch(query); + } + }); + } else { + AndroidUtilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + searchMessagesInternal(query); + } + }); + } + } + }, 200, 300); + } + } + + @Override + public boolean areAllItemsEnabled() { + return false; + } + + @Override + public boolean isEnabled(int i) { + return currentSearchType == 2 || i != searchResult.size(); + } + + @Override + public int getCount() { + if (currentSearchType == 2) { + return searchResultMessages.size(); + } else { + int count = searchResult.size(); + int globalCount = globalSearch.size(); + if (globalCount != 0) { + count += globalCount + 1; + } + return count; + } + } + + @Override + public Object getItem(int i) { + if (currentSearchType == 2) { + if (i < 0 || i >= searchResultMessages.size()) { + return null; + } + return searchResultMessages.get(i); + } else { + int localCount = searchResult.size(); + int globalCount = globalSearch.size(); + if (i >= 0 && i < localCount) { + return searchResult.get(i); + } else if (i > localCount && i <= globalCount + localCount) { + return globalSearch.get(i - localCount - 1); + } + } + return null; + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + int type = getItemViewType(i); + + if (type == 1) { + if (view == null) { + view = new SettingsSectionLayout(mContext); + ((SettingsSectionLayout) view).setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch)); + view.setPadding(AndroidUtilities.dp(11), 0, AndroidUtilities.dp(11), 0); + } + } else if (type == 0) { + if (view == null) { + view = new ChatOrUserCell(mContext); + } + + TLRPC.User user = null; + TLRPC.Chat chat = null; + TLRPC.EncryptedChat encryptedChat = null; + + ((ChatOrUserCell) view).useSeparator = (i != getCount() - 1 && i != searchResult.size() - 1); + Object obj = getItem(i); + if (obj instanceof TLRPC.User) { + user = MessagesController.getInstance().getUser(((TLRPC.User) obj).id); + if (user == null) { + user = (TLRPC.User) obj; + } + } else if (obj instanceof TLRPC.Chat) { + chat = MessagesController.getInstance().getChat(((TLRPC.Chat) obj).id); + } else if (obj instanceof TLRPC.EncryptedChat) { + encryptedChat = MessagesController.getInstance().getEncryptedChat(((TLRPC.EncryptedChat) obj).id); + user = MessagesController.getInstance().getUser(encryptedChat.user_id); + } + + CharSequence username = null; + CharSequence name = null; + if (i < searchResult.size()) { + name = searchResultNames.get(i); + if (name != null && user != null && user.username != null && user.username.length() > 0) { + if (name.toString().startsWith("@" + user.username)) { + username = name; + name = null; + } + } + } else if (i > searchResult.size() && user != null && user.username != null) { + try { + username = Html.fromHtml(String.format("@%s%s", user.username.substring(0, lastFoundUsername.length()), user.username.substring(lastFoundUsername.length()))); + } catch (Exception e) { + username = user.username; + FileLog.e("tmessages", e); + } + } + + ((ChatOrUserCell) view).setData(user, chat, encryptedChat, name, username); + } else if (type == 2) { + if (view == null) { + view = new DialogCell(mContext); + } + ((DialogCell) view).useSeparator = (i != getCount() - 1); + MessageObject messageObject = searchResultMessages.get(i); + ((DialogCell) view).setDialog(messageObject.getDialogId(), messageObject, false, messageObject.messageOwner.date, 0); + } + + return view; + } + + @Override + public int getItemViewType(int i) { + if (currentSearchType == 2) { + return 2; + } else { + if (i == searchResult.size()) { + return 1; + } + return 0; + } + } + + @Override + public int getViewTypeCount() { + return 3; + } + + @Override + public boolean isEmpty() { + if (currentSearchType == 2) { + return searchResultMessages.isEmpty(); + } + return searchResult.isEmpty() && globalSearch.isEmpty(); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java index f13332df1..b1b688769 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -21,6 +21,7 @@ import android.text.TextUtils; import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.LocaleController; +import org.telegram.android.MessageObject; import org.telegram.messenger.FileLog; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; @@ -28,7 +29,6 @@ import org.telegram.android.Emoji; import org.telegram.android.MessagesController; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; -import org.telegram.android.MessageObject; import org.telegram.android.ImageReceiver; public class DialogCell extends BaseCell { @@ -51,7 +51,12 @@ public class DialogCell extends BaseCell { private static Paint linePaint; - private TLRPC.TL_dialog currentDialog; + private long currentDialogId; + private boolean allowPrintStrings; + private int lastMessageDate; + private int unreadCount; + private MessageObject message; + private ImageReceiver avatarImage; private DialogCellLayout cellLayout; @@ -159,13 +164,17 @@ public class DialogCell extends BaseCell { init(); } - public void setDialog(TLRPC.TL_dialog dialog) { - currentDialog = dialog; + public void setDialog(long dialog_id, MessageObject messageObject, boolean usePrintStrings, int date, int unread) { + currentDialogId = dialog_id; + message = messageObject; + allowPrintStrings = usePrintStrings; + lastMessageDate = date; + unreadCount = unread; update(0); } - public TLRPC.TL_dialog getDialog() { - return currentDialog; + public long getDialogId() { + return currentDialogId; } @Override @@ -183,7 +192,7 @@ public class DialogCell extends BaseCell { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - if (currentDialog == null) { + if (currentDialogId == 0) { super.onLayout(changed, left, top, right, bottom); return; } @@ -199,8 +208,8 @@ public class DialogCell extends BaseCell { public void update(int mask) { if (mask != 0) { boolean continueUpdate = false; - if ((mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) { - CharSequence printString = MessagesController.getInstance().printingStrings.get(currentDialog.id); + if (allowPrintStrings && (mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) { + CharSequence printString = MessagesController.getInstance().printingStrings.get(currentDialogId); if (lastPrintString != null && printString == null || lastPrintString == null && printString != null || lastPrintString != null && printString != null && !lastPrintString.equals(printString)) { continueUpdate = true; } @@ -237,8 +246,8 @@ public class DialogCell extends BaseCell { chat = null; encryptedChat = null; - int lower_id = (int)currentDialog.id; - int high_id = (int)(currentDialog.id >> 32); + int lower_id = (int)currentDialogId; + int high_id = (int)(currentDialogId >> 32); if (lower_id != 0) { if (high_id == 1) { chat = MessagesController.getInstance().getChat(lower_id); @@ -286,7 +295,7 @@ public class DialogCell extends BaseCell { @Override protected void onDraw(Canvas canvas) { - if (currentDialog == null) { + if (currentDialogId == 0) { return; } @@ -404,12 +413,14 @@ public class DialogCell extends BaseCell { private int avatarLeft; public void build(int width, int height) { - MessageObject message = MessagesController.getInstance().dialogMessage.get(currentDialog.top_message); String nameString = ""; String timeString = ""; String countString = null; CharSequence messageString = ""; - CharSequence printingString = MessagesController.getInstance().printingStrings.get(currentDialog.id); + CharSequence printingString = null; + if (allowPrintStrings) { + printingString = MessagesController.getInstance().printingStrings.get(currentDialogId); + } TextPaint currentNamePaint = namePaint; TextPaint currentMessagePaint = messagePaint; boolean checkMessage = true; @@ -483,8 +494,8 @@ public class DialogCell extends BaseCell { } } } - if (currentDialog.last_message_date != 0) { - timeString = LocaleController.stringForMessageListDate(currentDialog.last_message_date); + if (lastMessageDate != 0) { + timeString = LocaleController.stringForMessageListDate(lastMessageDate); } drawCheck1 = false; drawCheck2 = false; @@ -494,8 +505,8 @@ public class DialogCell extends BaseCell { } else { TLRPC.User fromUser = MessagesController.getInstance().getUser(message.messageOwner.from_id); - if (currentDialog.last_message_date != 0) { - timeString = LocaleController.stringForMessageListDate(currentDialog.last_message_date); + if (lastMessageDate != 0) { + timeString = LocaleController.stringForMessageListDate(lastMessageDate); } else { timeString = LocaleController.stringForMessageListDate(message.messageOwner.date); } @@ -539,9 +550,9 @@ public class DialogCell extends BaseCell { } } - if (currentDialog.unread_count != 0) { + if (unreadCount != 0) { drawCount = true; - countString = String.format("%d", currentDialog.unread_count); + countString = String.format("%d", unreadCount); } else { drawCount = false; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 703bc1c81..565e39dc0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -145,15 +145,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private boolean cacheEndReaced = false; private boolean firstLoading = true; private int loadsCount = 0; + private int startLoadFromMessageId = 0; private int minDate = 0; private boolean first = true; private int unread_to_load = 0; private int first_unread_id = 0; - private int last_unread_id = 0; - private boolean unread_end_reached = true; + private int last_message_id = 0; + private boolean forward_end_reached = true; private boolean loadingForward = false; private MessageObject unreadMessageObject = null; + private MessageObject scrollToMessage = null; private String currentPicturePath; @@ -213,13 +215,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not final int chatId = arguments.getInt("chat_id", 0); final int userId = arguments.getInt("user_id", 0); final int encId = arguments.getInt("enc_id", 0); + startLoadFromMessageId = arguments.getInt("message_id", 0); scrollToTopOnResume = arguments.getBoolean("scrollToTopOnResume", false); if (chatId != 0) { currentChat = MessagesController.getInstance().getChat(chatId); if (currentChat == null) { final Semaphore semaphore = new Semaphore(0); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { currentChat = MessagesStorage.getInstance().getChat(chatId); @@ -259,7 +262,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not currentUser = MessagesController.getInstance().getUser(userId); if (currentUser == null) { final Semaphore semaphore = new Semaphore(0); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { currentUser = MessagesStorage.getInstance().getUser(userId); @@ -282,7 +285,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not currentEncryptedChat = MessagesController.getInstance().getEncryptedChat(encId); if (currentEncryptedChat == null) { final Semaphore semaphore = new Semaphore(0); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { currentEncryptedChat = MessagesStorage.getInstance().getEncryptedChat(encId); @@ -303,7 +306,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not currentUser = MessagesController.getInstance().getUser(currentEncryptedChat.user_id); if (currentUser == null) { final Semaphore semaphore = new Semaphore(0); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { currentUser = MessagesStorage.getInstance().getUser(currentEncryptedChat.user_id); @@ -373,7 +376,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not loading = true; - MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20, 0, true, 0, classGuid, true, false, null); + if (startLoadFromMessageId != 0) { + MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20, startLoadFromMessageId, true, 0, classGuid, 3); + } else { + MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20, 0, true, 0, classGuid, 2); + } if (currentUser != null) { userBlocked = MessagesController.getInstance().blockedUsers.contains(currentUser.id); @@ -941,20 +948,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (firstVisibleItem <= 10) { if (!endReached && !loading) { if (messagesByDays.size() != 0) { - MessagesController.getInstance().loadMessages(dialog_id, 20, maxMessageId, !cacheEndReaced, minDate, classGuid, false, false, null); + MessagesController.getInstance().loadMessages(dialog_id, 20, maxMessageId, !cacheEndReaced, minDate, classGuid, 0); } else { - MessagesController.getInstance().loadMessages(dialog_id, 20, 0, !cacheEndReaced, minDate, classGuid, false, false, null); + MessagesController.getInstance().loadMessages(dialog_id, 20, 0, !cacheEndReaced, minDate, classGuid, 0); } loading = true; } } if (firstVisibleItem + visibleItemCount >= totalItemCount - 6) { - if (!unread_end_reached && !loadingForward) { - MessagesController.getInstance().loadMessages(dialog_id, 20, minMessageId, true, maxDate, classGuid, false, true, null); + if (!forward_end_reached && !loadingForward) { + MessagesController.getInstance().loadMessages(dialog_id, 20, minMessageId, true, maxDate, classGuid, 1); loadingForward = true; } } - if (firstVisibleItem + visibleItemCount == totalItemCount && unread_end_reached) { + if (firstVisibleItem + visibleItemCount == totalItemCount && forward_end_reached) { showPagedownButton(false, true); } } @@ -1049,7 +1056,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } private void scrollToLastMessage() { - if (unread_end_reached || first_unread_id == 0) { + if (forward_end_reached || first_unread_id == 0) { chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); } else { messages.clear(); @@ -1066,10 +1073,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } maxDate = Integer.MIN_VALUE; minDate = 0; - unread_end_reached = true; + forward_end_reached = true; loading = true; chatAdapter.notifyDataSetChanged(); - MessagesController.getInstance().loadMessages(dialog_id, 30, 0, true, 0, classGuid, true, false, null); + MessagesController.getInstance().loadMessages(dialog_id, 30, 0, true, 0, classGuid, 0); } } @@ -1612,9 +1619,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private void removeUnreadPlane(boolean reload) { if (unreadMessageObject != null) { messages.remove(unreadMessageObject); - unread_end_reached = true; + forward_end_reached = true; first_unread_id = 0; - last_unread_id = 0; + last_message_id = 0; unread_to_load = 0; unreadMessageObject = null; if (reload) { @@ -1638,26 +1645,27 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not boolean isCache = (Boolean)args[3]; int fnid = (Integer)args[4]; int last_unread_date = (Integer)args[7]; - boolean forwardLoad = (Boolean)args[8]; + int load_type = (Integer)args[8]; boolean wasUnread = false; - boolean positionToUnread = false; if (fnid != 0) { first_unread_id = fnid; - last_unread_id = (Integer)args[5]; + last_message_id = (Integer)args[5]; unread_to_load = (Integer)args[6]; - positionToUnread = true; + } else if (startLoadFromMessageId != 0) { + last_message_id = (Integer)args[5]; } ArrayList messArr = (ArrayList)args[2]; int newRowsCount = 0; - unread_end_reached = last_unread_id == 0; + + forward_end_reached = startLoadFromMessageId == 0 && last_message_id == 0; if (loadsCount == 1 && messArr.size() > 20) { loadsCount++; } if (firstLoading) { - if (!unread_end_reached) { + if (!forward_end_reached) { messages.clear(); messagesByDays.clear(); messagesDict.clear(); @@ -1714,7 +1722,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not MessageObject dateObj = new MessageObject(dateMsg, null); dateObj.type = 10; dateObj.contentType = 4; - if (forwardLoad) { + if (load_type == 1) { messages.add(0, dateObj); } else { messages.add(dateObj); @@ -1724,45 +1732,47 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not newRowsCount++; dayArray.add(obj); - if (forwardLoad) { + if (load_type == 1) { messages.add(0, obj); } else { messages.add(messages.size() - 1, obj); } - if (!forwardLoad) { - if (obj.messageOwner.id == first_unread_id) { - TLRPC.Message dateMsg = new TLRPC.Message(); - dateMsg.message = ""; - dateMsg.id = 0; - MessageObject dateObj = new MessageObject(dateMsg, null); - dateObj.contentType = dateObj.type = 6; - boolean dateAdded = true; - if (a != messArr.size() - 1) { - MessageObject next = messArr.get(a + 1); - dateAdded = !next.dateKey.equals(obj.dateKey); - } - messages.add(messages.size() - (dateAdded ? 0 : 1), dateObj); - unreadMessageObject = dateObj; - newRowsCount++; - } - if (obj.messageOwner.id == last_unread_id) { - unread_end_reached = true; + if (load_type == 2 && obj.messageOwner.id == first_unread_id) { + TLRPC.Message dateMsg = new TLRPC.Message(); + dateMsg.message = ""; + dateMsg.id = 0; + MessageObject dateObj = new MessageObject(dateMsg, null); + dateObj.contentType = dateObj.type = 6; + boolean dateAdded = true; + if (a != messArr.size() - 1) { + MessageObject next = messArr.get(a + 1); + dateAdded = !next.dateKey.equals(obj.dateKey); } + messages.add(messages.size() - (dateAdded ? 0 : 1), dateObj); + unreadMessageObject = dateObj; + scrollToMessage = unreadMessageObject; + newRowsCount++; + } else if (load_type == 3 && obj.messageOwner.id == startLoadFromMessageId) { + scrollToMessage = obj; + startLoadFromMessageId = 0; } + if (obj.messageOwner.id == last_message_id) { + forward_end_reached = true; + } } - if (unread_end_reached) { + if (forward_end_reached) { first_unread_id = 0; - last_unread_id = 0; + last_message_id = 0; } - if (forwardLoad) { + if (load_type == 1) { if (messArr.size() != count) { - unread_end_reached = true; + forward_end_reached = true; first_unread_id = 0; - last_unread_id = 0; + last_message_id = 0; } chatAdapter.notifyDataSetChanged(); @@ -1784,21 +1794,21 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (chatListView != null) { if (first || scrollToTopOnResume) { chatAdapter.notifyDataSetChanged(); - if (positionToUnread && unreadMessageObject != null) { - if (messages.get(messages.size() - 1) == unreadMessageObject) { + if (scrollToMessage != null) { + if (messages.get(messages.size() - 1) == scrollToMessage) { chatListView.setSelectionFromTop(0, AndroidUtilities.dp(-11)); } else { - chatListView.setSelectionFromTop(messages.size() - messages.indexOf(unreadMessageObject), AndroidUtilities.dp(-11)); + chatListView.setSelectionFromTop(messages.size() - messages.indexOf(scrollToMessage), AndroidUtilities.dp(-11)); } ViewTreeObserver obs = chatListView.getViewTreeObserver(); obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (!messages.isEmpty()) { - if (messages.get(messages.size() - 1) == unreadMessageObject) { + if (messages.get(messages.size() - 1) == scrollToMessage) { chatListView.setSelectionFromTop(0, AndroidUtilities.dp(-11)); } else { - chatListView.setSelectionFromTop(messages.size() - messages.indexOf(unreadMessageObject), AndroidUtilities.dp(-11)); + chatListView.setSelectionFromTop(messages.size() - messages.indexOf(scrollToMessage), AndroidUtilities.dp(-11)); } } chatListView.getViewTreeObserver().removeOnPreDrawListener(this); @@ -1825,7 +1835,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (paused) { scrollToTopOnResume = true; - if (positionToUnread && unreadMessageObject != null) { + if (scrollToMessage != null) { scrollToTopUnReadOnResume = true; } } @@ -1837,15 +1847,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } else { scrollToTopOnResume = true; - if (positionToUnread && unreadMessageObject != null) { + if (scrollToMessage != null) { scrollToTopUnReadOnResume = true; } } } if (first && messages.size() > 0) { - if (last_unread_id != 0) { - MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).messageOwner.id, last_unread_id, 0, last_unread_date, wasUnread, false); + if (last_message_id != 0) { + MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).messageOwner.id, last_message_id, 0, last_unread_date, wasUnread, false); } else { MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).messageOwner.id, minMessageId, 0, maxDate, wasUnread, false); } @@ -1903,7 +1913,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } - if (!unread_end_reached) { + if (!forward_end_reached) { int currentMaxDate = Integer.MIN_VALUE; int currentMinMsgId = Integer.MIN_VALUE; if (currentEncryptedChat != null) { @@ -1927,8 +1937,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not currentMaxDate = Math.max(currentMaxDate, obj.messageOwner.date); if (obj.messageOwner.id > 0) { currentMinMsgId = Math.max(obj.messageOwner.id, currentMinMsgId); + last_message_id = Math.max(last_message_id, obj.messageOwner.id); } else if (currentEncryptedChat != null) { currentMinMsgId = Math.min(obj.messageOwner.id, currentMinMsgId); + last_message_id = Math.min(last_message_id, obj.messageOwner.id); } if (!obj.isOut() && obj.isUnread()) { @@ -2115,7 +2127,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } maxDate = Integer.MIN_VALUE; minDate = 0; - MessagesController.getInstance().loadMessages(dialog_id, 30, 0, !cacheEndReaced, minDate, classGuid, false, false, null); + MessagesController.getInstance().loadMessages(dialog_id, 30, 0, !cacheEndReaced, minDate, classGuid, 0); loading = true; } } @@ -2401,9 +2413,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } NotificationsController.getInstance().setOpennedDialogId(dialog_id); if (scrollToTopOnResume) { - if (scrollToTopUnReadOnResume && unreadMessageObject != null) { + if (scrollToTopUnReadOnResume && scrollToMessage != null) { if (chatListView != null) { - chatListView.setSelectionFromTop(messages.size() - messages.indexOf(unreadMessageObject), -chatListView.getPaddingTop() - AndroidUtilities.dp(7)); + chatListView.setSelectionFromTop(messages.size() - messages.indexOf(scrollToMessage), -chatListView.getPaddingTop() - AndroidUtilities.dp(7)); } } else { if (chatListView != null) { @@ -2412,6 +2424,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } scrollToTopUnReadOnResume = false; scrollToTopOnResume = false; + scrollToMessage = null; } paused = false; if (readWhenResume && !messages.isEmpty()) { @@ -3059,7 +3072,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (!endReached) { count++; } - if (!unread_end_reached) { + if (!forward_end_reached) { count++; } } @@ -3084,11 +3097,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not @Override public View getView(int i, View view, ViewGroup viewGroup) { int offset = 1; - if ((!endReached || !unread_end_reached) && messages.size() != 0) { + if ((!endReached || !forward_end_reached) && messages.size() != 0) { if (!endReached) { offset = 0; } - if (i == 0 && !endReached || !unread_end_reached && i == (messages.size() + 1 - offset)) { + if (i == 0 && !endReached || !forward_end_reached && i == (messages.size() + 1 - offset)) { View progressBar = null; if (view == null) { LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); @@ -3369,7 +3382,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return 5; } } - if (!unread_end_reached && i == (messages.size() + 1 - offset)) { + if (!forward_end_reached && i == (messages.size() + 1 - offset)) { return 5; } MessageObject message = messages.get(messages.size() - i - offset); @@ -3388,7 +3401,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (!endReached) { count++; } - if (!unread_end_reached) { + if (!forward_end_reached) { count++; } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java index f8f556b48..1dc77830f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java @@ -88,7 +88,7 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen currentChat = MessagesController.getInstance().getChat(chat_id); if (currentChat == null) { final Semaphore semaphore = new Semaphore(0); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { currentChat = MessagesStorage.getInstance().getChat(chat_id); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java index a65ce45d2..6097a7315 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java @@ -14,6 +14,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.text.InputType; import android.view.Gravity; @@ -26,6 +27,7 @@ import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.EditText; import android.widget.FrameLayout; +import android.widget.ListView; import android.widget.TextView; import org.telegram.android.AndroidUtilities; @@ -155,11 +157,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter ViewGroup group = (ViewGroup) listView.getParent(); listView.setAdapter(listViewAdapter); listViewAdapter.notifyDataSetChanged(); - if (!LocaleController.isRTL) { - listView.setPadding(AndroidUtilities.dp(16), listView.getPaddingTop(), AndroidUtilities.dp(30), listView.getPaddingBottom()); - } else { - listView.setPadding(AndroidUtilities.dp(30), listView.getPaddingTop(), AndroidUtilities.dp(16), listView.getPaddingBottom()); - } + listView.setPadding(AndroidUtilities.dp(LocaleController.isRTL ? 30 : 16), listView.getPaddingTop(), AndroidUtilities.dp(LocaleController.isRTL ? 16 : 30), listView.getPaddingBottom()); if (android.os.Build.VERSION.SDK_INT >= 11) { listView.setFastScrollAlwaysVisible(true); } @@ -206,6 +204,10 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter listView = (PinnedHeaderListView)fragmentView.findViewById(R.id.listView); listView.setEmptyView(emptyTextView); + listView.setPadding(AndroidUtilities.dp(LocaleController.isRTL ? 30 : 16), listView.getPaddingTop(), AndroidUtilities.dp(LocaleController.isRTL ? 16 : 30), listView.getPaddingBottom()); + if (Build.VERSION.SDK_INT >= 11) { + listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); + } emptyTextView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java index 331dc705f..82d19e28e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java @@ -82,7 +82,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati if (!usersToLoad.isEmpty()) { final Semaphore semaphore = new Semaphore(0); final ArrayList users = new ArrayList(); - MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { users.addAll(MessagesStorage.getInstance().getUsers(usersToLoad)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java index 477a519a5..b6592d9a5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java @@ -9,10 +9,9 @@ package org.telegram.ui; import android.app.AlertDialog; -import android.content.Context; import android.content.DialogInterface; +import android.os.Build; import android.os.Bundle; -import android.text.Html; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -26,35 +25,36 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; -import org.telegram.messenger.TLObject; +import org.telegram.android.MessageObject; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; -import org.telegram.messenger.FileLog; import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; -import org.telegram.messenger.Utilities; -import org.telegram.ui.Adapters.BaseContactsSearchAdapter; +import org.telegram.ui.Adapters.BaseFragmentAdapter; +import org.telegram.ui.Adapters.MessagesActivityAdapter; +import org.telegram.ui.Adapters.MessagesActivitySearchAdapter; import org.telegram.ui.Cells.ChatOrUserCell; import org.telegram.ui.Cells.DialogCell; import org.telegram.ui.Views.ActionBar.ActionBarLayer; import org.telegram.ui.Views.ActionBar.ActionBarMenu; import org.telegram.ui.Views.ActionBar.ActionBarMenuItem; import org.telegram.ui.Views.ActionBar.BaseFragment; -import org.telegram.ui.Views.SettingsSectionLayout; +import org.telegram.ui.Views.SlidingTabView; import java.util.ArrayList; -import java.util.Timer; -import java.util.TimerTask; public class MessagesActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { private ListView messagesListView; - private MessagesAdapter messagesListViewAdapter; + private MessagesActivityAdapter messagesActivityAdapter; + private MessagesActivitySearchAdapter messagesActivitySearchAdapter; private TextView searchEmptyView; private View progressView; private View emptyView; + private SlidingTabView searchPanelView; + private String selectAlertString; private String selectAlertStringGroup; private boolean serverOnly = false; @@ -63,7 +63,6 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter private boolean searching = false; private boolean searchWas = false; private boolean onlySelect = false; - private int activityToken = (int)(Utilities.random.nextDouble() * Integer.MAX_VALUE); private long selectedDialog; private MessagesActivityDelegate delegate; @@ -92,7 +91,6 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter NotificationCenter.getInstance().addObserver(this, NotificationCenter.dialogsNeedReload); NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded); NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateInterfaces); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.reloadSearchResults); NotificationCenter.getInstance().addObserver(this, NotificationCenter.encryptedChatUpdated); NotificationCenter.getInstance().addObserver(this, NotificationCenter.contactsDidLoaded); NotificationCenter.getInstance().addObserver(this, NotificationCenter.appDidLogout); @@ -116,7 +114,6 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter NotificationCenter.getInstance().removeObserver(this, NotificationCenter.dialogsNeedReload); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.emojiDidLoaded); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.updateInterfaces); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.reloadSearchResults); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.encryptedChatUpdated); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.contactsDidLoaded); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.appDidLogout); @@ -134,9 +131,9 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter searching = true; if (messagesListView != null) { messagesListView.setEmptyView(searchEmptyView); - } - if (emptyView != null) { + searchPanelView.setVisibility(View.VISIBLE); emptyView.setVisibility(View.GONE); + progressView.setVisibility(View.GONE); } } @@ -146,27 +143,37 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter searchWas = false; if (messagesListView != null) { messagesListView.setEmptyView(emptyView); + searchPanelView.setVisibility(View.GONE); searchEmptyView.setVisibility(View.GONE); + progressView.setVisibility(View.GONE); + messagesListView.setAdapter(messagesActivityAdapter); + messagesActivityAdapter.notifyDataSetChanged(); } - if (messagesListViewAdapter != null) { - messagesListViewAdapter.searchDialogs(null); + if (messagesActivitySearchAdapter != null) { + messagesActivitySearchAdapter.searchDialogs(null, 0); } } @Override public void onTextChanged(EditText editText) { String text = editText.getText().toString(); - if (messagesListViewAdapter != null) { - messagesListViewAdapter.searchDialogs(text); - } if (text.length() != 0) { searchWas = true; - if (messagesListViewAdapter != null) { - messagesListViewAdapter.notifyDataSetChanged(); + if (messagesActivitySearchAdapter != null) { + messagesListView.setAdapter(messagesActivitySearchAdapter); + messagesActivitySearchAdapter.notifyDataSetChanged(); } - if (searchEmptyView != null) { + if (searchEmptyView != null && messagesListView.getEmptyView() == emptyView) { messagesListView.setEmptyView(searchEmptyView); emptyView.setVisibility(View.GONE); + progressView.setVisibility(View.GONE); + } + } + if (messagesActivitySearchAdapter != null) { + if (searchPanelView.getSeletedTab() == 0) { + messagesActivitySearchAdapter.searchDialogs(text, serverOnly ? 1 : 0); + } else { + messagesActivitySearchAdapter.searchDialogs(text, 2); } } } @@ -226,13 +233,43 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter fragmentView = inflater.inflate(R.layout.messages_list, container, false); - messagesListViewAdapter = new MessagesAdapter(getParentActivity()); + messagesActivityAdapter = new MessagesActivityAdapter(getParentActivity(), serverOnly); + messagesActivitySearchAdapter = new MessagesActivitySearchAdapter(getParentActivity()); + messagesActivitySearchAdapter.setDelegate(new MessagesActivitySearchAdapter.MessagesActivitySearchAdapterDelegate() { + @Override + public void searchStateChanged(boolean search) { + if (searching && searchWas && messagesListView != null) { + progressView.setVisibility(search ? View.VISIBLE : View.GONE); + searchEmptyView.setVisibility(search ? View.GONE : View.VISIBLE); + messagesListView.setEmptyView(search ? progressView : searchEmptyView); + } + } + }); + searchPanelView = (SlidingTabView)fragmentView.findViewById(R.id.searchPanelView); + searchPanelView.addTextTab(0, LocaleController.getString("SearchConversations", R.string.SearchConversations)); + searchPanelView.addTextTab(1, LocaleController.getString("SearchMessages", R.string.SearchMessages)); + searchPanelView.setDelegate(new SlidingTabView.SlidingTabViewDelegate() { + @Override + public void didSelectTab(int tab) { + if (searching && searchWas) { + if (tab == 0) { + messagesActivitySearchAdapter.searchDialogs(messagesActivitySearchAdapter.getLastSearchText(), serverOnly ? 1 : 0); + } else { + messagesActivitySearchAdapter.searchDialogs(messagesActivitySearchAdapter.getLastSearchText(), 2); + } + messagesActivitySearchAdapter.notifyDataSetChanged(); + } + } + }); messagesListView = (ListView)fragmentView.findViewById(R.id.messages_list_view); - messagesListView.setAdapter(messagesListViewAdapter); + messagesListView.setAdapter(messagesActivityAdapter); + if (Build.VERSION.SDK_INT >= 11) { + messagesListView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); + } progressView = fragmentView.findViewById(R.id.progressLayout); - messagesListViewAdapter.notifyDataSetChanged(); + messagesActivityAdapter.notifyDataSetChanged(); searchEmptyView = (TextView)fragmentView.findViewById(R.id.searchEmptyView); searchEmptyView.setOnTouchListener(new View.OnTouchListener() { @Override @@ -254,10 +291,9 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter textView.setText(LocaleController.getString("NoChats", R.string.NoChatsHelp)); if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - messagesListView.setEmptyView(null); searchEmptyView.setVisibility(View.GONE); emptyView.setVisibility(View.GONE); - progressView.setVisibility(View.VISIBLE); + messagesListView.setEmptyView(progressView); } else { if (searching && searchWas) { messagesListView.setEmptyView(searchEmptyView); @@ -272,32 +308,45 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter messagesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { - if (messagesListViewAdapter == null) { - return; - } - TLObject obj = messagesListViewAdapter.getItem(i); - if (obj == null) { + if (messagesListView == null || messagesListView.getAdapter() == null) { return; } long dialog_id = 0; - if (obj instanceof TLRPC.User) { - dialog_id = ((TLRPC.User) obj).id; - if (messagesListViewAdapter.isGlobalSearch(i)) { - ArrayList users = new ArrayList(); - users.add((TLRPC.User)obj); - MessagesController.getInstance().putUsers(users, false); - MessagesStorage.getInstance().putUsersAndChats(users, null, false, true); + int message_id = 0; + BaseFragmentAdapter adapter = (BaseFragmentAdapter)messagesListView.getAdapter(); + if (adapter == messagesActivityAdapter) { + TLRPC.TL_dialog dialog = messagesActivityAdapter.getItem(i); + if (dialog == null) { + return; } - } else if (obj instanceof TLRPC.Chat) { - if (((TLRPC.Chat) obj).id > 0) { - dialog_id = -((TLRPC.Chat) obj).id; - } else { - dialog_id = AndroidUtilities.makeBroadcastId(((TLRPC.Chat) obj).id); + dialog_id = dialog.id; + } else if (adapter == messagesActivitySearchAdapter) { + Object obj = messagesActivitySearchAdapter.getItem(i); + if (obj instanceof TLRPC.User) { + dialog_id = ((TLRPC.User) obj).id; + if (messagesActivitySearchAdapter.isGlobalSearch(i)) { + ArrayList users = new ArrayList(); + users.add((TLRPC.User)obj); + MessagesController.getInstance().putUsers(users, false); + MessagesStorage.getInstance().putUsersAndChats(users, null, false, true); + } + } else if (obj instanceof TLRPC.Chat) { + if (((TLRPC.Chat) obj).id > 0) { + dialog_id = -((TLRPC.Chat) obj).id; + } else { + dialog_id = AndroidUtilities.makeBroadcastId(((TLRPC.Chat) obj).id); + } + } else if (obj instanceof TLRPC.EncryptedChat) { + dialog_id = ((long)((TLRPC.EncryptedChat) obj).id) << 32; + } else if (obj instanceof MessageObject) { + MessageObject messageObject = (MessageObject)obj; + dialog_id = messageObject.getDialogId(); + message_id = messageObject.messageOwner.id; } - } else if (obj instanceof TLRPC.EncryptedChat) { - dialog_id = ((long)((TLRPC.EncryptedChat) obj).id) << 32; - } else if (obj instanceof TLRPC.TL_dialog) { - dialog_id = ((TLRPC.TL_dialog) obj).id; + } + + if (dialog_id == 0) { + return; } if (onlySelect) { @@ -319,11 +368,14 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } else { args.putInt("enc_id", high_id); } + if (message_id != 0) { + args.putInt("message_id", message_id); + } if (AndroidUtilities.isTablet()) { if (openedDialogId == dialog_id) { return; } - openedDialogId = dialog_id; + messagesActivityAdapter.setOpenedDialogId(openedDialogId = dialog_id); } presentFragment(new ChatActivity(args)); updateVisibleRows(0); @@ -446,8 +498,11 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter public void onResume() { super.onResume(); showActionBar(); - if (messagesListViewAdapter != null) { - messagesListViewAdapter.notifyDataSetChanged(); + if (messagesActivityAdapter != null) { + messagesActivityAdapter.notifyDataSetChanged(); + } + if (messagesActivitySearchAdapter != null) { + messagesActivitySearchAdapter.notifyDataSetChanged(); } } @@ -455,17 +510,14 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter @SuppressWarnings("unchecked") public void didReceivedNotification(int id, Object... args) { if (id == NotificationCenter.dialogsNeedReload) { - if (messagesListViewAdapter != null) { - messagesListViewAdapter.notifyDataSetChanged(); + if (messagesActivityAdapter != null) { + messagesActivityAdapter.notifyDataSetChanged(); } if (messagesListView != null) { if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - if (messagesListView.getEmptyView() != null) { - messagesListView.setEmptyView(null); - } searchEmptyView.setVisibility(View.GONE); emptyView.setVisibility(View.GONE); - progressView.setVisibility(View.VISIBLE); + messagesListView.setEmptyView(progressView); } else { if (messagesListView.getEmptyView() == null) { if (searching && searchWas) { @@ -485,11 +537,6 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } } else if (id == NotificationCenter.updateInterfaces) { updateVisibleRows((Integer)args[0]); - } else if (id == NotificationCenter.reloadSearchResults) { - int token = (Integer)args[0]; - if (token == activityToken) { - messagesListViewAdapter.updateSearchResults((ArrayList) args[1], (ArrayList) args[2], (ArrayList) args[3]); - } } else if (id == NotificationCenter.appDidLogout) { dialogsLoaded = false; } else if (id == NotificationCenter.encryptedChatUpdated) { @@ -507,6 +554,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } else { openedDialogId = dialog_id; } + messagesActivityAdapter.setOpenedDialogId(openedDialogId); updateVisibleRows(0); } } @@ -521,8 +569,8 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter View child = messagesListView.getChildAt(a); if (child instanceof DialogCell) { DialogCell cell = (DialogCell) child; - if (!serverOnly && AndroidUtilities.isTablet() && cell.getDialog() != null) { - if (cell.getDialog().id == openedDialogId) { + if (!serverOnly && AndroidUtilities.isTablet()) { + if (cell.getDialogId() == openedDialogId) { child.setBackgroundColor(0x0f000000); } else { child.setBackgroundColor(0); @@ -614,287 +662,4 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } } } - - private class MessagesAdapter extends BaseContactsSearchAdapter { - - private Context mContext; - private Timer searchTimer; - private ArrayList searchResult = new ArrayList(); - private ArrayList searchResultNames = new ArrayList(); - - public MessagesAdapter(Context context) { - mContext = context; - } - - public void updateSearchResults(final ArrayList result, final ArrayList names, final ArrayList encUsers) { - AndroidUtilities.RunOnUIThread(new Runnable() { - @Override - public void run() { - for (TLObject obj : result) { - if (obj instanceof TLRPC.User) { - TLRPC.User user = (TLRPC.User) obj; - MessagesController.getInstance().putUser(user, true); - } else if (obj instanceof TLRPC.Chat) { - TLRPC.Chat chat = (TLRPC.Chat) obj; - MessagesController.getInstance().putChat(chat, true); - } else if (obj instanceof TLRPC.EncryptedChat) { - TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) obj; - MessagesController.getInstance().putEncryptedChat(chat, true); - } - } - for (TLRPC.User user : encUsers) { - MessagesController.getInstance().putUser(user, true); - } - searchResult = result; - searchResultNames = names; - if (searching) { - messagesListViewAdapter.notifyDataSetChanged(); - } - } - }); - } - - public boolean isGlobalSearch(int i) { - if (searching && searchWas) { - int localCount = searchResult.size(); - int globalCount = globalSearch.size(); - if (i >= 0 && i < localCount) { - return false; - } else if (i > localCount && i <= globalCount + localCount) { - return true; - } - } - return false; - } - - public void searchDialogs(final String query) { - if (query == null) { - searchResult.clear(); - searchResultNames.clear(); - queryServerSearch(null); - notifyDataSetChanged(); - } else { - try { - if (searchTimer != null) { - searchTimer.cancel(); - } - } catch (Exception e) { - FileLog.e("tmessages", e); - } - searchTimer = new Timer(); - searchTimer.schedule(new TimerTask() { - @Override - public void run() { - try { - searchTimer.cancel(); - searchTimer = null; - } catch (Exception e) { - FileLog.e("tmessages", e); - } - MessagesStorage.getInstance().searchDialogs(activityToken, query, !serverOnly); - AndroidUtilities.RunOnUIThread(new Runnable() { - @Override - public void run() { - queryServerSearch(query); - } - }); - } - }, 200, 300); - } - } - - @Override - public boolean areAllItemsEnabled() { - return false; - } - - @Override - public boolean isEnabled(int i) { - return !(searching && searchWas) || i != searchResult.size(); - } - - @Override - public int getCount() { - if (searching && searchWas) { - int count = searchResult.size(); - int globalCount = globalSearch.size(); - if (globalCount != 0) { - count += globalCount + 1; - } - return count; - } - int count; - if (serverOnly) { - count = MessagesController.getInstance().dialogsServerOnly.size(); - } else { - count = MessagesController.getInstance().dialogs.size(); - } - if (count == 0 && MessagesController.getInstance().loadingDialogs) { - return 0; - } - if (!MessagesController.getInstance().dialogsEndReached) { - count++; - } - return count; - } - - @Override - public TLObject getItem(int i) { - if (searching && searchWas) { - int localCount = searchResult.size(); - int globalCount = globalSearch.size(); - if (i >= 0 && i < localCount) { - return searchResult.get(i); - } else if (i > localCount && i <= globalCount + localCount) { - return globalSearch.get(i - localCount - 1); - } - return null; - } - if (serverOnly) { - if (i < 0 || i >= MessagesController.getInstance().dialogsServerOnly.size()) { - return null; - } - return MessagesController.getInstance().dialogsServerOnly.get(i); - } else { - if (i < 0 || i >= MessagesController.getInstance().dialogs.size()) { - return null; - } - return MessagesController.getInstance().dialogs.get(i); - } - } - - @Override - public long getItemId(int i) { - return i; - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public View getView(int i, View view, ViewGroup viewGroup) { - int type = getItemViewType(i); - - if (type == 3) { - if (view == null) { - view = new SettingsSectionLayout(mContext); - ((SettingsSectionLayout) view).setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch)); - view.setPadding(AndroidUtilities.dp(11), 0, AndroidUtilities.dp(11), 0); - } - } else if (type == 2) { - if (view == null) { - view = new ChatOrUserCell(mContext); - } - if (searching && searchWas) { - TLRPC.User user = null; - TLRPC.Chat chat = null; - TLRPC.EncryptedChat encryptedChat = null; - - ((ChatOrUserCell) view).useSeparator = (i != getCount() - 1 && i != searchResult.size() - 1); - TLObject obj = getItem(i); - if (obj instanceof TLRPC.User) { - user = MessagesController.getInstance().getUser(((TLRPC.User) obj).id); - if (user == null) { - user = (TLRPC.User) obj; - } - } else if (obj instanceof TLRPC.Chat) { - chat = MessagesController.getInstance().getChat(((TLRPC.Chat) obj).id); - } else if (obj instanceof TLRPC.EncryptedChat) { - encryptedChat = MessagesController.getInstance().getEncryptedChat(((TLRPC.EncryptedChat) obj).id); - user = MessagesController.getInstance().getUser(encryptedChat.user_id); - } - - CharSequence username = null; - CharSequence name = null; - if (i < searchResult.size()) { - name = searchResultNames.get(i); - if (name != null && user != null && user.username != null && user.username.length() > 0) { - if (name.toString().startsWith("@" + user.username)) { - username = name; - name = null; - } - } - } else if (i > searchResult.size() && user != null && user.username != null) { - try { - username = Html.fromHtml(String.format("@%s%s", user.username.substring(0, lastFoundUsername.length()), user.username.substring(lastFoundUsername.length()))); - } catch (Exception e) { - username = user.username; - FileLog.e("tmessages", e); - } - } - - ((ChatOrUserCell) view).setData(user, chat, encryptedChat, name, username); - } - } else if (type == 1) { - if (view == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.loading_more_layout, viewGroup, false); - } - } else if (type == 0) { - if (view == null) { - view = new DialogCell(mContext); - } - ((DialogCell) view).useSeparator = (i != getCount() - 1); - if (serverOnly) { - ((DialogCell) view).setDialog(MessagesController.getInstance().dialogsServerOnly.get(i)); - } else { - TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs.get(i); - if (AndroidUtilities.isTablet()) { - if (dialog.id == openedDialogId) { - view.setBackgroundColor(0x0f000000); - } else { - view.setBackgroundColor(0); - } - } - ((DialogCell) view).setDialog(dialog); - } - } - - return view; - } - - @Override - public int getItemViewType(int i) { - if (searching && searchWas) { - if (i == searchResult.size()) { - return 3; - } - return 2; - } - if (serverOnly && i == MessagesController.getInstance().dialogsServerOnly.size() || !serverOnly && i == MessagesController.getInstance().dialogs.size()) { - return 1; - } - return 0; - } - - @Override - public int getViewTypeCount() { - return 4; - } - - @Override - public boolean isEmpty() { - if (searching && searchWas) { - return searchResult.size() == 0 && globalSearch.isEmpty(); - } - if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - return false; - } - int count; - if (serverOnly) { - count = MessagesController.getInstance().dialogsServerOnly.size(); - } else { - count = MessagesController.getInstance().dialogs.size(); - } - if (count == 0 && MessagesController.getInstance().loadingDialogs) { - return true; - } - if (!MessagesController.getInstance().dialogsEndReached) { - count++; - } - return count == 0; - } - } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/SlidingTabView.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/SlidingTabView.java new file mode 100644 index 000000000..c4fdbc44c --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/SlidingTabView.java @@ -0,0 +1,153 @@ +/* + * This is the source code of Telegram for Android v. 1.7.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.ui.Views; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Typeface; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.view.animation.DecelerateInterpolator; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.messenger.R; + +public class SlidingTabView extends LinearLayout { + + public static interface SlidingTabViewDelegate { + public abstract void didSelectTab(int tab); + } + + private SlidingTabViewDelegate delegate; + private int selectedTab = 0; + private int tabCount = 0; + private float tabWidth = 0; + private float tabX = 0; + private float animateTabXTo = 0; + private Paint paint = new Paint(); + private long startAnimationTime = 0; + private long totalAnimationDiff = 0; + private float startAnimationX = 0; + private DecelerateInterpolator interpolator; + + private void init() { + setBackgroundResource(R.color.header); + setOrientation(HORIZONTAL); + setWeightSum(100); + interpolator = new DecelerateInterpolator(); + } + + public SlidingTabView(Context context) { + super(context); + init(); + } + + public SlidingTabView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public SlidingTabView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + public SlidingTabView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(); + } + + public void addTextTab(final int position, String title) { + TextView tab = new TextView(getContext()); + tab.setText(title); + tab.setFocusable(true); + tab.setGravity(Gravity.CENTER); + tab.setSingleLine(); + tab.setTextColor(0xffffffff); + tab.setTextSize(12); + tab.setTypeface(Typeface.DEFAULT_BOLD); + tab.setBackgroundResource(R.drawable.bar_selector); + + tab.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + didSelectTab(position); + } + }); + addView(tab); + LayoutParams layoutParams = (LayoutParams)tab.getLayoutParams(); + layoutParams.height = LayoutParams.MATCH_PARENT; + layoutParams.width = 0; + layoutParams.weight = 50; + tab.setLayoutParams(layoutParams); + + tabCount++; + } + + public void setDelegate(SlidingTabViewDelegate delegate) { + this.delegate = delegate; + } + + public int getSeletedTab() { + return selectedTab; + } + + private void didSelectTab(int tab) { + if (selectedTab == tab) { + return; + } + selectedTab = tab; + animateToTab(tab); + if (delegate != null) { + delegate.didSelectTab(tab); + } + } + + private void animateToTab(int tab) { + animateTabXTo = tab * tabWidth; + startAnimationX = tabX; + totalAnimationDiff = 0; + startAnimationTime = System.currentTimeMillis(); + invalidate(); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + tabWidth = (r - l) / (float)tabCount; + animateTabXTo = tabX = tabWidth * selectedTab; + } + + @Override + protected void onDraw(Canvas canvas) { + paint.setColor(0xaaffffff); + for (int a = 0; a < tabCount - 1; a++) { + canvas.drawRect(tabWidth + a * tabWidth - 1, AndroidUtilities.dp(12), tabWidth + a * tabWidth + 1, getHeight() - AndroidUtilities.dp(12), paint); + } + + if (tabX != animateTabXTo) { + long dt = System.currentTimeMillis() - startAnimationTime; + startAnimationTime = System.currentTimeMillis(); + totalAnimationDiff += dt; + if (totalAnimationDiff > 200) { + totalAnimationDiff = 200; + tabX = animateTabXTo; + } else { + tabX = startAnimationX + interpolator.getInterpolation(totalAnimationDiff / 200.0f) * (animateTabXTo - startAnimationX); + invalidate(); + } + } + + canvas.drawRect(tabX, getHeight() - AndroidUtilities.dp(4), (tabX + tabWidth), getHeight(), paint); + } +} diff --git a/TMessagesProj/src/main/res/layout-ar/contacts_layout.xml b/TMessagesProj/src/main/res/layout-ar/contacts_layout.xml deleted file mode 100644 index eccbfa38f..000000000 --- a/TMessagesProj/src/main/res/layout-ar/contacts_layout.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - diff --git a/TMessagesProj/src/main/res/layout-ar/messages_list.xml b/TMessagesProj/src/main/res/layout-ar/messages_list.xml deleted file mode 100644 index 15d7d46a1..000000000 --- a/TMessagesProj/src/main/res/layout-ar/messages_list.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/TMessagesProj/src/main/res/layout-ar/settings_blocked_users_layout.xml b/TMessagesProj/src/main/res/layout-ar/settings_blocked_users_layout.xml deleted file mode 100644 index f81b2ceb7..000000000 --- a/TMessagesProj/src/main/res/layout-ar/settings_blocked_users_layout.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - diff --git a/TMessagesProj/src/main/res/layout-ar/settings_layout.xml b/TMessagesProj/src/main/res/layout-ar/settings_layout.xml deleted file mode 100644 index 607e92470..000000000 --- a/TMessagesProj/src/main/res/layout-ar/settings_layout.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/TMessagesProj/src/main/res/layout/messages_list.xml b/TMessagesProj/src/main/res/layout/messages_list.xml index 1615aa8ea..60befc870 100644 --- a/TMessagesProj/src/main/res/layout/messages_list.xml +++ b/TMessagesProj/src/main/res/layout/messages_list.xml @@ -1,33 +1,38 @@ - + + + - + android:visibility="gone"/> @@ -40,7 +45,8 @@ android:textSize="24dp" android:id="@+id/list_empty_view_text1"/> - + android:visibility="gone"> + - + + diff --git a/TMessagesProj/src/main/res/values-ar/strings.xml b/TMessagesProj/src/main/res/values-ar/strings.xml index 64851a0e8..e9947eec1 100644 --- a/TMessagesProj/src/main/res/values-ar/strings.xml +++ b/TMessagesProj/src/main/res/values-ar/strings.xml @@ -53,6 +53,8 @@ اختر محادثة إضغط بإستمرار على المستخدم العرض %1$s يستخدم إصدار قديم من تيليجرام، لذلك، الصور السرية ستظهر في وضع الموافقة.\n\nعندما يقوم %2$s بتحديث تيليجرام، الصور التي بها عداد دقيقة أو أقل ستعمل بطريقة \"الاستمرار بالضغط للإستعراض\"، وسيتم إخبارك عندما يلتقط المستقبل صورة من شاشته. + Conversations + Messages قائمة الرسالة الجماعية رسالة جماعية جديدة diff --git a/TMessagesProj/src/main/res/values-de/strings.xml b/TMessagesProj/src/main/res/values-de/strings.xml index 9d8888043..9a9b14fa1 100644 --- a/TMessagesProj/src/main/res/values-de/strings.xml +++ b/TMessagesProj/src/main/res/values-de/strings.xml @@ -53,6 +53,8 @@ Chat auswählen Tippen und Halten %1$s benutzt eine ältere Version von Telegram, sodass Fotos in Geheimen Chats im Kompatibilitätsmodus angezeigt werden.\n\nSobald %2$s Telegram aktualisiert, werden Fotos mit Timern von 1 Minute und kürzer per \"Tippen und Halten\" angezeigt. Du wirst benachrichtigt, sobald dein Chatpartner ein Bildschirmfoto macht. + Conversations + Messages Broadcast Liste Neue Broadcast Liste diff --git a/TMessagesProj/src/main/res/values-es/strings.xml b/TMessagesProj/src/main/res/values-es/strings.xml index ce8ca4e7f..a3aa62b09 100644 --- a/TMessagesProj/src/main/res/values-es/strings.xml +++ b/TMessagesProj/src/main/res/values-es/strings.xml @@ -53,6 +53,8 @@ Elige el chat Mantén pulsado para ver %1$s usa una versión antigua de Telegram, así que las fotos secretas serán mostradas en un modo de compatibilidad.\n\nCuando %2$s actualice Telegram, las fotos con autodestrucción de 1 minuto o menos funcionarán con el modo \'Mantén pulsado para ver\', y te notificaremos siempre que la otra parte haga una captura de pantalla. + Conversations + Messages Lista de difusión Nueva difusión diff --git a/TMessagesProj/src/main/res/values-it/strings.xml b/TMessagesProj/src/main/res/values-it/strings.xml index 835962588..73d140275 100644 --- a/TMessagesProj/src/main/res/values-it/strings.xml +++ b/TMessagesProj/src/main/res/values-it/strings.xml @@ -53,6 +53,8 @@ Seleziona chat Tieni premuto per vedere %1$s sta usando una versione vecchia di Telegram, quindi le foto segrete verranno visualizzate in modalità di compatibilità.\n\nUna volta che %2$s avrà aggiornato Telegram, le foto con il timer minore di 1 minuto funzioneranno in modalità \'Tieni premuto per vedere\' , e verrai notificato ogni volta che l\'altro esegue uno screenshot. + Conversations + Messages Lista broadcast Nuova lista broadcast diff --git a/TMessagesProj/src/main/res/values-ko/strings.xml b/TMessagesProj/src/main/res/values-ko/strings.xml index c6314c7f0..674cf4615 100644 --- a/TMessagesProj/src/main/res/values-ko/strings.xml +++ b/TMessagesProj/src/main/res/values-ko/strings.xml @@ -53,6 +53,8 @@ 채팅방 선택 꾹 눌러서 보기 %1$s님의 텔레그램 버전이 낮아 비밀 사진을 호환성 모드로 표시합니다.\n\n%2$s님이 텔레그램을 업데이트하고 나면, 자동삭제 시간이 1분 이하인 사진은 \"탭하고 누르고 있어야 보임\" 상태가 되며, 상대방이 화면을 캡처할 때 마다 알림을 받습니다. + Conversations + Messages 단체 메시지 리스트 새 단체 메시지 리스트 diff --git a/TMessagesProj/src/main/res/values-nl/strings.xml b/TMessagesProj/src/main/res/values-nl/strings.xml index eafe28483..b2b3b24a7 100644 --- a/TMessagesProj/src/main/res/values-nl/strings.xml +++ b/TMessagesProj/src/main/res/values-nl/strings.xml @@ -53,6 +53,8 @@ Kies een gesprek Druk en houd ingedrukt %1$s gebruikt een oudere versie van Telegram, dus worden geheime foto\'s weergegeven in de compatibiliteitsmodus.\n\nZodra %2$s Telegram updatet werken foto\'s met timers voor 1 minuut of minder in de \'Druk en houd ingedrukt\'-modus en krijg je een bericht wanneer de andere partij een schermafbeelding maakt. + Conversations + Messages Verzendlijst Nieuwe verzendlijst diff --git a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml index df6d5c489..13f55a2b4 100644 --- a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml @@ -53,6 +53,8 @@ Selecione uma Conversa Toque e segure para ver %1$s está usando uma versão mais antiga do Telegram, por isso fotos secretas serão mostradas em modo de compatibilidade.\n\nAssim que %2$s atualize o Telegram, fotos com timers de 1 minuto ou menos passarão a funcionar no modo ‘Toque e segure para ver’, e você será notificado caso a outra pessoa salve a tela. + Conversations + Messages Lista de Broadcast Nova Lista de Broadcast diff --git a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml index f79e0ff23..0d36cec29 100644 --- a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml @@ -53,6 +53,8 @@ Selecione uma Conversa Toque e segure para ver %1$s está usando uma versão mais antiga do Telegram, por isso fotos secretas serão mostradas em modo de compatibilidade.\n\nAssim que %2$s atualize o Telegram, fotos com timers de 1 minuto ou menos passarão a funcionar no modo ‘Toque e segure para ver’, e você será notificado caso a outra pessoa salve a tela. + Conversations + Messages Lista de Broadcast Nova Lista de Broadcast diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index afb85da55..35a1c4601 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -53,6 +53,8 @@ Select Chat Tap and hold to view %1$s is using an older version of Telegram, so secret photos will be shown in compatibility mode.\n\nOnce %2$s updates Telegram, photos with timers for 1 minute or less will start working in \'Tap and hold to view\' mode, and you will be notified whenever the other party takes a screenshot. + CONVERSATIONS + MESSAGES Broadcast List New Broadcast List