Messages search (not finished)

This commit is contained in:
DrKLO 2014-10-31 22:02:29 +03:00
parent 6c4c5cf311
commit 1add11177d
30 changed files with 1254 additions and 874 deletions

View file

@ -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);
}

View file

@ -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,22 +1394,15 @@ 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);
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() {
@ -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<MessageObject> arr = messages.get(newMessage.dialog_id);
if (arr == null) {
arr = new ArrayList<MessageObject>();
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() {
@ -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() {

View file

@ -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<TLRPC.User> encUsers = new ArrayList<TLRPC.User>();
String q = query.trim().toLowerCase();
if (q.length() == 0) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadSearchResults, token, new ArrayList<TLObject>(), new ArrayList<CharSequence>(), new ArrayList<CharSequence>());
return;
}
ArrayList<TLObject> resultArray = new ArrayList<TLObject>();
ArrayList<CharSequence> resultArrayNames = new ArrayList<CharSequence>();
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("<font color=\"#00a60e\">" + ContactsController.formatName(user.first_name, user.last_name) + "</font>"));
} 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<TLRPC.TL_contact> 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<Integer> loadedUsers = new ArrayList<Integer>();
@ -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,12 +1772,14 @@ public class MessagesStorage {
}
}
buffersStorage.reuseFreeBuffer(data);
}
cursor.dispose();
Collections.sort(res.messages, new Comparator<TLRPC.Message>() {
@Override
public int compare(TLRPC.Message lhs, TLRPC.Message rhs) {
if (lhs.id > 0 && rhs.id > 0) {
if (!forward) {
if (load_type != 1) {
if (lhs.id > rhs.id) {
return -1;
} else if (lhs.id < rhs.id) {
@ -1880,7 +1793,7 @@ public class MessagesStorage {
}
}
} else if (lhs.id < 0 && rhs.id < 0) {
if (!forward) {
if (load_type != 1) {
if (lhs.id < rhs.id) {
return -1;
} else if (lhs.id > rhs.id) {
@ -1894,7 +1807,7 @@ public class MessagesStorage {
}
}
} else {
if (!forward) {
if (load_type != 1) {
if (lhs.date > rhs.date) {
return -1;
} else if (lhs.date < rhs.date) {
@ -1911,8 +1824,6 @@ public class MessagesStorage {
return 0;
}
});
}
cursor.dispose();
StringBuilder usersToLoad = new StringBuilder();
for (int uid : fromUser) {
@ -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);
}
}
});

View file

@ -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;

View file

@ -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) {

View file

@ -24,11 +24,11 @@ public class BaseContactsSearchAdapter extends BaseFragmentAdapter {
protected String lastFoundUsername = null;
public void queryServerSearch(final String query) {
if (query == null || query.length() < 5) {
if (reqId != 0) {
ConnectionsManager.getInstance().cancelRpc(reqId, true);
reqId = 0;
}
if (query == null || query.length() < 5) {
globalSearch.clear();
lastReqId = 0;
notifyDataSetChanged();

View file

@ -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

View file

@ -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;
}
}

View file

@ -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<TLObject> searchResult = new ArrayList<TLObject>();
private ArrayList<CharSequence> searchResultNames = new ArrayList<CharSequence>();
private ArrayList<MessageObject> searchResultMessages = new ArrayList<MessageObject>();
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<TLRPC.User> encUsers = new ArrayList<TLRPC.User>();
String q = query.trim().toLowerCase();
if (q.length() == 0) {
updateSearchResults(new ArrayList<TLObject>(), new ArrayList<CharSequence>(), new ArrayList<TLRPC.User>());
return;
}
ArrayList<TLObject> resultArray = new ArrayList<TLObject>();
ArrayList<CharSequence> resultArrayNames = new ArrayList<CharSequence>();
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("<font color=\"#00a60e\">" + ContactsController.formatName(user.first_name, user.last_name) + "</font>"));
} 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<TLObject> result, final ArrayList<CharSequence> names, final ArrayList<TLRPC.User> 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("<font color=\"#357aa8\">@%s</font>%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();
}
}

View file

@ -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;
}

View file

@ -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<MessageObject> messArr = (ArrayList<MessageObject>)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,14 +1732,13 @@ 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) {
if (load_type == 2 && obj.messageOwner.id == first_unread_id) {
TLRPC.Message dateMsg = new TLRPC.Message();
dateMsg.message = "";
dateMsg.id = 0;
@ -1744,25 +1751,28 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
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_unread_id) {
unread_end_reached = true;
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++;
}
}

View file

@ -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);

View file

@ -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) {

View file

@ -82,7 +82,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
if (!usersToLoad.isEmpty()) {
final Semaphore semaphore = new Semaphore(0);
final ArrayList<TLRPC.User> users = new ArrayList<TLRPC.User>();
MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
users.addAll(MessagesStorage.getInstance().getUsers(usersToLoad));

View file

@ -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,17 +308,23 @@ 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;
int message_id = 0;
BaseFragmentAdapter adapter = (BaseFragmentAdapter)messagesListView.getAdapter();
if (adapter == messagesActivityAdapter) {
TLRPC.TL_dialog dialog = messagesActivityAdapter.getItem(i);
if (dialog == null) {
return;
}
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 (messagesListViewAdapter.isGlobalSearch(i)) {
if (messagesActivitySearchAdapter.isGlobalSearch(i)) {
ArrayList<TLRPC.User> users = new ArrayList<TLRPC.User>();
users.add((TLRPC.User)obj);
MessagesController.getInstance().putUsers(users, false);
@ -296,8 +338,15 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter
}
} 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;
} else if (obj instanceof MessageObject) {
MessageObject messageObject = (MessageObject)obj;
dialog_id = messageObject.getDialogId();
message_id = messageObject.messageOwner.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<TLObject>) args[1], (ArrayList<CharSequence>) args[2], (ArrayList<TLRPC.User>) 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<TLObject> searchResult = new ArrayList<TLObject>();
private ArrayList<CharSequence> searchResultNames = new ArrayList<CharSequence>();
public MessagesAdapter(Context context) {
mContext = context;
}
public void updateSearchResults(final ArrayList<TLObject> result, final ArrayList<CharSequence> names, final ArrayList<TLRPC.User> 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("<font color=\"#357aa8\">@%s</font>%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;
}
}
}

View file

@ -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);
}
}

View file

@ -1,34 +0,0 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<org.telegram.ui.Views.PinnedHeaderListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/listView"
android:clipToPadding="false"
android:fadingEdge="none"
android:fadingEdgeLength="0dp"
android:paddingLeft="30dp"
android:paddingRight="16dp"
android:dividerHeight="0dp"
android:divider="@null"
android:paddingBottom="16dp"
android:fastScrollEnabled="true"
android:fastScrollAlwaysVisible="true"
android:scrollbarStyle="outsideOverlay"
android:layout_gravity="top"
android:verticalScrollbarPosition="left"/>
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#808080"
android:gravity="center"
android:textSize="24dp"
android:id="@+id/searchEmptyView"
android:visibility="invisible"
android:layout_gravity="top"/>
</FrameLayout>

View file

@ -1,67 +0,0 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/messages_list_view"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:clipToPadding="false"
android:fadingEdge="none"
android:divider="@null"
android:dividerHeight="0px"
android:fadingEdgeLength="0dp"
android:verticalScrollbarPosition="left"/>
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#808080"
android:gravity="center"
android:textSize="24dp"
android:id="@+id/searchEmptyView"
android:visibility="invisible"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/list_empty_view"
android:layout_centerInParent="true"
android:orientation="vertical"
android:gravity="center"
android:visibility="gone">
<TextView android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#959595"
android:textSize="24dp"
android:gravity="center"
android:id="@+id/list_empty_view_text1"/>
<TextView android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#959595"
android:gravity="center"
android:textSize="15dp"
android:paddingTop="6dp"
android:lineSpacingExtra="2dp"
android:id="@+id/list_empty_view_text2"/>
</LinearLayout>
<LinearLayout
android:id="@+id/progressLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone" >
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ProgressBar>
</LinearLayout>
</RelativeLayout>

View file

@ -1,45 +0,0 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/listView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:clipToPadding="false"
android:fadingEdge="none"
android:fadingEdgeLength="0dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:dividerHeight="0dp"
android:divider="@null"
android:scrollbars="none"
android:paddingBottom="16dp"
android:verticalScrollbarPosition="left"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#808080"
android:gravity="center"
android:textSize="24dp"
android:id="@+id/searchEmptyView"/>
<LinearLayout
android:id="@+id/progressLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</RelativeLayout>

View file

@ -1,24 +0,0 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/listView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:clipToPadding="false"
android:fadingEdge="none"
android:fadingEdgeLength="0dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:dividerHeight="0dp"
android:divider="@null"
android:scrollbars="none"
android:paddingBottom="16dp"
android:verticalScrollbarPosition="left"/>
</RelativeLayout>

View file

@ -1,33 +1,38 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<org.telegram.ui.Views.SlidingTabView
android:layout_width="match_parent"
android:layout_height="48dp"
android:visibility="gone"
android:id="@+id/searchPanelView"/>
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/messages_list_view"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:fadingEdge="none"
android:fadingEdgeLength="0dp"
android:divider="@null"
android:dividerHeight="0px"
android:animationCache="false"/>
<TextView android:layout_width="match_parent"
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#808080"
android:gravity="center"
android:textSize="24dp"
android:id="@+id/searchEmptyView"
android:visibility="invisible"/>
android:visibility="gone"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/list_empty_view"
android:layout_centerInParent="true"
android:orientation="vertical"
android:gravity="center"
android:visibility="gone">
@ -40,7 +45,8 @@
android:textSize="24dp"
android:id="@+id/list_empty_view_text1"/>
<TextView android:layout_width="wrap_content"
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#959595"
android:gravity="center"
@ -53,8 +59,8 @@
<LinearLayout
android:id="@+id/progressLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
@ -63,5 +69,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ProgressBar>
</LinearLayout>
</LinearLayout>
</RelativeLayout>

View file

@ -53,6 +53,8 @@
<string name="SelectChat">اختر محادثة</string>
<string name="PhotoTip">إضغط بإستمرار على المستخدم العرض</string>
<string name="CompatibilityChat">%1$s يستخدم إصدار قديم من تيليجرام، لذلك، الصور السرية ستظهر في وضع الموافقة.\n\nعندما يقوم %2$s بتحديث تيليجرام، الصور التي بها عداد دقيقة أو أقل ستعمل بطريقة \"الاستمرار بالضغط للإستعراض\"، وسيتم إخبارك عندما يلتقط المستقبل صورة من شاشته.</string>
<string name="SearchConversations">Conversations</string>
<string name="SearchMessages">Messages</string>
<!--broadcasts-->
<string name="BroadcastList">قائمة الرسالة الجماعية</string>
<string name="NewBroadcastList">رسالة جماعية جديدة</string>

View file

@ -53,6 +53,8 @@
<string name="SelectChat">Chat auswählen</string>
<string name="PhotoTip">Tippen und Halten</string>
<string name="CompatibilityChat">%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.</string>
<string name="SearchConversations">Conversations</string>
<string name="SearchMessages">Messages</string>
<!--broadcasts-->
<string name="BroadcastList">Broadcast Liste</string>
<string name="NewBroadcastList">Neue Broadcast Liste</string>

View file

@ -53,6 +53,8 @@
<string name="SelectChat">Elige el chat</string>
<string name="PhotoTip">Mantén pulsado para ver</string>
<string name="CompatibilityChat">%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.</string>
<string name="SearchConversations">Conversations</string>
<string name="SearchMessages">Messages</string>
<!--broadcasts-->
<string name="BroadcastList">Lista de difusión</string>
<string name="NewBroadcastList">Nueva difusión</string>

View file

@ -53,6 +53,8 @@
<string name="SelectChat">Seleziona chat</string>
<string name="PhotoTip">Tieni premuto per vedere</string>
<string name="CompatibilityChat">%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.</string>
<string name="SearchConversations">Conversations</string>
<string name="SearchMessages">Messages</string>
<!--broadcasts-->
<string name="BroadcastList">Lista broadcast</string>
<string name="NewBroadcastList">Nuova lista broadcast</string>

View file

@ -53,6 +53,8 @@
<string name="SelectChat">채팅방 선택</string>
<string name="PhotoTip">꾹 눌러서 보기</string>
<string name="CompatibilityChat">%1$s님의 텔레그램 버전이 낮아 비밀 사진을 호환성 모드로 표시합니다.\n\n%2$s님이 텔레그램을 업데이트하고 나면, 자동삭제 시간이 1분 이하인 사진은 \"탭하고 누르고 있어야 보임\" 상태가 되며, 상대방이 화면을 캡처할 때 마다 알림을 받습니다.</string>
<string name="SearchConversations">Conversations</string>
<string name="SearchMessages">Messages</string>
<!--broadcasts-->
<string name="BroadcastList">단체 메시지 리스트</string>
<string name="NewBroadcastList">새 단체 메시지 리스트</string>

View file

@ -53,6 +53,8 @@
<string name="SelectChat">Kies een gesprek</string>
<string name="PhotoTip">Druk en houd ingedrukt</string>
<string name="CompatibilityChat">%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.</string>
<string name="SearchConversations">Conversations</string>
<string name="SearchMessages">Messages</string>
<!--broadcasts-->
<string name="BroadcastList">Verzendlijst</string>
<string name="NewBroadcastList">Nieuwe verzendlijst</string>

View file

@ -53,6 +53,8 @@
<string name="SelectChat">Selecione uma Conversa</string>
<string name="PhotoTip">Toque e segure para ver</string>
<string name="CompatibilityChat">%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.</string>
<string name="SearchConversations">Conversations</string>
<string name="SearchMessages">Messages</string>
<!--broadcasts-->
<string name="BroadcastList">Lista de Broadcast</string>
<string name="NewBroadcastList">Nova Lista de Broadcast</string>

View file

@ -53,6 +53,8 @@
<string name="SelectChat">Selecione uma Conversa</string>
<string name="PhotoTip">Toque e segure para ver</string>
<string name="CompatibilityChat">%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.</string>
<string name="SearchConversations">Conversations</string>
<string name="SearchMessages">Messages</string>
<!--broadcasts-->
<string name="BroadcastList">Lista de Broadcast</string>
<string name="NewBroadcastList">Nova Lista de Broadcast</string>

View file

@ -53,6 +53,8 @@
<string name="SelectChat">Select Chat</string>
<string name="PhotoTip">Tap and hold to view</string>
<string name="CompatibilityChat">%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.</string>
<string name="SearchConversations">CONVERSATIONS</string>
<string name="SearchMessages">MESSAGES</string>
<!--broadcasts-->
<string name="BroadcastList">Broadcast List</string>
<string name="NewBroadcastList">New Broadcast List</string>