- Base updated: v3.1.2
* Recent search results * Tap and hold sticker to preview before sending - Bug fixes
This commit is contained in:
parent
3bc33bf670
commit
2b3d852636
@ -82,8 +82,8 @@ android {
|
|||||||
applicationId "org.telegram.plus"
|
applicationId "org.telegram.plus"
|
||||||
minSdkVersion 8
|
minSdkVersion 8
|
||||||
targetSdkVersion 22
|
targetSdkVersion 22
|
||||||
versionCode 590
|
versionCode 592
|
||||||
versionName "3.1.1.9"
|
versionName "3.1.2.0"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -940,10 +940,14 @@ public class ContactsController {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
FileLog.e("tmessages", "done loading contacts");
|
FileLog.e("tmessages", "done loading contacts");
|
||||||
if (from == 1 && contactsArr.isEmpty()) {
|
if (from == 1 && (contactsArr.isEmpty() || UserConfig.lastContactsSyncTime < (int) (System.currentTimeMillis() / 1000) - 24 * 60 * 60)) {
|
||||||
loadContacts(false, true);
|
loadContacts(false, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (from == 0) {
|
||||||
|
UserConfig.lastContactsSyncTime = (int) (System.currentTimeMillis() / 1000);
|
||||||
|
UserConfig.saveConfig(false);
|
||||||
|
}
|
||||||
|
|
||||||
for (TLRPC.TL_contact contact : contactsArr) {
|
for (TLRPC.TL_contact contact : contactsArr) {
|
||||||
if (usersDict.get(contact.user_id) == null && contact.user_id != UserConfig.getClientUserId()) {
|
if (usersDict.get(contact.user_id) == null && contact.user_id != UserConfig.getClientUserId()) {
|
||||||
@ -1809,18 +1813,14 @@ public class ContactsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String formatName(String firstName, String lastName) {
|
public static String formatName(String firstName, String lastName) {
|
||||||
if ((firstName == null || firstName.length() == 0) && (lastName == null || lastName.length() == 0)) {
|
/*if ((firstName == null || firstName.length() == 0) && (lastName == null || lastName.length() == 0)) {
|
||||||
return LocaleController.getString("HiddenName", R.string.HiddenName);
|
return LocaleController.getString("HiddenName", R.string.HiddenName);
|
||||||
}
|
}*/
|
||||||
if (firstName != null) {
|
if (firstName != null) {
|
||||||
firstName = firstName.trim();
|
firstName = firstName.trim();
|
||||||
//firstName = firstName.replaceAll("[^\\x00-\\x7F]", "");
|
|
||||||
//firstName = firstName.trim().replaceAll(" +", " ");
|
|
||||||
}
|
}
|
||||||
if (lastName != null) {
|
if (lastName != null) {
|
||||||
lastName = lastName.trim();
|
lastName = lastName.trim();
|
||||||
//lastName = lastName.replaceAll("[^\\x00-\\x7F]", "");
|
|
||||||
//lastName = lastName.trim().replaceAll(" +", " ");
|
|
||||||
}
|
}
|
||||||
StringBuilder result = new StringBuilder((firstName != null ? firstName.length() : 0) + (lastName != null ? lastName.length() : 0) + 1);
|
StringBuilder result = new StringBuilder((firstName != null ? firstName.length() : 0) + (lastName != null ? lastName.length() : 0) + 1);
|
||||||
if (LocaleController.nameDisplayOrder == 1) {
|
if (LocaleController.nameDisplayOrder == 1) {
|
||||||
|
@ -61,8 +61,6 @@ public class Emoji {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public static long[][] data = {
|
public static long[][] data = {
|
||||||
new long[]
|
|
||||||
{},
|
|
||||||
new long[]//189
|
new long[]//189
|
||||||
{
|
{
|
||||||
0x00000000D83DDE04L, 0x00000000D83DDE03L, 0x00000000D83DDE00L, 0x00000000D83DDE0AL, 0x000000000000263AL, 0x00000000D83DDE09L, 0x00000000D83DDE0DL,
|
0x00000000D83DDE04L, 0x00000000D83DDE03L, 0x00000000D83DDE00L, 0x00000000D83DDE0AL, 0x000000000000263AL, 0x00000000D83DDE09L, 0x00000000D83DDE0DL,
|
||||||
@ -215,10 +213,10 @@ public class Emoji {
|
|||||||
bigImgSize = AndroidUtilities.dp(32);
|
bigImgSize = AndroidUtilities.dp(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 1; j < data.length; j++) {
|
for (int j = 0; j < data.length; j++) {
|
||||||
for (int i = 0; i < data[j].length; i++) {
|
for (int i = 0; i < data[j].length; i++) {
|
||||||
Rect rect = new Rect((i % cols[j - 1]) * emojiFullSize, (i / cols[j - 1]) * emojiFullSize, (i % cols[j - 1] + 1) * emojiFullSize, (i / cols[j - 1] + 1) * emojiFullSize);
|
Rect rect = new Rect((i % cols[j]) * emojiFullSize, (i / cols[j]) * emojiFullSize, (i % cols[j] + 1) * emojiFullSize, (i / cols[j] + 1) * emojiFullSize);
|
||||||
rects.put(data[j][i], new DrawableInfo(rect, (byte) (j - 1)));
|
rects.put(data[j][i], new DrawableInfo(rect, (byte) j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
placeholderPaint = new Paint();
|
placeholderPaint = new Paint();
|
||||||
|
@ -1206,30 +1206,11 @@ public class ImageLoader {
|
|||||||
telegramPath = new File(Environment.getExternalStorageDirectory(), "Telegram");
|
telegramPath = new File(Environment.getExternalStorageDirectory(), "Telegram");
|
||||||
telegramPath.mkdirs();
|
telegramPath.mkdirs();
|
||||||
|
|
||||||
boolean canRename = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (int a = 0; a < 5; a++) {
|
|
||||||
File srcFile = new File(cachePath, "temp.file");
|
|
||||||
srcFile.createNewFile();
|
|
||||||
File dstFile = new File(telegramPath, "temp.file");
|
|
||||||
canRename = srcFile.renameTo(dstFile);
|
|
||||||
srcFile.delete();
|
|
||||||
dstFile.delete();
|
|
||||||
if (canRename) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
FileLog.e("tmessages", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canRename) {
|
|
||||||
if (telegramPath.isDirectory()) {
|
if (telegramPath.isDirectory()) {
|
||||||
try {
|
try {
|
||||||
File imagePath = new File(telegramPath, "Telegram Images");
|
File imagePath = new File(telegramPath, "Telegram Images");
|
||||||
imagePath.mkdir();
|
imagePath.mkdir();
|
||||||
if (imagePath.isDirectory()) {
|
if (imagePath.isDirectory() && canMoveFiles(cachePath, imagePath)) {
|
||||||
mediaDirs.put(FileLoader.MEDIA_DIR_IMAGE, imagePath);
|
mediaDirs.put(FileLoader.MEDIA_DIR_IMAGE, imagePath);
|
||||||
FileLog.e("tmessages", "image path = " + imagePath);
|
FileLog.e("tmessages", "image path = " + imagePath);
|
||||||
}
|
}
|
||||||
@ -1240,7 +1221,7 @@ public class ImageLoader {
|
|||||||
try {
|
try {
|
||||||
File videoPath = new File(telegramPath, "Telegram Video");
|
File videoPath = new File(telegramPath, "Telegram Video");
|
||||||
videoPath.mkdir();
|
videoPath.mkdir();
|
||||||
if (videoPath.isDirectory()) {
|
if (videoPath.isDirectory() && canMoveFiles(cachePath, videoPath)) {
|
||||||
mediaDirs.put(FileLoader.MEDIA_DIR_VIDEO, videoPath);
|
mediaDirs.put(FileLoader.MEDIA_DIR_VIDEO, videoPath);
|
||||||
FileLog.e("tmessages", "video path = " + videoPath);
|
FileLog.e("tmessages", "video path = " + videoPath);
|
||||||
}
|
}
|
||||||
@ -1251,7 +1232,7 @@ public class ImageLoader {
|
|||||||
try {
|
try {
|
||||||
File audioPath = new File(telegramPath, "Telegram Audio");
|
File audioPath = new File(telegramPath, "Telegram Audio");
|
||||||
audioPath.mkdir();
|
audioPath.mkdir();
|
||||||
if (audioPath.isDirectory()) {
|
if (audioPath.isDirectory() && canMoveFiles(cachePath, audioPath)) {
|
||||||
new File(audioPath, ".nomedia").createNewFile();
|
new File(audioPath, ".nomedia").createNewFile();
|
||||||
mediaDirs.put(FileLoader.MEDIA_DIR_AUDIO, audioPath);
|
mediaDirs.put(FileLoader.MEDIA_DIR_AUDIO, audioPath);
|
||||||
FileLog.e("tmessages", "audio path = " + audioPath);
|
FileLog.e("tmessages", "audio path = " + audioPath);
|
||||||
@ -1263,7 +1244,7 @@ public class ImageLoader {
|
|||||||
try {
|
try {
|
||||||
File documentPath = new File(telegramPath, "Telegram Documents");
|
File documentPath = new File(telegramPath, "Telegram Documents");
|
||||||
documentPath.mkdir();
|
documentPath.mkdir();
|
||||||
if (documentPath.isDirectory()) {
|
if (documentPath.isDirectory() && canMoveFiles(cachePath, documentPath)) {
|
||||||
new File(documentPath, ".nomedia").createNewFile();
|
new File(documentPath, ".nomedia").createNewFile();
|
||||||
mediaDirs.put(FileLoader.MEDIA_DIR_DOCUMENT, documentPath);
|
mediaDirs.put(FileLoader.MEDIA_DIR_DOCUMENT, documentPath);
|
||||||
FileLog.e("tmessages", "documents path = " + documentPath);
|
FileLog.e("tmessages", "documents path = " + documentPath);
|
||||||
@ -1275,7 +1256,7 @@ public class ImageLoader {
|
|||||||
try {
|
try {
|
||||||
File themesPath = new File(telegramPath, "Themes");
|
File themesPath = new File(telegramPath, "Themes");
|
||||||
themesPath.mkdir();
|
themesPath.mkdir();
|
||||||
if (themesPath.isDirectory()) {
|
if (themesPath.isDirectory() && canMoveFiles(cachePath, themesPath)) {
|
||||||
new File(themesPath, ".nomedia").createNewFile();
|
new File(themesPath, ".nomedia").createNewFile();
|
||||||
mediaDirs.put(FileLoader.MEDIA_DIR_THEME, themesPath);
|
mediaDirs.put(FileLoader.MEDIA_DIR_THEME, themesPath);
|
||||||
FileLog.e("tmessages", "themes path = " + themesPath);
|
FileLog.e("tmessages", "themes path = " + themesPath);
|
||||||
@ -1288,7 +1269,6 @@ public class ImageLoader {
|
|||||||
} else {
|
} else {
|
||||||
FileLog.e("tmessages", "this Android can't rename files");
|
FileLog.e("tmessages", "this Android can't rename files");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
MediaController.getInstance().checkSaveToGalleryFiles();
|
MediaController.getInstance().checkSaveToGalleryFiles();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
@ -1297,6 +1277,38 @@ public class ImageLoader {
|
|||||||
return mediaDirs;
|
return mediaDirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canMoveFiles(File from, File to) {
|
||||||
|
RandomAccessFile file = null;
|
||||||
|
try {
|
||||||
|
for (int a = 0; a < 5; a++) {
|
||||||
|
File srcFile = new File(from, "temp.file");
|
||||||
|
srcFile.createNewFile();
|
||||||
|
file = new RandomAccessFile(srcFile, "rws");
|
||||||
|
file.write(1);
|
||||||
|
file.close();
|
||||||
|
file = null;
|
||||||
|
File dstFile = new File(to, "temp.file");
|
||||||
|
boolean canRename = srcFile.renameTo(dstFile);
|
||||||
|
srcFile.delete();
|
||||||
|
dstFile.delete();
|
||||||
|
if (canRename) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (file != null) {
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public Float getFileProgress(String location) {
|
public Float getFileProgress(String location) {
|
||||||
if (location == null) {
|
if (location == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1449,6 +1449,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void buildShuffledPlayList() {
|
private void buildShuffledPlayList() {
|
||||||
|
if (playlist.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
ArrayList<MessageObject> all = new ArrayList<>(playlist);
|
ArrayList<MessageObject> all = new ArrayList<>(playlist);
|
||||||
shuffledPlaylist.clear();
|
shuffledPlaylist.clear();
|
||||||
|
|
||||||
@ -2496,7 +2499,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
|||||||
albumEntry.addPhoto(photoEntry);
|
albumEntry.addPhoto(photoEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Throwable e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
@ -2555,7 +2558,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
|||||||
albumEntry.addPhoto(photoEntry);
|
albumEntry.addPhoto(photoEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Throwable e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
|
@ -131,6 +131,8 @@ public class MessagesStorage {
|
|||||||
|
|
||||||
database.executeFast("CREATE TABLE sent_files_v2(uid TEXT, type INTEGER, data BLOB, PRIMARY KEY (uid, type))").stepThis().dispose();
|
database.executeFast("CREATE TABLE sent_files_v2(uid TEXT, type INTEGER, data BLOB, PRIMARY KEY (uid, type))").stepThis().dispose();
|
||||||
|
|
||||||
|
database.executeFast("CREATE TABLE search_recent(did INTEGER PRIMARY KEY, date INTEGER);").stepThis().dispose();
|
||||||
|
|
||||||
//database.executeFast("CREATE TABLE messages_holes(uid INTEGER, start INTEGER, end INTEGER, PRIMARY KEY(uid, start));").stepThis().dispose();
|
//database.executeFast("CREATE TABLE messages_holes(uid INTEGER, start INTEGER, end INTEGER, PRIMARY KEY(uid, start));").stepThis().dispose();
|
||||||
//database.executeFast("CREATE INDEX IF NOT EXISTS type_uid_end_messages_holes ON messages_holes(uid, end);").stepThis().dispose();
|
//database.executeFast("CREATE INDEX IF NOT EXISTS type_uid_end_messages_holes ON messages_holes(uid, end);").stepThis().dispose();
|
||||||
//database.executeFast("CREATE TABLE secret_holes(uid INTEGER, seq_in INTEGER, seq_out INTEGER, data BLOB, PRIMARY KEY (uid, seq_in, seq_out));").stepThis().dispose();
|
//database.executeFast("CREATE TABLE secret_holes(uid INTEGER, seq_in INTEGER, seq_out INTEGER, data BLOB, PRIMARY KEY (uid, seq_in, seq_out));").stepThis().dispose();
|
||||||
@ -170,7 +172,7 @@ public class MessagesStorage {
|
|||||||
database.executeFast("CREATE INDEX IF NOT EXISTS bot_keyboard_idx_mid ON bot_keyboard(mid);").stepThis().dispose();
|
database.executeFast("CREATE INDEX IF NOT EXISTS bot_keyboard_idx_mid ON bot_keyboard(mid);").stepThis().dispose();
|
||||||
|
|
||||||
//version
|
//version
|
||||||
database.executeFast("PRAGMA user_version = 20").stepThis().dispose();
|
database.executeFast("PRAGMA user_version = 21").stepThis().dispose();
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
SQLiteCursor cursor = database.queryFinalized("SELECT seq, pts, date, qts, lsv, sg, pbytes FROM params WHERE id = 1");
|
SQLiteCursor cursor = database.queryFinalized("SELECT seq, pts, date, qts, lsv, sg, pbytes FROM params WHERE id = 1");
|
||||||
@ -201,7 +203,7 @@ public class MessagesStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
int version = database.executeInt("PRAGMA user_version");
|
int version = database.executeInt("PRAGMA user_version");
|
||||||
if (version < 20) {
|
if (version < 21) {
|
||||||
updateDbToLastVersion(version);
|
updateDbToLastVersion(version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,7 +412,12 @@ public class MessagesStorage {
|
|||||||
database.executeFast("CREATE TABLE IF NOT EXISTS bot_keyboard(uid INTEGER PRIMARY KEY, mid INTEGER, info BLOB)").stepThis().dispose();
|
database.executeFast("CREATE TABLE IF NOT EXISTS bot_keyboard(uid INTEGER PRIMARY KEY, mid INTEGER, info BLOB)").stepThis().dispose();
|
||||||
database.executeFast("CREATE INDEX IF NOT EXISTS bot_keyboard_idx_mid ON bot_keyboard(mid);").stepThis().dispose();
|
database.executeFast("CREATE INDEX IF NOT EXISTS bot_keyboard_idx_mid ON bot_keyboard(mid);").stepThis().dispose();
|
||||||
database.executeFast("PRAGMA user_version = 20").stepThis().dispose();
|
database.executeFast("PRAGMA user_version = 20").stepThis().dispose();
|
||||||
//version = 20;
|
version = 20;
|
||||||
|
}
|
||||||
|
if (version == 20) {
|
||||||
|
database.executeFast("CREATE TABLE search_recent(did INTEGER PRIMARY KEY, date INTEGER);").stepThis().dispose();
|
||||||
|
database.executeFast("PRAGMA user_version = 21").stepThis().dispose();
|
||||||
|
//version = 21;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
@ -887,6 +894,7 @@ public class MessagesStorage {
|
|||||||
if (!messagesOnly) {
|
if (!messagesOnly) {
|
||||||
database.executeFast("DELETE FROM dialogs WHERE did = " + did).stepThis().dispose();
|
database.executeFast("DELETE FROM dialogs WHERE did = " + did).stepThis().dispose();
|
||||||
database.executeFast("DELETE FROM chat_settings WHERE uid = " + did).stepThis().dispose();
|
database.executeFast("DELETE FROM chat_settings WHERE uid = " + did).stepThis().dispose();
|
||||||
|
database.executeFast("DELETE FROM search_recent WHERE did = " + did).stepThis().dispose();
|
||||||
int lower_id = (int)did;
|
int lower_id = (int)did;
|
||||||
int high_id = (int)(did >> 32);
|
int high_id = (int)(did >> 32);
|
||||||
if (lower_id != 0) {
|
if (lower_id != 0) {
|
||||||
@ -2100,11 +2108,19 @@ public class MessagesStorage {
|
|||||||
storageQueue.postRunnable(new Runnable() {
|
storageQueue.postRunnable(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
database.commitTransaction();
|
try {
|
||||||
|
database.commitTransaction();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
database.commitTransaction();
|
try {
|
||||||
|
database.commitTransaction();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2745,6 +2761,7 @@ public class MessagesStorage {
|
|||||||
database.beginTransaction();
|
database.beginTransaction();
|
||||||
|
|
||||||
SQLitePreparedStatement state = database.executeFast("UPDATE messages SET data = ? WHERE mid = ?");
|
SQLitePreparedStatement state = database.executeFast("UPDATE messages SET data = ? WHERE mid = ?");
|
||||||
|
SQLitePreparedStatement state2 = database.executeFast("UPDATE media_v2 SET data = ? WHERE mid = ?");
|
||||||
for (TLRPC.Message message : messages) {
|
for (TLRPC.Message message : messages) {
|
||||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(message.getObjectSize());
|
ByteBufferDesc data = buffersStorage.getFreeBuffer(message.getObjectSize());
|
||||||
message.serializeToStream(data);
|
message.serializeToStream(data);
|
||||||
@ -2754,9 +2771,15 @@ public class MessagesStorage {
|
|||||||
state.bindInteger(2, message.id);
|
state.bindInteger(2, message.id);
|
||||||
state.step();
|
state.step();
|
||||||
|
|
||||||
|
state2.requery();
|
||||||
|
state2.bindByteBuffer(1, data.buffer);
|
||||||
|
state2.bindInteger(2, message.id);
|
||||||
|
state2.step();
|
||||||
|
|
||||||
buffersStorage.reuseFreeBuffer(data);
|
buffersStorage.reuseFreeBuffer(data);
|
||||||
}
|
}
|
||||||
state.dispose();
|
state.dispose();
|
||||||
|
state2.dispose();
|
||||||
|
|
||||||
database.commitTransaction();
|
database.commitTransaction();
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ public class SharedMediaQuery {
|
|||||||
public final static int MEDIA_PHOTOVIDEO = 0;
|
public final static int MEDIA_PHOTOVIDEO = 0;
|
||||||
public final static int MEDIA_FILE = 1;
|
public final static int MEDIA_FILE = 1;
|
||||||
public final static int MEDIA_AUDIO = 2;
|
public final static int MEDIA_AUDIO = 2;
|
||||||
|
public final static int MEDIA_URL = 3;
|
||||||
|
|
||||||
public static void loadMedia(final long uid, final int offset, final int count, final int max_id, final int type, final boolean fromCache, final int classGuid) {
|
public static void loadMedia(final long uid, final int offset, final int count, final int max_id, final int type, final boolean fromCache, final int classGuid) {
|
||||||
int lower_part = (int)uid;
|
int lower_part = (int)uid;
|
||||||
@ -48,6 +49,8 @@ public class SharedMediaQuery {
|
|||||||
req.filter = new TLRPC.TL_inputMessagesFilterDocument();
|
req.filter = new TLRPC.TL_inputMessagesFilterDocument();
|
||||||
} else if (type == MEDIA_AUDIO) {
|
} else if (type == MEDIA_AUDIO) {
|
||||||
req.filter = new TLRPC.TL_inputMessagesFilterAudio();
|
req.filter = new TLRPC.TL_inputMessagesFilterAudio();
|
||||||
|
} else if (type == MEDIA_URL) {
|
||||||
|
req.filter = new TLRPC.TL_inputMessagesFilterUrl();
|
||||||
}
|
}
|
||||||
req.q = "";
|
req.q = "";
|
||||||
if (uid < 0) {
|
if (uid < 0) {
|
||||||
@ -94,6 +97,8 @@ public class SharedMediaQuery {
|
|||||||
req.filter = new TLRPC.TL_inputMessagesFilterDocument();
|
req.filter = new TLRPC.TL_inputMessagesFilterDocument();
|
||||||
} else if (type == MEDIA_AUDIO) {
|
} else if (type == MEDIA_AUDIO) {
|
||||||
req.filter = new TLRPC.TL_inputMessagesFilterAudio();
|
req.filter = new TLRPC.TL_inputMessagesFilterAudio();
|
||||||
|
} else if (type == MEDIA_URL) {
|
||||||
|
req.filter = new TLRPC.TL_inputMessagesFilterUrl();
|
||||||
}
|
}
|
||||||
req.q = "";
|
req.q = "";
|
||||||
if (uid < 0) {
|
if (uid < 0) {
|
||||||
@ -144,15 +149,17 @@ public class SharedMediaQuery {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (message.media instanceof TLRPC.TL_messageMediaPhoto || message.media instanceof TLRPC.TL_messageMediaVideo) {
|
if (message.media instanceof TLRPC.TL_messageMediaPhoto || message.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||||
return SharedMediaQuery.MEDIA_PHOTOVIDEO;
|
return MEDIA_PHOTOVIDEO;
|
||||||
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
|
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
|
||||||
if (MessageObject.isStickerMessage(message)) {
|
if (MessageObject.isStickerMessage(message)) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
return SharedMediaQuery.MEDIA_FILE;
|
return MEDIA_FILE;
|
||||||
}
|
}
|
||||||
} else if (message.media instanceof TLRPC.TL_messageMediaAudio) {
|
} else if (message.media instanceof TLRPC.TL_messageMediaAudio) {
|
||||||
return SharedMediaQuery.MEDIA_AUDIO;
|
return MEDIA_AUDIO;
|
||||||
|
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||||
|
return MEDIA_URL;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -160,7 +167,11 @@ public class SharedMediaQuery {
|
|||||||
public static boolean canAddMessageToMedia(TLRPC.Message message) {
|
public static boolean canAddMessageToMedia(TLRPC.Message message) {
|
||||||
if (message instanceof TLRPC.TL_message_secret && message.media instanceof TLRPC.TL_messageMediaPhoto && message.ttl != 0 && message.ttl <= 60) {
|
if (message instanceof TLRPC.TL_message_secret && message.media instanceof TLRPC.TL_messageMediaPhoto && message.ttl != 0 && message.ttl <= 60) {
|
||||||
return false;
|
return false;
|
||||||
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto || message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaDocument || message.media instanceof TLRPC.TL_messageMediaAudio) {
|
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto ||
|
||||||
|
message.media instanceof TLRPC.TL_messageMediaVideo ||
|
||||||
|
message.media instanceof TLRPC.TL_messageMediaDocument ||
|
||||||
|
message.media instanceof TLRPC.TL_messageMediaAudio/* ||
|
||||||
|
message.media instanceof TLRPC.TL_messageMediaWebPage && !(message.media.webpage instanceof TLRPC.TL_webPageEmpty)*/) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -110,8 +110,9 @@ public class StickersQuery {
|
|||||||
ArrayList<TLRPC.TL_messages_stickerSet> newStickerArray = null;
|
ArrayList<TLRPC.TL_messages_stickerSet> newStickerArray = null;
|
||||||
int date = 0;
|
int date = 0;
|
||||||
String hash = null;
|
String hash = null;
|
||||||
|
SQLiteCursor cursor = null;
|
||||||
try {
|
try {
|
||||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, date, hash FROM stickers_v2 WHERE 1");
|
cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, date, hash FROM stickers_v2 WHERE 1");
|
||||||
if (cursor.next()) {
|
if (cursor.next()) {
|
||||||
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
|
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
|
||||||
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
|
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
|
||||||
@ -128,9 +129,12 @@ public class StickersQuery {
|
|||||||
hash = cursor.stringValue(2);
|
hash = cursor.stringValue(2);
|
||||||
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
|
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
|
||||||
}
|
}
|
||||||
cursor.dispose();
|
} catch (Throwable e) {
|
||||||
} catch (Exception e) {
|
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
|
} finally {
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
processLoadedStickers(newStickerArray, true, date, hash);
|
processLoadedStickers(newStickerArray, true, date, hash);
|
||||||
}
|
}
|
||||||
@ -229,7 +233,7 @@ public class StickersQuery {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long getStickerSetId(TLRPC.Document document) {
|
public static long getStickerSetId(TLRPC.Document document) {
|
||||||
for (TLRPC.DocumentAttribute attribute : document.attributes) {
|
for (TLRPC.DocumentAttribute attribute : document.attributes) {
|
||||||
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
|
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
|
||||||
if (attribute.stickerset instanceof TLRPC.TL_inputStickerSetID) {
|
if (attribute.stickerset instanceof TLRPC.TL_inputStickerSetID) {
|
||||||
|
@ -28,43 +28,43 @@ public interface Cache {
|
|||||||
* @param key Cache key
|
* @param key Cache key
|
||||||
* @return An {@link Entry} or null in the event of a cache miss
|
* @return An {@link Entry} or null in the event of a cache miss
|
||||||
*/
|
*/
|
||||||
Entry get(String key);
|
public Entry get(String key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds or replaces an entry to the cache.
|
* Adds or replaces an entry to the cache.
|
||||||
* @param key Cache key
|
* @param key Cache key
|
||||||
* @param entry Data to store and metadata for cache coherency, TTL, etc.
|
* @param entry Data to store and metadata for cache coherency, TTL, etc.
|
||||||
*/
|
*/
|
||||||
void put(String key, Entry entry);
|
public void put(String key, Entry entry);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs any potentially long-running actions needed to initialize the cache;
|
* Performs any potentially long-running actions needed to initialize the cache;
|
||||||
* will be called from a worker thread.
|
* will be called from a worker thread.
|
||||||
*/
|
*/
|
||||||
void initialize();
|
public void initialize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidates an entry in the cache.
|
* Invalidates an entry in the cache.
|
||||||
* @param key Cache key
|
* @param key Cache key
|
||||||
* @param fullExpire True to fully expire the entry, false to soft expire
|
* @param fullExpire True to fully expire the entry, false to soft expire
|
||||||
*/
|
*/
|
||||||
void invalidate(String key, boolean fullExpire);
|
public void invalidate(String key, boolean fullExpire);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes an entry from the cache.
|
* Removes an entry from the cache.
|
||||||
* @param key Cache key
|
* @param key Cache key
|
||||||
*/
|
*/
|
||||||
void remove(String key);
|
public void remove(String key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empties the cache.
|
* Empties the cache.
|
||||||
*/
|
*/
|
||||||
void clear();
|
public void clear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data and metadata for an entry returned by the cache.
|
* Data and metadata for an entry returned by the cache.
|
||||||
*/
|
*/
|
||||||
class Entry {
|
public static class Entry {
|
||||||
/** The data returned from cache. */
|
/** The data returned from cache. */
|
||||||
public byte[] data;
|
public byte[] data;
|
||||||
|
|
||||||
@ -74,6 +74,9 @@ public interface Cache {
|
|||||||
/** Date of this response as reported by the server. */
|
/** Date of this response as reported by the server. */
|
||||||
public long serverDate;
|
public long serverDate;
|
||||||
|
|
||||||
|
/** The last modified date for the requested object. */
|
||||||
|
public long lastModified;
|
||||||
|
|
||||||
/** TTL for this record. */
|
/** TTL for this record. */
|
||||||
public long ttl;
|
public long ttl;
|
||||||
|
|
||||||
|
@ -151,6 +151,7 @@ public class CacheDispatcher extends Thread {
|
|||||||
if (mQuit) {
|
if (mQuit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,5 +26,5 @@ public interface Network {
|
|||||||
* @return A {@link NetworkResponse} with data and caching metadata; will never be null
|
* @return A {@link NetworkResponse} with data and caching metadata; will never be null
|
||||||
* @throws VolleyError on errors
|
* @throws VolleyError on errors
|
||||||
*/
|
*/
|
||||||
NetworkResponse performRequest(Request<?> request) throws VolleyError;
|
public NetworkResponse performRequest(Request<?> request) throws VolleyError;
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,9 @@ import java.util.concurrent.BlockingQueue;
|
|||||||
* Provides a thread for performing network dispatch from a queue of requests.
|
* Provides a thread for performing network dispatch from a queue of requests.
|
||||||
*
|
*
|
||||||
* Requests added to the specified queue are processed from the network via a
|
* Requests added to the specified queue are processed from the network via a
|
||||||
* specified {@link org.telegram.android.volley.Network} interface. Responses are committed to cache, if
|
* specified {@link Network} interface. Responses are committed to cache, if
|
||||||
* eligible, using a specified {@link org.telegram.android.volley.Cache} interface. Valid responses and
|
* eligible, using a specified {@link Cache} interface. Valid responses and
|
||||||
* errors are posted back to the caller via a {@link org.telegram.android.volley.ResponseDelivery}.
|
* errors are posted back to the caller via a {@link ResponseDelivery}.
|
||||||
*/
|
*/
|
||||||
public class NetworkDispatcher extends Thread {
|
public class NetworkDispatcher extends Thread {
|
||||||
/** The queue of requests to service. */
|
/** The queue of requests to service. */
|
||||||
|
@ -22,7 +22,7 @@ import java.util.Collections;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data and headers returned from {@link org.telegram.android.volley.Network#performRequest(org.telegram.android.volley.Request)}.
|
* Data and headers returned from {@link Network#performRequest(Request)}.
|
||||||
*/
|
*/
|
||||||
public class NetworkResponse {
|
public class NetworkResponse {
|
||||||
/**
|
/**
|
||||||
|
@ -18,9 +18,13 @@ package org.telegram.android.volley;
|
|||||||
|
|
||||||
import android.net.TrafficStats;
|
import android.net.TrafficStats;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import org.telegram.android.volley.VolleyLog.MarkerLog;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -53,6 +57,9 @@ public abstract class Request<T> implements Comparable<Request<T>> {
|
|||||||
int PATCH = 7;
|
int PATCH = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** An event log tracing the lifetime of this request; for debugging. */
|
||||||
|
private final MarkerLog mEventLog = MarkerLog.ENABLED ? new MarkerLog() : null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request method of this request. Currently supports GET, POST, PUT, DELETE, HEAD, OPTIONS,
|
* Request method of this request. Currently supports GET, POST, PUT, DELETE, HEAD, OPTIONS,
|
||||||
* TRACE, and PATCH.
|
* TRACE, and PATCH.
|
||||||
@ -83,12 +90,6 @@ public abstract class Request<T> implements Comparable<Request<T>> {
|
|||||||
/** Whether or not a response has been delivered for this request yet. */
|
/** Whether or not a response has been delivered for this request yet. */
|
||||||
private boolean mResponseDelivered = false;
|
private boolean mResponseDelivered = false;
|
||||||
|
|
||||||
// A cheap variant of request tracing used to dump slow requests.
|
|
||||||
private long mRequestBirthTime = 0;
|
|
||||||
|
|
||||||
/** Threshold at which we should log the request (even when debug logging is not enabled). */
|
|
||||||
private static final long SLOW_REQUEST_THRESHOLD_MS = 3000;
|
|
||||||
|
|
||||||
/** The retry policy for this request. */
|
/** The retry policy for this request. */
|
||||||
private RetryPolicy mRetryPolicy;
|
private RetryPolicy mRetryPolicy;
|
||||||
|
|
||||||
@ -108,6 +109,7 @@ public abstract class Request<T> implements Comparable<Request<T>> {
|
|||||||
* is provided by subclasses, who have a better idea of how to deliver an
|
* is provided by subclasses, who have a better idea of how to deliver an
|
||||||
* already-parsed response.
|
* already-parsed response.
|
||||||
*
|
*
|
||||||
|
* @deprecated Use {@link #Request(int, String, com.android.volley.Response.ErrorListener)}.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Request(String url, Response.ErrorListener listener) {
|
public Request(String url, Response.ErrorListener listener) {
|
||||||
@ -155,6 +157,9 @@ public abstract class Request<T> implements Comparable<Request<T>> {
|
|||||||
return mTag;
|
return mTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return this request's {@link com.android.volley.Response.ErrorListener}.
|
||||||
|
*/
|
||||||
public Response.ErrorListener getErrorListener() {
|
public Response.ErrorListener getErrorListener() {
|
||||||
return mErrorListener;
|
return mErrorListener;
|
||||||
}
|
}
|
||||||
@ -196,8 +201,8 @@ public abstract class Request<T> implements Comparable<Request<T>> {
|
|||||||
* Adds an event to this request's event log; for debugging.
|
* Adds an event to this request's event log; for debugging.
|
||||||
*/
|
*/
|
||||||
public void addMarker(String tag) {
|
public void addMarker(String tag) {
|
||||||
if (mRequestBirthTime == 0) {
|
if (MarkerLog.ENABLED) {
|
||||||
mRequestBirthTime = SystemClock.elapsedRealtime();
|
mEventLog.add(tag, Thread.currentThread().getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,9 +215,24 @@ public abstract class Request<T> implements Comparable<Request<T>> {
|
|||||||
if (mRequestQueue != null) {
|
if (mRequestQueue != null) {
|
||||||
mRequestQueue.finish(this);
|
mRequestQueue.finish(this);
|
||||||
}
|
}
|
||||||
long requestTime = SystemClock.elapsedRealtime() - mRequestBirthTime;
|
if (MarkerLog.ENABLED) {
|
||||||
if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) {
|
final long threadId = Thread.currentThread().getId();
|
||||||
VolleyLog.d("%d ms: %s", requestTime, this.toString());
|
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||||
|
// If we finish marking off of the main thread, we need to
|
||||||
|
// actually do it on the main thread to ensure correct ordering.
|
||||||
|
Handler mainThread = new Handler(Looper.getMainLooper());
|
||||||
|
mainThread.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mEventLog.add(tag, threadId);
|
||||||
|
mEventLog.finish(this.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mEventLog.add(tag, threadId);
|
||||||
|
mEventLog.finish(this.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,9 +19,11 @@ package org.telegram.android.volley;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -31,12 +33,18 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
/**
|
/**
|
||||||
* A request dispatch queue with a thread pool of dispatchers.
|
* A request dispatch queue with a thread pool of dispatchers.
|
||||||
*
|
*
|
||||||
* Calling {@link #add(org.telegram.android.volley.Request)} will enqueue the given Request for dispatch,
|
* Calling {@link #add(Request)} will enqueue the given Request for dispatch,
|
||||||
* resolving from either cache or network on a worker thread, and then delivering
|
* resolving from either cache or network on a worker thread, and then delivering
|
||||||
* a parsed response on the main thread.
|
* a parsed response on the main thread.
|
||||||
*/
|
*/
|
||||||
public class RequestQueue {
|
public class RequestQueue {
|
||||||
|
|
||||||
|
/** Callback interface for completed requests. */
|
||||||
|
public static interface RequestFinishedListener<T> {
|
||||||
|
/** Called when a request has finished processing. */
|
||||||
|
public void onRequestFinished(Request<T> request);
|
||||||
|
}
|
||||||
|
|
||||||
/** Used for generating monotonically-increasing sequence numbers for requests. */
|
/** Used for generating monotonically-increasing sequence numbers for requests. */
|
||||||
private AtomicInteger mSequenceGenerator = new AtomicInteger();
|
private AtomicInteger mSequenceGenerator = new AtomicInteger();
|
||||||
|
|
||||||
@ -86,6 +94,9 @@ public class RequestQueue {
|
|||||||
/** The cache dispatcher. */
|
/** The cache dispatcher. */
|
||||||
private CacheDispatcher mCacheDispatcher;
|
private CacheDispatcher mCacheDispatcher;
|
||||||
|
|
||||||
|
private List<RequestFinishedListener> mFinishedListeners =
|
||||||
|
new ArrayList<RequestFinishedListener>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the worker pool. Processing will not begin until {@link #start()} is called.
|
* Creates the worker pool. Processing will not begin until {@link #start()} is called.
|
||||||
*
|
*
|
||||||
@ -149,9 +160,9 @@ public class RequestQueue {
|
|||||||
if (mCacheDispatcher != null) {
|
if (mCacheDispatcher != null) {
|
||||||
mCacheDispatcher.quit();
|
mCacheDispatcher.quit();
|
||||||
}
|
}
|
||||||
for (NetworkDispatcher mDispatcher : mDispatchers) {
|
for (int i = 0; i < mDispatchers.length; i++) {
|
||||||
if (mDispatcher != null) {
|
if (mDispatchers[i] != null) {
|
||||||
mDispatcher.quit();
|
mDispatchers[i].quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,7 +186,7 @@ public class RequestQueue {
|
|||||||
* {@link RequestQueue#cancelAll(RequestFilter)}.
|
* {@link RequestQueue#cancelAll(RequestFilter)}.
|
||||||
*/
|
*/
|
||||||
public interface RequestFilter {
|
public interface RequestFilter {
|
||||||
boolean apply(Request<?> request);
|
public boolean apply(Request<?> request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -261,11 +272,16 @@ public class RequestQueue {
|
|||||||
* <p>Releases waiting requests for <code>request.getCacheKey()</code> if
|
* <p>Releases waiting requests for <code>request.getCacheKey()</code> if
|
||||||
* <code>request.shouldCache()</code>.</p>
|
* <code>request.shouldCache()</code>.</p>
|
||||||
*/
|
*/
|
||||||
void finish(Request<?> request) {
|
<T> void finish(Request<T> request) {
|
||||||
// Remove from the set of requests currently being processed.
|
// Remove from the set of requests currently being processed.
|
||||||
synchronized (mCurrentRequests) {
|
synchronized (mCurrentRequests) {
|
||||||
mCurrentRequests.remove(request);
|
mCurrentRequests.remove(request);
|
||||||
}
|
}
|
||||||
|
synchronized (mFinishedListeners) {
|
||||||
|
for (RequestFinishedListener<T> listener : mFinishedListeners) {
|
||||||
|
listener.onRequestFinished(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (request.shouldCache()) {
|
if (request.shouldCache()) {
|
||||||
synchronized (mWaitingRequests) {
|
synchronized (mWaitingRequests) {
|
||||||
@ -283,4 +299,19 @@ public class RequestQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> void addRequestFinishedListener(RequestFinishedListener<T> listener) {
|
||||||
|
synchronized (mFinishedListeners) {
|
||||||
|
mFinishedListeners.add(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a RequestFinishedListener. Has no effect if listener was not previously added.
|
||||||
|
*/
|
||||||
|
public <T> void removeRequestFinishedListener(RequestFinishedListener<T> listener) {
|
||||||
|
synchronized (mFinishedListeners) {
|
||||||
|
mFinishedListeners.remove(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ public class Response<T> {
|
|||||||
/** Callback interface for delivering parsed responses. */
|
/** Callback interface for delivering parsed responses. */
|
||||||
public interface Listener<T> {
|
public interface Listener<T> {
|
||||||
/** Called when a response is received. */
|
/** Called when a response is received. */
|
||||||
void onResponse(T response);
|
public void onResponse(T response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Callback interface for delivering error responses. */
|
/** Callback interface for delivering error responses. */
|
||||||
@ -35,7 +35,7 @@ public class Response<T> {
|
|||||||
* Callback method that an error has been occurred with the
|
* Callback method that an error has been occurred with the
|
||||||
* provided error code and optional user-readable message.
|
* provided error code and optional user-readable message.
|
||||||
*/
|
*/
|
||||||
void onErrorResponse(VolleyError error);
|
public void onErrorResponse(VolleyError error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a successful response containing the parsed result. */
|
/** Returns a successful response containing the parsed result. */
|
||||||
|
@ -20,16 +20,16 @@ public interface ResponseDelivery {
|
|||||||
/**
|
/**
|
||||||
* Parses a response from the network or cache and delivers it.
|
* Parses a response from the network or cache and delivers it.
|
||||||
*/
|
*/
|
||||||
void postResponse(Request<?> request, Response<?> response);
|
public void postResponse(Request<?> request, Response<?> response);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a response from the network or cache and delivers it. The provided
|
* Parses a response from the network or cache and delivers it. The provided
|
||||||
* Runnable will be executed after delivery.
|
* Runnable will be executed after delivery.
|
||||||
*/
|
*/
|
||||||
void postResponse(Request<?> request, Response<?> response, Runnable runnable);
|
public void postResponse(Request<?> request, Response<?> response, Runnable runnable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Posts an error for the given request.
|
* Posts an error for the given request.
|
||||||
*/
|
*/
|
||||||
void postError(Request<?> request, VolleyError error);
|
public void postError(Request<?> request, VolleyError error);
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,12 @@ public interface RetryPolicy {
|
|||||||
/**
|
/**
|
||||||
* Returns the current timeout (used for logging).
|
* Returns the current timeout (used for logging).
|
||||||
*/
|
*/
|
||||||
int getCurrentTimeout();
|
public int getCurrentTimeout();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current retry count (used for logging).
|
* Returns the current retry count (used for logging).
|
||||||
*/
|
*/
|
||||||
int getCurrentRetryCount();
|
public int getCurrentRetryCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares for the next retry by applying a backoff to the timeout.
|
* Prepares for the next retry by applying a backoff to the timeout.
|
||||||
@ -37,5 +37,5 @@ public interface RetryPolicy {
|
|||||||
* @throws VolleyError In the event that the retry could not be performed (for example if we
|
* @throws VolleyError In the event that the retry could not be performed (for example if we
|
||||||
* ran out of attempts), the passed in error is thrown.
|
* ran out of attempts), the passed in error is thrown.
|
||||||
*/
|
*/
|
||||||
void retry(VolleyError error) throws VolleyError;
|
public void retry(VolleyError error) throws VolleyError;
|
||||||
}
|
}
|
||||||
|
@ -29,3 +29,4 @@ public class ServerError extends VolleyError {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
/** Logging helper class. */
|
/**
|
||||||
|
* Logging helper class.
|
||||||
|
* <p/>
|
||||||
|
* to see Volley logs call:<br/>
|
||||||
|
* {@code <android-sdk>/platform-tools/adb shell setprop log.tag.Volley VERBOSE}
|
||||||
|
*/
|
||||||
public class VolleyLog {
|
public class VolleyLog {
|
||||||
public static String TAG = "Volley";
|
public static String TAG = "Volley";
|
||||||
|
|
||||||
@ -89,7 +94,7 @@ public class VolleyLog {
|
|||||||
callingClass = callingClass.substring(callingClass.lastIndexOf('.') + 1);
|
callingClass = callingClass.substring(callingClass.lastIndexOf('.') + 1);
|
||||||
callingClass = callingClass.substring(callingClass.lastIndexOf('$') + 1);
|
callingClass = callingClass.substring(callingClass.lastIndexOf('$') + 1);
|
||||||
|
|
||||||
caller = callingClass + "" + trace[i].getMethodName();
|
caller = callingClass + "." + trace[i].getMethodName();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.telegram.android.volley.toolbox;
|
package org.telegram.android.volley.toolbox;
|
||||||
|
|
||||||
|
import org.telegram.android.volley.AuthFailureError;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
import android.accounts.AccountManagerFuture;
|
import android.accounts.AccountManagerFuture;
|
||||||
@ -23,14 +25,12 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import org.telegram.android.volley.AuthFailureError;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An Authenticator that uses {@link AccountManager} to get auth
|
* An Authenticator that uses {@link AccountManager} to get auth
|
||||||
* tokens of a specified type for a specified account.
|
* tokens of a specified type for a specified account.
|
||||||
*/
|
*/
|
||||||
public class AndroidAuthenticator implements Authenticator {
|
public class AndroidAuthenticator implements Authenticator {
|
||||||
private final Context mContext;
|
private final AccountManager mAccountManager;
|
||||||
private final Account mAccount;
|
private final Account mAccount;
|
||||||
private final String mAuthTokenType;
|
private final String mAuthTokenType;
|
||||||
private final boolean mNotifyAuthFailure;
|
private final boolean mNotifyAuthFailure;
|
||||||
@ -54,7 +54,13 @@ public class AndroidAuthenticator implements Authenticator {
|
|||||||
*/
|
*/
|
||||||
public AndroidAuthenticator(Context context, Account account, String authTokenType,
|
public AndroidAuthenticator(Context context, Account account, String authTokenType,
|
||||||
boolean notifyAuthFailure) {
|
boolean notifyAuthFailure) {
|
||||||
mContext = context;
|
this(AccountManager.get(context), account, authTokenType, notifyAuthFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visible for testing. Allows injection of a mock AccountManager.
|
||||||
|
AndroidAuthenticator(AccountManager accountManager, Account account,
|
||||||
|
String authTokenType, boolean notifyAuthFailure) {
|
||||||
|
mAccountManager = accountManager;
|
||||||
mAccount = account;
|
mAccount = account;
|
||||||
mAuthTokenType = authTokenType;
|
mAuthTokenType = authTokenType;
|
||||||
mNotifyAuthFailure = notifyAuthFailure;
|
mNotifyAuthFailure = notifyAuthFailure;
|
||||||
@ -71,8 +77,7 @@ public class AndroidAuthenticator implements Authenticator {
|
|||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public String getAuthToken() throws AuthFailureError {
|
public String getAuthToken() throws AuthFailureError {
|
||||||
final AccountManager accountManager = AccountManager.get(mContext);
|
AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(mAccount,
|
||||||
AccountManagerFuture<Bundle> future = accountManager.getAuthToken(mAccount,
|
|
||||||
mAuthTokenType, mNotifyAuthFailure, null, null);
|
mAuthTokenType, mNotifyAuthFailure, null, null);
|
||||||
Bundle result;
|
Bundle result;
|
||||||
try {
|
try {
|
||||||
@ -97,6 +102,6 @@ public class AndroidAuthenticator implements Authenticator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateAuthToken(String authToken) {
|
public void invalidateAuthToken(String authToken) {
|
||||||
AccountManager.get(mContext).invalidateAuthToken(mAccount.type, authToken);
|
mAccountManager.invalidateAuthToken(mAccount.type, authToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,10 @@ public interface Authenticator {
|
|||||||
*
|
*
|
||||||
* @throws AuthFailureError If authentication did not succeed
|
* @throws AuthFailureError If authentication did not succeed
|
||||||
*/
|
*/
|
||||||
String getAuthToken() throws AuthFailureError;
|
public String getAuthToken() throws AuthFailureError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidates the provided auth token.
|
* Invalidates the provided auth token.
|
||||||
*/
|
*/
|
||||||
void invalidateAuthToken(String authToken);
|
public void invalidateAuthToken(String authToken);
|
||||||
}
|
}
|
||||||
|
@ -18,15 +18,9 @@ package org.telegram.android.volley.toolbox;
|
|||||||
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
import org.apache.http.Header;
|
|
||||||
import org.apache.http.HttpEntity;
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.HttpStatus;
|
|
||||||
import org.apache.http.StatusLine;
|
|
||||||
import org.apache.http.conn.ConnectTimeoutException;
|
|
||||||
import org.apache.http.impl.cookie.DateUtils;
|
|
||||||
import org.telegram.android.volley.AuthFailureError;
|
import org.telegram.android.volley.AuthFailureError;
|
||||||
import org.telegram.android.volley.Cache;
|
import org.telegram.android.volley.Cache;
|
||||||
|
import org.telegram.android.volley.Cache.Entry;
|
||||||
import org.telegram.android.volley.Network;
|
import org.telegram.android.volley.Network;
|
||||||
import org.telegram.android.volley.NetworkError;
|
import org.telegram.android.volley.NetworkError;
|
||||||
import org.telegram.android.volley.NetworkResponse;
|
import org.telegram.android.volley.NetworkResponse;
|
||||||
@ -38,6 +32,14 @@ import org.telegram.android.volley.TimeoutError;
|
|||||||
import org.telegram.android.volley.VolleyError;
|
import org.telegram.android.volley.VolleyError;
|
||||||
import org.telegram.android.volley.VolleyLog;
|
import org.telegram.android.volley.VolleyLog;
|
||||||
|
|
||||||
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.apache.http.StatusLine;
|
||||||
|
import org.apache.http.conn.ConnectTimeoutException;
|
||||||
|
import org.apache.http.impl.cookie.DateUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
@ -49,14 +51,14 @@ import java.util.Map;
|
|||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A network performing Volley requests over an {@link org.telegram.android.volley.toolbox.HttpStack}.
|
* A network performing Volley requests over an {@link HttpStack}.
|
||||||
*/
|
*/
|
||||||
public class BasicNetwork implements Network {
|
public class BasicNetwork implements Network {
|
||||||
protected static final boolean DEBUG = VolleyLog.DEBUG;
|
protected static final boolean DEBUG = VolleyLog.DEBUG;
|
||||||
|
|
||||||
private static final int SLOW_REQUEST_THRESHOLD_MS = 3000;
|
private static int SLOW_REQUEST_THRESHOLD_MS = 3000;
|
||||||
|
|
||||||
private static final int DEFAULT_POOL_SIZE = 4096;
|
private static int DEFAULT_POOL_SIZE = 4096;
|
||||||
|
|
||||||
protected final HttpStack mHttpStack;
|
protected final HttpStack mHttpStack;
|
||||||
|
|
||||||
@ -99,7 +101,7 @@ public class BasicNetwork implements Network {
|
|||||||
// Handle cache validation.
|
// Handle cache validation.
|
||||||
if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
|
if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
|
||||||
|
|
||||||
Cache.Entry entry = request.getCacheEntry();
|
Entry entry = request.getCacheEntry();
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED, null,
|
return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED, null,
|
||||||
responseHeaders, true,
|
responseHeaders, true,
|
||||||
@ -210,8 +212,8 @@ public class BasicNetwork implements Network {
|
|||||||
headers.put("If-None-Match", entry.etag);
|
headers.put("If-None-Match", entry.etag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.serverDate > 0) {
|
if (entry.lastModified > 0) {
|
||||||
Date refTime = new Date(entry.serverDate);
|
Date refTime = new Date(entry.lastModified);
|
||||||
headers.put("If-Modified-Since", DateUtils.formatDate(refTime));
|
headers.put("If-Modified-Since", DateUtils.formatDate(refTime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,8 +258,8 @@ public class BasicNetwork implements Network {
|
|||||||
*/
|
*/
|
||||||
protected static Map<String, String> convertHeaders(Header[] headers) {
|
protected static Map<String, String> convertHeaders(Header[] headers) {
|
||||||
Map<String, String> result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
Map<String, String> result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
||||||
for (Header header : headers) {
|
for (int i = 0; i < headers.length; i++) {
|
||||||
result.put(header.getName(), header.getValue());
|
result.put(headers[i].getName(), headers[i].getValue());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
package org.telegram.android.volley.toolbox;
|
package org.telegram.android.volley.toolbox;
|
||||||
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
|
|
||||||
import org.telegram.android.volley.Cache;
|
import org.telegram.android.volley.Cache;
|
||||||
import org.telegram.android.volley.NetworkResponse;
|
import org.telegram.android.volley.NetworkResponse;
|
||||||
import org.telegram.android.volley.Request;
|
import org.telegram.android.volley.Request;
|
||||||
import org.telegram.android.volley.Response;
|
import org.telegram.android.volley.Response;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A synthetic request used for clearing the cache.
|
* A synthetic request used for clearing the cache.
|
||||||
*/
|
*/
|
||||||
|
@ -22,6 +22,7 @@ import org.telegram.android.volley.Cache;
|
|||||||
import org.telegram.android.volley.VolleyLog;
|
import org.telegram.android.volley.VolleyLog;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -42,46 +43,31 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class DiskBasedCache implements Cache {
|
public class DiskBasedCache implements Cache {
|
||||||
|
|
||||||
/**
|
/** Map of the Key, CacheHeader pairs */
|
||||||
* Map of the Key, CacheHeader pairs
|
|
||||||
*/
|
|
||||||
private final Map<String, CacheHeader> mEntries =
|
private final Map<String, CacheHeader> mEntries =
|
||||||
new LinkedHashMap<String, CacheHeader>(16, .75f, true);
|
new LinkedHashMap<String, CacheHeader>(16, .75f, true);
|
||||||
|
|
||||||
/**
|
/** Total amount of space currently used by the cache in bytes. */
|
||||||
* Total amount of space currently used by the cache in bytes.
|
|
||||||
*/
|
|
||||||
private long mTotalSize = 0;
|
private long mTotalSize = 0;
|
||||||
|
|
||||||
/**
|
/** The root directory to use for the cache. */
|
||||||
* The root directory to use for the cache.
|
|
||||||
*/
|
|
||||||
private final File mRootDirectory;
|
private final File mRootDirectory;
|
||||||
|
|
||||||
/**
|
/** The maximum size of the cache in bytes. */
|
||||||
* The maximum size of the cache in bytes.
|
|
||||||
*/
|
|
||||||
private final int mMaxCacheSizeInBytes;
|
private final int mMaxCacheSizeInBytes;
|
||||||
|
|
||||||
/**
|
/** Default maximum disk usage in bytes. */
|
||||||
* Default maximum disk usage in bytes.
|
|
||||||
*/
|
|
||||||
private static final int DEFAULT_DISK_USAGE_BYTES = 5 * 1024 * 1024;
|
private static final int DEFAULT_DISK_USAGE_BYTES = 5 * 1024 * 1024;
|
||||||
|
|
||||||
/**
|
/** High water mark percentage for the cache */
|
||||||
* High water mark percentage for the cache
|
|
||||||
*/
|
|
||||||
private static final float HYSTERESIS_FACTOR = 0.9f;
|
private static final float HYSTERESIS_FACTOR = 0.9f;
|
||||||
|
|
||||||
/**
|
/** Magic number for current version of cache file format. */
|
||||||
* Magic number for current version of cache file format.
|
private static final int CACHE_MAGIC = 0x20150306;
|
||||||
*/
|
|
||||||
private static final int CACHE_MAGIC = 0x20140623;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance of the DiskBasedCache at the specified directory.
|
* Constructs an instance of the DiskBasedCache at the specified directory.
|
||||||
*
|
* @param rootDirectory The root directory of the cache.
|
||||||
* @param rootDirectory The root directory of the cache.
|
|
||||||
* @param maxCacheSizeInBytes The maximum size of the cache in bytes.
|
* @param maxCacheSizeInBytes The maximum size of the cache in bytes.
|
||||||
*/
|
*/
|
||||||
public DiskBasedCache(File rootDirectory, int maxCacheSizeInBytes) {
|
public DiskBasedCache(File rootDirectory, int maxCacheSizeInBytes) {
|
||||||
@ -92,7 +78,6 @@ public class DiskBasedCache implements Cache {
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance of the DiskBasedCache at the specified directory using
|
* Constructs an instance of the DiskBasedCache at the specified directory using
|
||||||
* the default maximum cache size of 5MB.
|
* the default maximum cache size of 5MB.
|
||||||
*
|
|
||||||
* @param rootDirectory The root directory of the cache.
|
* @param rootDirectory The root directory of the cache.
|
||||||
*/
|
*/
|
||||||
public DiskBasedCache(File rootDirectory) {
|
public DiskBasedCache(File rootDirectory) {
|
||||||
@ -129,7 +114,7 @@ public class DiskBasedCache implements Cache {
|
|||||||
File file = getFileForKey(key);
|
File file = getFileForKey(key);
|
||||||
CountingInputStream cis = null;
|
CountingInputStream cis = null;
|
||||||
try {
|
try {
|
||||||
cis = new CountingInputStream(new FileInputStream(file));
|
cis = new CountingInputStream(new BufferedInputStream(new FileInputStream(file)));
|
||||||
CacheHeader.readHeader(cis); // eat header
|
CacheHeader.readHeader(cis); // eat header
|
||||||
byte[] data = streamToBytes(cis, (int) (file.length() - cis.bytesRead));
|
byte[] data = streamToBytes(cis, (int) (file.length() - cis.bytesRead));
|
||||||
return entry.toCacheEntry(data);
|
return entry.toCacheEntry(data);
|
||||||
@ -174,23 +159,21 @@ public class DiskBasedCache implements Cache {
|
|||||||
putEntry(entry.key, entry);
|
putEntry(entry.key, entry);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
if (fis != null) {
|
if (fis != null) {
|
||||||
fis.close();
|
fis.close();
|
||||||
}
|
}
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) { }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidates an entry in the cache.
|
* Invalidates an entry in the cache.
|
||||||
*
|
* @param key Cache key
|
||||||
* @param key Cache key
|
|
||||||
* @param fullExpire True to fully expire the entry, false to soft expire
|
* @param fullExpire True to fully expire the entry, false to soft expire
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ -214,7 +197,7 @@ public class DiskBasedCache implements Cache {
|
|||||||
pruneIfNeeded(entry.data.length);
|
pruneIfNeeded(entry.data.length);
|
||||||
File file = getFileForKey(key);
|
File file = getFileForKey(key);
|
||||||
try {
|
try {
|
||||||
FileOutputStream fos = new FileOutputStream(file);
|
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(file));
|
||||||
CacheHeader e = new CacheHeader(key, entry);
|
CacheHeader e = new CacheHeader(key, entry);
|
||||||
boolean success = e.writeHeader(fos);
|
boolean success = e.writeHeader(fos);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
@ -227,7 +210,6 @@ public class DiskBasedCache implements Cache {
|
|||||||
putEntry(key, e);
|
putEntry(key, e);
|
||||||
return;
|
return;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
/**/
|
|
||||||
}
|
}
|
||||||
boolean deleted = file.delete();
|
boolean deleted = file.delete();
|
||||||
if (!deleted) {
|
if (!deleted) {
|
||||||
@ -250,7 +232,6 @@ public class DiskBasedCache implements Cache {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a pseudo-unique filename for the specified cache key.
|
* Creates a pseudo-unique filename for the specified cache key.
|
||||||
*
|
|
||||||
* @param key The key to generate a file name for.
|
* @param key The key to generate a file name for.
|
||||||
* @return A pseudo-unique filename.
|
* @return A pseudo-unique filename.
|
||||||
*/
|
*/
|
||||||
@ -270,7 +251,6 @@ public class DiskBasedCache implements Cache {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Prunes the cache to fit the amount of bytes specified.
|
* Prunes the cache to fit the amount of bytes specified.
|
||||||
*
|
|
||||||
* @param neededSpace The amount of bytes we are trying to fit into the cache.
|
* @param neededSpace The amount of bytes we are trying to fit into the cache.
|
||||||
*/
|
*/
|
||||||
private void pruneIfNeeded(int neededSpace) {
|
private void pruneIfNeeded(int neededSpace) {
|
||||||
@ -293,8 +273,8 @@ public class DiskBasedCache implements Cache {
|
|||||||
if (deleted) {
|
if (deleted) {
|
||||||
mTotalSize -= e.size;
|
mTotalSize -= e.size;
|
||||||
} else {
|
} else {
|
||||||
VolleyLog.d("Could not delete cache entry for key=%s, filename=%s",
|
VolleyLog.d("Could not delete cache entry for key=%s, filename=%s",
|
||||||
e.key, getFilenameForKey(e.key));
|
e.key, getFilenameForKey(e.key));
|
||||||
}
|
}
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
prunedFiles++;
|
prunedFiles++;
|
||||||
@ -312,8 +292,7 @@ public class DiskBasedCache implements Cache {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Puts the entry with the specified key into the cache.
|
* Puts the entry with the specified key into the cache.
|
||||||
*
|
* @param key The key to identify the entry by.
|
||||||
* @param key The key to identify the entry by.
|
|
||||||
* @param entry The entry to cache.
|
* @param entry The entry to cache.
|
||||||
*/
|
*/
|
||||||
private void putEntry(String key, CacheHeader entry) {
|
private void putEntry(String key, CacheHeader entry) {
|
||||||
@ -339,7 +318,7 @@ public class DiskBasedCache implements Cache {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the contents of an InputStream into a byte[].
|
* Reads the contents of an InputStream into a byte[].
|
||||||
*/
|
* */
|
||||||
private static byte[] streamToBytes(InputStream in, int length) throws IOException {
|
private static byte[] streamToBytes(InputStream in, int length) throws IOException {
|
||||||
byte[] bytes = new byte[length];
|
byte[] bytes = new byte[length];
|
||||||
int count;
|
int count;
|
||||||
@ -358,49 +337,36 @@ public class DiskBasedCache implements Cache {
|
|||||||
*/
|
*/
|
||||||
// Visible for testing.
|
// Visible for testing.
|
||||||
static class CacheHeader {
|
static class CacheHeader {
|
||||||
/**
|
/** The size of the data identified by this CacheHeader. (This is not
|
||||||
* The size of the data identified by this CacheHeader. (This is not
|
* serialized to disk. */
|
||||||
* serialized to disk.
|
|
||||||
*/
|
|
||||||
public long size;
|
public long size;
|
||||||
|
|
||||||
/**
|
/** The key that identifies the cache entry. */
|
||||||
* The key that identifies the cache entry.
|
|
||||||
*/
|
|
||||||
public String key;
|
public String key;
|
||||||
|
|
||||||
/**
|
/** ETag for cache coherence. */
|
||||||
* ETag for cache coherence.
|
|
||||||
*/
|
|
||||||
public String etag;
|
public String etag;
|
||||||
|
|
||||||
/**
|
/** Date of this response as reported by the server. */
|
||||||
* Date of this response as reported by the server.
|
|
||||||
*/
|
|
||||||
public long serverDate;
|
public long serverDate;
|
||||||
|
|
||||||
/**
|
/** The last modified date for the requested object. */
|
||||||
* TTL for this record.
|
public long lastModified;
|
||||||
*/
|
|
||||||
|
/** TTL for this record. */
|
||||||
public long ttl;
|
public long ttl;
|
||||||
|
|
||||||
/**
|
/** Soft TTL for this record. */
|
||||||
* Soft TTL for this record.
|
|
||||||
*/
|
|
||||||
public long softTtl;
|
public long softTtl;
|
||||||
|
|
||||||
/**
|
/** Headers from the response resulting in this cache entry. */
|
||||||
* Headers from the response resulting in this cache entry.
|
|
||||||
*/
|
|
||||||
public Map<String, String> responseHeaders;
|
public Map<String, String> responseHeaders;
|
||||||
|
|
||||||
private CacheHeader() {
|
private CacheHeader() { }
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new CacheHeader object
|
* Instantiates a new CacheHeader object
|
||||||
*
|
* @param key The key that identifies the cache entry
|
||||||
* @param key The key that identifies the cache entry
|
|
||||||
* @param entry The cache entry.
|
* @param entry The cache entry.
|
||||||
*/
|
*/
|
||||||
public CacheHeader(String key, Entry entry) {
|
public CacheHeader(String key, Entry entry) {
|
||||||
@ -408,6 +374,7 @@ public class DiskBasedCache implements Cache {
|
|||||||
this.size = entry.data.length;
|
this.size = entry.data.length;
|
||||||
this.etag = entry.etag;
|
this.etag = entry.etag;
|
||||||
this.serverDate = entry.serverDate;
|
this.serverDate = entry.serverDate;
|
||||||
|
this.lastModified = entry.lastModified;
|
||||||
this.ttl = entry.ttl;
|
this.ttl = entry.ttl;
|
||||||
this.softTtl = entry.softTtl;
|
this.softTtl = entry.softTtl;
|
||||||
this.responseHeaders = entry.responseHeaders;
|
this.responseHeaders = entry.responseHeaders;
|
||||||
@ -415,7 +382,6 @@ public class DiskBasedCache implements Cache {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the header off of an InputStream and returns a CacheHeader object.
|
* Reads the header off of an InputStream and returns a CacheHeader object.
|
||||||
*
|
|
||||||
* @param is The InputStream to read from.
|
* @param is The InputStream to read from.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@ -432,9 +398,11 @@ public class DiskBasedCache implements Cache {
|
|||||||
entry.etag = null;
|
entry.etag = null;
|
||||||
}
|
}
|
||||||
entry.serverDate = readLong(is);
|
entry.serverDate = readLong(is);
|
||||||
|
entry.lastModified = readLong(is);
|
||||||
entry.ttl = readLong(is);
|
entry.ttl = readLong(is);
|
||||||
entry.softTtl = readLong(is);
|
entry.softTtl = readLong(is);
|
||||||
entry.responseHeaders = readStringStringMap(is);
|
entry.responseHeaders = readStringStringMap(is);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,6 +414,7 @@ public class DiskBasedCache implements Cache {
|
|||||||
e.data = data;
|
e.data = data;
|
||||||
e.etag = etag;
|
e.etag = etag;
|
||||||
e.serverDate = serverDate;
|
e.serverDate = serverDate;
|
||||||
|
e.lastModified = lastModified;
|
||||||
e.ttl = ttl;
|
e.ttl = ttl;
|
||||||
e.softTtl = softTtl;
|
e.softTtl = softTtl;
|
||||||
e.responseHeaders = responseHeaders;
|
e.responseHeaders = responseHeaders;
|
||||||
@ -462,6 +431,7 @@ public class DiskBasedCache implements Cache {
|
|||||||
writeString(os, key);
|
writeString(os, key);
|
||||||
writeString(os, etag == null ? "" : etag);
|
writeString(os, etag == null ? "" : etag);
|
||||||
writeLong(os, serverDate);
|
writeLong(os, serverDate);
|
||||||
|
writeLong(os, lastModified);
|
||||||
writeLong(os, ttl);
|
writeLong(os, ttl);
|
||||||
writeLong(os, softTtl);
|
writeLong(os, softTtl);
|
||||||
writeStringStringMap(responseHeaders, os);
|
writeStringStringMap(responseHeaders, os);
|
||||||
@ -537,14 +507,14 @@ public class DiskBasedCache implements Cache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void writeLong(OutputStream os, long n) throws IOException {
|
static void writeLong(OutputStream os, long n) throws IOException {
|
||||||
os.write((byte) (n >>> 0));
|
os.write((byte)(n >>> 0));
|
||||||
os.write((byte) (n >>> 8));
|
os.write((byte)(n >>> 8));
|
||||||
os.write((byte) (n >>> 16));
|
os.write((byte)(n >>> 16));
|
||||||
os.write((byte) (n >>> 24));
|
os.write((byte)(n >>> 24));
|
||||||
os.write((byte) (n >>> 32));
|
os.write((byte)(n >>> 32));
|
||||||
os.write((byte) (n >>> 40));
|
os.write((byte)(n >>> 40));
|
||||||
os.write((byte) (n >>> 48));
|
os.write((byte)(n >>> 48));
|
||||||
os.write((byte) (n >>> 56));
|
os.write((byte)(n >>> 56));
|
||||||
}
|
}
|
||||||
|
|
||||||
static long readLong(InputStream is) throws IOException {
|
static long readLong(InputStream is) throws IOException {
|
||||||
@ -596,4 +566,6 @@ public class DiskBasedCache implements Cache {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
package org.telegram.android.volley.toolbox;
|
package org.telegram.android.volley.toolbox;
|
||||||
|
|
||||||
|
import org.telegram.android.volley.AuthFailureError;
|
||||||
|
import org.telegram.android.volley.Request;
|
||||||
|
import org.telegram.android.volley.Request.Method;
|
||||||
|
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
@ -33,8 +37,6 @@ import org.apache.http.entity.ByteArrayEntity;
|
|||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
import org.apache.http.params.HttpConnectionParams;
|
import org.apache.http.params.HttpConnectionParams;
|
||||||
import org.apache.http.params.HttpParams;
|
import org.apache.http.params.HttpParams;
|
||||||
import org.telegram.android.volley.AuthFailureError;
|
|
||||||
import org.telegram.android.volley.Request;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -92,7 +94,7 @@ public class HttpClientStack implements HttpStack {
|
|||||||
/* protected */ static HttpUriRequest createHttpRequest(Request<?> request,
|
/* protected */ static HttpUriRequest createHttpRequest(Request<?> request,
|
||||||
Map<String, String> additionalHeaders) throws AuthFailureError {
|
Map<String, String> additionalHeaders) throws AuthFailureError {
|
||||||
switch (request.getMethod()) {
|
switch (request.getMethod()) {
|
||||||
case Request.Method.DEPRECATED_GET_OR_POST: {
|
case Method.DEPRECATED_GET_OR_POST: {
|
||||||
// This is the deprecated way that needs to be handled for backwards compatibility.
|
// This is the deprecated way that needs to be handled for backwards compatibility.
|
||||||
// If the request's post body is null, then the assumption is that the request is
|
// If the request's post body is null, then the assumption is that the request is
|
||||||
// GET. Otherwise, it is assumed that the request is a POST.
|
// GET. Otherwise, it is assumed that the request is a POST.
|
||||||
@ -108,29 +110,29 @@ public class HttpClientStack implements HttpStack {
|
|||||||
return new HttpGet(request.getUrl());
|
return new HttpGet(request.getUrl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case Request.Method.GET:
|
case Method.GET:
|
||||||
return new HttpGet(request.getUrl());
|
return new HttpGet(request.getUrl());
|
||||||
case Request.Method.DELETE:
|
case Method.DELETE:
|
||||||
return new HttpDelete(request.getUrl());
|
return new HttpDelete(request.getUrl());
|
||||||
case Request.Method.POST: {
|
case Method.POST: {
|
||||||
HttpPost postRequest = new HttpPost(request.getUrl());
|
HttpPost postRequest = new HttpPost(request.getUrl());
|
||||||
postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
|
postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
|
||||||
setEntityIfNonEmptyBody(postRequest, request);
|
setEntityIfNonEmptyBody(postRequest, request);
|
||||||
return postRequest;
|
return postRequest;
|
||||||
}
|
}
|
||||||
case Request.Method.PUT: {
|
case Method.PUT: {
|
||||||
HttpPut putRequest = new HttpPut(request.getUrl());
|
HttpPut putRequest = new HttpPut(request.getUrl());
|
||||||
putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
|
putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
|
||||||
setEntityIfNonEmptyBody(putRequest, request);
|
setEntityIfNonEmptyBody(putRequest, request);
|
||||||
return putRequest;
|
return putRequest;
|
||||||
}
|
}
|
||||||
case Request.Method.HEAD:
|
case Method.HEAD:
|
||||||
return new HttpHead(request.getUrl());
|
return new HttpHead(request.getUrl());
|
||||||
case Request.Method.OPTIONS:
|
case Method.OPTIONS:
|
||||||
return new HttpOptions(request.getUrl());
|
return new HttpOptions(request.getUrl());
|
||||||
case Request.Method.TRACE:
|
case Method.TRACE:
|
||||||
return new HttpTrace(request.getUrl());
|
return new HttpTrace(request.getUrl());
|
||||||
case Request.Method.PATCH: {
|
case Method.PATCH: {
|
||||||
HttpPatch patchRequest = new HttpPatch(request.getUrl());
|
HttpPatch patchRequest = new HttpPatch(request.getUrl());
|
||||||
patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
|
patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
|
||||||
setEntityIfNonEmptyBody(patchRequest, request);
|
setEntityIfNonEmptyBody(patchRequest, request);
|
||||||
|
@ -16,11 +16,12 @@
|
|||||||
|
|
||||||
package org.telegram.android.volley.toolbox;
|
package org.telegram.android.volley.toolbox;
|
||||||
|
|
||||||
|
import org.telegram.android.volley.Cache;
|
||||||
|
import org.telegram.android.volley.NetworkResponse;
|
||||||
|
|
||||||
import org.apache.http.impl.cookie.DateParseException;
|
import org.apache.http.impl.cookie.DateParseException;
|
||||||
import org.apache.http.impl.cookie.DateUtils;
|
import org.apache.http.impl.cookie.DateUtils;
|
||||||
import org.apache.http.protocol.HTTP;
|
import org.apache.http.protocol.HTTP;
|
||||||
import org.telegram.android.volley.Cache;
|
|
||||||
import org.telegram.android.volley.NetworkResponse;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -41,10 +42,14 @@ public class HttpHeaderParser {
|
|||||||
Map<String, String> headers = response.headers;
|
Map<String, String> headers = response.headers;
|
||||||
|
|
||||||
long serverDate = 0;
|
long serverDate = 0;
|
||||||
|
long lastModified = 0;
|
||||||
long serverExpires = 0;
|
long serverExpires = 0;
|
||||||
long softExpire = 0;
|
long softExpire = 0;
|
||||||
|
long finalExpire = 0;
|
||||||
long maxAge = 0;
|
long maxAge = 0;
|
||||||
|
long staleWhileRevalidate = 0;
|
||||||
boolean hasCacheControl = false;
|
boolean hasCacheControl = false;
|
||||||
|
boolean mustRevalidate = false;
|
||||||
|
|
||||||
String serverEtag = null;
|
String serverEtag = null;
|
||||||
String headerValue;
|
String headerValue;
|
||||||
@ -58,18 +63,22 @@ public class HttpHeaderParser {
|
|||||||
if (headerValue != null) {
|
if (headerValue != null) {
|
||||||
hasCacheControl = true;
|
hasCacheControl = true;
|
||||||
String[] tokens = headerValue.split(",");
|
String[] tokens = headerValue.split(",");
|
||||||
for (String token1 : tokens) {
|
for (int i = 0; i < tokens.length; i++) {
|
||||||
String token = token1.trim();
|
String token = tokens[i].trim();
|
||||||
if (token.equals("no-cache") || token.equals("no-store")) {
|
if (token.equals("no-cache") || token.equals("no-store")) {
|
||||||
return null;
|
return null;
|
||||||
} else if (token.startsWith("max-age=")) {
|
} else if (token.startsWith("max-age=")) {
|
||||||
try {
|
try {
|
||||||
maxAge = Long.parseLong(token.substring(8));
|
maxAge = Long.parseLong(token.substring(8));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
/**/
|
}
|
||||||
|
} else if (token.startsWith("stale-while-revalidate=")) {
|
||||||
|
try {
|
||||||
|
staleWhileRevalidate = Long.parseLong(token.substring(23));
|
||||||
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
} else if (token.equals("must-revalidate") || token.equals("proxy-revalidate")) {
|
} else if (token.equals("must-revalidate") || token.equals("proxy-revalidate")) {
|
||||||
maxAge = 0;
|
mustRevalidate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,23 +88,33 @@ public class HttpHeaderParser {
|
|||||||
serverExpires = parseDateAsEpoch(headerValue);
|
serverExpires = parseDateAsEpoch(headerValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
headerValue = headers.get("Last-Modified");
|
||||||
|
if (headerValue != null) {
|
||||||
|
lastModified = parseDateAsEpoch(headerValue);
|
||||||
|
}
|
||||||
|
|
||||||
serverEtag = headers.get("ETag");
|
serverEtag = headers.get("ETag");
|
||||||
|
|
||||||
// Cache-Control takes precedence over an Expires header, even if both exist and Expires
|
// Cache-Control takes precedence over an Expires header, even if both exist and Expires
|
||||||
// is more restrictive.
|
// is more restrictive.
|
||||||
if (hasCacheControl) {
|
if (hasCacheControl) {
|
||||||
softExpire = now + maxAge * 1000;
|
softExpire = now + maxAge * 1000;
|
||||||
|
finalExpire = mustRevalidate
|
||||||
|
? softExpire
|
||||||
|
: softExpire + staleWhileRevalidate * 1000;
|
||||||
} else if (serverDate > 0 && serverExpires >= serverDate) {
|
} else if (serverDate > 0 && serverExpires >= serverDate) {
|
||||||
// Default semantic for Expire header in HTTP specification is softExpire.
|
// Default semantic for Expire header in HTTP specification is softExpire.
|
||||||
softExpire = now + (serverExpires - serverDate);
|
softExpire = now + (serverExpires - serverDate);
|
||||||
|
finalExpire = softExpire;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache.Entry entry = new Cache.Entry();
|
Cache.Entry entry = new Cache.Entry();
|
||||||
entry.data = response.data;
|
entry.data = response.data;
|
||||||
entry.etag = serverEtag;
|
entry.etag = serverEtag;
|
||||||
entry.softTtl = softExpire;
|
entry.softTtl = softExpire;
|
||||||
entry.ttl = entry.softTtl;
|
entry.ttl = finalExpire;
|
||||||
entry.serverDate = serverDate;
|
entry.serverDate = serverDate;
|
||||||
|
entry.lastModified = lastModified;
|
||||||
entry.responseHeaders = headers;
|
entry.responseHeaders = headers;
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
@ -115,10 +134,14 @@ public class HttpHeaderParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the charset specified in the Content-Type of this header,
|
* Retrieve a charset from headers
|
||||||
* or the HTTP default (ISO-8859-1) if none can be found.
|
*
|
||||||
|
* @param headers An {@link java.util.Map} of headers
|
||||||
|
* @param defaultCharset Charset to return if none can be found
|
||||||
|
* @return Returns the charset specified in the Content-Type of this header,
|
||||||
|
* or the defaultCharset if none can be found.
|
||||||
*/
|
*/
|
||||||
public static String parseCharset(Map<String, String> headers) {
|
public static String parseCharset(Map<String, String> headers, String defaultCharset) {
|
||||||
String contentType = headers.get(HTTP.CONTENT_TYPE);
|
String contentType = headers.get(HTTP.CONTENT_TYPE);
|
||||||
if (contentType != null) {
|
if (contentType != null) {
|
||||||
String[] params = contentType.split(";");
|
String[] params = contentType.split(";");
|
||||||
@ -132,6 +155,14 @@ public class HttpHeaderParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return HTTP.DEFAULT_CONTENT_CHARSET;
|
return defaultCharset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the charset specified in the Content-Type of this header,
|
||||||
|
* or the HTTP default (ISO-8859-1) if none can be found.
|
||||||
|
*/
|
||||||
|
public static String parseCharset(Map<String, String> headers) {
|
||||||
|
return parseCharset(headers, HTTP.DEFAULT_CONTENT_CHARSET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,11 @@
|
|||||||
|
|
||||||
package org.telegram.android.volley.toolbox;
|
package org.telegram.android.volley.toolbox;
|
||||||
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.telegram.android.volley.AuthFailureError;
|
import org.telegram.android.volley.AuthFailureError;
|
||||||
import org.telegram.android.volley.Request;
|
import org.telegram.android.volley.Request;
|
||||||
|
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ public interface HttpStack {
|
|||||||
* {@link Request#getHeaders()}
|
* {@link Request#getHeaders()}
|
||||||
* @return the HTTP response
|
* @return the HTTP response
|
||||||
*/
|
*/
|
||||||
HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
|
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
|
||||||
throws IOException, AuthFailureError;
|
throws IOException, AuthFailureError;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,17 +16,20 @@
|
|||||||
|
|
||||||
package org.telegram.android.volley.toolbox;
|
package org.telegram.android.volley.toolbox;
|
||||||
|
|
||||||
|
import org.telegram.android.volley.AuthFailureError;
|
||||||
|
import org.telegram.android.volley.Request;
|
||||||
|
import org.telegram.android.volley.Request.Method;
|
||||||
|
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
import org.apache.http.ProtocolVersion;
|
import org.apache.http.ProtocolVersion;
|
||||||
import org.apache.http.StatusLine;
|
import org.apache.http.StatusLine;
|
||||||
import org.apache.http.entity.BasicHttpEntity;
|
import org.apache.http.entity.BasicHttpEntity;
|
||||||
import org.apache.http.message.BasicHeader;
|
import org.apache.http.message.BasicHeader;
|
||||||
import org.apache.http.message.BasicHttpResponse;
|
import org.apache.http.message.BasicHttpResponse;
|
||||||
import org.apache.http.message.BasicStatusLine;
|
import org.apache.http.message.BasicStatusLine;
|
||||||
import org.telegram.android.volley.AuthFailureError;
|
|
||||||
import org.telegram.android.volley.Request;
|
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -42,7 +45,7 @@ import javax.net.ssl.HttpsURLConnection;
|
|||||||
import javax.net.ssl.SSLSocketFactory;
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link org.telegram.android.volley.toolbox.HttpStack} based on {@link HttpURLConnection}.
|
* An {@link HttpStack} based on {@link HttpURLConnection}.
|
||||||
*/
|
*/
|
||||||
public class HurlStack implements HttpStack {
|
public class HurlStack implements HttpStack {
|
||||||
|
|
||||||
@ -56,7 +59,7 @@ public class HurlStack implements HttpStack {
|
|||||||
* Returns a URL to use instead of the provided one, or null to indicate
|
* Returns a URL to use instead of the provided one, or null to indicate
|
||||||
* this URL should not be used at all.
|
* this URL should not be used at all.
|
||||||
*/
|
*/
|
||||||
String rewriteUrl(String originalUrl);
|
public String rewriteUrl(String originalUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final UrlRewriter mUrlRewriter;
|
private final UrlRewriter mUrlRewriter;
|
||||||
@ -113,7 +116,9 @@ public class HurlStack implements HttpStack {
|
|||||||
StatusLine responseStatus = new BasicStatusLine(protocolVersion,
|
StatusLine responseStatus = new BasicStatusLine(protocolVersion,
|
||||||
connection.getResponseCode(), connection.getResponseMessage());
|
connection.getResponseCode(), connection.getResponseMessage());
|
||||||
BasicHttpResponse response = new BasicHttpResponse(responseStatus);
|
BasicHttpResponse response = new BasicHttpResponse(responseStatus);
|
||||||
response.setEntity(entityFromConnection(connection));
|
if (hasResponseBody(request.getMethod(), responseStatus.getStatusCode())) {
|
||||||
|
response.setEntity(entityFromConnection(connection));
|
||||||
|
}
|
||||||
for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
|
for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
|
||||||
if (header.getKey() != null) {
|
if (header.getKey() != null) {
|
||||||
Header h = new BasicHeader(header.getKey(), header.getValue().get(0));
|
Header h = new BasicHeader(header.getKey(), header.getValue().get(0));
|
||||||
@ -123,6 +128,20 @@ public class HurlStack implements HttpStack {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a response message contains a body.
|
||||||
|
* @see <a href="https://tools.ietf.org/html/rfc7230#section-3.3">RFC 7230 section 3.3</a>
|
||||||
|
* @param requestMethod request method
|
||||||
|
* @param responseCode response status code
|
||||||
|
* @return whether the response has a body
|
||||||
|
*/
|
||||||
|
private static boolean hasResponseBody(int requestMethod, int responseCode) {
|
||||||
|
return requestMethod != Request.Method.HEAD
|
||||||
|
&& !(HttpStatus.SC_CONTINUE <= responseCode && responseCode < HttpStatus.SC_OK)
|
||||||
|
&& responseCode != HttpStatus.SC_NO_CONTENT
|
||||||
|
&& responseCode != HttpStatus.SC_NOT_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an {@link HttpEntity} from the given {@link HttpURLConnection}.
|
* Initializes an {@link HttpEntity} from the given {@link HttpURLConnection}.
|
||||||
* @param connection
|
* @param connection
|
||||||
@ -177,7 +196,7 @@ public class HurlStack implements HttpStack {
|
|||||||
/* package */ static void setConnectionParametersForRequest(HttpURLConnection connection,
|
/* package */ static void setConnectionParametersForRequest(HttpURLConnection connection,
|
||||||
Request<?> request) throws IOException, AuthFailureError {
|
Request<?> request) throws IOException, AuthFailureError {
|
||||||
switch (request.getMethod()) {
|
switch (request.getMethod()) {
|
||||||
case Request.Method.DEPRECATED_GET_OR_POST:
|
case Method.DEPRECATED_GET_OR_POST:
|
||||||
// This is the deprecated way that needs to be handled for backwards compatibility.
|
// This is the deprecated way that needs to be handled for backwards compatibility.
|
||||||
// If the request's post body is null, then the assumption is that the request is
|
// If the request's post body is null, then the assumption is that the request is
|
||||||
// GET. Otherwise, it is assumed that the request is a POST.
|
// GET. Otherwise, it is assumed that the request is a POST.
|
||||||
@ -195,32 +214,32 @@ public class HurlStack implements HttpStack {
|
|||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Request.Method.GET:
|
case Method.GET:
|
||||||
// Not necessary to set the request method because connection defaults to GET but
|
// Not necessary to set the request method because connection defaults to GET but
|
||||||
// being explicit here.
|
// being explicit here.
|
||||||
connection.setRequestMethod("GET");
|
connection.setRequestMethod("GET");
|
||||||
break;
|
break;
|
||||||
case Request.Method.DELETE:
|
case Method.DELETE:
|
||||||
connection.setRequestMethod("DELETE");
|
connection.setRequestMethod("DELETE");
|
||||||
break;
|
break;
|
||||||
case Request.Method.POST:
|
case Method.POST:
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
addBodyIfExists(connection, request);
|
addBodyIfExists(connection, request);
|
||||||
break;
|
break;
|
||||||
case Request.Method.PUT:
|
case Method.PUT:
|
||||||
connection.setRequestMethod("PUT");
|
connection.setRequestMethod("PUT");
|
||||||
addBodyIfExists(connection, request);
|
addBodyIfExists(connection, request);
|
||||||
break;
|
break;
|
||||||
case Request.Method.HEAD:
|
case Method.HEAD:
|
||||||
connection.setRequestMethod("HEAD");
|
connection.setRequestMethod("HEAD");
|
||||||
break;
|
break;
|
||||||
case Request.Method.OPTIONS:
|
case Method.OPTIONS:
|
||||||
connection.setRequestMethod("OPTIONS");
|
connection.setRequestMethod("OPTIONS");
|
||||||
break;
|
break;
|
||||||
case Request.Method.TRACE:
|
case Method.TRACE:
|
||||||
connection.setRequestMethod("TRACE");
|
connection.setRequestMethod("TRACE");
|
||||||
break;
|
break;
|
||||||
case Request.Method.PATCH:
|
case Method.PATCH:
|
||||||
connection.setRequestMethod("PATCH");
|
connection.setRequestMethod("PATCH");
|
||||||
addBodyIfExists(connection, request);
|
addBodyIfExists(connection, request);
|
||||||
break;
|
break;
|
||||||
|
@ -20,10 +20,11 @@ import android.graphics.Bitmap.Config;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ImageView.ScaleType;
|
||||||
import org.telegram.android.volley.Request;
|
import org.telegram.android.volley.Request;
|
||||||
import org.telegram.android.volley.RequestQueue;
|
import org.telegram.android.volley.RequestQueue;
|
||||||
import org.telegram.android.volley.Response;
|
import org.telegram.android.volley.Response.ErrorListener;
|
||||||
|
import org.telegram.android.volley.Response.Listener;
|
||||||
import org.telegram.android.volley.VolleyError;
|
import org.telegram.android.volley.VolleyError;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -71,8 +72,8 @@ public class ImageLoader {
|
|||||||
* must not block. Implementation with an LruCache is recommended.
|
* must not block. Implementation with an LruCache is recommended.
|
||||||
*/
|
*/
|
||||||
public interface ImageCache {
|
public interface ImageCache {
|
||||||
Bitmap getBitmap(String url);
|
public Bitmap getBitmap(String url);
|
||||||
void putBitmap(String url, Bitmap bitmap);
|
public void putBitmap(String url, Bitmap bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,7 +128,7 @@ public class ImageLoader {
|
|||||||
* or
|
* or
|
||||||
* - onErrorResponse will be called if there was an error loading the image.
|
* - onErrorResponse will be called if there was an error loading the image.
|
||||||
*/
|
*/
|
||||||
public interface ImageListener extends Response.ErrorListener {
|
public interface ImageListener extends ErrorListener {
|
||||||
/**
|
/**
|
||||||
* Listens for non-error changes to the loading of the image request.
|
* Listens for non-error changes to the loading of the image request.
|
||||||
*
|
*
|
||||||
@ -138,7 +139,7 @@ public class ImageLoader {
|
|||||||
* image loading in order to, for example, run an animation to fade in network loaded
|
* image loading in order to, for example, run an animation to fade in network loaded
|
||||||
* images.
|
* images.
|
||||||
*/
|
*/
|
||||||
void onResponse(ImageContainer response, boolean isImmediate);
|
public void onResponse(ImageContainer response, boolean isImmediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,9 +150,22 @@ public class ImageLoader {
|
|||||||
* @return True if the item exists in cache, false otherwise.
|
* @return True if the item exists in cache, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isCached(String requestUrl, int maxWidth, int maxHeight) {
|
public boolean isCached(String requestUrl, int maxWidth, int maxHeight) {
|
||||||
|
return isCached(requestUrl, maxWidth, maxHeight, ScaleType.CENTER_INSIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the item is available in the cache.
|
||||||
|
*
|
||||||
|
* @param requestUrl The url of the remote image
|
||||||
|
* @param maxWidth The maximum width of the returned image.
|
||||||
|
* @param maxHeight The maximum height of the returned image.
|
||||||
|
* @param scaleType The scaleType of the imageView.
|
||||||
|
* @return True if the item exists in cache, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isCached(String requestUrl, int maxWidth, int maxHeight, ScaleType scaleType) {
|
||||||
throwIfNotOnMainThread();
|
throwIfNotOnMainThread();
|
||||||
|
|
||||||
String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight);
|
String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight, scaleType);
|
||||||
return mCache.getBitmap(cacheKey) != null;
|
return mCache.getBitmap(cacheKey) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +182,15 @@ public class ImageLoader {
|
|||||||
return get(requestUrl, listener, 0, 0);
|
return get(requestUrl, listener, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equivalent to calling {@link #get(String, ImageListener, int, int, ScaleType)} with
|
||||||
|
* {@code Scaletype == ScaleType.CENTER_INSIDE}.
|
||||||
|
*/
|
||||||
|
public ImageContainer get(String requestUrl, ImageListener imageListener,
|
||||||
|
int maxWidth, int maxHeight) {
|
||||||
|
return get(requestUrl, imageListener, maxWidth, maxHeight, ScaleType.CENTER_INSIDE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Issues a bitmap request with the given URL if that image is not available
|
* Issues a bitmap request with the given URL if that image is not available
|
||||||
* in the cache, and returns a bitmap container that contains all of the data
|
* in the cache, and returns a bitmap container that contains all of the data
|
||||||
@ -177,15 +200,17 @@ public class ImageLoader {
|
|||||||
* @param imageListener The listener to call when the remote image is loaded
|
* @param imageListener The listener to call when the remote image is loaded
|
||||||
* @param maxWidth The maximum width of the returned image.
|
* @param maxWidth The maximum width of the returned image.
|
||||||
* @param maxHeight The maximum height of the returned image.
|
* @param maxHeight The maximum height of the returned image.
|
||||||
|
* @param scaleType The ImageViews ScaleType used to calculate the needed image size.
|
||||||
* @return A container object that contains all of the properties of the request, as well as
|
* @return A container object that contains all of the properties of the request, as well as
|
||||||
* the currently available image (default if remote is not loaded).
|
* the currently available image (default if remote is not loaded).
|
||||||
*/
|
*/
|
||||||
public ImageContainer get(String requestUrl, ImageListener imageListener,
|
public ImageContainer get(String requestUrl, ImageListener imageListener,
|
||||||
int maxWidth, int maxHeight) {
|
int maxWidth, int maxHeight, ScaleType scaleType) {
|
||||||
|
|
||||||
// only fulfill requests that were initiated from the main thread.
|
// only fulfill requests that were initiated from the main thread.
|
||||||
throwIfNotOnMainThread();
|
throwIfNotOnMainThread();
|
||||||
|
|
||||||
final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight);
|
final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight, scaleType);
|
||||||
|
|
||||||
// Try to look up the request in the cache of remote images.
|
// Try to look up the request in the cache of remote images.
|
||||||
Bitmap cachedBitmap = mCache.getBitmap(cacheKey);
|
Bitmap cachedBitmap = mCache.getBitmap(cacheKey);
|
||||||
@ -213,7 +238,8 @@ public class ImageLoader {
|
|||||||
|
|
||||||
// The request is not already in flight. Send the new request to the network and
|
// The request is not already in flight. Send the new request to the network and
|
||||||
// track it.
|
// track it.
|
||||||
Request<Bitmap> newRequest = makeImageRequest(requestUrl, maxWidth, maxHeight, cacheKey);
|
Request<Bitmap> newRequest = makeImageRequest(requestUrl, maxWidth, maxHeight, scaleType,
|
||||||
|
cacheKey);
|
||||||
|
|
||||||
mRequestQueue.add(newRequest);
|
mRequestQueue.add(newRequest);
|
||||||
mInFlightRequests.put(cacheKey,
|
mInFlightRequests.put(cacheKey,
|
||||||
@ -221,14 +247,14 @@ public class ImageLoader {
|
|||||||
return imageContainer;
|
return imageContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Request<Bitmap> makeImageRequest(String requestUrl, int maxWidth, int maxHeight, final String cacheKey) {
|
protected Request<Bitmap> makeImageRequest(String requestUrl, int maxWidth, int maxHeight,
|
||||||
return new ImageRequest(requestUrl, new Response.Listener<Bitmap>() {
|
ScaleType scaleType, final String cacheKey) {
|
||||||
|
return new ImageRequest(requestUrl, new Listener<Bitmap>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Bitmap response) {
|
public void onResponse(Bitmap response) {
|
||||||
onGetImageSuccess(cacheKey, response);
|
onGetImageSuccess(cacheKey, response);
|
||||||
}
|
}
|
||||||
}, maxWidth, maxHeight,
|
}, maxWidth, maxHeight, scaleType, Config.RGB_565, new ErrorListener() {
|
||||||
Config.RGB_565, new Response.ErrorListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onErrorResponse(VolleyError error) {
|
public void onErrorResponse(VolleyError error) {
|
||||||
onGetImageError(cacheKey, error);
|
onGetImageError(cacheKey, error);
|
||||||
@ -471,8 +497,11 @@ public class ImageLoader {
|
|||||||
* @param url The URL of the request.
|
* @param url The URL of the request.
|
||||||
* @param maxWidth The max-width of the output.
|
* @param maxWidth The max-width of the output.
|
||||||
* @param maxHeight The max-height of the output.
|
* @param maxHeight The max-height of the output.
|
||||||
|
* @param scaleType The scaleType of the imageView.
|
||||||
*/
|
*/
|
||||||
private static String getCacheKey(String url, int maxWidth, int maxHeight) {
|
private static String getCacheKey(String url, int maxWidth, int maxHeight, ScaleType scaleType) {
|
||||||
return "#W" + maxWidth + "#H" + maxHeight + url;
|
return new StringBuilder(url.length() + 12).append("#W").append(maxWidth)
|
||||||
|
.append("#H").append(maxHeight).append("#S").append(scaleType.ordinal()).append(url)
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
package org.telegram.android.volley.toolbox;
|
package org.telegram.android.volley.toolbox;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Bitmap.Config;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
|
|
||||||
import org.telegram.android.volley.DefaultRetryPolicy;
|
import org.telegram.android.volley.DefaultRetryPolicy;
|
||||||
import org.telegram.android.volley.NetworkResponse;
|
import org.telegram.android.volley.NetworkResponse;
|
||||||
import org.telegram.android.volley.ParseError;
|
import org.telegram.android.volley.ParseError;
|
||||||
@ -27,6 +23,11 @@ import org.telegram.android.volley.Request;
|
|||||||
import org.telegram.android.volley.Response;
|
import org.telegram.android.volley.Response;
|
||||||
import org.telegram.android.volley.VolleyLog;
|
import org.telegram.android.volley.VolleyLog;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Bitmap.Config;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.widget.ImageView.ScaleType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A canned request for getting an image at a given URL and calling
|
* A canned request for getting an image at a given URL and calling
|
||||||
* back with a decoded Bitmap.
|
* back with a decoded Bitmap.
|
||||||
@ -45,6 +46,7 @@ public class ImageRequest extends Request<Bitmap> {
|
|||||||
private final Config mDecodeConfig;
|
private final Config mDecodeConfig;
|
||||||
private final int mMaxWidth;
|
private final int mMaxWidth;
|
||||||
private final int mMaxHeight;
|
private final int mMaxHeight;
|
||||||
|
private ScaleType mScaleType;
|
||||||
|
|
||||||
/** Decoding lock so that we don't decode more than one image at a time (to avoid OOM's) */
|
/** Decoding lock so that we don't decode more than one image at a time (to avoid OOM's) */
|
||||||
private static final Object sDecodeLock = new Object();
|
private static final Object sDecodeLock = new Object();
|
||||||
@ -63,20 +65,32 @@ public class ImageRequest extends Request<Bitmap> {
|
|||||||
* @param maxWidth Maximum width to decode this bitmap to, or zero for none
|
* @param maxWidth Maximum width to decode this bitmap to, or zero for none
|
||||||
* @param maxHeight Maximum height to decode this bitmap to, or zero for
|
* @param maxHeight Maximum height to decode this bitmap to, or zero for
|
||||||
* none
|
* none
|
||||||
|
* @param scaleType The ImageViews ScaleType used to calculate the needed image size.
|
||||||
* @param decodeConfig Format to decode the bitmap to
|
* @param decodeConfig Format to decode the bitmap to
|
||||||
* @param errorListener Error listener, or null to ignore errors
|
* @param errorListener Error listener, or null to ignore errors
|
||||||
*/
|
*/
|
||||||
public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,
|
public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,
|
||||||
Config decodeConfig, Response.ErrorListener errorListener) {
|
ScaleType scaleType, Config decodeConfig, Response.ErrorListener errorListener) {
|
||||||
super(Method.GET, url, errorListener);
|
super(Method.GET, url, errorListener);
|
||||||
setRetryPolicy(
|
setRetryPolicy(
|
||||||
new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT));
|
new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT));
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
mDecodeConfig = decodeConfig;
|
mDecodeConfig = decodeConfig;
|
||||||
mMaxWidth = maxWidth;
|
mMaxWidth = maxWidth;
|
||||||
mMaxHeight = maxHeight;
|
mMaxHeight = maxHeight;
|
||||||
|
mScaleType = scaleType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For API compatibility with the pre-ScaleType variant of the constructor. Equivalent to
|
||||||
|
* the normal constructor with {@code ScaleType.CENTER_INSIDE}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,
|
||||||
|
Config decodeConfig, Response.ErrorListener errorListener) {
|
||||||
|
this(url, listener, maxWidth, maxHeight,
|
||||||
|
ScaleType.CENTER_INSIDE, decodeConfig, errorListener);
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public Priority getPriority() {
|
public Priority getPriority() {
|
||||||
return Priority.LOW;
|
return Priority.LOW;
|
||||||
@ -92,14 +106,24 @@ public class ImageRequest extends Request<Bitmap> {
|
|||||||
* maintain aspect ratio with primary dimension
|
* maintain aspect ratio with primary dimension
|
||||||
* @param actualPrimary Actual size of the primary dimension
|
* @param actualPrimary Actual size of the primary dimension
|
||||||
* @param actualSecondary Actual size of the secondary dimension
|
* @param actualSecondary Actual size of the secondary dimension
|
||||||
|
* @param scaleType The ScaleType used to calculate the needed image size.
|
||||||
*/
|
*/
|
||||||
private static int getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary,
|
private static int getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary,
|
||||||
int actualSecondary) {
|
int actualSecondary, ScaleType scaleType) {
|
||||||
|
|
||||||
// If no dominant value at all, just return the actual.
|
// If no dominant value at all, just return the actual.
|
||||||
if (maxPrimary == 0 && maxSecondary == 0) {
|
if ((maxPrimary == 0) && (maxSecondary == 0)) {
|
||||||
return actualPrimary;
|
return actualPrimary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If ScaleType.FIT_XY fill the whole rectangle, ignore ratio.
|
||||||
|
if (scaleType == ScaleType.FIT_XY) {
|
||||||
|
if (maxPrimary == 0) {
|
||||||
|
return actualPrimary;
|
||||||
|
}
|
||||||
|
return maxPrimary;
|
||||||
|
}
|
||||||
|
|
||||||
// If primary is unspecified, scale primary to match secondary's scaling ratio.
|
// If primary is unspecified, scale primary to match secondary's scaling ratio.
|
||||||
if (maxPrimary == 0) {
|
if (maxPrimary == 0) {
|
||||||
double ratio = (double) maxSecondary / (double) actualSecondary;
|
double ratio = (double) maxSecondary / (double) actualSecondary;
|
||||||
@ -112,7 +136,16 @@ public class ImageRequest extends Request<Bitmap> {
|
|||||||
|
|
||||||
double ratio = (double) actualSecondary / (double) actualPrimary;
|
double ratio = (double) actualSecondary / (double) actualPrimary;
|
||||||
int resized = maxPrimary;
|
int resized = maxPrimary;
|
||||||
if (resized * ratio > maxSecondary) {
|
|
||||||
|
// If ScaleType.CENTER_CROP fill the whole rectangle, preserve aspect ratio.
|
||||||
|
if (scaleType == ScaleType.CENTER_CROP) {
|
||||||
|
if ((resized * ratio) < maxSecondary) {
|
||||||
|
resized = (int) (maxSecondary / ratio);
|
||||||
|
}
|
||||||
|
return resized;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((resized * ratio) > maxSecondary) {
|
||||||
resized = (int) (maxSecondary / ratio);
|
resized = (int) (maxSecondary / ratio);
|
||||||
}
|
}
|
||||||
return resized;
|
return resized;
|
||||||
@ -150,9 +183,9 @@ public class ImageRequest extends Request<Bitmap> {
|
|||||||
|
|
||||||
// Then compute the dimensions we would ideally like to decode to.
|
// Then compute the dimensions we would ideally like to decode to.
|
||||||
int desiredWidth = getResizedDimension(mMaxWidth, mMaxHeight,
|
int desiredWidth = getResizedDimension(mMaxWidth, mMaxHeight,
|
||||||
actualWidth, actualHeight);
|
actualWidth, actualHeight, mScaleType);
|
||||||
int desiredHeight = getResizedDimension(mMaxHeight, mMaxWidth,
|
int desiredHeight = getResizedDimension(mMaxHeight, mMaxWidth,
|
||||||
actualHeight, actualWidth);
|
actualHeight, actualWidth, mScaleType);
|
||||||
|
|
||||||
// Decode to the nearest power of two scaling factor.
|
// Decode to the nearest power of two scaling factor.
|
||||||
decodeOptions.inJustDecodeBounds = false;
|
decodeOptions.inJustDecodeBounds = false;
|
||||||
|
@ -16,11 +16,14 @@
|
|||||||
|
|
||||||
package org.telegram.android.volley.toolbox;
|
package org.telegram.android.volley.toolbox;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.telegram.android.volley.NetworkResponse;
|
import org.telegram.android.volley.NetworkResponse;
|
||||||
import org.telegram.android.volley.ParseError;
|
import org.telegram.android.volley.ParseError;
|
||||||
import org.telegram.android.volley.Response;
|
import org.telegram.android.volley.Response;
|
||||||
|
import org.telegram.android.volley.Response.ErrorListener;
|
||||||
|
import org.telegram.android.volley.Response.Listener;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
@ -35,15 +38,30 @@ public class JsonArrayRequest extends JsonRequest<JSONArray> {
|
|||||||
* @param listener Listener to receive the JSON response
|
* @param listener Listener to receive the JSON response
|
||||||
* @param errorListener Error listener, or null to ignore errors.
|
* @param errorListener Error listener, or null to ignore errors.
|
||||||
*/
|
*/
|
||||||
public JsonArrayRequest(String url, Response.Listener<JSONArray> listener, Response.ErrorListener errorListener) {
|
public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener) {
|
||||||
super(Method.GET, url, null, listener, errorListener);
|
super(Method.GET, url, null, listener, errorListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new request.
|
||||||
|
* @param method the HTTP method to use
|
||||||
|
* @param url URL to fetch the JSON from
|
||||||
|
* @param jsonRequest A {@link JSONArray} to post with the request. Null is allowed and
|
||||||
|
* indicates no parameters will be posted along with request.
|
||||||
|
* @param listener Listener to receive the JSON response
|
||||||
|
* @param errorListener Error listener, or null to ignore errors.
|
||||||
|
*/
|
||||||
|
public JsonArrayRequest(int method, String url, JSONArray jsonRequest,
|
||||||
|
Listener<JSONArray> listener, ErrorListener errorListener) {
|
||||||
|
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
|
||||||
|
errorListener);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
|
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
|
||||||
try {
|
try {
|
||||||
String jsonString =
|
String jsonString = new String(response.data,
|
||||||
new String(response.data, HttpHeaderParser.parseCharset(response.headers));
|
HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
|
||||||
return Response.success(new JSONArray(jsonString),
|
return Response.success(new JSONArray(jsonString),
|
||||||
HttpHeaderParser.parseCacheHeaders(response));
|
HttpHeaderParser.parseCacheHeaders(response));
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
@ -16,11 +16,14 @@
|
|||||||
|
|
||||||
package org.telegram.android.volley.toolbox;
|
package org.telegram.android.volley.toolbox;
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.telegram.android.volley.NetworkResponse;
|
import org.telegram.android.volley.NetworkResponse;
|
||||||
import org.telegram.android.volley.ParseError;
|
import org.telegram.android.volley.ParseError;
|
||||||
import org.telegram.android.volley.Response;
|
import org.telegram.android.volley.Response;
|
||||||
|
import org.telegram.android.volley.Response.ErrorListener;
|
||||||
|
import org.telegram.android.volley.Response.Listener;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
@ -40,7 +43,7 @@ public class JsonObjectRequest extends JsonRequest<JSONObject> {
|
|||||||
* @param errorListener Error listener, or null to ignore errors.
|
* @param errorListener Error listener, or null to ignore errors.
|
||||||
*/
|
*/
|
||||||
public JsonObjectRequest(int method, String url, JSONObject jsonRequest,
|
public JsonObjectRequest(int method, String url, JSONObject jsonRequest,
|
||||||
Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
|
Listener<JSONObject> listener, ErrorListener errorListener) {
|
||||||
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
|
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
|
||||||
errorListener);
|
errorListener);
|
||||||
}
|
}
|
||||||
@ -49,9 +52,10 @@ public class JsonObjectRequest extends JsonRequest<JSONObject> {
|
|||||||
* Constructor which defaults to <code>GET</code> if <code>jsonRequest</code> is
|
* Constructor which defaults to <code>GET</code> if <code>jsonRequest</code> is
|
||||||
* <code>null</code>, <code>POST</code> otherwise.
|
* <code>null</code>, <code>POST</code> otherwise.
|
||||||
*
|
*
|
||||||
|
* @see #JsonObjectRequest(int, String, JSONObject, Listener, ErrorListener)
|
||||||
*/
|
*/
|
||||||
public JsonObjectRequest(String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener,
|
public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener,
|
||||||
Response.ErrorListener errorListener) {
|
ErrorListener errorListener) {
|
||||||
this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest,
|
this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest,
|
||||||
listener, errorListener);
|
listener, errorListener);
|
||||||
}
|
}
|
||||||
@ -59,8 +63,8 @@ public class JsonObjectRequest extends JsonRequest<JSONObject> {
|
|||||||
@Override
|
@Override
|
||||||
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
|
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
|
||||||
try {
|
try {
|
||||||
String jsonString =
|
String jsonString = new String(response.data,
|
||||||
new String(response.data, HttpHeaderParser.parseCharset(response.headers));
|
HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
|
||||||
return Response.success(new JSONObject(jsonString),
|
return Response.success(new JSONObject(jsonString),
|
||||||
HttpHeaderParser.parseCacheHeaders(response));
|
HttpHeaderParser.parseCacheHeaders(response));
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
@ -19,6 +19,8 @@ package org.telegram.android.volley.toolbox;
|
|||||||
import org.telegram.android.volley.NetworkResponse;
|
import org.telegram.android.volley.NetworkResponse;
|
||||||
import org.telegram.android.volley.Request;
|
import org.telegram.android.volley.Request;
|
||||||
import org.telegram.android.volley.Response;
|
import org.telegram.android.volley.Response;
|
||||||
|
import org.telegram.android.volley.Response.ErrorListener;
|
||||||
|
import org.telegram.android.volley.Response.Listener;
|
||||||
import org.telegram.android.volley.VolleyLog;
|
import org.telegram.android.volley.VolleyLog;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
@ -30,28 +32,29 @@ import java.io.UnsupportedEncodingException;
|
|||||||
* @param <T> JSON type of response expected
|
* @param <T> JSON type of response expected
|
||||||
*/
|
*/
|
||||||
public abstract class JsonRequest<T> extends Request<T> {
|
public abstract class JsonRequest<T> extends Request<T> {
|
||||||
/** Charset for request. */
|
/** Default charset for JSON request. */
|
||||||
private static final String PROTOCOL_CHARSET = "utf-8";
|
protected static final String PROTOCOL_CHARSET = "utf-8";
|
||||||
|
|
||||||
/** Content type for request. */
|
/** Content type for request. */
|
||||||
private static final String PROTOCOL_CONTENT_TYPE =
|
private static final String PROTOCOL_CONTENT_TYPE =
|
||||||
String.format("application/json; charset=%s", PROTOCOL_CHARSET);
|
String.format("application/json; charset=%s", PROTOCOL_CHARSET);
|
||||||
|
|
||||||
private final Response.Listener<T> mListener;
|
private final Listener<T> mListener;
|
||||||
private final String mRequestBody;
|
private final String mRequestBody;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated constructor for a JsonRequest which defaults to GET unless {@link #getPostBody()}
|
* Deprecated constructor for a JsonRequest which defaults to GET unless {@link #getPostBody()}
|
||||||
* or {@link #getPostParams()} is overridden (which defaults to POST).
|
* or {@link #getPostParams()} is overridden (which defaults to POST).
|
||||||
*
|
*
|
||||||
|
* @deprecated Use {@link #JsonRequest(int, String, String, Listener, ErrorListener)}.
|
||||||
*/
|
*/
|
||||||
public JsonRequest(String url, String requestBody, Response.Listener<T> listener,
|
public JsonRequest(String url, String requestBody, Listener<T> listener,
|
||||||
Response.ErrorListener errorListener) {
|
ErrorListener errorListener) {
|
||||||
this(Method.DEPRECATED_GET_OR_POST, url, requestBody, listener, errorListener);
|
this(Method.DEPRECATED_GET_OR_POST, url, requestBody, listener, errorListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonRequest(int method, String url, String requestBody, Response.Listener<T> listener,
|
public JsonRequest(int method, String url, String requestBody, Listener<T> listener,
|
||||||
Response.ErrorListener errorListener) {
|
ErrorListener errorListener) {
|
||||||
super(method, url, errorListener);
|
super(method, url, errorListener);
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
mRequestBody = requestBody;
|
mRequestBody = requestBody;
|
||||||
|
@ -103,6 +103,7 @@ public class NetworkImageView extends ImageView {
|
|||||||
void loadImageIfNecessary(final boolean isInLayoutPass) {
|
void loadImageIfNecessary(final boolean isInLayoutPass) {
|
||||||
int width = getWidth();
|
int width = getWidth();
|
||||||
int height = getHeight();
|
int height = getHeight();
|
||||||
|
ScaleType scaleType = getScaleType();
|
||||||
|
|
||||||
boolean wrapWidth = false, wrapHeight = false;
|
boolean wrapWidth = false, wrapHeight = false;
|
||||||
if (getLayoutParams() != null) {
|
if (getLayoutParams() != null) {
|
||||||
@ -177,7 +178,7 @@ public class NetworkImageView extends ImageView {
|
|||||||
setImageResource(mDefaultImageId);
|
setImageResource(mDefaultImageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, maxWidth, maxHeight);
|
}, maxWidth, maxHeight, scaleType);
|
||||||
|
|
||||||
// update the ImageContainer to be the new bitmap container.
|
// update the ImageContainer to be the new bitmap container.
|
||||||
mImageContainer = newContainer;
|
mImageContainer = newContainer;
|
||||||
|
@ -25,7 +25,7 @@ import java.io.IOException;
|
|||||||
*/
|
*/
|
||||||
public class PoolingByteArrayOutputStream extends ByteArrayOutputStream {
|
public class PoolingByteArrayOutputStream extends ByteArrayOutputStream {
|
||||||
/**
|
/**
|
||||||
* If the {@link #PoolingByteArrayOutputStream(org.telegram.android.volley.toolbox.ByteArrayPool)} constructor is called, this is
|
* If the {@link #PoolingByteArrayOutputStream(ByteArrayPool)} constructor is called, this is
|
||||||
* the default size to which the underlying byte array is initialized.
|
* the default size to which the underlying byte array is initialized.
|
||||||
*/
|
*/
|
||||||
private static final int DEFAULT_SIZE = 256;
|
private static final int DEFAULT_SIZE = 256;
|
||||||
|
@ -126,7 +126,10 @@ public class RequestFuture<T> implements Future<T>, Response.Listener<T>,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCancelled() {
|
public boolean isCancelled() {
|
||||||
return mRequest != null && mRequest.isCanceled();
|
if (mRequest == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return mRequest.isCanceled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,6 +19,8 @@ package org.telegram.android.volley.toolbox;
|
|||||||
import org.telegram.android.volley.NetworkResponse;
|
import org.telegram.android.volley.NetworkResponse;
|
||||||
import org.telegram.android.volley.Request;
|
import org.telegram.android.volley.Request;
|
||||||
import org.telegram.android.volley.Response;
|
import org.telegram.android.volley.Response;
|
||||||
|
import org.telegram.android.volley.Response.ErrorListener;
|
||||||
|
import org.telegram.android.volley.Response.Listener;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ import java.io.UnsupportedEncodingException;
|
|||||||
* A canned request for retrieving the response body at a given URL as a String.
|
* A canned request for retrieving the response body at a given URL as a String.
|
||||||
*/
|
*/
|
||||||
public class StringRequest extends Request<String> {
|
public class StringRequest extends Request<String> {
|
||||||
private final Response.Listener<String> mListener;
|
private final Listener<String> mListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new request with the given method.
|
* Creates a new request with the given method.
|
||||||
@ -36,8 +38,8 @@ public class StringRequest extends Request<String> {
|
|||||||
* @param listener Listener to receive the String response
|
* @param listener Listener to receive the String response
|
||||||
* @param errorListener Error listener, or null to ignore errors
|
* @param errorListener Error listener, or null to ignore errors
|
||||||
*/
|
*/
|
||||||
public StringRequest(int method, String url, Response.Listener<String> listener,
|
public StringRequest(int method, String url, Listener<String> listener,
|
||||||
Response.ErrorListener errorListener) {
|
ErrorListener errorListener) {
|
||||||
super(method, url, errorListener);
|
super(method, url, errorListener);
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
}
|
}
|
||||||
@ -49,7 +51,7 @@ public class StringRequest extends Request<String> {
|
|||||||
* @param listener Listener to receive the String response
|
* @param listener Listener to receive the String response
|
||||||
* @param errorListener Error listener, or null to ignore errors
|
* @param errorListener Error listener, or null to ignore errors
|
||||||
*/
|
*/
|
||||||
public StringRequest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener) {
|
public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
|
||||||
this(Method.GET, url, listener, errorListener);
|
this(Method.GET, url, listener, errorListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,6 @@ public class Volley {
|
|||||||
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
|
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
|
||||||
userAgent = packageName + "/" + info.versionCode;
|
userAgent = packageName + "/" + info.versionCode;
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
/**/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stack == null) {
|
if (stack == null) {
|
||||||
|
@ -10,7 +10,6 @@ package org.telegram.messenger;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.Application;
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -25,6 +24,7 @@ import android.os.Build;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.support.multidex.MultiDex;
|
import android.support.multidex.MultiDex;
|
||||||
|
import android.support.multidex.MultiDexApplication;
|
||||||
|
|
||||||
import com.google.android.gms.common.ConnectionResult;
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
import com.google.android.gms.common.GooglePlayServicesUtil;
|
import com.google.android.gms.common.GooglePlayServicesUtil;
|
||||||
@ -44,7 +44,8 @@ import org.telegram.ui.Components.ForegroundDetector;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class ApplicationLoader extends Application {
|
//public class ApplicationLoader extends Application {
|
||||||
|
public class ApplicationLoader extends MultiDexApplication {
|
||||||
|
|
||||||
private GoogleCloudMessaging gcm;
|
private GoogleCloudMessaging gcm;
|
||||||
private AtomicInteger msgId = new AtomicInteger();
|
private AtomicInteger msgId = new AtomicInteger();
|
||||||
@ -360,8 +361,15 @@ public class ApplicationLoader extends Application {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void attachBaseContext(Context base) {
|
protected void attachBaseContext(Context base) {
|
||||||
super.attachBaseContext(base);
|
try{
|
||||||
MultiDex.install(this);
|
super.attachBaseContext(base);
|
||||||
|
MultiDex.install(this);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String vmName = System.getProperty("java.vm.name");
|
||||||
|
if (!vmName.startsWith("Java")) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeRegistrationId(Context context, String regId) {
|
private void storeRegistrationId(Context context, String regId) {
|
||||||
|
@ -113,7 +113,7 @@ public class BuffersStorage {
|
|||||||
arrayToReuse = freeBuffers128;
|
arrayToReuse = freeBuffers128;
|
||||||
} else if (buffer.buffer.capacity() == 1024 + 200) {
|
} else if (buffer.buffer.capacity() == 1024 + 200) {
|
||||||
arrayToReuse = freeBuffers1024;
|
arrayToReuse = freeBuffers1024;
|
||||||
} if (buffer.buffer.capacity() == 4096 + 200) {
|
} else if (buffer.buffer.capacity() == 4096 + 200) {
|
||||||
arrayToReuse = freeBuffers4096;
|
arrayToReuse = freeBuffers4096;
|
||||||
} else if (buffer.buffer.capacity() == 16384 + 200) {
|
} else if (buffer.buffer.capacity() == 16384 + 200) {
|
||||||
arrayToReuse = freeBuffers16384;
|
arrayToReuse = freeBuffers16384;
|
||||||
|
@ -243,6 +243,11 @@ public class FileLoadOperation {
|
|||||||
downloadedBytes = (int)cacheFileTemp.length();
|
downloadedBytes = (int)cacheFileTemp.length();
|
||||||
nextDownloadOffset = downloadedBytes = downloadedBytes / currentDownloadChunkSize * currentDownloadChunkSize;
|
nextDownloadOffset = downloadedBytes = downloadedBytes / currentDownloadChunkSize * currentDownloadChunkSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BuildVars.DEBUG_VERSION) {
|
||||||
|
FileLog.d("tmessages", "start loading file to temp = " + cacheFileTemp + " final = " + cacheFileFinal);
|
||||||
|
}
|
||||||
|
|
||||||
if (fileNameIv != null) {
|
if (fileNameIv != null) {
|
||||||
cacheIvTemp = new File(tempPath, fileNameIv);
|
cacheIvTemp = new File(tempPath, fileNameIv);
|
||||||
try {
|
try {
|
||||||
@ -307,6 +312,9 @@ public class FileLoadOperation {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state = stateFailed;
|
state = stateFailed;
|
||||||
|
if (BuildVars.DEBUG_VERSION) {
|
||||||
|
FileLog.e("tmessages", "cancel downloading file to " + cacheFileFinal);
|
||||||
|
}
|
||||||
cleanup();
|
cleanup();
|
||||||
for (RequestInfo requestInfo : requestInfos) {
|
for (RequestInfo requestInfo : requestInfos) {
|
||||||
if (requestInfo.requestToken != 0) {
|
if (requestInfo.requestToken != 0) {
|
||||||
@ -356,9 +364,15 @@ public class FileLoadOperation {
|
|||||||
}
|
}
|
||||||
if (cacheFileTemp != null) {
|
if (cacheFileTemp != null) {
|
||||||
if (!cacheFileTemp.renameTo(cacheFileFinal)) {
|
if (!cacheFileTemp.renameTo(cacheFileFinal)) {
|
||||||
|
if (BuildVars.DEBUG_VERSION) {
|
||||||
|
FileLog.e("tmessages", "unable to rename temp = " + cacheFileTemp + " to final = " + cacheFileFinal);
|
||||||
|
}
|
||||||
cacheFileFinal = cacheFileTemp;
|
cacheFileFinal = cacheFileTemp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (BuildVars.DEBUG_VERSION) {
|
||||||
|
FileLog.e("tmessages", "finished downloading file to " + cacheFileFinal);
|
||||||
|
}
|
||||||
delegate.didFinishLoadingFile(FileLoadOperation.this, cacheFileFinal);
|
delegate.didFinishLoadingFile(FileLoadOperation.this, cacheFileFinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,6 +577,14 @@ public class FileLoader {
|
|||||||
return getPathToAttach(sizeFull);
|
return getPathToAttach(sizeFull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage && message.media.webpage.photo != null) {
|
||||||
|
ArrayList<TLRPC.PhotoSize> sizes = message.media.webpage.photo.sizes;
|
||||||
|
if (sizes.size() > 0) {
|
||||||
|
TLRPC.PhotoSize sizeFull = getClosestPhotoSizeWithSize(sizes, AndroidUtilities.getPhotoSize());
|
||||||
|
if (sizeFull != null) {
|
||||||
|
return getPathToAttach(sizeFull);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new File("");
|
return new File("");
|
||||||
@ -621,7 +629,7 @@ public class FileLoader {
|
|||||||
}
|
}
|
||||||
} else if (attach instanceof TLRPC.PhotoSize) {
|
} else if (attach instanceof TLRPC.PhotoSize) {
|
||||||
TLRPC.PhotoSize photoSize = (TLRPC.PhotoSize) attach;
|
TLRPC.PhotoSize photoSize = (TLRPC.PhotoSize) attach;
|
||||||
if (photoSize.location == null || photoSize.location.key != null || photoSize.location.volume_id == Integer.MIN_VALUE && photoSize.location.local_id < 0) {
|
if (photoSize.location == null || photoSize.location.key != null || photoSize.location.volume_id == Integer.MIN_VALUE && photoSize.location.local_id < 0 || photoSize.size < 0) {
|
||||||
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
|
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
|
||||||
} else {
|
} else {
|
||||||
dir = getInstance().getDirectory(MEDIA_DIR_IMAGE);
|
dir = getInstance().getDirectory(MEDIA_DIR_IMAGE);
|
||||||
|
@ -89,6 +89,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
|
|
||||||
final Object lock = new Object();
|
final Object lock = new Object();
|
||||||
static ArrayList<HashMap<String, Object>> serverPublicKeys = null;
|
static ArrayList<HashMap<String, Object>> serverPublicKeys = null;
|
||||||
|
|
||||||
HashMap<String, Object> selectPublicKey(ArrayList<Long> fingerprints) {
|
HashMap<String, Object> selectPublicKey(ArrayList<Long> fingerprints) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (serverPublicKeys == null) {
|
if (serverPublicKeys == null) {
|
||||||
@ -150,7 +151,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (HashMap<String, Object> keyDesc : serverPublicKeys) {
|
for (HashMap<String, Object> keyDesc : serverPublicKeys) {
|
||||||
long keyFingerprint = (Long)keyDesc.get("fingerprint");
|
long keyFingerprint = (Long) keyDesc.get("fingerprint");
|
||||||
for (long nFingerprint : fingerprints) {
|
for (long nFingerprint : fingerprints) {
|
||||||
if (nFingerprint == keyFingerprint) {
|
if (nFingerprint == keyFingerprint) {
|
||||||
return keyDesc;
|
return keyDesc;
|
||||||
@ -161,7 +162,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
}
|
}
|
||||||
|
|
||||||
long generateMessageId() {
|
long generateMessageId() {
|
||||||
long messageId = (long)((((double)System.currentTimeMillis()) * 4294967296.0) / 1000.0);
|
long messageId = (long) ((((double) System.currentTimeMillis()) * 4294967296.0) / 1000.0);
|
||||||
if (messageId <= lastOutgoingMessageId) {
|
if (messageId <= lastOutgoingMessageId) {
|
||||||
messageId = lastOutgoingMessageId + 1;
|
messageId = lastOutgoingMessageId + 1;
|
||||||
}
|
}
|
||||||
@ -197,7 +198,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
}
|
}
|
||||||
|
|
||||||
processedPQRes = true;
|
processedPQRes = true;
|
||||||
final TLRPC.TL_resPQ resPq = (TLRPC.TL_resPQ)message;
|
final TLRPC.TL_resPQ resPq = (TLRPC.TL_resPQ) message;
|
||||||
if (Utilities.arraysEquals(authNonce, 0, resPq.nonce, 0)) {
|
if (Utilities.arraysEquals(authNonce, 0, resPq.nonce, 0)) {
|
||||||
final HashMap<String, Object> publicKey = selectPublicKey(resPq.server_public_key_fingerprints);
|
final HashMap<String, Object> publicKey = selectPublicKey(resPq.server_public_key_fingerprints);
|
||||||
if (publicKey == null) {
|
if (publicKey == null) {
|
||||||
@ -221,11 +222,11 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ByteBuffer pBytes = ByteBuffer.allocate(4);
|
ByteBuffer pBytes = ByteBuffer.allocate(4);
|
||||||
pBytes.putInt((int)factorizedPq.p);
|
pBytes.putInt((int) factorizedPq.p);
|
||||||
byte[] pData = pBytes.array();
|
byte[] pData = pBytes.array();
|
||||||
|
|
||||||
ByteBuffer qBytes = ByteBuffer.allocate(4);
|
ByteBuffer qBytes = ByteBuffer.allocate(4);
|
||||||
qBytes.putInt((int)factorizedPq.q);
|
qBytes.putInt((int) factorizedPq.q);
|
||||||
byte[] qData = qBytes.array();
|
byte[] qData = qBytes.array();
|
||||||
|
|
||||||
TLRPC.TL_req_DH_params reqDH = new TLRPC.TL_req_DH_params();
|
TLRPC.TL_req_DH_params reqDH = new TLRPC.TL_req_DH_params();
|
||||||
@ -233,7 +234,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
reqDH.server_nonce = authServerNonce;
|
reqDH.server_nonce = authServerNonce;
|
||||||
reqDH.p = pData;
|
reqDH.p = pData;
|
||||||
reqDH.q = qData;
|
reqDH.q = qData;
|
||||||
reqDH.public_key_fingerprint = (Long)publicKey.get("fingerprint");
|
reqDH.public_key_fingerprint = (Long) publicKey.get("fingerprint");
|
||||||
|
|
||||||
SerializedData os = new SerializedData();
|
SerializedData os = new SerializedData();
|
||||||
|
|
||||||
@ -261,7 +262,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
dataWithHash.writeByte(b[0]);
|
dataWithHash.writeByte(b[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] encryptedBytes = Utilities.encryptWithRSA((BigInteger[])publicKey.get("key"), dataWithHash.toByteArray());
|
byte[] encryptedBytes = Utilities.encryptWithRSA((BigInteger[]) publicKey.get("key"), dataWithHash.toByteArray());
|
||||||
dataWithHash.cleanup();
|
dataWithHash.cleanup();
|
||||||
SerializedData encryptedData = new SerializedData();
|
SerializedData encryptedData = new SerializedData();
|
||||||
encryptedData.writeRaw(encryptedBytes);
|
encryptedData.writeRaw(encryptedBytes);
|
||||||
@ -300,7 +301,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
if (authNewNonce == null) {
|
if (authNewNonce == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TLRPC.TL_server_DH_params_ok serverDhParams = (TLRPC.TL_server_DH_params_ok)message;
|
TLRPC.TL_server_DH_params_ok serverDhParams = (TLRPC.TL_server_DH_params_ok) message;
|
||||||
|
|
||||||
SerializedData tmpAesKey = new SerializedData();
|
SerializedData tmpAesKey = new SerializedData();
|
||||||
|
|
||||||
@ -423,17 +424,17 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
for (int i = 7; i >= 0; i--) {
|
for (int i = 7; i >= 0; i--) {
|
||||||
byte a_ = authNewNonce[i];
|
byte a_ = authNewNonce[i];
|
||||||
byte b_ = authServerNonce[i];
|
byte b_ = authServerNonce[i];
|
||||||
byte x = (byte)(a_ ^ b_);
|
byte x = (byte) (a_ ^ b_);
|
||||||
serverSaltData.writeByte(x);
|
serverSaltData.writeByte(x);
|
||||||
}
|
}
|
||||||
ByteBuffer saltBuffer = ByteBuffer.wrap(serverSaltData.toByteArray());
|
ByteBuffer saltBuffer = ByteBuffer.wrap(serverSaltData.toByteArray());
|
||||||
serverSaltData.cleanup();
|
serverSaltData.cleanup();
|
||||||
|
|
||||||
timeDifference = dhInnerData.server_time - (int)(System.currentTimeMillis() / 1000);
|
timeDifference = dhInnerData.server_time - (int) (System.currentTimeMillis() / 1000);
|
||||||
|
|
||||||
serverSalt = new ServerSalt();
|
serverSalt = new ServerSalt();
|
||||||
serverSalt.validSince = (int)(System.currentTimeMillis() / 1000) + timeDifference;
|
serverSalt.validSince = (int) (System.currentTimeMillis() / 1000) + timeDifference;
|
||||||
serverSalt.validUntil = (int)(System.currentTimeMillis() / 1000) + timeDifference + 30 * 60;
|
serverSalt.validUntil = (int) (System.currentTimeMillis() / 1000) + timeDifference + 30 * 60;
|
||||||
serverSalt.value = saltBuffer.getLong();
|
serverSalt.value = saltBuffer.getLong();
|
||||||
|
|
||||||
FileLog.d("tmessages", String.format(Locale.US, "===== Time difference: %d", timeDifference));
|
FileLog.d("tmessages", String.format(Locale.US, "===== Time difference: %d", timeDifference));
|
||||||
@ -489,7 +490,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
setClientDHParamsMsgData = null;
|
setClientDHParamsMsgData = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
TLRPC.Set_client_DH_params_answer dhAnswer = (TLRPC.Set_client_DH_params_answer)message;
|
TLRPC.Set_client_DH_params_answer dhAnswer = (TLRPC.Set_client_DH_params_answer) message;
|
||||||
|
|
||||||
if (!Utilities.arraysEquals(authNonce, 0, dhAnswer.nonce, 0)) {
|
if (!Utilities.arraysEquals(authNonce, 0, dhAnswer.nonce, 0)) {
|
||||||
FileLog.e("tmessages", "***** Invalid DH answer nonce");
|
FileLog.e("tmessages", "***** Invalid DH answer nonce");
|
||||||
@ -544,7 +545,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
System.arraycopy(newNonceHash3Full, newNonceHash3Full.length - 16, newNonceHash3, 0, 16);
|
System.arraycopy(newNonceHash3Full, newNonceHash3Full.length - 16, newNonceHash3, 0, 16);
|
||||||
|
|
||||||
if (message instanceof TLRPC.TL_dh_gen_ok) {
|
if (message instanceof TLRPC.TL_dh_gen_ok) {
|
||||||
TLRPC.TL_dh_gen_ok dhGenOk = (TLRPC.TL_dh_gen_ok)message;
|
TLRPC.TL_dh_gen_ok dhGenOk = (TLRPC.TL_dh_gen_ok) message;
|
||||||
if (!Utilities.arraysEquals(newNonceHash1, 0, dhGenOk.new_nonce_hash1, 0)) {
|
if (!Utilities.arraysEquals(newNonceHash1, 0, dhGenOk.new_nonce_hash1, 0)) {
|
||||||
FileLog.e("tmessages", "***** Invalid DH answer nonce hash 1");
|
FileLog.e("tmessages", "***** Invalid DH answer nonce hash 1");
|
||||||
beginHandshake(false);
|
beginHandshake(false);
|
||||||
@ -569,7 +570,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (message instanceof TLRPC.TL_dh_gen_retry) {
|
} else if (message instanceof TLRPC.TL_dh_gen_retry) {
|
||||||
TLRPC.TL_dh_gen_retry dhRetry = (TLRPC.TL_dh_gen_retry)message;
|
TLRPC.TL_dh_gen_retry dhRetry = (TLRPC.TL_dh_gen_retry) message;
|
||||||
if (!Utilities.arraysEquals(newNonceHash2, 0, dhRetry.new_nonce_hash2, 0)) {
|
if (!Utilities.arraysEquals(newNonceHash2, 0, dhRetry.new_nonce_hash2, 0)) {
|
||||||
FileLog.e("tmessages", "***** Invalid DH answer nonce hash 2");
|
FileLog.e("tmessages", "***** Invalid DH answer nonce hash 2");
|
||||||
beginHandshake(false);
|
beginHandshake(false);
|
||||||
@ -578,7 +579,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
|||||||
FileLog.d("tmessages", "***** Retry DH");
|
FileLog.d("tmessages", "***** Retry DH");
|
||||||
beginHandshake(false);
|
beginHandshake(false);
|
||||||
} else if (message instanceof TLRPC.TL_dh_gen_fail) {
|
} else if (message instanceof TLRPC.TL_dh_gen_fail) {
|
||||||
TLRPC.TL_dh_gen_fail dhFail = (TLRPC.TL_dh_gen_fail)message;
|
TLRPC.TL_dh_gen_fail dhFail = (TLRPC.TL_dh_gen_fail) message;
|
||||||
if (!Utilities.arraysEquals(newNonceHash3, 0, dhFail.new_nonce_hash3, 0)) {
|
if (!Utilities.arraysEquals(newNonceHash3, 0, dhFail.new_nonce_hash3, 0)) {
|
||||||
FileLog.e("tmessages", "***** Invalid DH answer nonce hash 3");
|
FileLog.e("tmessages", "***** Invalid DH answer nonce hash 3");
|
||||||
beginHandshake(false);
|
beginHandshake(false);
|
||||||
|
@ -11729,6 +11729,15 @@ public class TLRPC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TL_inputMessagesFilterUrl extends MessagesFilter {
|
||||||
|
public static int constructor = 0x7ef0dd87;
|
||||||
|
|
||||||
|
|
||||||
|
public void serializeToStream(AbsSerializedData stream) {
|
||||||
|
stream.writeInt32(constructor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class TL_inputMessagesFilterPhotoVideo extends MessagesFilter {
|
public static class TL_inputMessagesFilterPhotoVideo extends MessagesFilter {
|
||||||
public static int constructor = 0x56e9f0e4;
|
public static int constructor = 0x56e9f0e4;
|
||||||
|
|
||||||
|
@ -300,10 +300,6 @@ public class TcpConnection extends ConnectionContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resumeConnection() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reconnect() {
|
private void reconnect() {
|
||||||
suspendConnection(false);
|
suspendConnection(false);
|
||||||
connectionState = TcpConnectionState.TcpConnectionStageReconnecting;
|
connectionState = TcpConnectionState.TcpConnectionStageReconnecting;
|
||||||
|
@ -39,6 +39,7 @@ public class UserConfig {
|
|||||||
public static int lastPauseTime = 0;
|
public static int lastPauseTime = 0;
|
||||||
public static boolean isWaitingForPasscodeEnter = false;
|
public static boolean isWaitingForPasscodeEnter = false;
|
||||||
public static int lastUpdateVersion;
|
public static int lastUpdateVersion;
|
||||||
|
public static int lastContactsSyncTime;
|
||||||
|
|
||||||
public static int getNewMessageId() {
|
public static int getNewMessageId() {
|
||||||
int id;
|
int id;
|
||||||
@ -76,6 +77,7 @@ public class UserConfig {
|
|||||||
editor.putInt("autoLockIn", autoLockIn);
|
editor.putInt("autoLockIn", autoLockIn);
|
||||||
editor.putInt("lastPauseTime", lastPauseTime);
|
editor.putInt("lastPauseTime", lastPauseTime);
|
||||||
editor.putInt("lastUpdateVersion", lastUpdateVersion);
|
editor.putInt("lastUpdateVersion", lastUpdateVersion);
|
||||||
|
editor.putInt("lastContactsSyncTime", lastContactsSyncTime);
|
||||||
|
|
||||||
if (currentUser != null) {
|
if (currentUser != null) {
|
||||||
if (withFile) {
|
if (withFile) {
|
||||||
@ -206,6 +208,7 @@ public class UserConfig {
|
|||||||
autoLockIn = preferences.getInt("autoLockIn", 60 * 60);
|
autoLockIn = preferences.getInt("autoLockIn", 60 * 60);
|
||||||
lastPauseTime = preferences.getInt("lastPauseTime", 0);
|
lastPauseTime = preferences.getInt("lastPauseTime", 0);
|
||||||
lastUpdateVersion = preferences.getInt("lastUpdateVersion", 511);
|
lastUpdateVersion = preferences.getInt("lastUpdateVersion", 511);
|
||||||
|
lastContactsSyncTime = preferences.getInt("lastContactsSyncTime", (int) (System.currentTimeMillis() / 1000) - 23 * 60 * 60);
|
||||||
String user = preferences.getString("user", null);
|
String user = preferences.getString("user", null);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
byte[] userBytes = Base64.decode(user, Base64.DEFAULT);
|
byte[] userBytes = Base64.decode(user, Base64.DEFAULT);
|
||||||
@ -279,6 +282,7 @@ public class UserConfig {
|
|||||||
lastPauseTime = 0;
|
lastPauseTime = 0;
|
||||||
isWaitingForPasscodeEnter = false;
|
isWaitingForPasscodeEnter = false;
|
||||||
lastUpdateVersion = BuildVars.BUILD_VERSION;
|
lastUpdateVersion = BuildVars.BUILD_VERSION;
|
||||||
|
lastContactsSyncTime = (int) (System.currentTimeMillis() / 1000) - 23 * 60 * 60;
|
||||||
saveConfig(true);
|
saveConfig(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -629,7 +629,7 @@ public class Utilities {
|
|||||||
editor.commit();
|
editor.commit();
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
Utilities.loadWallpaperFromSDPath(ApplicationLoader.applicationContext, wName);
|
loadWallpaperFromSDPath(ApplicationLoader.applicationContext, wName);
|
||||||
}
|
}
|
||||||
return themeName;
|
return themeName;
|
||||||
}
|
}
|
||||||
|
@ -135,8 +135,8 @@ public class ActionBarPopupWindow extends PopupWindow {
|
|||||||
if (child.getVisibility() != VISIBLE) {
|
if (child.getVisibility() != VISIBLE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int position = positions.get(child);
|
Integer position = positions.get(child);
|
||||||
if (height - (position * AndroidUtilities.dp(48) + AndroidUtilities.dp(32)) > value * height) {
|
if (position != null && height - (position * AndroidUtilities.dp(48) + AndroidUtilities.dp(32)) > value * height) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lastStartedChild = a - 1;
|
lastStartedChild = a - 1;
|
||||||
@ -148,8 +148,8 @@ public class ActionBarPopupWindow extends PopupWindow {
|
|||||||
if (child.getVisibility() != VISIBLE) {
|
if (child.getVisibility() != VISIBLE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int position = positions.get(child);
|
Integer position = positions.get(child);
|
||||||
if ((position + 1) * AndroidUtilities.dp(48) - AndroidUtilities.dp(24) > value * height) {
|
if (position != null && (position + 1) * AndroidUtilities.dp(48) - AndroidUtilities.dp(24) > value * height) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lastStartedChild = a + 1;
|
lastStartedChild = a + 1;
|
||||||
|
@ -29,7 +29,8 @@ public class MenuDrawable extends Drawable {
|
|||||||
|
|
||||||
public MenuDrawable() {
|
public MenuDrawable() {
|
||||||
super();
|
super();
|
||||||
paint.setColor(0xffffffff);
|
//paint.setColor(0xffffffff);
|
||||||
|
paint.setColor(AndroidUtilities.getIntDef("chatsHeaderIconsColor", 0xffffffff)); //Plus
|
||||||
paint.setStrokeWidth(AndroidUtilities.dp(2));
|
paint.setStrokeWidth(AndroidUtilities.dp(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import org.telegram.SQLite.SQLiteCursor;
|
import org.telegram.SQLite.SQLiteCursor;
|
||||||
|
import org.telegram.SQLite.SQLitePreparedStatement;
|
||||||
import org.telegram.android.AndroidUtilities;
|
import org.telegram.android.AndroidUtilities;
|
||||||
import org.telegram.android.ContactsController;
|
import org.telegram.android.ContactsController;
|
||||||
import org.telegram.android.LocaleController;
|
import org.telegram.android.LocaleController;
|
||||||
@ -60,6 +61,10 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
private boolean messagesSearchEndReached;
|
private boolean messagesSearchEndReached;
|
||||||
private String lastMessagesSearchString;
|
private String lastMessagesSearchString;
|
||||||
private int lastSearchId = 0;
|
private int lastSearchId = 0;
|
||||||
|
private int dialogsType;
|
||||||
|
|
||||||
|
private ArrayList<RecentSearchObject> recentSearchObjects = new ArrayList<>();
|
||||||
|
private HashMap<Long, RecentSearchObject> recentSearchObjectsById = new HashMap<>();
|
||||||
|
|
||||||
private class Holder extends RecyclerView.ViewHolder {
|
private class Holder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
@ -74,13 +79,21 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
public CharSequence name;
|
public CharSequence name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static class RecentSearchObject {
|
||||||
|
TLObject object;
|
||||||
|
int date;
|
||||||
|
long did;
|
||||||
|
}
|
||||||
|
|
||||||
public interface MessagesActivitySearchAdapterDelegate {
|
public interface MessagesActivitySearchAdapterDelegate {
|
||||||
void searchStateChanged(boolean searching);
|
void searchStateChanged(boolean searching);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DialogsSearchAdapter(Context context, int messagesSearch) {
|
public DialogsSearchAdapter(Context context, int messagesSearch, int type) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
needMessagesSearch = messagesSearch;
|
needMessagesSearch = messagesSearch;
|
||||||
|
dialogsType = type;
|
||||||
|
loadRecentSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDelegate(MessagesActivitySearchAdapterDelegate delegate) {
|
public void setDelegate(MessagesActivitySearchAdapterDelegate delegate) {
|
||||||
@ -162,7 +175,194 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
}, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors);
|
}, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void searchDialogsInternal(final String query, final int dialogsType, final int searchId) {
|
public boolean hasRecentRearch() {
|
||||||
|
return !recentSearchObjects.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRecentSearchDisplayed() {
|
||||||
|
return (lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadRecentSearch() {
|
||||||
|
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT did, date FROM search_recent WHERE 1");
|
||||||
|
|
||||||
|
ArrayList<Integer> usersToLoad = new ArrayList<>();
|
||||||
|
ArrayList<Integer> chatsToLoad = new ArrayList<>();
|
||||||
|
ArrayList<Integer> encryptedToLoad = new ArrayList<>();
|
||||||
|
ArrayList<TLRPC.User> encUsers = new ArrayList<>();
|
||||||
|
|
||||||
|
final ArrayList<RecentSearchObject> arrayList = new ArrayList<>();
|
||||||
|
final HashMap<Long, RecentSearchObject> hashMap = new HashMap<>();
|
||||||
|
while (cursor.next()) {
|
||||||
|
long did = cursor.longValue(0);
|
||||||
|
|
||||||
|
boolean add = false;
|
||||||
|
int lower_id = (int) did;
|
||||||
|
int high_id = (int) (did >> 32);
|
||||||
|
if (lower_id != 0) {
|
||||||
|
if (high_id == 1) {
|
||||||
|
if (dialogsType == 0 && !chatsToLoad.contains(lower_id)) {
|
||||||
|
chatsToLoad.add(lower_id);
|
||||||
|
add = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (lower_id > 0) {
|
||||||
|
if (dialogsType != 2 && !usersToLoad.contains(lower_id)) {
|
||||||
|
usersToLoad.add(lower_id);
|
||||||
|
add = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!chatsToLoad.contains(-lower_id)) {
|
||||||
|
chatsToLoad.add(-lower_id);
|
||||||
|
add = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dialogsType == 0) {
|
||||||
|
if (!encryptedToLoad.contains(high_id)) {
|
||||||
|
encryptedToLoad.add(high_id);
|
||||||
|
add = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (add) {
|
||||||
|
RecentSearchObject recentSearchObject = new RecentSearchObject();
|
||||||
|
recentSearchObject.did = did;
|
||||||
|
recentSearchObject.date = cursor.intValue(1);
|
||||||
|
arrayList.add(recentSearchObject);
|
||||||
|
hashMap.put(recentSearchObject.did, recentSearchObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor.dispose();
|
||||||
|
|
||||||
|
|
||||||
|
ArrayList<TLRPC.User> users = new ArrayList<>();
|
||||||
|
|
||||||
|
if (!encryptedToLoad.isEmpty()) {
|
||||||
|
ArrayList<TLRPC.EncryptedChat> encryptedChats = new ArrayList<>();
|
||||||
|
MessagesStorage.getInstance().getEncryptedChatsInternal(TextUtils.join(",", encryptedToLoad), encryptedChats, usersToLoad);
|
||||||
|
for (int a = 0; a < encryptedChats.size(); a++) {
|
||||||
|
hashMap.get((long) encryptedChats.get(a).id << 32).object = encryptedChats.get(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chatsToLoad.isEmpty()) {
|
||||||
|
ArrayList<TLRPC.Chat> chats = new ArrayList<>();
|
||||||
|
MessagesStorage.getInstance().getChatsInternal(TextUtils.join(",", chatsToLoad), chats);
|
||||||
|
for (int a = 0; a < chats.size(); a++) {
|
||||||
|
TLRPC.Chat chat = chats.get(a);
|
||||||
|
long did;
|
||||||
|
if (chat.id > 0) {
|
||||||
|
did = -chat.id;
|
||||||
|
} else {
|
||||||
|
did = AndroidUtilities.makeBroadcastId(chat.id);
|
||||||
|
}
|
||||||
|
hashMap.get(did).object = chat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!usersToLoad.isEmpty()) {
|
||||||
|
MessagesStorage.getInstance().getUsersInternal(TextUtils.join(",", usersToLoad), users);
|
||||||
|
for (int a = 0; a < users.size(); a++) {
|
||||||
|
TLRPC.User user = users.get(a);
|
||||||
|
RecentSearchObject recentSearchObject = hashMap.get((long) user.id);
|
||||||
|
if (recentSearchObject != null) {
|
||||||
|
recentSearchObject.object = user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(arrayList, new Comparator<RecentSearchObject>() {
|
||||||
|
@Override
|
||||||
|
public int compare(RecentSearchObject lhs, RecentSearchObject rhs) {
|
||||||
|
if (lhs.date < rhs.date) {
|
||||||
|
return 1;
|
||||||
|
} else if (lhs.date > rhs.date) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
setRecentSearch(arrayList, hashMap);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putRecentSearch(final long did, TLObject object) {
|
||||||
|
RecentSearchObject recentSearchObject = recentSearchObjectsById.get(did);
|
||||||
|
if (recentSearchObject == null) {
|
||||||
|
recentSearchObject = new RecentSearchObject();
|
||||||
|
recentSearchObjectsById.put(did, recentSearchObject);
|
||||||
|
} else {
|
||||||
|
recentSearchObjects.remove(recentSearchObject);
|
||||||
|
}
|
||||||
|
recentSearchObjects.add(0, recentSearchObject);
|
||||||
|
recentSearchObject.did = did;
|
||||||
|
recentSearchObject.object = object;
|
||||||
|
recentSearchObject.date = (int) System.currentTimeMillis() / 1000;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO search_recent VALUES(?, ?)");
|
||||||
|
state.requery();
|
||||||
|
state.bindLong(1, did);
|
||||||
|
state.bindInteger(2, (int) System.currentTimeMillis() / 1000);
|
||||||
|
state.step();
|
||||||
|
state.dispose();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearRecentSearch() {
|
||||||
|
recentSearchObjectsById = new HashMap<>();
|
||||||
|
recentSearchObjects = new ArrayList<>();
|
||||||
|
notifyDataSetChanged();
|
||||||
|
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM search_recent WHERE 1").stepThis().dispose();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRecentSearch(ArrayList<RecentSearchObject> arrayList, HashMap<Long, RecentSearchObject> hashMap) {
|
||||||
|
recentSearchObjects = arrayList;
|
||||||
|
recentSearchObjectsById = hashMap;
|
||||||
|
for (int a = 0; a < recentSearchObjects.size(); a++) {
|
||||||
|
RecentSearchObject recentSearchObject = recentSearchObjects.get(a);
|
||||||
|
if (recentSearchObject.object instanceof TLRPC.User) {
|
||||||
|
MessagesController.getInstance().putUser((TLRPC.User) recentSearchObject.object, true);
|
||||||
|
} else if (recentSearchObject.object instanceof TLRPC.Chat) {
|
||||||
|
MessagesController.getInstance().putChat((TLRPC.Chat) recentSearchObject.object, true);
|
||||||
|
} else if (recentSearchObject.object instanceof TLRPC.EncryptedChat) {
|
||||||
|
MessagesController.getInstance().putEncryptedChat((TLRPC.EncryptedChat) recentSearchObject.object, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void searchDialogsInternal(final String query, final int searchId) {
|
||||||
if (needMessagesSearch == 2) {
|
if (needMessagesSearch == 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -479,10 +679,6 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLastSearchText() {
|
|
||||||
return lastSearchText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isGlobalSearch(int i) {
|
public boolean isGlobalSearch(int i) {
|
||||||
return i > searchResult.size() && i <= globalSearch.size() + searchResult.size();
|
return i > searchResult.size() && i <= globalSearch.size() + searchResult.size();
|
||||||
}
|
}
|
||||||
@ -506,10 +702,11 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void searchDialogs(final String query, final int dialogsType) {
|
public void searchDialogs(final String query) {
|
||||||
if (query != null && lastSearchText != null && query.equals(lastSearchText)) {
|
if (query != null && lastSearchText != null && query.equals(lastSearchText)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
lastSearchText = query;
|
||||||
try {
|
try {
|
||||||
if (searchTimer != null) {
|
if (searchTimer != null) {
|
||||||
searchTimer.cancel();
|
searchTimer.cancel();
|
||||||
@ -564,7 +761,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
}
|
}
|
||||||
searchDialogsInternal(query, dialogsType, searchId);
|
searchDialogsInternal(query, searchId);
|
||||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -581,6 +778,9 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
|
if ((lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
|
||||||
|
return recentSearchObjects.size() + 1;
|
||||||
|
}
|
||||||
if (!searchResultHashtags.isEmpty()) {
|
if (!searchResultHashtags.isEmpty()) {
|
||||||
return searchResultHashtags.size() + 1;
|
return searchResultHashtags.size() + 1;
|
||||||
}
|
}
|
||||||
@ -597,8 +797,19 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Object getItem(int i) {
|
public Object getItem(int i) {
|
||||||
|
if ((lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
|
||||||
|
if (i > 0 && i - 1 < recentSearchObjects.size()) {
|
||||||
|
return recentSearchObjects.get(i - 1).object;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!searchResultHashtags.isEmpty()) {
|
if (!searchResultHashtags.isEmpty()) {
|
||||||
|
if (i > 0) {
|
||||||
return searchResultHashtags.get(i - 1);
|
return searchResultHashtags.get(i - 1);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int localCount = searchResult.size();
|
int localCount = searchResult.size();
|
||||||
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
|
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
|
||||||
@ -652,11 +863,14 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
TLRPC.User user = null;
|
TLRPC.User user = null;
|
||||||
TLRPC.Chat chat = null;
|
TLRPC.Chat chat = null;
|
||||||
TLRPC.EncryptedChat encryptedChat = null;
|
TLRPC.EncryptedChat encryptedChat = null;
|
||||||
|
CharSequence username = null;
|
||||||
|
CharSequence name = null;
|
||||||
|
boolean isRecent = false;
|
||||||
|
|
||||||
int localCount = searchResult.size();
|
|
||||||
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
|
|
||||||
String hexDarkColor = String.format("#%08X", (0xFFFFFFFF & AndroidUtilities.getIntDarkerColor("themeColor", 0x15)));
|
String hexDarkColor = String.format("#%08X", (0xFFFFFFFF & AndroidUtilities.getIntDarkerColor("themeColor", 0x15)));
|
||||||
cell.useSeparator = (position != getItemCount() - 1 && position != localCount - 1 && position != localCount + globalCount - 1);
|
|
||||||
Object obj = getItem(position);
|
Object obj = getItem(position);
|
||||||
if (obj instanceof TLRPC.User) {
|
if (obj instanceof TLRPC.User) {
|
||||||
user = (TLRPC.User) obj;
|
user = (TLRPC.User) obj;
|
||||||
@ -667,8 +881,14 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
user = MessagesController.getInstance().getUser(encryptedChat.user_id);
|
user = MessagesController.getInstance().getUser(encryptedChat.user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
CharSequence username = null;
|
if ((lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
|
||||||
CharSequence name = null;
|
isRecent = true;
|
||||||
|
cell.useSeparator = position != getItemCount() - 1;
|
||||||
|
} else {
|
||||||
|
int localCount = searchResult.size();
|
||||||
|
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
|
||||||
|
cell.useSeparator = (position != getItemCount() - 1 && position != localCount - 1 && position != localCount + globalCount - 1);
|
||||||
|
|
||||||
if (position < searchResult.size()) {
|
if (position < searchResult.size()) {
|
||||||
name = searchResultNames.get(position);
|
name = searchResultNames.get(position);
|
||||||
if (name != null && user != null && user.username != null && user.username.length() > 0) {
|
if (name != null && user != null && user.username != null && user.username.length() > 0) {
|
||||||
@ -690,15 +910,17 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
cell.setData(user, chat, encryptedChat, name, username);
|
cell.setData(user, chat, encryptedChat, name, username, isRecent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
GreySectionCell cell = (GreySectionCell) holder.itemView;
|
GreySectionCell cell = (GreySectionCell) holder.itemView;
|
||||||
cell.setBackgroundColor(themePrefs.getInt("chatsRowColor", 0xfff2f2f2));
|
cell.setBackgroundColor(themePrefs.getInt("chatsRowColor", 0xfff2f2f2));
|
||||||
cell.setTextColor(themePrefs.getInt("chatsNameColor", 0xff8a8a8a));
|
cell.setTextColor(themePrefs.getInt("chatsNameColor", 0xff8a8a8a));
|
||||||
if (!searchResultHashtags.isEmpty()) {
|
if ((lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
|
||||||
|
cell.setText(LocaleController.getString("Recent", R.string.Recent).toUpperCase());
|
||||||
|
} else if (!searchResultHashtags.isEmpty()) {
|
||||||
cell.setText(LocaleController.getString("Hashtags", R.string.Hashtags).toUpperCase());
|
cell.setText(LocaleController.getString("Hashtags", R.string.Hashtags).toUpperCase());
|
||||||
} else if (!globalSearch.isEmpty() && position == searchResult.size()) {
|
} else if (!globalSearch.isEmpty() && position == searchResult.size()) {
|
||||||
cell.setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch));
|
cell.setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch));
|
||||||
@ -729,6 +951,9 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemViewType(int i) {
|
public int getItemViewType(int i) {
|
||||||
|
if ((lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
|
||||||
|
return i == 0 ? 1 : 0;
|
||||||
|
}
|
||||||
if (!searchResultHashtags.isEmpty()) {
|
if (!searchResultHashtags.isEmpty()) {
|
||||||
return i == 0 ? 1 : 4;
|
return i == 0 ? 1 : 4;
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ public class SearchAdapter extends BaseSearchAdapter {
|
|||||||
((UserCell) view).setChecked(checkedMap.containsKey(user.id), false);
|
((UserCell) view).setChecked(checkedMap.containsKey(user.id), false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
((ProfileSearchCell) view).setData(user, null, null, name, username);
|
((ProfileSearchCell) view).setData(user, null, null, name, username, false);
|
||||||
((ProfileSearchCell) view).useSeparator = (i != getCount() - 1 && i != searchResult.size() - 1);
|
((ProfileSearchCell) view).useSeparator = (i != getCount() - 1 && i != searchResult.size() - 1);
|
||||||
if (ignoreUsers != null) {
|
if (ignoreUsers != null) {
|
||||||
if (ignoreUsers.containsKey(user.id)) {
|
if (ignoreUsers.containsKey(user.id)) {
|
||||||
|
@ -288,6 +288,7 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe
|
|||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
view = new UserCell(mContext, 1);
|
view = new UserCell(mContext, 1);
|
||||||
|
view.setTag("Pref");
|
||||||
}
|
}
|
||||||
((UserCell) view).setNameColor(preferences.getInt("prefTitleColor", 0xff212121));
|
((UserCell) view).setNameColor(preferences.getInt("prefTitleColor", 0xff212121));
|
||||||
((UserCell) view).setStatusColor(preferences.getInt("prefSummaryColor", 0xff8a8a8a));
|
((UserCell) view).setStatusColor(preferences.getInt("prefSummaryColor", 0xff8a8a8a));
|
||||||
|
@ -56,7 +56,9 @@ public class BaseCell extends View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void setDrawableBounds(Drawable drawable, int x, int y, int w, int h) {
|
protected void setDrawableBounds(Drawable drawable, int x, int y, int w, int h) {
|
||||||
drawable.setBounds(x, y, x + w, y + h);
|
if (drawable != null) {
|
||||||
|
drawable.setBounds(x, y, x + w, y + h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void startCheckLongPress() {
|
protected void startCheckLongPress() {
|
||||||
|
@ -22,16 +22,18 @@ import org.telegram.android.AndroidUtilities;
|
|||||||
import org.telegram.android.ImageLoader;
|
import org.telegram.android.ImageLoader;
|
||||||
import org.telegram.android.MessagesController;
|
import org.telegram.android.MessagesController;
|
||||||
import org.telegram.android.SendMessagesHelper;
|
import org.telegram.android.SendMessagesHelper;
|
||||||
|
import org.telegram.messenger.BuildVars;
|
||||||
import org.telegram.messenger.FileLoader;
|
import org.telegram.messenger.FileLoader;
|
||||||
import org.telegram.android.MediaController;
|
import org.telegram.android.MediaController;
|
||||||
import org.telegram.android.MessageObject;
|
import org.telegram.android.MessageObject;
|
||||||
|
import org.telegram.messenger.FileLog;
|
||||||
import org.telegram.ui.Components.RadialProgress;
|
import org.telegram.ui.Components.RadialProgress;
|
||||||
import org.telegram.ui.Components.ResourceLoader;
|
import org.telegram.ui.Components.ResourceLoader;
|
||||||
import org.telegram.ui.Components.SeekBar;
|
import org.telegram.ui.Components.SeekBar;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelegate, MediaController.FileDownloadProgressListener {
|
public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelegate {
|
||||||
|
|
||||||
private static TextPaint timePaint;
|
private static TextPaint timePaint;
|
||||||
private static Paint circlePaint;
|
private static Paint circlePaint;
|
||||||
@ -51,11 +53,8 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
|
|||||||
private int timeWidth;
|
private int timeWidth;
|
||||||
private String lastTimeString = null;
|
private String lastTimeString = null;
|
||||||
|
|
||||||
private int TAG;
|
|
||||||
|
|
||||||
public ChatAudioCell(Context context) {
|
public ChatAudioCell(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
TAG = MediaController.getInstance().generateObserverTag();
|
|
||||||
|
|
||||||
seekBar = new SeekBar(context);
|
seekBar = new SeekBar(context);
|
||||||
seekBar.delegate = this;
|
seekBar.delegate = this;
|
||||||
@ -222,6 +221,9 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
|
|||||||
if (cacheFile == null) {
|
if (cacheFile == null) {
|
||||||
cacheFile = FileLoader.getPathToMessage(currentMessageObject.messageOwner);
|
cacheFile = FileLoader.getPathToMessage(currentMessageObject.messageOwner);
|
||||||
}
|
}
|
||||||
|
if (BuildVars.DEBUG_VERSION) {
|
||||||
|
FileLog.d("tmessages", "looking for audio in " + cacheFile);
|
||||||
|
}
|
||||||
if (cacheFile.exists()) {
|
if (cacheFile.exists()) {
|
||||||
MediaController.getInstance().removeLoadingFileObserver(this);
|
MediaController.getInstance().removeLoadingFileObserver(this);
|
||||||
boolean playing = MediaController.getInstance().isPlayingAudio(currentMessageObject);
|
boolean playing = MediaController.getInstance().isPlayingAudio(currentMessageObject);
|
||||||
@ -277,11 +279,6 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
|
|||||||
radialProgress.setProgress(progress, true);
|
radialProgress.setProgress(progress, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getObserverTag() {
|
|
||||||
return TAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSeekBarDrag(float progress) {
|
public void onSeekBarDrag(float progress) {
|
||||||
if (currentMessageObject == null) {
|
if (currentMessageObject == null) {
|
||||||
@ -382,7 +379,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
|
|||||||
timePaint.setColor(0xffa1aab3);
|
timePaint.setColor(0xffa1aab3);
|
||||||
circlePaint.setColor(0xff4195e5);
|
circlePaint.setColor(0xff4195e5);
|
||||||
}
|
}
|
||||||
radialProgress.onDraw(canvas);
|
radialProgress.draw(canvas);
|
||||||
|
|
||||||
canvas.save();
|
canvas.save();
|
||||||
canvas.translate(timeX, AndroidUtilities.dp(42) + namesOffset);
|
canvas.translate(timeX, AndroidUtilities.dp(42) + namesOffset);
|
||||||
|
@ -28,6 +28,7 @@ import org.telegram.android.AndroidUtilities;
|
|||||||
import org.telegram.android.Emoji;
|
import org.telegram.android.Emoji;
|
||||||
import org.telegram.android.ImageReceiver;
|
import org.telegram.android.ImageReceiver;
|
||||||
import org.telegram.android.LocaleController;
|
import org.telegram.android.LocaleController;
|
||||||
|
import org.telegram.android.MediaController;
|
||||||
import org.telegram.android.MessageObject;
|
import org.telegram.android.MessageObject;
|
||||||
import org.telegram.android.MessagesController;
|
import org.telegram.android.MessagesController;
|
||||||
import org.telegram.android.UserObject;
|
import org.telegram.android.UserObject;
|
||||||
@ -41,7 +42,7 @@ import org.telegram.ui.Components.LinkPath;
|
|||||||
import org.telegram.ui.Components.ResourceLoader;
|
import org.telegram.ui.Components.ResourceLoader;
|
||||||
import org.telegram.ui.Components.StaticLayoutEx;
|
import org.telegram.ui.Components.StaticLayoutEx;
|
||||||
|
|
||||||
public class ChatBaseCell extends BaseCell {
|
public class ChatBaseCell extends BaseCell implements MediaController.FileDownloadProgressListener {
|
||||||
|
|
||||||
public interface ChatBaseCellDelegate {
|
public interface ChatBaseCellDelegate {
|
||||||
void didPressedUserAvatar(ChatBaseCell cell, TLRPC.User user);
|
void didPressedUserAvatar(ChatBaseCell cell, TLRPC.User user);
|
||||||
@ -50,6 +51,7 @@ public class ChatBaseCell extends BaseCell {
|
|||||||
void didPressReplyMessage(ChatBaseCell cell, int id);
|
void didPressReplyMessage(ChatBaseCell cell, int id);
|
||||||
void didPressUrl(MessageObject messageObject, String url);
|
void didPressUrl(MessageObject messageObject, String url);
|
||||||
void needOpenWebView(String url, String title, String originalUrl, int w, int h);
|
void needOpenWebView(String url, String title, String originalUrl, int w, int h);
|
||||||
|
void didClickedImage(ChatBaseCell cell);
|
||||||
boolean canPerformActions();
|
boolean canPerformActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +59,7 @@ public class ChatBaseCell extends BaseCell {
|
|||||||
protected boolean linkPreviewPressed;
|
protected boolean linkPreviewPressed;
|
||||||
protected LinkPath urlPath = new LinkPath();
|
protected LinkPath urlPath = new LinkPath();
|
||||||
protected static Paint urlPaint;
|
protected static Paint urlPaint;
|
||||||
|
private int TAG;
|
||||||
|
|
||||||
public boolean isChat = false;
|
public boolean isChat = false;
|
||||||
protected boolean isPressed = false;
|
protected boolean isPressed = false;
|
||||||
@ -185,6 +188,7 @@ public class ChatBaseCell extends BaseCell {
|
|||||||
avatarImage.setRoundRadius(AndroidUtilities.dp(21));
|
avatarImage.setRoundRadius(AndroidUtilities.dp(21));
|
||||||
avatarDrawable = new AvatarDrawable();
|
avatarDrawable = new AvatarDrawable();
|
||||||
replyImageReceiver = new ImageReceiver(this);
|
replyImageReceiver = new ImageReceiver(this);
|
||||||
|
TAG = MediaController.getInstance().generateObserverTag();
|
||||||
//Chat Photo
|
//Chat Photo
|
||||||
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
||||||
int radius = AndroidUtilities.dp(themePrefs.getInt("chatAvatarRadius", 32));
|
int radius = AndroidUtilities.dp(themePrefs.getInt("chatAvatarRadius", 32));
|
||||||
@ -719,6 +723,10 @@ public class ChatBaseCell extends BaseCell {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImageReceiver getPhotoImage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onLongPress() {
|
protected void onLongPress() {
|
||||||
if (delegate != null) {
|
if (delegate != null) {
|
||||||
@ -783,7 +791,7 @@ public class ChatBaseCell extends BaseCell {
|
|||||||
setDrawableBounds(currentBackgroundDrawable, (!media ? 0 : AndroidUtilities.dp(9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2));
|
setDrawableBounds(currentBackgroundDrawable, (!media ? 0 : AndroidUtilities.dp(9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (drawBackground) {
|
if (drawBackground && currentBackgroundDrawable != null) {
|
||||||
currentBackgroundDrawable.draw(canvas);
|
currentBackgroundDrawable.draw(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1061,4 +1069,29 @@ public class ChatBaseCell extends BaseCell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailedDownload(String fileName) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccessDownload(String fileName) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgressDownload(String fileName, float progress) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgressUpload(String fileName, float progress, boolean isEncrypted) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getObserverTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,11 +52,9 @@ import org.telegram.ui.PhotoViewer;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class ChatMediaCell extends ChatBaseCell implements MediaController.FileDownloadProgressListener {
|
public class ChatMediaCell extends ChatBaseCell {
|
||||||
|
|
||||||
public interface ChatMediaCellDelegate {
|
public interface ChatMediaCellDelegate {
|
||||||
void didClickedImage(ChatMediaCell cell);
|
|
||||||
|
|
||||||
void didPressedOther(ChatMediaCell cell);
|
void didPressedOther(ChatMediaCell cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,8 +82,6 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
|||||||
|
|
||||||
private boolean allowedToSetPhoto = true;
|
private boolean allowedToSetPhoto = true;
|
||||||
|
|
||||||
private int TAG;
|
|
||||||
|
|
||||||
private int buttonState = 0;
|
private int buttonState = 0;
|
||||||
private int buttonPressed = 0;
|
private int buttonPressed = 0;
|
||||||
private boolean imagePressed = false;
|
private boolean imagePressed = false;
|
||||||
@ -143,8 +139,6 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
|||||||
locationAddressPaint.setTextSize(AndroidUtilities.dp(14));
|
locationAddressPaint.setTextSize(AndroidUtilities.dp(14));
|
||||||
}
|
}
|
||||||
|
|
||||||
TAG = MediaController.getInstance().generateObserverTag();
|
|
||||||
|
|
||||||
photoImage = new ImageReceiver(this);
|
photoImage = new ImageReceiver(this);
|
||||||
radialProgress = new RadialProgress(this);
|
radialProgress = new RadialProgress(this);
|
||||||
}
|
}
|
||||||
@ -359,8 +353,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
|||||||
private void didClickedImage() {
|
private void didClickedImage() {
|
||||||
if (currentMessageObject.type == 1) {
|
if (currentMessageObject.type == 1) {
|
||||||
if (buttonState == -1) {
|
if (buttonState == -1) {
|
||||||
if (mediaDelegate != null) {
|
if (delegate != null) {
|
||||||
mediaDelegate.didClickedImage(this);
|
delegate.didClickedImage(this);
|
||||||
}
|
}
|
||||||
} else if (buttonState == 0) {
|
} else if (buttonState == 0) {
|
||||||
didPressedButton(false);
|
didPressedButton(false);
|
||||||
@ -381,13 +375,13 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
|||||||
didPressedButton(false);
|
didPressedButton(false);
|
||||||
}
|
}
|
||||||
} else if (currentMessageObject.type == 4) {
|
} else if (currentMessageObject.type == 4) {
|
||||||
if (mediaDelegate != null) {
|
if (delegate != null) {
|
||||||
mediaDelegate.didClickedImage(this);
|
delegate.didClickedImage(this);
|
||||||
}
|
}
|
||||||
} else if (currentMessageObject.type == 9) {
|
} else if (currentMessageObject.type == 9) {
|
||||||
if (buttonState == -1) {
|
if (buttonState == -1) {
|
||||||
if (mediaDelegate != null) {
|
if (delegate != null) {
|
||||||
mediaDelegate.didClickedImage(this);
|
delegate.didClickedImage(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,8 +457,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
|||||||
radialProgress.setBackground(getDrawableForCurrentState(), false, animated);
|
radialProgress.setBackground(getDrawableForCurrentState(), false, animated);
|
||||||
}
|
}
|
||||||
} else if (buttonState == 3) {
|
} else if (buttonState == 3) {
|
||||||
if (mediaDelegate != null) {
|
if (delegate != null) {
|
||||||
mediaDelegate.didClickedImage(this);
|
delegate.didClickedImage(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -931,6 +925,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
|||||||
updateButtonState(dataChanged);
|
updateButtonState(dataChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ImageReceiver getPhotoImage() {
|
public ImageReceiver getPhotoImage() {
|
||||||
return photoImage;
|
return photoImage;
|
||||||
}
|
}
|
||||||
@ -981,10 +976,11 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
|||||||
if (cacheFile.exists() && cacheFile.length() == 0) {
|
if (cacheFile.exists() && cacheFile.length() == 0) {
|
||||||
cacheFile.delete();
|
cacheFile.delete();
|
||||||
}
|
}
|
||||||
//
|
//Plus
|
||||||
if (!currentMessageObject.isOut() && cacheFile.exists() && cacheFile.length() != 0 && currentMessageObject.messageOwner.media.document != null) {
|
//if (!currentMessageObject.isOut() && cacheFile.exists() && cacheFile.length() != 0 && currentMessageObject.messageOwner.media.document != null) {
|
||||||
if(cacheFile.lastModified()/1000 < currentMessageObject.messageOwner.media.document.date)cacheFile.delete();
|
// Log.e("ChatMediaCell", cacheFile.getAbsolutePath().toString());
|
||||||
}
|
// if(cacheFile.lastModified()/1000 < currentMessageObject.messageOwner.media.document.date)cacheFile.delete();
|
||||||
|
//}
|
||||||
//
|
//
|
||||||
if (!cacheFile.exists()) {
|
if (!cacheFile.exists()) {
|
||||||
MediaController.getInstance().addLoadingFileObserver(fileName, this);
|
MediaController.getInstance().addLoadingFileObserver(fileName, this);
|
||||||
@ -1187,7 +1183,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
radialProgress.onDraw(canvas);
|
radialProgress.draw(canvas);
|
||||||
try{
|
try{
|
||||||
if(themePrefs.getBoolean("chatMemberColorCheck", false)){
|
if(themePrefs.getBoolean("chatMemberColorCheck", false)){
|
||||||
senderPaint.setColor(themePrefs.getInt("chatMemberColor", AndroidUtilities.getIntDarkerColor("themeColor", 0x15)));
|
senderPaint.setColor(themePrefs.getInt("chatMemberColor", AndroidUtilities.getIntDarkerColor("themeColor", 0x15)));
|
||||||
@ -1321,9 +1317,4 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
|||||||
public void onProgressUpload(String fileName, float progress, boolean isEncrypted) {
|
public void onProgressUpload(String fileName, float progress, boolean isEncrypted) {
|
||||||
radialProgress.setProgress(progress, true);
|
radialProgress.setProgress(progress, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getObserverTag() {
|
|
||||||
return TAG;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,10 @@ import android.text.TextPaint;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.style.ClickableSpan;
|
import android.text.style.ClickableSpan;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
import android.view.SoundEffectConstants;
|
||||||
|
|
||||||
import org.telegram.android.AndroidUtilities;
|
import org.telegram.android.AndroidUtilities;
|
||||||
|
import org.telegram.android.ImageLoader;
|
||||||
import org.telegram.android.ImageReceiver;
|
import org.telegram.android.ImageReceiver;
|
||||||
import org.telegram.android.MediaController;
|
import org.telegram.android.MediaController;
|
||||||
import org.telegram.android.MessageObject;
|
import org.telegram.android.MessageObject;
|
||||||
@ -35,6 +37,7 @@ import org.telegram.messenger.FileLoader;
|
|||||||
import org.telegram.messenger.FileLog;
|
import org.telegram.messenger.FileLog;
|
||||||
import org.telegram.messenger.R;
|
import org.telegram.messenger.R;
|
||||||
import org.telegram.messenger.TLRPC;
|
import org.telegram.messenger.TLRPC;
|
||||||
|
import org.telegram.ui.Components.RadialProgress;
|
||||||
import org.telegram.ui.Components.ResourceLoader;
|
import org.telegram.ui.Components.ResourceLoader;
|
||||||
import org.telegram.ui.Components.StaticLayoutEx;
|
import org.telegram.ui.Components.StaticLayoutEx;
|
||||||
import org.telegram.ui.Components.URLSpanNoUnderline;
|
import org.telegram.ui.Components.URLSpanNoUnderline;
|
||||||
@ -52,8 +55,10 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
private int firstVisibleBlockNum = 0;
|
private int firstVisibleBlockNum = 0;
|
||||||
private int totalVisibleBlocksCount = 0;
|
private int totalVisibleBlocksCount = 0;
|
||||||
|
|
||||||
|
private RadialProgress radialProgress;
|
||||||
private ImageReceiver linkImageView;
|
private ImageReceiver linkImageView;
|
||||||
private boolean isSmallImage;
|
private boolean isSmallImage;
|
||||||
|
private boolean drawImageButton;
|
||||||
private boolean drawLinkImageView;
|
private boolean drawLinkImageView;
|
||||||
private boolean hasLinkPreview;
|
private boolean hasLinkPreview;
|
||||||
private int linkPreviewHeight;
|
private int linkPreviewHeight;
|
||||||
@ -70,19 +75,31 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
private StaticLayout authorLayout;
|
private StaticLayout authorLayout;
|
||||||
private static TextPaint durationPaint;
|
private static TextPaint durationPaint;
|
||||||
|
|
||||||
|
private int buttonX;
|
||||||
|
private int buttonY;
|
||||||
|
private int buttonState;
|
||||||
|
private boolean buttonPressed;
|
||||||
|
private boolean photoNotSet;
|
||||||
|
private TLRPC.PhotoSize currentPhotoObject;
|
||||||
|
private TLRPC.PhotoSize currentPhotoObjectThumb;
|
||||||
|
private String currentPhotoFilter;
|
||||||
|
private String currentPhotoFilterThumb;
|
||||||
|
private boolean cancelLoading;
|
||||||
|
|
||||||
private static Drawable igvideoDrawable;
|
private static Drawable igvideoDrawable;
|
||||||
|
|
||||||
public ChatMessageCell(Context context) {
|
public ChatMessageCell(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
drawForwardedName = true;
|
drawForwardedName = true;
|
||||||
linkImageView = new ImageReceiver(this);
|
linkImageView = new ImageReceiver(this);
|
||||||
|
radialProgress = new RadialProgress(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
if (currentMessageObject != null && currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty() && currentMessageObject.messageText instanceof Spannable && delegate.canPerformActions()) {
|
if (currentMessageObject != null && currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty() && currentMessageObject.messageText instanceof Spannable && delegate.canPerformActions()) {
|
||||||
if (event.getAction() == MotionEvent.ACTION_DOWN || (linkPreviewPressed || pressedLink != null) && event.getAction() == MotionEvent.ACTION_UP) {
|
if (event.getAction() == MotionEvent.ACTION_DOWN || (linkPreviewPressed || pressedLink != null || buttonPressed) && event.getAction() == MotionEvent.ACTION_UP) {
|
||||||
int x = (int) event.getX();
|
int x = (int) event.getX();
|
||||||
int y = (int) event.getY();
|
int y = (int) event.getY();
|
||||||
if (x >= textX && y >= textY && x <= textX + currentMessageObject.textWidth && y <= textY + currentMessageObject.textHeight) {
|
if (x >= textX && y >= textY && x <= textX + currentMessageObject.textWidth && y <= textY + currentMessageObject.textHeight) {
|
||||||
@ -150,8 +167,13 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
resetPressedLink();
|
resetPressedLink();
|
||||||
if (drawLinkImageView && linkImageView.isInsideImage(x, y)) {
|
if (drawLinkImageView && linkImageView.isInsideImage(x, y)) {
|
||||||
|
if (drawImageButton && buttonState != -1 && x >= buttonX && x <= buttonX + AndroidUtilities.dp(48) && y >= buttonY && y <= buttonY + AndroidUtilities.dp(48)) {
|
||||||
|
buttonPressed = true;
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
linkPreviewPressed = true;
|
linkPreviewPressed = true;
|
||||||
result = true;
|
result = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (descriptionLayout != null && y >= descriptionY) {
|
if (descriptionLayout != null && y >= descriptionY) {
|
||||||
try {
|
try {
|
||||||
@ -194,8 +216,11 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
if (pressedLink != null) {
|
if (pressedLink != null) {
|
||||||
pressedLink.onClick(this);
|
pressedLink.onClick(this);
|
||||||
} else {
|
} else {
|
||||||
|
if (drawImageButton && delegate != null) {
|
||||||
|
delegate.didClickedImage(this);
|
||||||
|
} else {
|
||||||
TLRPC.WebPage webPage = currentMessageObject.messageOwner.media.webpage;
|
TLRPC.WebPage webPage = currentMessageObject.messageOwner.media.webpage;
|
||||||
if (Build.VERSION.SDK_INT >= 19 && webPage.embed_url != null && webPage.embed_url.length() != 0) {
|
if (Build.VERSION.SDK_INT >= 16 && webPage.embed_url != null && webPage.embed_url.length() != 0) {
|
||||||
delegate.needOpenWebView(webPage.embed_url, webPage.site_name, webPage.url, webPage.embed_width, webPage.embed_height);
|
delegate.needOpenWebView(webPage.embed_url, webPage.site_name, webPage.url, webPage.embed_width, webPage.embed_height);
|
||||||
} else {
|
} else {
|
||||||
Uri uri = Uri.parse(webPage.url);
|
Uri uri = Uri.parse(webPage.url);
|
||||||
@ -204,11 +229,27 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
getContext().startActivity(intent);
|
getContext().startActivity(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
}
|
}
|
||||||
resetPressedLink();
|
resetPressedLink();
|
||||||
result = true;
|
result = true;
|
||||||
|
} else if (buttonPressed) {
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||||
|
buttonPressed = false;
|
||||||
|
playSoundEffect(SoundEffectConstants.CLICK);
|
||||||
|
didPressedButton(false);
|
||||||
|
invalidate();
|
||||||
|
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||||
|
buttonPressed = false;
|
||||||
|
invalidate();
|
||||||
|
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||||
|
if (!(x >= buttonX && x <= buttonX + AndroidUtilities.dp(48) && y >= buttonY && y <= buttonY + AndroidUtilities.dp(48))) {
|
||||||
|
buttonPressed = false;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resetPressedLink();
|
resetPressedLink();
|
||||||
@ -263,7 +304,7 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
return left1 <= right2;
|
return left1 <= right2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StaticLayout generateStaticLayout(CharSequence text, TextPaint paint, int maxWidth, int smallWidth, int linesCount, int maxLines) {
|
public static StaticLayout generateStaticLayout(CharSequence text, TextPaint paint, int maxWidth, int smallWidth, int linesCount, int maxLines) {
|
||||||
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(text);
|
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(text);
|
||||||
int addedChars = 0;
|
int addedChars = 0;
|
||||||
StaticLayout layout = new StaticLayout(text, paint, smallWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
StaticLayout layout = new StaticLayout(text, paint, smallWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||||
@ -298,21 +339,30 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
return super.isUserDataChanged();
|
return super.isUserDataChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImageReceiver getPhotoImage() {
|
||||||
|
return linkImageView;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDetachedFromWindow() {
|
protected void onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
linkImageView.onDetachedFromWindow();
|
linkImageView.onDetachedFromWindow();
|
||||||
|
MediaController.getInstance().removeLoadingFileObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onAttachedToWindow() {
|
protected void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
linkImageView.onAttachedToWindow();
|
if (linkImageView.onAttachedToWindow()) {
|
||||||
|
updateButtonState(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMessageObject(MessageObject messageObject) {
|
public void setMessageObject(MessageObject messageObject) {
|
||||||
if (currentMessageObject != messageObject || isUserDataChanged()) {
|
boolean dataChanged = currentMessageObject == messageObject && (isUserDataChanged() || photoNotSet);
|
||||||
|
if (currentMessageObject != messageObject || dataChanged) {
|
||||||
if (currentMessageObject != messageObject) {
|
if (currentMessageObject != messageObject) {
|
||||||
firstVisibleBlockNum = 0;
|
firstVisibleBlockNum = 0;
|
||||||
lastVisibleBlockNum = 0;
|
lastVisibleBlockNum = 0;
|
||||||
@ -321,6 +371,7 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
hasLinkPreview = false;
|
hasLinkPreview = false;
|
||||||
resetPressedLink();
|
resetPressedLink();
|
||||||
linkPreviewPressed = false;
|
linkPreviewPressed = false;
|
||||||
|
buttonPressed = false;
|
||||||
linkPreviewHeight = 0;
|
linkPreviewHeight = 0;
|
||||||
isInstagram = false;
|
isInstagram = false;
|
||||||
durationLayout = null;
|
durationLayout = null;
|
||||||
@ -328,6 +379,10 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
titleLayout = null;
|
titleLayout = null;
|
||||||
siteNameLayout = null;
|
siteNameLayout = null;
|
||||||
authorLayout = null;
|
authorLayout = null;
|
||||||
|
drawImageButton = false;
|
||||||
|
currentPhotoObject = null;
|
||||||
|
currentPhotoObjectThumb = null;
|
||||||
|
currentPhotoFilter = null;
|
||||||
int maxWidth;
|
int maxWidth;
|
||||||
|
|
||||||
if (AndroidUtilities.isTablet()) {
|
if (AndroidUtilities.isTablet()) {
|
||||||
@ -352,13 +407,10 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
|
|
||||||
backgroundWidth = maxWidth;
|
backgroundWidth = maxWidth;
|
||||||
|
|
||||||
//Log.e("setMessageObject 1", "backgroundWidth " + backgroundWidth+" layoutWidth " + layoutWidth);
|
|
||||||
|
|
||||||
super.setMessageObject(messageObject);
|
super.setMessageObject(messageObject);
|
||||||
|
|
||||||
backgroundWidth = messageObject.textWidth;
|
backgroundWidth = messageObject.textWidth;
|
||||||
totalHeight = messageObject.textHeight + AndroidUtilities.dp(19.5f) + namesOffset;
|
totalHeight = messageObject.textHeight + AndroidUtilities.dp(19.5f) + namesOffset;
|
||||||
//Log.e("setMessageObject 2", "backgroundWidth " + backgroundWidth+" namesOffset " + namesOffset);
|
|
||||||
|
|
||||||
int maxChildWidth = Math.max(backgroundWidth, nameWidth);
|
int maxChildWidth = Math.max(backgroundWidth, nameWidth);
|
||||||
maxChildWidth = Math.max(maxChildWidth, forwardedNameWidth);
|
maxChildWidth = Math.max(maxChildWidth, forwardedNameWidth);
|
||||||
@ -551,9 +603,10 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
smallImage = false;
|
smallImage = false;
|
||||||
isSmallImage = false;
|
isSmallImage = false;
|
||||||
}
|
}
|
||||||
|
drawImageButton = webPage.type != null && webPage.type.equals("photo");
|
||||||
int maxPhotoWidth = smallImage ? AndroidUtilities.dp(48) : linkPreviewMaxWidth;
|
int maxPhotoWidth = smallImage ? AndroidUtilities.dp(48) : linkPreviewMaxWidth;
|
||||||
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, maxPhotoWidth, true);
|
currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, drawImageButton ? AndroidUtilities.getPhotoSize() : maxPhotoWidth, !drawImageButton);
|
||||||
TLRPC.PhotoSize currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 80);
|
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 80);
|
||||||
if (currentPhotoObjectThumb == currentPhotoObject) {
|
if (currentPhotoObjectThumb == currentPhotoObject) {
|
||||||
currentPhotoObjectThumb = null;
|
currentPhotoObjectThumb = null;
|
||||||
}
|
}
|
||||||
@ -606,11 +659,14 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
photoExist = false;
|
photoExist = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String filter = String.format(Locale.US, "%d_%d", width, height);
|
currentPhotoFilter = String.format(Locale.US, "%d_%d", width, height);
|
||||||
|
currentPhotoFilterThumb = String.format(Locale.US, "%d_%d_b", width, height);
|
||||||
|
|
||||||
if (photoExist || MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO) || FileLoader.getInstance().isLoadingFile(fileName)) {
|
if (photoExist || MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO) || FileLoader.getInstance().isLoadingFile(fileName)) {
|
||||||
linkImageView.setImage(currentPhotoObject.location, filter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, String.format(Locale.US, "%d_%d_b", width, height), 0, null, false);
|
photoNotSet = false;
|
||||||
|
linkImageView.setImage(currentPhotoObject.location, currentPhotoFilter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilterThumb, 0, null, false);
|
||||||
} else {
|
} else {
|
||||||
|
photoNotSet = true;
|
||||||
if (currentPhotoObjectThumb != null) {
|
if (currentPhotoObjectThumb != null) {
|
||||||
linkImageView.setImage(null, null, currentPhotoObjectThumb.location, String.format(Locale.US, "%d_%d_b", width, height), 0, null, false);
|
linkImageView.setImage(null, null, currentPhotoObjectThumb.location, String.format(Locale.US, "%d_%d_b", width, height), 0, null, false);
|
||||||
} else {
|
} else {
|
||||||
@ -671,6 +727,7 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
|
|
||||||
//Log.e("setMessageObject 3", "backgroundWidth " + backgroundWidth+" maxChildWidth " + maxChildWidth);
|
//Log.e("setMessageObject 3", "backgroundWidth " + backgroundWidth+" maxChildWidth " + maxChildWidth);
|
||||||
}
|
}
|
||||||
|
updateButtonState(dataChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -813,8 +870,17 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
linkImageView.setImageCoords(textX + backgroundWidth - AndroidUtilities.dp(77), smallImageStartY, linkImageView.getImageWidth(), linkImageView.getImageHeight());
|
linkImageView.setImageCoords(textX + backgroundWidth - AndroidUtilities.dp(77), smallImageStartY, linkImageView.getImageWidth(), linkImageView.getImageHeight());
|
||||||
} else {
|
} else {
|
||||||
linkImageView.setImageCoords(textX + AndroidUtilities.dp(10), linkPreviewY, linkImageView.getImageWidth(), linkImageView.getImageHeight());
|
linkImageView.setImageCoords(textX + AndroidUtilities.dp(10), linkPreviewY, linkImageView.getImageWidth(), linkImageView.getImageHeight());
|
||||||
|
if (drawImageButton) {
|
||||||
|
int size = AndroidUtilities.dp(48);
|
||||||
|
buttonX = (int) (linkImageView.getImageX() + (linkImageView.getImageWidth() - size) / 2.0f);
|
||||||
|
buttonY = (int) (linkImageView.getImageY() + (linkImageView.getImageHeight() - size) / 2.0f) + namesOffset;
|
||||||
|
radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(48), buttonY + AndroidUtilities.dp(48));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
linkImageView.draw(canvas);
|
linkImageView.draw(canvas);
|
||||||
|
if (drawImageButton) {
|
||||||
|
radialProgress.draw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
if (isInstagram && igvideoDrawable != null) {
|
if (isInstagram && igvideoDrawable != null) {
|
||||||
int x = linkImageView.getImageX() + linkImageView.getImageWidth() - igvideoDrawable.getIntrinsicWidth() - AndroidUtilities.dp(4);
|
int x = linkImageView.getImageX() + linkImageView.getImageWidth() - igvideoDrawable.getIntrinsicWidth() - AndroidUtilities.dp(4);
|
||||||
@ -837,4 +903,99 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Drawable getDrawableForCurrentState() {
|
||||||
|
if (buttonState >= 0 && buttonState < 4) {
|
||||||
|
if (buttonState == 1) {
|
||||||
|
return ResourceLoader.buttonStatesDrawables[4];
|
||||||
|
} else {
|
||||||
|
return ResourceLoader.buttonStatesDrawables[buttonState];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateButtonState(boolean animated) {
|
||||||
|
if (currentPhotoObject == null || !drawImageButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String fileName = FileLoader.getAttachFileName(currentPhotoObject);
|
||||||
|
File cacheFile = FileLoader.getPathToAttach(currentPhotoObject, true);
|
||||||
|
if (fileName == null) {
|
||||||
|
radialProgress.setBackground(null, false, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!cacheFile.exists()) {
|
||||||
|
MediaController.getInstance().addLoadingFileObserver(fileName, this);
|
||||||
|
float setProgress = 0;
|
||||||
|
boolean progressVisible = false;
|
||||||
|
if (!FileLoader.getInstance().isLoadingFile(fileName)) {
|
||||||
|
if (cancelLoading || !MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO)) {
|
||||||
|
buttonState = 0;
|
||||||
|
} else {
|
||||||
|
progressVisible = true;
|
||||||
|
buttonState = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
progressVisible = true;
|
||||||
|
buttonState = 1;
|
||||||
|
Float progress = ImageLoader.getInstance().getFileProgress(fileName);
|
||||||
|
setProgress = progress != null ? progress : 0;
|
||||||
|
}
|
||||||
|
radialProgress.setProgress(setProgress, false);
|
||||||
|
radialProgress.setBackground(getDrawableForCurrentState(), progressVisible, animated);
|
||||||
|
invalidate();
|
||||||
|
} else {
|
||||||
|
MediaController.getInstance().removeLoadingFileObserver(this);
|
||||||
|
buttonState = -1;
|
||||||
|
radialProgress.setBackground(getDrawableForCurrentState(), false, animated);
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void didPressedButton(boolean animated) {
|
||||||
|
if (buttonState == 0) {
|
||||||
|
cancelLoading = false;
|
||||||
|
radialProgress.setProgress(0, false);
|
||||||
|
linkImageView.setImage(currentPhotoObject.location, currentPhotoFilter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilterThumb, 0, null, false);
|
||||||
|
buttonState = 1;
|
||||||
|
radialProgress.setBackground(getDrawableForCurrentState(), true, animated);
|
||||||
|
invalidate();
|
||||||
|
} else if (buttonState == 1) {
|
||||||
|
if (currentMessageObject.isOut() && currentMessageObject.isSending()) {
|
||||||
|
if (delegate != null) {
|
||||||
|
delegate.didPressedCancelSendButton(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cancelLoading = true;
|
||||||
|
linkImageView.cancelLoadImage();
|
||||||
|
buttonState = 0;
|
||||||
|
radialProgress.setBackground(getDrawableForCurrentState(), false, animated);
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailedDownload(String fileName) {
|
||||||
|
updateButtonState(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccessDownload(String fileName) {
|
||||||
|
radialProgress.setProgress(1, true);
|
||||||
|
if (!photoNotSet) {
|
||||||
|
updateButtonState(true);
|
||||||
|
} else {
|
||||||
|
setMessageObject(currentMessageObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgressDownload(String fileName, float progress) {
|
||||||
|
radialProgress.setProgress(progress, true);
|
||||||
|
if (buttonState != 1) {
|
||||||
|
updateButtonState(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,9 @@ public class DrawerActionCell extends FrameLayout {
|
|||||||
textView.setText(text);
|
textView.setText(text);
|
||||||
//textView.setCompoundDrawablesWithIntrinsicBounds(resId, 0, 0, 0);
|
//textView.setCompoundDrawablesWithIntrinsicBounds(resId, 0, 0, 0);
|
||||||
int color = AndroidUtilities.getIntDef("drawerIconColor", 0xff737373);
|
int color = AndroidUtilities.getIntDef("drawerIconColor", 0xff737373);
|
||||||
getResources().getDrawable(resId).setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
Drawable d = getResources().getDrawable(resId);
|
||||||
textView.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(resId), null, null, null);
|
d.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||||
|
textView.setCompoundDrawablesWithIntrinsicBounds(d, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTextAndIcon(String text, Drawable drawable) {
|
public void setTextAndIcon(String text, Drawable drawable) {
|
||||||
|
@ -40,9 +40,11 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
private static TextPaint nameEncryptedPaint;
|
private static TextPaint nameEncryptedPaint;
|
||||||
private static TextPaint onlinePaint;
|
private static TextPaint onlinePaint;
|
||||||
private static TextPaint offlinePaint;
|
private static TextPaint offlinePaint;
|
||||||
|
private static TextPaint countPaint;
|
||||||
private static Drawable lockDrawable;
|
private static Drawable lockDrawable;
|
||||||
private static Drawable broadcastDrawable;
|
private static Drawable broadcastDrawable;
|
||||||
private static Drawable groupDrawable;
|
private static Drawable groupDrawable;
|
||||||
|
private static Drawable countDrawable;
|
||||||
private static Paint linePaint;
|
private static Paint linePaint;
|
||||||
|
|
||||||
private CharSequence currentName;
|
private CharSequence currentName;
|
||||||
@ -53,6 +55,7 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
private TLRPC.User user = null;
|
private TLRPC.User user = null;
|
||||||
private TLRPC.Chat chat = null;
|
private TLRPC.Chat chat = null;
|
||||||
private TLRPC.EncryptedChat encryptedChat = null;
|
private TLRPC.EncryptedChat encryptedChat = null;
|
||||||
|
long dialog_id;
|
||||||
|
|
||||||
private String lastName = null;
|
private String lastName = null;
|
||||||
private int lastStatus = 0;
|
private int lastStatus = 0;
|
||||||
@ -70,6 +73,13 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
private int nameLockLeft;
|
private int nameLockLeft;
|
||||||
private int nameLockTop;
|
private int nameLockTop;
|
||||||
|
|
||||||
|
private boolean drawCount;
|
||||||
|
private int lastUnreadCount;
|
||||||
|
private int countTop = AndroidUtilities.dp(25);
|
||||||
|
private int countLeft;
|
||||||
|
private int countWidth;
|
||||||
|
private StaticLayout countLayout;
|
||||||
|
|
||||||
private int onlineLeft;
|
private int onlineLeft;
|
||||||
private StaticLayout onlineLayout;
|
private StaticLayout onlineLayout;
|
||||||
|
|
||||||
@ -100,9 +110,15 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
linePaint = new Paint();
|
linePaint = new Paint();
|
||||||
linePaint.setColor(0xffdcdcdc);
|
linePaint.setColor(0xffdcdcdc);
|
||||||
|
|
||||||
|
countPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
|
||||||
|
countPaint.setTextSize(AndroidUtilities.dp(13));
|
||||||
|
countPaint.setColor(0xffffffff);
|
||||||
|
countPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||||
|
|
||||||
broadcastDrawable = getResources().getDrawable(R.drawable.list_broadcast);
|
broadcastDrawable = getResources().getDrawable(R.drawable.list_broadcast);
|
||||||
lockDrawable = getResources().getDrawable(R.drawable.list_secret);
|
lockDrawable = getResources().getDrawable(R.drawable.list_secret);
|
||||||
groupDrawable = getResources().getDrawable(R.drawable.list_group);
|
groupDrawable = getResources().getDrawable(R.drawable.list_group);
|
||||||
|
countDrawable = getResources().getDrawable(R.drawable.dialogs_badge);
|
||||||
}
|
}
|
||||||
|
|
||||||
avatarImage = new ImageReceiver(this);
|
avatarImage = new ImageReceiver(this);
|
||||||
@ -120,12 +136,13 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
return super.onTouchEvent(event);
|
return super.onTouchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setData(TLRPC.User u, TLRPC.Chat c, TLRPC.EncryptedChat ec, CharSequence n, CharSequence s) {
|
public void setData(TLRPC.User u, TLRPC.Chat c, TLRPC.EncryptedChat ec, CharSequence n, CharSequence s, boolean needCount) {
|
||||||
currentName = n;
|
currentName = n;
|
||||||
user = u;
|
user = u;
|
||||||
chat = c;
|
chat = c;
|
||||||
encryptedChat = ec;
|
encryptedChat = ec;
|
||||||
subLabel = s;
|
subLabel = s;
|
||||||
|
drawCount = needCount;
|
||||||
update(0);
|
update(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +184,7 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
|
|
||||||
if (encryptedChat != null) {
|
if (encryptedChat != null) {
|
||||||
drawNameLock = true;
|
drawNameLock = true;
|
||||||
|
dialog_id = ((long) encryptedChat.id) << 32;
|
||||||
if (!LocaleController.isRTL) {
|
if (!LocaleController.isRTL) {
|
||||||
nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
|
nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
|
||||||
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4) + lockDrawable.getIntrinsicWidth();
|
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4) + lockDrawable.getIntrinsicWidth();
|
||||||
@ -177,11 +195,12 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
nameLockTop = AndroidUtilities.dp(16.5f);
|
nameLockTop = AndroidUtilities.dp(16.5f);
|
||||||
} else {
|
} else {
|
||||||
if (chat != null) {
|
if (chat != null) {
|
||||||
|
|
||||||
if (chat.id < 0) {
|
if (chat.id < 0) {
|
||||||
|
dialog_id = AndroidUtilities.makeBroadcastId(chat.id);
|
||||||
drawNameBroadcast = true;
|
drawNameBroadcast = true;
|
||||||
nameLockTop = AndroidUtilities.dp(28.5f);
|
nameLockTop = AndroidUtilities.dp(28.5f);
|
||||||
} else {
|
} else {
|
||||||
|
dialog_id = -chat.id;
|
||||||
drawNameGroup = true;
|
drawNameGroup = true;
|
||||||
nameLockTop = AndroidUtilities.dp(30);
|
nameLockTop = AndroidUtilities.dp(30);
|
||||||
}
|
}
|
||||||
@ -193,6 +212,7 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
nameLeft = AndroidUtilities.dp(11);
|
nameLeft = AndroidUtilities.dp(11);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
dialog_id = user.id;
|
||||||
if (!LocaleController.isRTL) {
|
if (!LocaleController.isRTL) {
|
||||||
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
|
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
|
||||||
} else {
|
} else {
|
||||||
@ -240,6 +260,30 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
nameWidth -= AndroidUtilities.dp(6) + groupDrawable.getIntrinsicWidth();
|
nameWidth -= AndroidUtilities.dp(6) + groupDrawable.getIntrinsicWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (drawCount) {
|
||||||
|
TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id);
|
||||||
|
if (dialog != null && dialog.unread_count != 0) {
|
||||||
|
lastUnreadCount = dialog.unread_count;
|
||||||
|
String countString = String.format("%d", dialog.unread_count);
|
||||||
|
countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(countPaint.measureText(countString)));
|
||||||
|
countLayout = new StaticLayout(countString, countPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
|
||||||
|
int w = countWidth + AndroidUtilities.dp(18);
|
||||||
|
nameWidth -= w;
|
||||||
|
if (!LocaleController.isRTL) {
|
||||||
|
countLeft = getMeasuredWidth() - countWidth - AndroidUtilities.dp(19);
|
||||||
|
} else {
|
||||||
|
countLeft = AndroidUtilities.dp(19);
|
||||||
|
nameLeft += w;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lastUnreadCount = 0;
|
||||||
|
countLayout = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lastUnreadCount = 0;
|
||||||
|
countLayout = null;
|
||||||
|
}
|
||||||
|
|
||||||
CharSequence nameStringFinal = TextUtils.ellipsize(nameString, currentNamePaint, nameWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
|
CharSequence nameStringFinal = TextUtils.ellipsize(nameString, currentNamePaint, nameWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
|
||||||
nameLayout = new StaticLayout(nameStringFinal, currentNamePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
nameLayout = new StaticLayout(nameStringFinal, currentNamePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||||
|
|
||||||
@ -250,12 +294,12 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
onlineLeft = AndroidUtilities.dp(11);
|
onlineLeft = AndroidUtilities.dp(11);
|
||||||
}
|
}
|
||||||
|
|
||||||
CharSequence onlineString;
|
CharSequence onlineString = "";
|
||||||
TextPaint currentOnlinePaint = offlinePaint;
|
TextPaint currentOnlinePaint = offlinePaint;
|
||||||
|
|
||||||
if (subLabel != null) {
|
if (subLabel != null) {
|
||||||
onlineString = subLabel;
|
onlineString = subLabel;
|
||||||
} else {
|
} else if (user != null) {
|
||||||
if ((user.flags & TLRPC.USER_FLAG_BOT) != 0) {
|
if ((user.flags & TLRPC.USER_FLAG_BOT) != 0) {
|
||||||
onlineString = LocaleController.getString("Bot", R.string.Bot);
|
onlineString = LocaleController.getString("Bot", R.string.Bot);
|
||||||
} else {
|
} else {
|
||||||
@ -370,6 +414,12 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
continueUpdate = true;
|
continueUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!continueUpdate && drawCount && (mask & MessagesController.UPDATE_MASK_READ_DIALOG_MESSAGE) != 0) {
|
||||||
|
TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id);
|
||||||
|
if (dialog != null && dialog.unread_count != lastUnreadCount) {
|
||||||
|
continueUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!continueUpdate) {
|
if (!continueUpdate) {
|
||||||
return;
|
return;
|
||||||
@ -428,10 +478,12 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
broadcastDrawable.draw(canvas);
|
broadcastDrawable.draw(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nameLayout != null) {
|
||||||
canvas.save();
|
canvas.save();
|
||||||
canvas.translate(nameLeft, nameTop);
|
canvas.translate(nameLeft, nameTop);
|
||||||
nameLayout.draw(canvas);
|
nameLayout.draw(canvas);
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
if (onlineLayout != null) {
|
if (onlineLayout != null) {
|
||||||
canvas.save();
|
canvas.save();
|
||||||
@ -440,6 +492,15 @@ public class ProfileSearchCell extends BaseCell {
|
|||||||
canvas.restore();
|
canvas.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (countLayout != null) {
|
||||||
|
setDrawableBounds(countDrawable, countLeft - AndroidUtilities.dp(5.5f), countTop, countWidth + AndroidUtilities.dp(11), countDrawable.getIntrinsicHeight());
|
||||||
|
countDrawable.draw(canvas);
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(countLeft, countTop + AndroidUtilities.dp(4));
|
||||||
|
countLayout.draw(canvas);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
avatarImage.draw(canvas);
|
avatarImage.draw(canvas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,12 @@
|
|||||||
package org.telegram.ui.Cells;
|
package org.telegram.ui.Cells;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.os.Build;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.AccelerateInterpolator;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@ -26,6 +30,13 @@ public class StickerEmojiCell extends FrameLayout {
|
|||||||
private BackupImageView imageView;
|
private BackupImageView imageView;
|
||||||
private TLRPC.Document sticker;
|
private TLRPC.Document sticker;
|
||||||
private TextView emojiTextView;
|
private TextView emojiTextView;
|
||||||
|
private float alpha = 1;
|
||||||
|
private boolean changingAlpha;
|
||||||
|
private long lastUpdateTime;
|
||||||
|
private boolean scaled;
|
||||||
|
private float scale;
|
||||||
|
private long time = 0;
|
||||||
|
private AccelerateInterpolator interpolator = new AccelerateInterpolator(0.5f);
|
||||||
|
|
||||||
public StickerEmojiCell(Context context) {
|
public StickerEmojiCell(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -39,15 +50,6 @@ public class StickerEmojiCell extends FrameLayout {
|
|||||||
addView(emojiTextView, LayoutHelper.createFrame(28, 28, Gravity.BOTTOM | Gravity.RIGHT));
|
addView(emojiTextView, LayoutHelper.createFrame(28, 28, Gravity.BOTTOM | Gravity.RIGHT));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPressed(boolean pressed) {
|
|
||||||
if (imageView.getImageReceiver().getPressed() != pressed) {
|
|
||||||
imageView.getImageReceiver().setPressed(pressed);
|
|
||||||
imageView.invalidate();
|
|
||||||
}
|
|
||||||
super.setPressed(pressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TLRPC.Document getSticker() {
|
public TLRPC.Document getSticker() {
|
||||||
return sticker;
|
return sticker;
|
||||||
}
|
}
|
||||||
@ -78,4 +80,67 @@ public class StickerEmojiCell extends FrameLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void disable() {
|
||||||
|
changingAlpha = true;
|
||||||
|
alpha = 0.5f;
|
||||||
|
time = 0;
|
||||||
|
imageView.getImageReceiver().setAlpha(alpha);
|
||||||
|
imageView.invalidate();
|
||||||
|
lastUpdateTime = System.currentTimeMillis();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScaled(boolean value) {
|
||||||
|
scaled = value;
|
||||||
|
lastUpdateTime = System.currentTimeMillis();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDisabled() {
|
||||||
|
return changingAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean showingBitmap() {
|
||||||
|
return imageView.getImageReceiver().getBitmap() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||||
|
boolean result = super.drawChild(canvas, child, drawingTime);
|
||||||
|
if (child == imageView && (changingAlpha || scaled && scale != 0.8f || !scaled && scale != 1.0f)) {
|
||||||
|
long newTime = System.currentTimeMillis();
|
||||||
|
long dt = (newTime - lastUpdateTime);
|
||||||
|
lastUpdateTime = newTime;
|
||||||
|
if (changingAlpha) {
|
||||||
|
time += dt;
|
||||||
|
if (time > 1050) {
|
||||||
|
time = 1050;
|
||||||
|
}
|
||||||
|
alpha = 0.5f + interpolator.getInterpolation(time / 1050.0f) * 0.5f;
|
||||||
|
if (alpha >= 1.0f) {
|
||||||
|
changingAlpha = false;
|
||||||
|
alpha = 1.0f;
|
||||||
|
}
|
||||||
|
imageView.getImageReceiver().setAlpha(alpha);
|
||||||
|
} else if (scaled && scale != 0.8f) {
|
||||||
|
scale -= dt / 400.0f;
|
||||||
|
if (scale < 0.8f) {
|
||||||
|
scale = 0.8f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scale += dt / 400.0f;
|
||||||
|
if (scale > 1.0f) {
|
||||||
|
scale = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= 11) {
|
||||||
|
imageView.setScaleX(scale);
|
||||||
|
imageView.setScaleY(scale);
|
||||||
|
}
|
||||||
|
imageView.invalidate();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,10 @@ public class UserCell extends FrameLayout {
|
|||||||
Drawable d = getResources().getDrawable(currentDrawable);
|
Drawable d = getResources().getDrawable(currentDrawable);
|
||||||
d.setColorFilter(dColor, PorterDuff.Mode.SRC_IN);
|
d.setColorFilter(dColor, PorterDuff.Mode.SRC_IN);
|
||||||
}
|
}
|
||||||
|
}else if(tag.contains("Pref")){
|
||||||
|
setStatusColors(themePrefs.getInt("prefSummaryColor", 0xff8a8a8a), AndroidUtilities.getIntDarkerColor("themeColor", -0x40));
|
||||||
|
nameColor = themePrefs.getInt("prefTitleColor", 0xff212121);
|
||||||
|
nameTextView.setTextColor(nameColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,10 +287,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
private final static int bot_help = 30;
|
private final static int bot_help = 30;
|
||||||
private final static int bot_settings = 31;
|
private final static int bot_settings = 31;
|
||||||
|
|
||||||
|
|
||||||
private final static int attach_photo = 0;//6;
|
private final static int attach_photo = 0;//6;
|
||||||
private final static int attach_gallery = 1;//7;
|
private final static int attach_gallery = 1;//7;
|
||||||
private final static int attach_video = 2;//8;
|
private final static int attach_video = 2;//8;
|
||||||
|
|
||||||
private final static int attach_audio = 3;
|
private final static int attach_audio = 3;
|
||||||
private final static int attach_document = 4;//9;
|
private final static int attach_document = 4;//9;
|
||||||
private final static int attach_contact = 5;
|
private final static int attach_contact = 5;
|
||||||
@ -841,23 +841,31 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRevealAnimationStart(boolean open) {
|
public void onRevealAnimationStart(boolean open) {
|
||||||
|
if (chatAttachView != null) {
|
||||||
chatAttachView.onRevealAnimationStart(open);
|
chatAttachView.onRevealAnimationStart(open);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRevealAnimationProgress(boolean open, float radius, int x, int y) {
|
public void onRevealAnimationProgress(boolean open, float radius, int x, int y) {
|
||||||
|
if (chatAttachView != null) {
|
||||||
chatAttachView.onRevealAnimationProgress(open, radius, x, y);
|
chatAttachView.onRevealAnimationProgress(open, radius, x, y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRevealAnimationEnd(boolean open) {
|
public void onRevealAnimationEnd(boolean open) {
|
||||||
|
if (chatAttachView != null) {
|
||||||
chatAttachView.onRevealAnimationEnd(open);
|
chatAttachView.onRevealAnimationEnd(open);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOpenAnimationEnd() {
|
public void onOpenAnimationEnd() {
|
||||||
|
if (chatAttachView != null) {
|
||||||
chatAttachView.onRevealAnimationEnd(true);
|
chatAttachView.onRevealAnimationEnd(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getRevealView() {
|
public View getRevealView() {
|
||||||
@ -1134,8 +1142,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
|
||||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
|
||||||
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
|
||||||
@ -1436,8 +1442,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (SecretPhotoViewer.getInstance().isVisible()) {
|
||||||
if (SecretPhotoViewer.getInstance().isVisible()) {
|
|
||||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -1447,7 +1452,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
});
|
});
|
||||||
SecretPhotoViewer.getInstance().closePhoto();
|
SecretPhotoViewer.getInstance().closePhoto();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (event.getAction() != MotionEvent.ACTION_DOWN) {
|
} else if (event.getAction() != MotionEvent.ACTION_DOWN) {
|
||||||
if (SecretPhotoViewer.getInstance().isVisible()) {
|
if (SecretPhotoViewer.getInstance().isVisible()) {
|
||||||
return true;
|
return true;
|
||||||
@ -1477,12 +1481,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
int x = (int) event.getX();
|
int x = (int) event.getX();
|
||||||
int y = (int) event.getY();
|
int y = (int) event.getY();
|
||||||
int count = chatListView.getChildCount();
|
int count = chatListView.getChildCount();
|
||||||
Rect rect = new Rect();
|
|
||||||
for (int a = 0; a < count; a++) {
|
for (int a = 0; a < count; a++) {
|
||||||
View view = chatListView.getChildAt(a);
|
View view = chatListView.getChildAt(a);
|
||||||
int top = view.getTop();
|
int top = view.getTop();
|
||||||
int bottom = view.getBottom();
|
int bottom = view.getBottom();
|
||||||
view.getLocalVisibleRect(rect);
|
|
||||||
if (top > y || bottom < y) {
|
if (top > y || bottom < y) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3372,8 +3374,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
if (extractUriFrom.contains("com.google.android.apps.photos.contentprovider")) {
|
if (extractUriFrom.contains("com.google.android.apps.photos.contentprovider")) {
|
||||||
try {
|
try {
|
||||||
String firstExtraction = extractUriFrom.split("/1/")[1];
|
String firstExtraction = extractUriFrom.split("/1/")[1];
|
||||||
if (firstExtraction.contains("/ACTUAL")) {
|
int index = firstExtraction.indexOf("/ACTUAL");
|
||||||
firstExtraction = firstExtraction.replace("/ACTUAL", "");
|
if (index != -1) {
|
||||||
|
firstExtraction = firstExtraction.substring(0, index);
|
||||||
String secondExtraction = URLDecoder.decode(firstExtraction, "UTF-8");
|
String secondExtraction = URLDecoder.decode(firstExtraction, "UTF-8");
|
||||||
uri = Uri.parse(secondExtraction);
|
uri = Uri.parse(secondExtraction);
|
||||||
}
|
}
|
||||||
@ -4267,9 +4270,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
if (cell.getMessageObject() != null && cell.getMessageObject().getId() == mid) {
|
if (cell.getMessageObject() != null && cell.getMessageObject().getId() == mid) {
|
||||||
MessageObject playing = cell.getMessageObject();
|
MessageObject playing = cell.getMessageObject();
|
||||||
MessageObject player = MediaController.getInstance().getPlayingMessageObject();
|
MessageObject player = MediaController.getInstance().getPlayingMessageObject();
|
||||||
|
if (player != null) {
|
||||||
playing.audioProgress = player.audioProgress;
|
playing.audioProgress = player.audioProgress;
|
||||||
playing.audioProgressSec = player.audioProgressSec;
|
playing.audioProgressSec = player.audioProgressSec;
|
||||||
cell.updateProgress();
|
cell.updateProgress();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5061,6 +5066,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
moveScrollToLastMessage();
|
moveScrollToLastMessage();
|
||||||
}
|
}
|
||||||
} else if (option == 1) {
|
} else if (option == 1) {
|
||||||
|
if (getParentActivity() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final MessageObject finalSelectedObject = selectedObject;
|
final MessageObject finalSelectedObject = selectedObject;
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
|
||||||
builder.setMessage(LocaleController.formatString("AreYouSureDeleteMessages", R.string.AreYouSureDeleteMessages, LocaleController.formatPluralString("messages", 1)));
|
builder.setMessage(LocaleController.formatString("AreYouSureDeleteMessages", R.string.AreYouSureDeleteMessages, LocaleController.formatPluralString("messages", 1)));
|
||||||
@ -5108,7 +5116,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
}
|
}
|
||||||
} else if (option == 4) {
|
} else if (option == 4) {
|
||||||
String fileName = selectedObject.getFileName();
|
|
||||||
String path = selectedObject.messageOwner.attachPath;
|
String path = selectedObject.messageOwner.attachPath;
|
||||||
if (path != null && path.length() > 0) {
|
if (path != null && path.length() > 0) {
|
||||||
File temp = new File(path);
|
File temp = new File(path);
|
||||||
@ -5446,8 +5453,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
MessageObject messageToOpen = null;
|
MessageObject messageToOpen = null;
|
||||||
ImageReceiver imageReceiver = null;
|
ImageReceiver imageReceiver = null;
|
||||||
View view = chatListView.getChildAt(a);
|
View view = chatListView.getChildAt(a);
|
||||||
if (view instanceof ChatMediaCell) {
|
if (view instanceof ChatBaseCell) {
|
||||||
ChatMediaCell cell = (ChatMediaCell) view;
|
ChatBaseCell cell = (ChatBaseCell) view;
|
||||||
MessageObject message = cell.getMessageObject();
|
MessageObject message = cell.getMessageObject();
|
||||||
if (message != null && message.getId() == messageObject.getId()) {
|
if (message != null && message.getId() == messageObject.getId()) {
|
||||||
messageToOpen = message;
|
messageToOpen = message;
|
||||||
@ -5671,7 +5678,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
@Override
|
@Override
|
||||||
public void needOpenWebView(String url, String title, String originalUrl, int w, int h) {
|
public void needOpenWebView(String url, String title, String originalUrl, int w, int h) {
|
||||||
BottomSheet.Builder builder = new BottomSheet.Builder(mContext);
|
BottomSheet.Builder builder = new BottomSheet.Builder(mContext);
|
||||||
|
|
||||||
builder.setCustomView(new WebFrameLayout(mContext, builder.create(), title, originalUrl, url, w, h));
|
builder.setCustomView(new WebFrameLayout(mContext, builder.create(), title, originalUrl, url, w, h));
|
||||||
builder.setUseFullWidth(true);
|
builder.setUseFullWidth(true);
|
||||||
showDialog(builder.create());
|
showDialog(builder.create());
|
||||||
@ -5681,12 +5687,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
public void didPressReplyMessage(ChatBaseCell cell, int id) {
|
public void didPressReplyMessage(ChatBaseCell cell, int id) {
|
||||||
scrollToMessageId(id, cell.getMessageObject().getId(), true);
|
scrollToMessageId(id, cell.getMessageObject().getId(), true);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
if (view instanceof ChatMediaCell) {
|
@Override
|
||||||
((ChatMediaCell) view).setAllowedToSetPhoto(openAnimationEnded);
|
public void didClickedImage(ChatBaseCell cell) {
|
||||||
((ChatMediaCell) view).setMediaDelegate(new ChatMediaCell.ChatMediaCellDelegate() {
|
|
||||||
@Override
|
|
||||||
public void didClickedImage(ChatMediaCell cell) {
|
|
||||||
MessageObject message = cell.getMessageObject();
|
MessageObject message = cell.getMessageObject();
|
||||||
if (message.isSendError()) {
|
if (message.isSendError()) {
|
||||||
createMenu(cell, false);
|
createMenu(cell, false);
|
||||||
@ -5694,7 +5697,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
} else if (message.isSending()) {
|
} else if (message.isSending()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (message.type == 1) {
|
if (message.type == 1 || message.type == 0) {
|
||||||
PhotoViewer.getInstance().setParentActivity(getParentActivity());
|
PhotoViewer.getInstance().setParentActivity(getParentActivity());
|
||||||
PhotoViewer.getInstance().openPhoto(message, ChatActivity.this);
|
PhotoViewer.getInstance().openPhoto(message, ChatActivity.this);
|
||||||
} else if (message.type == 3) {
|
} else if (message.type == 3) {
|
||||||
@ -5770,7 +5773,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
if (view instanceof ChatMediaCell) {
|
||||||
|
((ChatMediaCell) view).setAllowedToSetPhoto(openAnimationEnded);
|
||||||
|
((ChatMediaCell) view).setMediaDelegate(new ChatMediaCell.ChatMediaCellDelegate() {
|
||||||
@Override
|
@Override
|
||||||
public void didPressedOther(ChatMediaCell cell) {
|
public void didPressedOther(ChatMediaCell cell) {
|
||||||
createMenu(cell, true);
|
createMenu(cell, true);
|
||||||
|
@ -177,7 +177,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||||||
|
|
||||||
emojiButton = new ImageView(context);
|
emojiButton = new ImageView(context);
|
||||||
//emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles);
|
//emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles);
|
||||||
Drawable emoji = parentActivity.getResources().getDrawable(R.drawable.ic_msg_panel_smiles);
|
Drawable emoji = getResources().getDrawable(R.drawable.ic_msg_panel_smiles);
|
||||||
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
||||||
final int color = themePrefs.getInt("chatEditTextIconsColor", 0xffadadad);
|
final int color = themePrefs.getInt("chatEditTextIconsColor", 0xffadadad);
|
||||||
emoji.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
emoji.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||||
@ -380,7 +380,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||||||
//audioSendButton.setImageResource(R.drawable.mic_button_states);
|
//audioSendButton.setImageResource(R.drawable.mic_button_states);
|
||||||
//audioSendButton.setBackgroundColor(0xffffffff);
|
//audioSendButton.setBackgroundColor(0xffffffff);
|
||||||
audioSendButton.setSoundEffectsEnabled(false);
|
audioSendButton.setSoundEffectsEnabled(false);
|
||||||
Drawable mic = parentActivity.getResources().getDrawable(R.drawable.mic);
|
Drawable mic = getResources().getDrawable(R.drawable.mic);
|
||||||
mic.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
mic.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||||
audioSendButton.setImageDrawable(mic);
|
audioSendButton.setImageDrawable(mic);
|
||||||
audioSendButton.setBackgroundColor(0x00000000);
|
audioSendButton.setBackgroundColor(0x00000000);
|
||||||
@ -389,7 +389,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||||||
audioSendButton.setOnTouchListener(new View.OnTouchListener() {
|
audioSendButton.setOnTouchListener(new View.OnTouchListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||||
Drawable mic = parentActivity.getResources().getDrawable(R.drawable.mic);
|
Drawable mic = getResources().getDrawable(R.drawable.mic);
|
||||||
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
|
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
mic.setColorFilter(0xffda564d, PorterDuff.Mode.SRC_IN);
|
mic.setColorFilter(0xffda564d, PorterDuff.Mode.SRC_IN);
|
||||||
audioSendButton.setImageDrawable(mic);
|
audioSendButton.setImageDrawable(mic);
|
||||||
@ -495,7 +495,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||||||
private void updateTheme() {
|
private void updateTheme() {
|
||||||
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
||||||
int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor);
|
int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor);
|
||||||
Drawable send = parentActivity.getResources().getDrawable(R.drawable.ic_send);
|
Drawable send = getResources().getDrawable(R.drawable.ic_send);
|
||||||
send.setColorFilter(themePrefs.getInt("chatSendIconColor", themePrefs.getInt("chatEditTextIconsColor", def)), PorterDuff.Mode.SRC_IN);
|
send.setColorFilter(themePrefs.getInt("chatSendIconColor", themePrefs.getInt("chatEditTextIconsColor", def)), PorterDuff.Mode.SRC_IN);
|
||||||
sendButton.setImageDrawable(send);
|
sendButton.setImageDrawable(send);
|
||||||
messageEditText.setTextColor(themePrefs.getInt("chatEditTextColor", 0xff000000));
|
messageEditText.setTextColor(themePrefs.getInt("chatEditTextColor", 0xff000000));
|
||||||
@ -1257,7 +1257,6 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||||||
private void showPopup(int show, int contentType) {
|
private void showPopup(int show, int contentType) {
|
||||||
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
||||||
int color = themePrefs.getInt("chatEditTextIconsColor", 0xffadadad);
|
int color = themePrefs.getInt("chatEditTextIconsColor", 0xffadadad);
|
||||||
Drawable d;
|
|
||||||
if (show == 1) {
|
if (show == 1) {
|
||||||
if (contentType == 0 && emojiView == null) {
|
if (contentType == 0 && emojiView == null) {
|
||||||
if (parentActivity == null) {
|
if (parentActivity == null) {
|
||||||
@ -1340,23 +1339,27 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||||||
if (sizeNotifierLayout != null) {
|
if (sizeNotifierLayout != null) {
|
||||||
emojiPadding = currentHeight;
|
emojiPadding = currentHeight;
|
||||||
sizeNotifierLayout.requestLayout();
|
sizeNotifierLayout.requestLayout();
|
||||||
|
try{
|
||||||
if (contentType == 0) {
|
if (contentType == 0) {
|
||||||
d = getResources().getDrawable(R.drawable.ic_msg_panel_kb);
|
Drawable d = getResources().getDrawable(R.drawable.ic_msg_panel_kb);
|
||||||
d.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
d.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||||
emojiButton.setImageDrawable(d);
|
emojiButton.setImageDrawable(d);
|
||||||
//emojiButton.setImageResource(R.drawable.ic_msg_panel_kb);
|
//emojiButton.setImageResource(R.drawable.ic_msg_panel_kb);
|
||||||
} else if (contentType == 1) {
|
} else if (contentType == 1) {
|
||||||
d = getResources().getDrawable(R.drawable.ic_msg_panel_smiles);
|
Drawable d = getResources().getDrawable(R.drawable.ic_msg_panel_smiles);
|
||||||
d.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
d.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||||
emojiButton.setImageDrawable(d);
|
emojiButton.setImageDrawable(d);
|
||||||
//emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles);
|
//emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
updateBotButton();
|
updateBotButton();
|
||||||
onWindowSizeChanged();
|
onWindowSizeChanged();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (emojiButton != null) {
|
if (emojiButton != null) {
|
||||||
d = getResources().getDrawable(R.drawable.ic_msg_panel_smiles);
|
Drawable d = getResources().getDrawable(R.drawable.ic_msg_panel_smiles);
|
||||||
d.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
d.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||||
emojiButton.setImageDrawable(d);
|
emojiButton.setImageDrawable(d);
|
||||||
//emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles);
|
//emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles);
|
||||||
|
@ -23,6 +23,7 @@ import android.view.MotionEvent;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AbsListView;
|
import android.widget.AbsListView;
|
||||||
|
import android.widget.AdapterView;
|
||||||
import android.widget.BaseAdapter;
|
import android.widget.BaseAdapter;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.GridView;
|
import android.widget.GridView;
|
||||||
@ -42,6 +43,7 @@ import org.telegram.messenger.R;
|
|||||||
import org.telegram.messenger.TLRPC;
|
import org.telegram.messenger.TLRPC;
|
||||||
import org.telegram.ui.Cells.EmptyCell;
|
import org.telegram.ui.Cells.EmptyCell;
|
||||||
import org.telegram.ui.Cells.StickerEmojiCell;
|
import org.telegram.ui.Cells.StickerEmojiCell;
|
||||||
|
import org.telegram.ui.StickerPreviewViewer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -57,8 +59,11 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<EmojiGridAdapter> adapters = new ArrayList<>();
|
private ArrayList<EmojiGridAdapter> adapters = new ArrayList<>();
|
||||||
|
private HashMap<Long, Integer> emojiUseHistory = new HashMap<>();
|
||||||
|
private ArrayList<Long> recentEmoji = new ArrayList<>();
|
||||||
private HashMap<Long, Integer> stickersUseHistory = new HashMap<>();
|
private HashMap<Long, Integer> stickersUseHistory = new HashMap<>();
|
||||||
private ArrayList<TLRPC.Document> recentStickers = new ArrayList<>();
|
private ArrayList<TLRPC.Document> recentStickers = new ArrayList<>();
|
||||||
|
private HashMap<Long, Integer> stickerSetsUseCount = new HashMap<>();
|
||||||
private ArrayList<TLRPC.TL_messages_stickerSet> stickerSets = new ArrayList<>();
|
private ArrayList<TLRPC.TL_messages_stickerSet> stickerSets = new ArrayList<>();
|
||||||
|
|
||||||
private int[] icons = {
|
private int[] icons = {
|
||||||
@ -79,6 +84,13 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
private StickersGridAdapter stickersGridAdapter;
|
private StickersGridAdapter stickersGridAdapter;
|
||||||
private LinearLayout pagerSlidingTabStripContainer;
|
private LinearLayout pagerSlidingTabStripContainer;
|
||||||
private ScrollSlidingTabStrip scrollSlidingTabStrip;
|
private ScrollSlidingTabStrip scrollSlidingTabStrip;
|
||||||
|
private GridView stickersGridView;
|
||||||
|
private AdapterView.OnItemClickListener stickersOnItemClickListener;
|
||||||
|
private Runnable openStickerPreviewRunnable;
|
||||||
|
private StickerEmojiCell currentStickerPreviewCell;
|
||||||
|
|
||||||
|
private int startX;
|
||||||
|
private int startY;
|
||||||
|
|
||||||
private int oldWidth;
|
private int oldWidth;
|
||||||
private int lastNotifyWidth;
|
private int lastNotifyWidth;
|
||||||
@ -96,7 +108,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
int tabColor = themePrefs.getInt("chatEmojiViewTabColor", AndroidUtilities.getIntDarkerColor("themeColor", -0x15));
|
int tabColor = themePrefs.getInt("chatEmojiViewTabColor", AndroidUtilities.getIntDarkerColor("themeColor", -0x15));
|
||||||
int lineColor = bgColor == 0xfff5f6f7 ? 0xffe2e5e7 : AndroidUtilities.setDarkColor(bgColor, 0x10);
|
int lineColor = bgColor == 0xfff5f6f7 ? 0xffe2e5e7 : AndroidUtilities.setDarkColor(bgColor, 0x10);
|
||||||
//setOrientation(LinearLayout.VERTICAL);
|
//setOrientation(LinearLayout.VERTICAL);
|
||||||
for (int i = 0; i < Emoji.data.length; i++) {
|
for (int i = 0; i < Emoji.data.length + 1; i++) {
|
||||||
GridView gridView = new GridView(context);
|
GridView gridView = new GridView(context);
|
||||||
if (AndroidUtilities.isTablet()) {
|
if (AndroidUtilities.isTablet()) {
|
||||||
gridView.setColumnWidth(AndroidUtilities.dp(60));
|
gridView.setColumnWidth(AndroidUtilities.dp(60));
|
||||||
@ -106,7 +118,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
gridView.setNumColumns(-1);
|
gridView.setNumColumns(-1);
|
||||||
views.add(gridView);
|
views.add(gridView);
|
||||||
|
|
||||||
EmojiGridAdapter emojiGridAdapter = new EmojiGridAdapter(Emoji.data[i]);
|
EmojiGridAdapter emojiGridAdapter = new EmojiGridAdapter(i - 1);
|
||||||
gridView.setAdapter(emojiGridAdapter);
|
gridView.setAdapter(emojiGridAdapter);
|
||||||
//AndroidUtilities.setListViewEdgeEffectColor(gridView, 0xfff5f6f7);
|
//AndroidUtilities.setListViewEdgeEffectColor(gridView, 0xfff5f6f7);
|
||||||
AndroidUtilities.setListViewEdgeEffectColor(gridView, bgColor);
|
AndroidUtilities.setListViewEdgeEffectColor(gridView, bgColor);
|
||||||
@ -115,25 +127,187 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
|
|
||||||
if (showStickers) {
|
if (showStickers) {
|
||||||
StickersQuery.checkStickers();
|
StickersQuery.checkStickers();
|
||||||
GridView gridView = new GridView(context);
|
stickersGridView = new GridView(context) {
|
||||||
gridView.setColumnWidth(AndroidUtilities.dp(72));
|
@Override
|
||||||
gridView.setNumColumns(-1);
|
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||||
gridView.setPadding(0, AndroidUtilities.dp(4), 0, 0);
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
gridView.setClipToPadding(false);
|
int x = (int) event.getX();
|
||||||
views.add(gridView);
|
int y = (int) event.getY();
|
||||||
|
int count = stickersGridView.getChildCount();
|
||||||
|
for (int a = 0; a < count; a++) {
|
||||||
|
View view = stickersGridView.getChildAt(a);
|
||||||
|
int top = view.getTop();
|
||||||
|
int bottom = view.getBottom();
|
||||||
|
int left = view.getLeft();
|
||||||
|
int right = view.getRight();
|
||||||
|
if (top > y || bottom < y || left > x || right < x) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!(view instanceof StickerEmojiCell) || !((StickerEmojiCell) view).showingBitmap()) {
|
||||||
|
return super.onInterceptTouchEvent(event);
|
||||||
|
}
|
||||||
|
startX = x;
|
||||||
|
startY = y;
|
||||||
|
currentStickerPreviewCell = (StickerEmojiCell) view;
|
||||||
|
openStickerPreviewRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (openStickerPreviewRunnable == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
stickersGridView.setOnItemClickListener(null);
|
||||||
|
stickersGridView.requestDisallowInterceptTouchEvent(true);
|
||||||
|
openStickerPreviewRunnable = null;
|
||||||
|
StickerPreviewViewer.getInstance().setParentActivity((Activity) getContext());
|
||||||
|
StickerPreviewViewer.getInstance().setKeyboardHeight(EmojiView.this.getMeasuredHeight());
|
||||||
|
StickerPreviewViewer.getInstance().open(currentStickerPreviewCell.getSticker());
|
||||||
|
currentStickerPreviewCell.setScaled(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
AndroidUtilities.runOnUIThread(openStickerPreviewRunnable, 200);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stickersGridView.setSelector(R.drawable.transparent);
|
||||||
|
stickersGridView.setColumnWidth(AndroidUtilities.dp(72));
|
||||||
|
stickersGridView.setNumColumns(-1);
|
||||||
|
stickersGridView.setPadding(0, AndroidUtilities.dp(4), 0, 0);
|
||||||
|
stickersGridView.setClipToPadding(false);
|
||||||
|
views.add(stickersGridView);
|
||||||
stickersGridAdapter = new StickersGridAdapter(context);
|
stickersGridAdapter = new StickersGridAdapter(context);
|
||||||
gridView.setAdapter(stickersGridAdapter);
|
stickersGridView.setAdapter(stickersGridAdapter);
|
||||||
//AndroidUtilities.setListViewEdgeEffectColor(gridView, 0xfff5f6f7);
|
stickersGridView.setOnTouchListener(new OnTouchListener() {
|
||||||
AndroidUtilities.setListViewEdgeEffectColor(gridView, bgColor);
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
if (openStickerPreviewRunnable != null || StickerPreviewViewer.getInstance().isVisible()) {
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_POINTER_UP) {
|
||||||
|
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
stickersGridView.setOnItemClickListener(stickersOnItemClickListener);
|
||||||
|
}
|
||||||
|
}, 150);
|
||||||
|
if (openStickerPreviewRunnable != null) {
|
||||||
|
AndroidUtilities.cancelRunOnUIThread(openStickerPreviewRunnable);
|
||||||
|
openStickerPreviewRunnable = null;
|
||||||
|
} else if (StickerPreviewViewer.getInstance().isVisible()) {
|
||||||
|
StickerPreviewViewer.getInstance().close();
|
||||||
|
if (currentStickerPreviewCell != null) {
|
||||||
|
currentStickerPreviewCell.setScaled(false);
|
||||||
|
currentStickerPreviewCell = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (event.getAction() != MotionEvent.ACTION_DOWN) {
|
||||||
|
if (StickerPreviewViewer.getInstance().isVisible()) {
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||||
|
int x = (int) event.getX();
|
||||||
|
int y = (int) event.getY();
|
||||||
|
int count = stickersGridView.getChildCount();
|
||||||
|
for (int a = 0; a < count; a++) {
|
||||||
|
View view = stickersGridView.getChildAt(a);
|
||||||
|
int top = view.getTop();
|
||||||
|
int bottom = view.getBottom();
|
||||||
|
int left = view.getLeft();
|
||||||
|
int right = view.getRight();
|
||||||
|
if (top > y || bottom < y || left > x || right < x) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!(view instanceof StickerEmojiCell) || view == currentStickerPreviewCell) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (currentStickerPreviewCell != null) {
|
||||||
|
currentStickerPreviewCell.setScaled(false);
|
||||||
|
}
|
||||||
|
currentStickerPreviewCell = (StickerEmojiCell) view;
|
||||||
|
StickerPreviewViewer.getInstance().setKeyboardHeight(EmojiView.this.getMeasuredHeight());
|
||||||
|
StickerPreviewViewer.getInstance().open(currentStickerPreviewCell.getSticker());
|
||||||
|
currentStickerPreviewCell.setScaled(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else if (openStickerPreviewRunnable != null) {
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||||
|
if (Math.hypot(startX - event.getX(), startY - event.getY()) > AndroidUtilities.dp(10)) {
|
||||||
|
AndroidUtilities.cancelRunOnUIThread(openStickerPreviewRunnable);
|
||||||
|
openStickerPreviewRunnable = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AndroidUtilities.cancelRunOnUIThread(openStickerPreviewRunnable);
|
||||||
|
openStickerPreviewRunnable = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
stickersOnItemClickListener = new AdapterView.OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> parent, View view, int position, long i) {
|
||||||
|
if (!(view instanceof StickerEmojiCell)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (openStickerPreviewRunnable != null) {
|
||||||
|
AndroidUtilities.cancelRunOnUIThread(openStickerPreviewRunnable);
|
||||||
|
openStickerPreviewRunnable = null;
|
||||||
|
}
|
||||||
|
if (currentStickerPreviewCell != null) {
|
||||||
|
currentStickerPreviewCell.setScaled(false);
|
||||||
|
currentStickerPreviewCell = null;
|
||||||
|
}
|
||||||
|
StickerEmojiCell cell = (StickerEmojiCell) view;
|
||||||
|
if (cell.isDisabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cell.disable();
|
||||||
|
TLRPC.Document document = cell.getSticker();
|
||||||
|
Integer count = stickersUseHistory.get(document.id);
|
||||||
|
if (count == null) {
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
if (count == 0 && stickersUseHistory.size() > 19) {
|
||||||
|
for (int a = recentStickers.size() - 1; a >= 0; a--) {
|
||||||
|
TLRPC.Document sticker = recentStickers.get(a);
|
||||||
|
stickersUseHistory.remove(sticker.id);
|
||||||
|
recentStickers.remove(a);
|
||||||
|
if (stickersUseHistory.size() <= 19) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stickersUseHistory.put(document.id, ++count);
|
||||||
|
|
||||||
|
long id = StickersQuery.getStickerSetId(document);
|
||||||
|
if (id != -1) {
|
||||||
|
count = stickerSetsUseCount.get(id);
|
||||||
|
if (count == null) {
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
stickerSetsUseCount.put(id, ++count);
|
||||||
|
}
|
||||||
|
|
||||||
|
saveRecentStickers();
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onStickerSelected(document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stickersGridView.setOnItemClickListener(stickersOnItemClickListener);
|
||||||
|
AndroidUtilities.setListViewEdgeEffectColor(stickersGridView, 0xfff5f6f7);
|
||||||
|
|
||||||
stickersWrap = new FrameLayout(context);
|
stickersWrap = new FrameLayout(context);
|
||||||
stickersWrap.addView(gridView);
|
stickersWrap.addView(stickersGridView);
|
||||||
|
|
||||||
TextView textView = new TextView(context);
|
TextView textView = new TextView(context);
|
||||||
textView.setText(LocaleController.getString("NoStickers", R.string.NoStickers));
|
textView.setText(LocaleController.getString("NoStickers", R.string.NoStickers));
|
||||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
|
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
|
||||||
textView.setTextColor(0xff888888);
|
textView.setTextColor(0xff888888);
|
||||||
stickersWrap.addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
|
stickersWrap.addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
|
||||||
gridView.setEmptyView(textView);
|
stickersGridView.setEmptyView(textView);
|
||||||
|
|
||||||
scrollSlidingTabStrip = new ScrollSlidingTabStrip(context) {
|
scrollSlidingTabStrip = new ScrollSlidingTabStrip(context) {
|
||||||
|
|
||||||
@ -226,7 +400,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
gridView.setOnScrollListener(new AbsListView.OnScrollListener() {
|
stickersGridView.setOnScrollListener(new AbsListView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
||||||
|
|
||||||
@ -246,7 +420,6 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
scrollSlidingTabStrip.onPageScrolled(stickersGridAdapter.getTabForPosition(firstVisibleItem) + 1, 0);
|
scrollSlidingTabStrip.onPageScrolled(stickersGridAdapter.getTabForPosition(firstVisibleItem) + 1, 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//setBackgroundColor(0xfff5f6f7);
|
//setBackgroundColor(0xfff5f6f7);
|
||||||
@ -317,7 +490,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
} else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
|
} else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
|
||||||
backspacePressed = false;
|
backspacePressed = false;
|
||||||
if (!backspaceOnce) {
|
if (!backspaceOnce) {
|
||||||
if (EmojiView.this.listener != null && EmojiView.this.listener.onBackspace()) {
|
if (listener != null && listener.onBackspace()) {
|
||||||
backspaceButton.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
backspaceButton.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,7 +570,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
if (!backspacePressed) {
|
if (!backspacePressed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (EmojiView.this.listener != null && EmojiView.this.listener.onBackspace()) {
|
if (listener != null && listener.onBackspace()) {
|
||||||
backspaceButton.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
backspaceButton.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
||||||
}
|
}
|
||||||
backspaceOnce = true;
|
backspaceOnce = true;
|
||||||
@ -406,33 +579,6 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
}, time);
|
}, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addToRecent(long code) {
|
|
||||||
if (pager.getCurrentItem() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ArrayList<Long> recent = new ArrayList<>();
|
|
||||||
long[] currentRecent = Emoji.data[0];
|
|
||||||
boolean was = false;
|
|
||||||
for (long aCurrentRecent : currentRecent) {
|
|
||||||
if (code == aCurrentRecent) {
|
|
||||||
recent.add(0, code);
|
|
||||||
was = true;
|
|
||||||
} else {
|
|
||||||
recent.add(aCurrentRecent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!was) {
|
|
||||||
recent.add(0, code);
|
|
||||||
}
|
|
||||||
Emoji.data[0] = new long[Math.min(recent.size(), 50)];
|
|
||||||
for (int q = 0; q < Emoji.data[0].length; q++) {
|
|
||||||
Emoji.data[0][q] = recent.get(q);
|
|
||||||
}
|
|
||||||
adapters.get(0).data = Emoji.data[0];
|
|
||||||
adapters.get(0).notifyDataSetChanged();
|
|
||||||
saveRecents();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String convert(long paramLong) {
|
private String convert(long paramLong) {
|
||||||
String str = "";
|
String str = "";
|
||||||
for (int i = 0; ; i++) {
|
for (int i = 0; ; i++) {
|
||||||
@ -446,16 +592,22 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveRecents() {
|
private void saveRecentEmoji() {
|
||||||
ArrayList<Long> arrayList = new ArrayList<>(Emoji.data[0].length);
|
SharedPreferences preferences = getContext().getSharedPreferences("emoji", Activity.MODE_PRIVATE);
|
||||||
for (int j = 0; j < Emoji.data[0].length; j++) {
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
arrayList.add(Emoji.data[0][j]);
|
for (HashMap.Entry<Long, Integer> entry : emojiUseHistory.entrySet()) {
|
||||||
|
if (stringBuilder.length() != 0) {
|
||||||
|
stringBuilder.append(",");
|
||||||
|
}
|
||||||
|
stringBuilder.append(entry.getKey());
|
||||||
|
stringBuilder.append("=");
|
||||||
|
stringBuilder.append(entry.getValue());
|
||||||
}
|
}
|
||||||
getContext().getSharedPreferences("emoji", 0).edit().putString("recents", TextUtils.join(",", arrayList)).commit();
|
preferences.edit().putString("emojis", stringBuilder.toString()).commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveRecentStickers() {
|
private void saveRecentStickers() {
|
||||||
SharedPreferences preferences = getContext().getSharedPreferences("emoji", Activity.MODE_PRIVATE);
|
SharedPreferences.Editor editor = getContext().getSharedPreferences("emoji", Activity.MODE_PRIVATE).edit();
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
for (HashMap.Entry<Long, Integer> entry : stickersUseHistory.entrySet()) {
|
for (HashMap.Entry<Long, Integer> entry : stickersUseHistory.entrySet()) {
|
||||||
if (stringBuilder.length() != 0) {
|
if (stringBuilder.length() != 0) {
|
||||||
@ -465,7 +617,64 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
stringBuilder.append("=");
|
stringBuilder.append("=");
|
||||||
stringBuilder.append(entry.getValue());
|
stringBuilder.append(entry.getValue());
|
||||||
}
|
}
|
||||||
preferences.edit().putString("stickers", stringBuilder.toString()).commit();
|
editor.putString("stickers", stringBuilder.toString());
|
||||||
|
|
||||||
|
ArrayList<Long> toRemove = null;
|
||||||
|
for (HashMap.Entry<Long, Integer> entry : stickerSetsUseCount.entrySet()) {
|
||||||
|
if (!StickersQuery.isStickerPackInstalled(entry.getKey())) {
|
||||||
|
if (toRemove == null) {
|
||||||
|
toRemove = new ArrayList<>();
|
||||||
|
}
|
||||||
|
toRemove.add(entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (toRemove != null) {
|
||||||
|
for (int a = 0; a < toRemove.size(); a++) {
|
||||||
|
stickerSetsUseCount.remove(toRemove.get(a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stringBuilder.setLength(0);
|
||||||
|
for (HashMap.Entry<Long, Integer> entry : stickerSetsUseCount.entrySet()) {
|
||||||
|
if (stringBuilder.length() != 0) {
|
||||||
|
stringBuilder.append(",");
|
||||||
|
}
|
||||||
|
stringBuilder.append(entry.getKey());
|
||||||
|
stringBuilder.append("=");
|
||||||
|
stringBuilder.append(entry.getValue());
|
||||||
|
}
|
||||||
|
editor.putString("sets", stringBuilder.toString());
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sortEmoji() {
|
||||||
|
recentEmoji.clear();
|
||||||
|
for (HashMap.Entry<Long, Integer> entry : emojiUseHistory.entrySet()) {
|
||||||
|
recentEmoji.add(entry.getKey());
|
||||||
|
}
|
||||||
|
Collections.sort(recentEmoji, new Comparator<Long>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Long lhs, Long rhs) {
|
||||||
|
Integer count1 = emojiUseHistory.get(lhs);
|
||||||
|
Integer count2 = emojiUseHistory.get(rhs);
|
||||||
|
if (count1 == null) {
|
||||||
|
count1 = 0;
|
||||||
|
}
|
||||||
|
if (count2 == null) {
|
||||||
|
count2 = 0;
|
||||||
|
}
|
||||||
|
if (count1 > count2) {
|
||||||
|
return -1;
|
||||||
|
} else if (count1 < count2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
while (recentEmoji.size() > 50) {
|
||||||
|
recentEmoji.remove(recentEmoji.size() - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sortStickers() {
|
private void sortStickers() {
|
||||||
@ -482,11 +691,9 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
hashMap.put(sticker.id, entry.getValue());
|
hashMap.put(sticker.id, entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!stickersUseHistory.isEmpty()) {
|
if (stickersUseHistory.size() != hashMap.size()) {
|
||||||
stickersUseHistory = hashMap;
|
|
||||||
saveRecents();
|
|
||||||
} else {
|
|
||||||
stickersUseHistory = hashMap;
|
stickersUseHistory = hashMap;
|
||||||
|
saveRecentStickers();
|
||||||
}
|
}
|
||||||
Collections.sort(recentStickers, new Comparator<TLRPC.Document>() {
|
Collections.sort(recentStickers, new Comparator<TLRPC.Document>() {
|
||||||
@Override
|
@Override
|
||||||
@ -526,33 +733,80 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
stickerSets.add(pack);
|
stickerSets.add(pack);
|
||||||
scrollSlidingTabStrip.addStickerTab(pack.documents.get(0));
|
}
|
||||||
|
Collections.sort(stickerSets, new Comparator<TLRPC.TL_messages_stickerSet>() {
|
||||||
|
@Override
|
||||||
|
public int compare(TLRPC.TL_messages_stickerSet lhs, TLRPC.TL_messages_stickerSet rhs) {
|
||||||
|
Integer count1 = stickerSetsUseCount.get(lhs.set.id);
|
||||||
|
Integer count2 = stickerSetsUseCount.get(rhs.set.id);
|
||||||
|
if (count1 == null) {
|
||||||
|
count1 = 0;
|
||||||
|
}
|
||||||
|
if (count2 == null) {
|
||||||
|
count2 = 0;
|
||||||
|
}
|
||||||
|
if (count1 > count2) {
|
||||||
|
return -1;
|
||||||
|
} else if (count1 < count2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (int a = 0; a < stickerSets.size(); a++) {
|
||||||
|
scrollSlidingTabStrip.addStickerTab(stickerSets.get(a).documents.get(0));
|
||||||
}
|
}
|
||||||
scrollSlidingTabStrip.updateTabStyles();
|
scrollSlidingTabStrip.updateTabStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadRecents() {
|
public void loadRecents() {
|
||||||
|
String str;
|
||||||
SharedPreferences preferences = getContext().getSharedPreferences("emoji", Activity.MODE_PRIVATE);
|
SharedPreferences preferences = getContext().getSharedPreferences("emoji", Activity.MODE_PRIVATE);
|
||||||
String str = preferences.getString("recents", "");
|
|
||||||
try {
|
if (preferences.contains("recents")) {
|
||||||
if (str != null && str.length() > 0) {
|
try {
|
||||||
String[] args = str.split(",");
|
str = preferences.getString("recents", "");
|
||||||
Emoji.data[0] = new long[args.length];
|
if (str != null && str.length() > 0) {
|
||||||
|
String[] args = str.split(",");
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
Emoji.data[0][i] = Long.parseLong(args[i]);
|
emojiUseHistory.put(Long.parseLong(args[i]), args.length - i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
sortEmoji();
|
||||||
|
preferences.edit().remove("recents").commit();
|
||||||
|
saveRecentEmoji();
|
||||||
|
adapters.get(0).notifyDataSetChanged();
|
||||||
} else {
|
} else {
|
||||||
Emoji.data[0] = new long[]{0x00000000D83DDE02L, 0x00000000D83DDE18L, 0x0000000000002764L, 0x00000000D83DDE0DL, 0x00000000D83DDE0AL, 0x00000000D83DDE01L,
|
try {
|
||||||
|
emojiUseHistory.clear();
|
||||||
|
str = preferences.getString("emojis", "");
|
||||||
|
if (str != null && str.length() > 0) {
|
||||||
|
String[] args = str.split(",");
|
||||||
|
for (String arg : args) {
|
||||||
|
String[] args2 = arg.split("=");
|
||||||
|
emojiUseHistory.put(Long.parseLong(args2[0]), Integer.parseInt(args2[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (emojiUseHistory.isEmpty()) {
|
||||||
|
long[] newRecent = new long[]{0x00000000D83DDE02L, 0x00000000D83DDE18L, 0x0000000000002764L, 0x00000000D83DDE0DL, 0x00000000D83DDE0AL, 0x00000000D83DDE01L,
|
||||||
0x00000000D83DDC4DL, 0x000000000000263AL, 0x00000000D83DDE14L, 0x00000000D83DDE04L, 0x00000000D83DDE2DL, 0x00000000D83DDC8BL,
|
0x00000000D83DDC4DL, 0x000000000000263AL, 0x00000000D83DDE14L, 0x00000000D83DDE04L, 0x00000000D83DDE2DL, 0x00000000D83DDC8BL,
|
||||||
0x00000000D83DDE12L, 0x00000000D83DDE33L, 0x00000000D83DDE1CL, 0x00000000D83DDE48L, 0x00000000D83DDE09L, 0x00000000D83DDE03L,
|
0x00000000D83DDE12L, 0x00000000D83DDE33L, 0x00000000D83DDE1CL, 0x00000000D83DDE48L, 0x00000000D83DDE09L, 0x00000000D83DDE03L,
|
||||||
0x00000000D83DDE22L, 0x00000000D83DDE1DL, 0x00000000D83DDE31L, 0x00000000D83DDE21L, 0x00000000D83DDE0FL, 0x00000000D83DDE1EL,
|
0x00000000D83DDE22L, 0x00000000D83DDE1DL, 0x00000000D83DDE31L, 0x00000000D83DDE21L, 0x00000000D83DDE0FL, 0x00000000D83DDE1EL,
|
||||||
0x00000000D83DDE05L, 0x00000000D83DDE1AL, 0x00000000D83DDE4AL, 0x00000000D83DDE0CL, 0x00000000D83DDE00L, 0x00000000D83DDE0BL,
|
0x00000000D83DDE05L, 0x00000000D83DDE1AL, 0x00000000D83DDE4AL, 0x00000000D83DDE0CL, 0x00000000D83DDE00L, 0x00000000D83DDE0BL,
|
||||||
0x00000000D83DDE06L, 0x00000000D83DDC4CL, 0x00000000D83DDE10L, 0x00000000D83DDE15L};
|
0x00000000D83DDE06L, 0x00000000D83DDC4CL, 0x00000000D83DDE10L, 0x00000000D83DDE15L};
|
||||||
}
|
for (int i = 0; i < newRecent.length; i++) {
|
||||||
adapters.get(0).data = Emoji.data[0];
|
emojiUseHistory.put(newRecent[i], newRecent.length - i);
|
||||||
adapters.get(0).notifyDataSetChanged();
|
}
|
||||||
} catch (Exception e) {
|
saveRecentEmoji();
|
||||||
FileLog.e("tmessages", e);
|
}
|
||||||
|
sortEmoji();
|
||||||
|
adapters.get(0).notifyDataSetChanged();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showStickers) {
|
if (showStickers) {
|
||||||
@ -566,6 +820,16 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
stickersUseHistory.put(Long.parseLong(args2[0]), Integer.parseInt(args2[1]));
|
stickersUseHistory.put(Long.parseLong(args2[0]), Integer.parseInt(args2[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stickerSetsUseCount.clear();
|
||||||
|
str = preferences.getString("sets", "");
|
||||||
|
if (str != null && str.length() > 0) {
|
||||||
|
String[] args = str.split(",");
|
||||||
|
for (String arg : args) {
|
||||||
|
String[] args2 = arg.split("=");
|
||||||
|
stickerSetsUseCount.put(Long.parseLong(args2[0]), Integer.parseInt(args2[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
sortStickers();
|
sortStickers();
|
||||||
updateStickerTabs();
|
updateStickerTabs();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -600,13 +864,28 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||||
if (lastNotifyWidth != right - left) {
|
if (lastNotifyWidth != right - left) {
|
||||||
lastNotifyWidth = right - left;
|
lastNotifyWidth = right - left;
|
||||||
if (stickersGridAdapter != null) {
|
reloadStickersAdapter();
|
||||||
stickersGridAdapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
super.onLayout(changed, left, top, right, bottom);
|
super.onLayout(changed, left, top, right, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void reloadStickersAdapter() {
|
||||||
|
if (stickersGridAdapter != null) {
|
||||||
|
stickersGridAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
if (StickerPreviewViewer.getInstance().isVisible()) {
|
||||||
|
StickerPreviewViewer.getInstance().close();
|
||||||
|
}
|
||||||
|
if (openStickerPreviewRunnable != null) {
|
||||||
|
AndroidUtilities.cancelRunOnUIThread(openStickerPreviewRunnable);
|
||||||
|
openStickerPreviewRunnable = null;
|
||||||
|
}
|
||||||
|
if (currentStickerPreviewCell != null) {
|
||||||
|
currentStickerPreviewCell.setScaled(false);
|
||||||
|
currentStickerPreviewCell = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setListener(Listener value) {
|
public void setListener(Listener value) {
|
||||||
listener = value;
|
listener = value;
|
||||||
}
|
}
|
||||||
@ -630,11 +909,15 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
@Override
|
@Override
|
||||||
public void setVisibility(int visibility) {
|
public void setVisibility(int visibility) {
|
||||||
super.setVisibility(visibility);
|
super.setVisibility(visibility);
|
||||||
if (visibility != GONE && stickersGridAdapter != null) {
|
if (visibility != GONE) {
|
||||||
|
sortEmoji();
|
||||||
|
adapters.get(0).notifyDataSetChanged();
|
||||||
|
if (stickersGridAdapter != null) {
|
||||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.stickersDidLoaded);
|
NotificationCenter.getInstance().addObserver(this, NotificationCenter.stickersDidLoaded);
|
||||||
sortStickers();
|
sortStickers();
|
||||||
updateStickerTabs();
|
updateStickerTabs();
|
||||||
stickersGridAdapter.notifyDataSetChanged();
|
reloadStickersAdapter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,7 +933,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
public void didReceivedNotification(int id, Object... args) {
|
public void didReceivedNotification(int id, Object... args) {
|
||||||
if (id == NotificationCenter.stickersDidLoaded) {
|
if (id == NotificationCenter.stickersDidLoaded) {
|
||||||
updateStickerTabs();
|
updateStickerTabs();
|
||||||
stickersGridAdapter.notifyDataSetChanged();
|
reloadStickersAdapter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,31 +1014,6 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(82), MeasureSpec.EXACTLY));
|
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(82), MeasureSpec.EXACTLY));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
view.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (listener != null) {
|
|
||||||
TLRPC.Document document = ((StickerEmojiCell) v).getSticker();
|
|
||||||
Integer count = stickersUseHistory.get(document.id);
|
|
||||||
if (count == null) {
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
if (count == 0 && stickersUseHistory.size() > 19) {
|
|
||||||
for (int a = recentStickers.size() - 1; a >= 0; a--) {
|
|
||||||
TLRPC.Document sticker = recentStickers.get(a);
|
|
||||||
stickersUseHistory.remove(sticker.id);
|
|
||||||
recentStickers.remove(a);
|
|
||||||
if (stickersUseHistory.size() <= 19) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stickersUseHistory.put(document.id, ++count);
|
|
||||||
saveRecentStickers();
|
|
||||||
listener.onStickerSelected(document);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
((StickerEmojiCell) view).setSticker(sticker, false);
|
((StickerEmojiCell) view).setSticker(sticker, false);
|
||||||
} else {
|
} else {
|
||||||
@ -825,45 +1083,76 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class EmojiGridAdapter extends BaseAdapter {
|
private class EmojiGridAdapter extends BaseAdapter {
|
||||||
long[] data;
|
|
||||||
|
|
||||||
public EmojiGridAdapter(long[] arg2) {
|
private int emojiPage;
|
||||||
this.data = arg2;
|
|
||||||
|
public EmojiGridAdapter(int page) {
|
||||||
|
emojiPage = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return data.length;
|
if (emojiPage == -1) {
|
||||||
|
return recentEmoji.size();
|
||||||
|
}
|
||||||
|
return Emoji.data[emojiPage].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getItem(int i) {
|
public Object getItem(int i) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getItemId(int i) {
|
@Override
|
||||||
return data[i];
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public View getView(int i, View view, ViewGroup paramViewGroup) {
|
public View getView(int i, View view, ViewGroup paramViewGroup) {
|
||||||
ImageView imageView = (ImageView)view;
|
ImageView imageView = (ImageView)view;
|
||||||
if (imageView == null) {
|
if (imageView == null) {
|
||||||
imageView = new ImageView(EmojiView.this.getContext()) {
|
imageView = new ImageView(getContext()) {
|
||||||
public void onMeasure(int paramAnonymousInt1, int paramAnonymousInt2) {
|
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
setMeasuredDimension(View.MeasureSpec.getSize(paramAnonymousInt1), View.MeasureSpec.getSize(paramAnonymousInt1));
|
setMeasuredDimension(View.MeasureSpec.getSize(widthMeasureSpec), View.MeasureSpec.getSize(widthMeasureSpec));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
imageView.setOnClickListener(new View.OnClickListener() {
|
imageView.setOnClickListener(new View.OnClickListener() {
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (EmojiView.this.listener != null) {
|
Long code = (Long) view.getTag();
|
||||||
EmojiView.this.listener.onEmojiSelected(EmojiView.this.convert((Long)view.getTag()));
|
Integer count = emojiUseHistory.get(code);
|
||||||
|
if (count == null) {
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
if (count == 0 && emojiUseHistory.size() > 50) {
|
||||||
|
for (int a = recentEmoji.size() - 1; a >= 0; a--) {
|
||||||
|
Long emoji = recentEmoji.get(a);
|
||||||
|
emojiUseHistory.remove(emoji);
|
||||||
|
recentEmoji.remove(a);
|
||||||
|
if (emojiUseHistory.size() <= 50) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emojiUseHistory.put(code, ++count);
|
||||||
|
if (pager.getCurrentItem() != 0) {
|
||||||
|
sortEmoji();
|
||||||
|
}
|
||||||
|
saveRecentEmoji();
|
||||||
|
adapters.get(0).notifyDataSetChanged();
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onEmojiSelected(convert((Long)view.getTag()));
|
||||||
}
|
}
|
||||||
EmojiView.this.addToRecent((Long)view.getTag());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
imageView.setBackgroundResource(R.drawable.list_selector);
|
imageView.setBackgroundResource(R.drawable.list_selector);
|
||||||
imageView.setScaleType(ImageView.ScaleType.CENTER);
|
imageView.setScaleType(ImageView.ScaleType.CENTER);
|
||||||
}
|
}
|
||||||
imageView.setImageDrawable(Emoji.getEmojiBigDrawable(data[i]));
|
long code;
|
||||||
imageView.setTag(data[i]);
|
if (emojiPage == -1) {
|
||||||
|
code = recentEmoji.get(i);
|
||||||
|
} else {
|
||||||
|
code = Emoji.data[emojiPage][i];
|
||||||
|
}
|
||||||
|
imageView.setImageDrawable(Emoji.getEmojiBigDrawable(code));
|
||||||
|
imageView.setTag(code);
|
||||||
return imageView;
|
return imageView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ public class RadialProgress {
|
|||||||
return previousDrawable != null || currentDrawable != null ? animatedAlphaValue : 0.0f;
|
return previousDrawable != null || currentDrawable != null ? animatedAlphaValue : 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDraw(Canvas canvas) {
|
public void draw(Canvas canvas) {
|
||||||
if (previousDrawable != null) {
|
if (previousDrawable != null) {
|
||||||
previousDrawable.setAlpha((int)(255 * animatedAlphaValue));
|
previousDrawable.setAlpha((int)(255 * animatedAlphaValue));
|
||||||
previousDrawable.setBounds((int)progressRect.left, (int)progressRect.top, (int)progressRect.right, (int)progressRect.bottom);
|
previousDrawable.setBounds((int)progressRect.left, (int)progressRect.top, (int)progressRect.right, (int)progressRect.bottom);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package org.telegram.ui.Components;
|
package org.telegram.ui.Components;
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.ColorFilter;
|
import android.graphics.ColorFilter;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
@ -15,6 +16,7 @@ import android.graphics.RectF;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
import org.telegram.android.AndroidUtilities;
|
import org.telegram.android.AndroidUtilities;
|
||||||
|
import org.telegram.messenger.ApplicationLoader;
|
||||||
|
|
||||||
public class RecordStatusDrawable extends Drawable {
|
public class RecordStatusDrawable extends Drawable {
|
||||||
|
|
||||||
@ -27,7 +29,9 @@ public class RecordStatusDrawable extends Drawable {
|
|||||||
|
|
||||||
public RecordStatusDrawable() {
|
public RecordStatusDrawable() {
|
||||||
super();
|
super();
|
||||||
paint.setColor(0xffd7e8f7);
|
//paint.setColor(0xffd7e8f7);
|
||||||
|
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
||||||
|
paint.setColor(themePrefs.getInt("chatStatusColor", AndroidUtilities.getIntDarkerColor("themeColor", -0x40)));
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
paint.setStrokeWidth(AndroidUtilities.dp(2));
|
paint.setStrokeWidth(AndroidUtilities.dp(2));
|
||||||
paint.setStrokeCap(Paint.Cap.ROUND);
|
paint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package org.telegram.ui.Components;
|
package org.telegram.ui.Components;
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.ColorFilter;
|
import android.graphics.ColorFilter;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
@ -16,6 +17,7 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
|
||||||
import org.telegram.android.AndroidUtilities;
|
import org.telegram.android.AndroidUtilities;
|
||||||
|
import org.telegram.messenger.ApplicationLoader;
|
||||||
|
|
||||||
public class SendingFileDrawable extends Drawable {
|
public class SendingFileDrawable extends Drawable {
|
||||||
|
|
||||||
@ -33,7 +35,9 @@ public class SendingFileDrawable extends Drawable {
|
|||||||
|
|
||||||
public SendingFileDrawable() {
|
public SendingFileDrawable() {
|
||||||
super();
|
super();
|
||||||
paint.setColor(0xffd7e8f7);
|
//paint.setColor(0xffd7e8f7);
|
||||||
|
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
||||||
|
paint.setColor(themePrefs.getInt("chatStatusColor", AndroidUtilities.getIntDarkerColor("themeColor", -0x40)));
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
paint.setStrokeWidth(AndroidUtilities.dp(2));
|
paint.setStrokeWidth(AndroidUtilities.dp(2));
|
||||||
paint.setStrokeCap(Paint.Cap.ROUND);
|
paint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
@ -8,12 +8,14 @@
|
|||||||
|
|
||||||
package org.telegram.ui.Components;
|
package org.telegram.ui.Components;
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.ColorFilter;
|
import android.graphics.ColorFilter;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
import org.telegram.android.AndroidUtilities;
|
import org.telegram.android.AndroidUtilities;
|
||||||
|
import org.telegram.messenger.ApplicationLoader;
|
||||||
|
|
||||||
public class SendingFileEx2Drawable extends Drawable {
|
public class SendingFileEx2Drawable extends Drawable {
|
||||||
|
|
||||||
@ -25,7 +27,9 @@ public class SendingFileEx2Drawable extends Drawable {
|
|||||||
|
|
||||||
public SendingFileEx2Drawable() {
|
public SendingFileEx2Drawable() {
|
||||||
super();
|
super();
|
||||||
paint.setColor(0xffd7e8f7);
|
//paint.setColor(0xffd7e8f7);
|
||||||
|
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
||||||
|
paint.setColor(themePrefs.getInt("chatStatusColor", AndroidUtilities.getIntDarkerColor("themeColor", -0x40)));
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
paint.setStrokeWidth(AndroidUtilities.dp(3));
|
paint.setStrokeWidth(AndroidUtilities.dp(3));
|
||||||
paint.setStrokeCap(Paint.Cap.ROUND);
|
paint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
@ -8,12 +8,14 @@
|
|||||||
|
|
||||||
package org.telegram.ui.Components;
|
package org.telegram.ui.Components;
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.ColorFilter;
|
import android.graphics.ColorFilter;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
import org.telegram.android.AndroidUtilities;
|
import org.telegram.android.AndroidUtilities;
|
||||||
|
import org.telegram.messenger.ApplicationLoader;
|
||||||
|
|
||||||
public class SendingFileExDrawable extends Drawable {
|
public class SendingFileExDrawable extends Drawable {
|
||||||
|
|
||||||
@ -25,7 +27,9 @@ public class SendingFileExDrawable extends Drawable {
|
|||||||
|
|
||||||
public SendingFileExDrawable() {
|
public SendingFileExDrawable() {
|
||||||
super();
|
super();
|
||||||
paint.setColor(0xffd7e8f7);
|
//paint.setColor(0xffd7e8f7);
|
||||||
|
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
||||||
|
paint.setColor(themePrefs.getInt("chatStatusColor", AndroidUtilities.getIntDarkerColor("themeColor", -0x40)));
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
paint.setStrokeWidth(AndroidUtilities.dp(2));
|
paint.setStrokeWidth(AndroidUtilities.dp(2));
|
||||||
paint.setStrokeCap(Paint.Cap.ROUND);
|
paint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package org.telegram.ui.Components;
|
package org.telegram.ui.Components;
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.ColorFilter;
|
import android.graphics.ColorFilter;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
@ -15,6 +16,7 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
|
||||||
import org.telegram.android.AndroidUtilities;
|
import org.telegram.android.AndroidUtilities;
|
||||||
|
import org.telegram.messenger.ApplicationLoader;
|
||||||
|
|
||||||
public class TypingDotsDrawable extends Drawable {
|
public class TypingDotsDrawable extends Drawable {
|
||||||
|
|
||||||
@ -29,7 +31,9 @@ public class TypingDotsDrawable extends Drawable {
|
|||||||
|
|
||||||
public TypingDotsDrawable() {
|
public TypingDotsDrawable() {
|
||||||
super();
|
super();
|
||||||
paint.setColor(0xffd7e8f7);
|
//paint.setColor(0xffd7e8f7);
|
||||||
|
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
||||||
|
paint.setColor(themePrefs.getInt("chatStatusColor", AndroidUtilities.getIntDarkerColor("themeColor", -0x40)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIsChat(boolean value) {
|
public void setIsChat(boolean value) {
|
||||||
|
@ -32,6 +32,7 @@ import org.telegram.android.AndroidUtilities;
|
|||||||
import org.telegram.android.AnimationCompat.AnimatorSetProxy;
|
import org.telegram.android.AnimationCompat.AnimatorSetProxy;
|
||||||
import org.telegram.android.AnimationCompat.ObjectAnimatorProxy;
|
import org.telegram.android.AnimationCompat.ObjectAnimatorProxy;
|
||||||
import org.telegram.android.LocaleController;
|
import org.telegram.android.LocaleController;
|
||||||
|
import org.telegram.messenger.ApplicationLoader;
|
||||||
import org.telegram.messenger.FileLog;
|
import org.telegram.messenger.FileLog;
|
||||||
import org.telegram.messenger.R;
|
import org.telegram.messenger.R;
|
||||||
import org.telegram.ui.ActionBar.ActionBar;
|
import org.telegram.ui.ActionBar.ActionBar;
|
||||||
@ -48,6 +49,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
public class DocumentSelectActivity extends BaseFragment {
|
public class DocumentSelectActivity extends BaseFragment {
|
||||||
|
|
||||||
@ -118,7 +121,7 @@ public class DocumentSelectActivity extends BaseFragment {
|
|||||||
public void onFragmentDestroy() {
|
public void onFragmentDestroy() {
|
||||||
try {
|
try {
|
||||||
if (receiverRegistered) {
|
if (receiverRegistered) {
|
||||||
getParentActivity().unregisterReceiver(receiver);
|
ApplicationLoader.applicationContext.unregisterReceiver(receiver);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
@ -142,7 +145,7 @@ public class DocumentSelectActivity extends BaseFragment {
|
|||||||
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTABLE);
|
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTABLE);
|
||||||
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
|
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
|
||||||
filter.addDataScheme("file");
|
filter.addDataScheme("file");
|
||||||
getParentActivity().registerReceiver(receiver, filter);
|
ApplicationLoader.applicationContext.registerReceiver(receiver, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
|
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
|
||||||
@ -311,7 +314,7 @@ public class DocumentSelectActivity extends BaseFragment {
|
|||||||
} else {
|
} else {
|
||||||
if (!file.canRead()) {
|
if (!file.canRead()) {
|
||||||
showErrorBox(LocaleController.getString("AccessError", R.string.AccessError));
|
showErrorBox(LocaleController.getString("AccessError", R.string.AccessError));
|
||||||
return;
|
file = new File("/mnt/sdcard");
|
||||||
}
|
}
|
||||||
if (sizeLimit != 0) {
|
if (sizeLimit != 0) {
|
||||||
if (file.length() > sizeLimit) {
|
if (file.length() > sizeLimit) {
|
||||||
@ -494,47 +497,57 @@ public class DocumentSelectActivity extends BaseFragment {
|
|||||||
private void listRoots() {
|
private void listRoots() {
|
||||||
currentDir = null;
|
currentDir = null;
|
||||||
items.clear();
|
items.clear();
|
||||||
String extStorage = Environment.getExternalStorageDirectory().getAbsolutePath();
|
|
||||||
|
HashSet<String> paths = new HashSet<>();
|
||||||
|
String defaultPath = Environment.getExternalStorageDirectory().getPath();
|
||||||
|
boolean isDefaultPathRemovable = Build.VERSION.SDK_INT >= 9 && Environment.isExternalStorageRemovable();
|
||||||
|
String defaultPathState = Environment.getExternalStorageState();
|
||||||
|
if (defaultPathState.equals(Environment.MEDIA_MOUNTED) || defaultPathState.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
|
||||||
ListItem ext = new ListItem();
|
ListItem ext = new ListItem();
|
||||||
if (Build.VERSION.SDK_INT < 9 || Environment.isExternalStorageRemovable()) {
|
if (Build.VERSION.SDK_INT < 9 || Environment.isExternalStorageRemovable()) {
|
||||||
ext.title = LocaleController.getString("SdCard", R.string.SdCard);
|
ext.title = LocaleController.getString("SdCard", R.string.SdCard);
|
||||||
|
ext.icon = R.drawable.ic_external_storage;
|
||||||
} else {
|
} else {
|
||||||
ext.title = LocaleController.getString("InternalStorage", R.string.InternalStorage);
|
ext.title = LocaleController.getString("InternalStorage", R.string.InternalStorage);
|
||||||
}
|
ext.icon = R.drawable.ic_storage;
|
||||||
ext.icon = Build.VERSION.SDK_INT < 9 || Environment.isExternalStorageRemovable() ? R.drawable.ic_external_storage : R.drawable.ic_storage;
|
}
|
||||||
ext.subtitle = getRootSubtitle(extStorage);
|
ext.subtitle = getRootSubtitle(defaultPath);
|
||||||
ext.file = Environment.getExternalStorageDirectory();
|
ext.file = Environment.getExternalStorageDirectory();
|
||||||
items.add(ext);
|
items.add(ext);
|
||||||
|
paths.add(defaultPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedReader bufferedReader = null;
|
||||||
try {
|
try {
|
||||||
BufferedReader reader = new BufferedReader(new FileReader("/proc/mounts"));
|
bufferedReader = new BufferedReader(new FileReader("/proc/mounts"));
|
||||||
String line;
|
String line;
|
||||||
HashMap<String, ArrayList<String>> aliases = new HashMap<>();
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
ArrayList<String> result = new ArrayList<>();
|
if (line.contains("vfat") || line.contains("/mnt")) {
|
||||||
String extDevice = null;
|
FileLog.e("tmessages", line);
|
||||||
while ((line = reader.readLine()) != null) {
|
StringTokenizer tokens = new StringTokenizer(line, " ");
|
||||||
if ((!line.contains("/mnt") && !line.contains("/storage") && !line.contains("/sdcard")) || line.contains("asec") || line.contains("tmpfs") || line.contains("none")) {
|
String unused = tokens.nextToken();
|
||||||
continue;
|
String path = tokens.nextToken();
|
||||||
}
|
if (paths.contains(path)) {
|
||||||
String[] info = line.split(" ");
|
continue;
|
||||||
if (!aliases.containsKey(info[0])) {
|
}
|
||||||
aliases.put(info[0], new ArrayList<String>());
|
if (line.contains("/dev/block/vold")) {
|
||||||
}
|
if (!line.contains("/mnt/secure") && !line.contains("/mnt/asec") && !line.contains("/mnt/obb") && !line.contains("/dev/mapper") && !line.contains("tmpfs")) {
|
||||||
aliases.get(info[0]).add(info[1]);
|
if (!new File(path).isDirectory()) {
|
||||||
if (info[1].equals(extStorage)) {
|
int index = path.lastIndexOf('/');
|
||||||
extDevice=info[0];
|
if (index != -1) {
|
||||||
}
|
String newPath = "/storage/" + path.substring(index + 1);
|
||||||
result.add(info[1]);
|
if (new File(newPath).isDirectory()) {
|
||||||
}
|
path = newPath;
|
||||||
reader.close();
|
}
|
||||||
if (extDevice != null) {
|
}
|
||||||
result.removeAll(aliases.get(extDevice));
|
}
|
||||||
for (String path : result) {
|
paths.add(path);
|
||||||
try {
|
try {
|
||||||
ListItem item = new ListItem();
|
ListItem item = new ListItem();
|
||||||
if (path.toLowerCase().contains("sd")) {
|
if (path.toLowerCase().contains("sd")) {
|
||||||
ext.title = LocaleController.getString("SdCard", R.string.SdCard);
|
item.title = LocaleController.getString("SdCard", R.string.SdCard);
|
||||||
} else {
|
} else {
|
||||||
ext.title = LocaleController.getString("ExternalStorage", R.string.ExternalStorage);
|
item.title = LocaleController.getString("ExternalStorage", R.string.ExternalStorage);
|
||||||
}
|
}
|
||||||
item.icon = R.drawable.ic_external_storage;
|
item.icon = R.drawable.ic_external_storage;
|
||||||
item.subtitle = getRootSubtitle(path);
|
item.subtitle = getRootSubtitle(path);
|
||||||
@ -545,8 +558,18 @@ public class DocumentSelectActivity extends BaseFragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
|
} finally {
|
||||||
|
if (bufferedReader != null) {
|
||||||
|
try {
|
||||||
|
bufferedReader.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ListItem fs = new ListItem();
|
ListItem fs = new ListItem();
|
||||||
fs.title = "/";
|
fs.title = "/";
|
||||||
@ -582,6 +605,7 @@ public class DocumentSelectActivity extends BaseFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getRootSubtitle(String path) {
|
private String getRootSubtitle(String path) {
|
||||||
|
try {
|
||||||
StatFs stat = new StatFs(path);
|
StatFs stat = new StatFs(path);
|
||||||
long total = (long)stat.getBlockCount() * (long)stat.getBlockSize();
|
long total = (long)stat.getBlockCount() * (long)stat.getBlockSize();
|
||||||
long free = (long)stat.getAvailableBlocks() * (long)stat.getBlockSize();
|
long free = (long)stat.getAvailableBlocks() * (long)stat.getBlockSize();
|
||||||
@ -589,6 +613,10 @@ public class DocumentSelectActivity extends BaseFragment {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return LocaleController.formatString("FreeOfTotal", R.string.FreeOfTotal, AndroidUtilities.formatFileSize(free), AndroidUtilities.formatFileSize(total));
|
return LocaleController.formatString("FreeOfTotal", R.string.FreeOfTotal, AndroidUtilities.formatFileSize(free), AndroidUtilities.formatFileSize(total));
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ListAdapter extends BaseFragmentAdapter {
|
private class ListAdapter extends BaseFragmentAdapter {
|
||||||
|
@ -643,7 +643,6 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
|||||||
}
|
}
|
||||||
Uri uri = (Uri) parcelable;
|
Uri uri = (Uri) parcelable;
|
||||||
if (uri != null && (type != null && type.startsWith("image/") || uri.toString().toLowerCase().endsWith(".jpg"))) {
|
if (uri != null && (type != null && type.startsWith("image/") || uri.toString().toLowerCase().endsWith(".jpg"))) {
|
||||||
String tempPath = AndroidUtilities.getPath(uri);
|
|
||||||
if (photoPathsArray == null) {
|
if (photoPathsArray == null) {
|
||||||
photoPathsArray = new ArrayList<>();
|
photoPathsArray = new ArrayList<>();
|
||||||
}
|
}
|
||||||
@ -742,19 +741,23 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
|||||||
String sticker = null;
|
String sticker = null;
|
||||||
String botUser = null;
|
String botUser = null;
|
||||||
String botChat = null;
|
String botChat = null;
|
||||||
|
String message = null;
|
||||||
String scheme = data.getScheme();
|
String scheme = data.getScheme();
|
||||||
if (scheme != null) {
|
if (scheme != null) {
|
||||||
if ((scheme.equals("http") || scheme.equals("https"))) {
|
if ((scheme.equals("http") || scheme.equals("https"))) {
|
||||||
String host = data.getHost().toLowerCase();
|
String host = data.getHost().toLowerCase();
|
||||||
if (host.equals("telegram.me")) {
|
if (host.equals("telegram.me")) {
|
||||||
String path = data.getPath();
|
String path = data.getPath();
|
||||||
if (path != null && path.length() >= 6) {
|
if (path != null) {
|
||||||
path = path.substring(1);
|
path = path.substring(1);
|
||||||
if (path.startsWith("joinchat/")) {
|
if (path.startsWith("joinchat/")) {
|
||||||
group = path.replace("joinchat/", "");
|
group = path.replace("joinchat/", "");
|
||||||
} else if (path.startsWith("addstickers/")) {
|
} else if (path.startsWith("addstickers/")) {
|
||||||
sticker = path.replace("addstickers/", "");
|
sticker = path.replace("addstickers/", "");
|
||||||
} else {
|
} else if (path.startsWith("msg/")) {
|
||||||
|
message = data.getQueryParameter("text");
|
||||||
|
message += " " + data.getQueryParameter("url");
|
||||||
|
} else if (path.length() >= 5) {
|
||||||
username = data.getLastPathSegment();
|
username = data.getLastPathSegment();
|
||||||
botUser = data.getQueryParameter("start");
|
botUser = data.getQueryParameter("start");
|
||||||
botChat = data.getQueryParameter("startgroup");
|
botChat = data.getQueryParameter("startgroup");
|
||||||
@ -777,11 +780,16 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
|||||||
url = url.replace("tg:addstickers", "tg://telegram.org").replace("tg://addstickers", "tg://telegram.org");
|
url = url.replace("tg:addstickers", "tg://telegram.org").replace("tg://addstickers", "tg://telegram.org");
|
||||||
data = Uri.parse(url);
|
data = Uri.parse(url);
|
||||||
sticker = data.getQueryParameter("set");
|
sticker = data.getQueryParameter("set");
|
||||||
|
} else if (url.startsWith("tg:msg") || url.startsWith("tg://msg")) {
|
||||||
|
url = url.replace("tg:msg", "tg://telegram.org").replace("tg://msg", "tg://telegram.org");
|
||||||
|
data = Uri.parse(url);
|
||||||
|
message = data.getQueryParameter("text");
|
||||||
|
message += " " + data.getQueryParameter("url");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (username != null || group != null || sticker != null) {
|
if (username != null || group != null || sticker != null || message != null) {
|
||||||
runLinkRequest(username, group, sticker, botUser, botChat, 0);
|
runLinkRequest(username, group, sticker, botUser, botChat, message, 0);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null);
|
Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null);
|
||||||
@ -959,7 +967,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runLinkRequest(final String username, final String group, final String sticker, final String botUser, final String botChat, final int state) {
|
private void runLinkRequest(final String username, final String group, final String sticker, final String botUser, final String botChat, final String message, final int state) {
|
||||||
final ProgressDialog progressDialog = new ProgressDialog(this);
|
final ProgressDialog progressDialog = new ProgressDialog(this);
|
||||||
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
|
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
|
||||||
progressDialog.setCanceledOnTouchOutside(false);
|
progressDialog.setCanceledOnTouchOutside(false);
|
||||||
@ -1070,7 +1078,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
|||||||
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() {
|
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
runLinkRequest(username, group, sticker, botUser, botChat, 1);
|
runLinkRequest(username, group, sticker, botUser, botChat, message, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
|
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
|
||||||
@ -1144,8 +1152,42 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
|||||||
StickersQuery.loadStickers(mainFragmentsStack.get(0), stickerset);
|
StickersQuery.loadStickers(mainFragmentsStack.get(0), stickerset);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
} else if (message != null) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putBoolean("onlySelect", true);
|
||||||
|
DialogsActivity fragment = new DialogsActivity(args);
|
||||||
|
fragment.setDelegate(new DialogsActivity.MessagesActivityDelegate() {
|
||||||
|
@Override
|
||||||
|
public void didSelectDialog(DialogsActivity fragment, long did, boolean param) {
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats);
|
||||||
|
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
editor.putString("dialog_" + did, message);
|
||||||
|
editor.commit();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putBoolean("scrollToTopOnResume", true);
|
||||||
|
int lower_part = (int) did;
|
||||||
|
int high_id = (int) (did >> 32);
|
||||||
|
if (lower_part != 0) {
|
||||||
|
if (high_id == 1) {
|
||||||
|
args.putInt("chat_id", lower_part);
|
||||||
|
} else {
|
||||||
|
if (lower_part > 0) {
|
||||||
|
args.putInt("user_id", lower_part);
|
||||||
|
} else if (lower_part < 0) {
|
||||||
|
args.putInt("chat_id", -lower_part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.putInt("enc_id", high_id);
|
||||||
|
}
|
||||||
|
actionBarLayout.presentFragment(new ChatActivity(args), true, false, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
presentFragment(fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (requestId != 0) {
|
||||||
final long reqId = requestId;
|
final long reqId = requestId;
|
||||||
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() {
|
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -1160,6 +1202,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
|||||||
});
|
});
|
||||||
progressDialog.show();
|
progressDialog.show();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public AlertDialog showAlertDialog(AlertDialog.Builder builder) {
|
public AlertDialog showAlertDialog(AlertDialog.Builder builder) {
|
||||||
try {
|
try {
|
||||||
@ -1425,6 +1468,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
|||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
PhotoViewer.getInstance().destroyPhotoViewer();
|
PhotoViewer.getInstance().destroyPhotoViewer();
|
||||||
SecretPhotoViewer.getInstance().destroyPhotoViewer();
|
SecretPhotoViewer.getInstance().destroyPhotoViewer();
|
||||||
|
StickerPreviewViewer.getInstance().destroy();
|
||||||
try {
|
try {
|
||||||
if (visibleDialog != null) {
|
if (visibleDialog != null) {
|
||||||
visibleDialog.dismiss();
|
visibleDialog.dismiss();
|
||||||
@ -1471,7 +1515,6 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
|||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void didReceivedNotification(int id, Object... args) {
|
public void didReceivedNotification(int id, Object... args) {
|
||||||
//Log.e("didReceivedNotification", id + "");
|
|
||||||
if (id == NotificationCenter.appDidLogout) {
|
if (id == NotificationCenter.appDidLogout) {
|
||||||
if (drawerLayoutAdapter != null) {
|
if (drawerLayoutAdapter != null) {
|
||||||
drawerLayoutAdapter.notifyDataSetChanged();
|
drawerLayoutAdapter.notifyDataSetChanged();
|
||||||
|
@ -18,6 +18,7 @@ import android.graphics.Bitmap;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.Browser;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
@ -38,38 +39,42 @@ import android.widget.ProgressBar;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.telegram.android.AndroidUtilities;
|
import org.telegram.android.AndroidUtilities;
|
||||||
import org.telegram.android.AnimationCompat.AnimatorSetProxy;
|
|
||||||
import org.telegram.android.AnimationCompat.ObjectAnimatorProxy;
|
|
||||||
import org.telegram.android.LocaleController;
|
import org.telegram.android.LocaleController;
|
||||||
import org.telegram.android.MediaController;
|
import org.telegram.android.MediaController;
|
||||||
import org.telegram.android.MessageObject;
|
|
||||||
import org.telegram.android.MessagesController;
|
import org.telegram.android.MessagesController;
|
||||||
import org.telegram.android.NotificationCenter;
|
|
||||||
import org.telegram.android.query.SharedMediaQuery;
|
import org.telegram.android.query.SharedMediaQuery;
|
||||||
import org.telegram.messenger.ApplicationLoader;
|
import org.telegram.messenger.ApplicationLoader;
|
||||||
|
import org.telegram.messenger.BuildConfig;
|
||||||
import org.telegram.messenger.ConnectionsManager;
|
import org.telegram.messenger.ConnectionsManager;
|
||||||
import org.telegram.messenger.FileLoader;
|
import org.telegram.messenger.FileLoader;
|
||||||
import org.telegram.messenger.FileLog;
|
import org.telegram.messenger.FileLog;
|
||||||
import org.telegram.messenger.R;
|
|
||||||
import org.telegram.messenger.RPCRequest;
|
import org.telegram.messenger.RPCRequest;
|
||||||
import org.telegram.messenger.TLObject;
|
import org.telegram.messenger.TLObject;
|
||||||
import org.telegram.messenger.TLRPC;
|
import org.telegram.messenger.TLRPC;
|
||||||
|
import org.telegram.android.MessageObject;
|
||||||
|
import org.telegram.android.NotificationCenter;
|
||||||
|
import org.telegram.messenger.R;
|
||||||
import org.telegram.messenger.Utilities;
|
import org.telegram.messenger.Utilities;
|
||||||
import org.telegram.ui.ActionBar.ActionBar;
|
|
||||||
import org.telegram.ui.ActionBar.ActionBarMenu;
|
import org.telegram.ui.ActionBar.ActionBarMenu;
|
||||||
import org.telegram.ui.ActionBar.ActionBarMenuItem;
|
import org.telegram.ui.ActionBar.ActionBarMenuItem;
|
||||||
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
|
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
|
||||||
import org.telegram.ui.ActionBar.BaseFragment;
|
import org.telegram.ui.ActionBar.ActionBar;
|
||||||
|
import org.telegram.ui.ActionBar.BottomSheet;
|
||||||
import org.telegram.ui.Adapters.BaseFragmentAdapter;
|
import org.telegram.ui.Adapters.BaseFragmentAdapter;
|
||||||
import org.telegram.ui.Adapters.BaseSectionsAdapter;
|
import org.telegram.ui.Adapters.BaseSectionsAdapter;
|
||||||
|
import org.telegram.android.AnimationCompat.AnimatorSetProxy;
|
||||||
|
import org.telegram.android.AnimationCompat.ObjectAnimatorProxy;
|
||||||
import org.telegram.ui.Cells.GreySectionCell;
|
import org.telegram.ui.Cells.GreySectionCell;
|
||||||
import org.telegram.ui.Cells.LoadingCell;
|
import org.telegram.ui.Cells.LoadingCell;
|
||||||
import org.telegram.ui.Cells.SharedDocumentCell;
|
import org.telegram.ui.Cells.SharedDocumentCell;
|
||||||
|
import org.telegram.ui.Cells.SharedLinkCell;
|
||||||
import org.telegram.ui.Cells.SharedMediaSectionCell;
|
import org.telegram.ui.Cells.SharedMediaSectionCell;
|
||||||
import org.telegram.ui.Cells.SharedPhotoVideoCell;
|
import org.telegram.ui.Cells.SharedPhotoVideoCell;
|
||||||
import org.telegram.ui.Components.BackupImageView;
|
import org.telegram.ui.Components.BackupImageView;
|
||||||
|
import org.telegram.ui.ActionBar.BaseFragment;
|
||||||
import org.telegram.ui.Components.LayoutHelper;
|
import org.telegram.ui.Components.LayoutHelper;
|
||||||
import org.telegram.ui.Components.SectionsListView;
|
import org.telegram.ui.Components.SectionsListView;
|
||||||
|
import org.telegram.ui.Components.WebFrameLayout;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -81,8 +86,10 @@ import java.util.TimerTask;
|
|||||||
public class MediaActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, PhotoViewer.PhotoViewerProvider {
|
public class MediaActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, PhotoViewer.PhotoViewerProvider {
|
||||||
|
|
||||||
private SharedPhotoVideoAdapter photoVideoAdapter;
|
private SharedPhotoVideoAdapter photoVideoAdapter;
|
||||||
|
private SharedLinksAdapter linksAdapter;
|
||||||
private SharedDocumentsAdapter documentsAdapter;
|
private SharedDocumentsAdapter documentsAdapter;
|
||||||
private DocumentsSearchAdapter documentsSearchAdapter;
|
private MediaSearchAdapter documentsSearchAdapter;
|
||||||
|
private MediaSearchAdapter linksSearchAdapter;
|
||||||
private SectionsListView listView;
|
private SectionsListView listView;
|
||||||
private LinearLayout progressView;
|
private LinearLayout progressView;
|
||||||
private TextView emptyTextView;
|
private TextView emptyTextView;
|
||||||
@ -179,10 +186,11 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SharedMediaData sharedMediaData[] = new SharedMediaData[3];
|
private SharedMediaData sharedMediaData[] = new SharedMediaData[4];
|
||||||
|
|
||||||
private final static int shared_media_item = 1;
|
private final static int shared_media_item = 1;
|
||||||
private final static int files_item = 2;
|
private final static int files_item = 2;
|
||||||
|
private final static int links_item = 5;
|
||||||
private final static int forward = 3;
|
private final static int forward = 3;
|
||||||
private final static int delete = 4;
|
private final static int delete = 4;
|
||||||
|
|
||||||
@ -230,6 +238,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
listView = null;
|
listView = null;
|
||||||
photoVideoAdapter = null;
|
photoVideoAdapter = null;
|
||||||
documentsAdapter = null;
|
documentsAdapter = null;
|
||||||
|
linksAdapter = null;
|
||||||
}
|
}
|
||||||
finishFragment();
|
finishFragment();
|
||||||
} else if (id == -2) {
|
} else if (id == -2) {
|
||||||
@ -248,6 +257,12 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
}
|
}
|
||||||
selectedMode = 1;
|
selectedMode = 1;
|
||||||
switchToCurrentSelectedMode();
|
switchToCurrentSelectedMode();
|
||||||
|
} else if (id == links_item) {
|
||||||
|
if (selectedMode == 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedMode = 3;
|
||||||
|
switchToCurrentSelectedMode();
|
||||||
} else if (id == delete) {
|
} else if (id == delete) {
|
||||||
if (getParentActivity() == null) {
|
if (getParentActivity() == null) {
|
||||||
return;
|
return;
|
||||||
@ -348,7 +363,11 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
@Override
|
@Override
|
||||||
public void onSearchCollapse() {
|
public void onSearchCollapse() {
|
||||||
dropDownContainer.setVisibility(View.VISIBLE);
|
dropDownContainer.setVisibility(View.VISIBLE);
|
||||||
documentsSearchAdapter.searchDocuments(null);
|
if (selectedMode == 1) {
|
||||||
|
documentsSearchAdapter.search(null);
|
||||||
|
} else if (selectedMode == 3) {
|
||||||
|
linksSearchAdapter.search(null);
|
||||||
|
}
|
||||||
searching = false;
|
searching = false;
|
||||||
searchWas = false;
|
searchWas = false;
|
||||||
switchToCurrentSelectedMode();
|
switchToCurrentSelectedMode();
|
||||||
@ -356,15 +375,22 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(EditText editText) {
|
public void onTextChanged(EditText editText) {
|
||||||
if (documentsSearchAdapter == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String text = editText.getText().toString();
|
String text = editText.getText().toString();
|
||||||
if (text.length() != 0) {
|
if (text.length() != 0) {
|
||||||
searchWas = true;
|
searchWas = true;
|
||||||
switchToCurrentSelectedMode();
|
switchToCurrentSelectedMode();
|
||||||
}
|
}
|
||||||
documentsSearchAdapter.searchDocuments(text);
|
if (selectedMode == 1) {
|
||||||
|
if (documentsSearchAdapter == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
documentsSearchAdapter.search(text);
|
||||||
|
} else if (selectedMode == 3) {
|
||||||
|
if (linksSearchAdapter == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
linksSearchAdapter.search(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
searchItem.getSearchField().setHint(LocaleController.getString("Search", R.string.Search));
|
searchItem.getSearchField().setHint(LocaleController.getString("Search", R.string.Search));
|
||||||
@ -374,6 +400,9 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
dropDownContainer.setSubMenuOpenSide(1);
|
dropDownContainer.setSubMenuOpenSide(1);
|
||||||
dropDownContainer.addSubItem(shared_media_item, LocaleController.getString("SharedMediaTitle", R.string.SharedMediaTitle), 0);
|
dropDownContainer.addSubItem(shared_media_item, LocaleController.getString("SharedMediaTitle", R.string.SharedMediaTitle), 0);
|
||||||
dropDownContainer.addSubItem(files_item, LocaleController.getString("DocumentsTitle", R.string.DocumentsTitle), 0);
|
dropDownContainer.addSubItem(files_item, LocaleController.getString("DocumentsTitle", R.string.DocumentsTitle), 0);
|
||||||
|
//if ((int) dialog_id != 0) {
|
||||||
|
if(BuildConfig.DEBUG)dropDownContainer.addSubItem(links_item, LocaleController.getString("LinksTitle", R.string.LinksTitle), 0);
|
||||||
|
//}
|
||||||
actionBar.addView(dropDownContainer, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, AndroidUtilities.isTablet() ? 64 : 56, 0, 40, 0));
|
actionBar.addView(dropDownContainer, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, AndroidUtilities.isTablet() ? 64 : 56, 0, 40, 0));
|
||||||
dropDownContainer.setOnClickListener(new View.OnClickListener() {
|
dropDownContainer.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -422,7 +451,9 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
|
|
||||||
photoVideoAdapter = new SharedPhotoVideoAdapter(context);
|
photoVideoAdapter = new SharedPhotoVideoAdapter(context);
|
||||||
documentsAdapter = new SharedDocumentsAdapter(context);
|
documentsAdapter = new SharedDocumentsAdapter(context);
|
||||||
documentsSearchAdapter = new DocumentsSearchAdapter(context);
|
documentsSearchAdapter = new MediaSearchAdapter(context, 1);
|
||||||
|
linksSearchAdapter = new MediaSearchAdapter(context, 3);
|
||||||
|
linksAdapter = new SharedLinksAdapter(context);
|
||||||
|
|
||||||
FrameLayout frameLayout;
|
FrameLayout frameLayout;
|
||||||
fragmentView = frameLayout = new FrameLayout(context);
|
fragmentView = frameLayout = new FrameLayout(context);
|
||||||
@ -437,9 +468,9 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> adapterView, View view, final int i, long l) {
|
public void onItemClick(AdapterView<?> adapterView, View view, final int i, long l) {
|
||||||
if (selectedMode == 1 && view instanceof SharedDocumentCell) {
|
if (selectedMode == 1 && view instanceof SharedDocumentCell) {
|
||||||
SharedDocumentCell cell = (SharedDocumentCell) view;
|
MediaActivity.this.onItemClick(i, view, ((SharedDocumentCell) view).getDocument(), 0);
|
||||||
MessageObject message = cell.getDocument();
|
} else if (selectedMode == 3 && view instanceof SharedLinkCell) {
|
||||||
MediaActivity.this.onItemClick(i, view, message, 0);
|
MediaActivity.this.onItemClick(i, view, ((SharedLinkCell) view).getMessage(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -464,8 +495,10 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
type = SharedMediaQuery.MEDIA_PHOTOVIDEO;
|
type = SharedMediaQuery.MEDIA_PHOTOVIDEO;
|
||||||
} else if (selectedMode == 1) {
|
} else if (selectedMode == 1) {
|
||||||
type = SharedMediaQuery.MEDIA_FILE;
|
type = SharedMediaQuery.MEDIA_FILE;
|
||||||
} else {
|
} else if (selectedMode == 2) {
|
||||||
type = SharedMediaQuery.MEDIA_AUDIO;
|
type = SharedMediaQuery.MEDIA_AUDIO;
|
||||||
|
} else {
|
||||||
|
type = SharedMediaQuery.MEDIA_URL;
|
||||||
}
|
}
|
||||||
SharedMediaQuery.loadMedia(dialog_id, 0, 50, sharedMediaData[selectedMode].max_id, type, !sharedMediaData[selectedMode].cacheEndReached, classGuid);
|
SharedMediaQuery.loadMedia(dialog_id, 0, 50, sharedMediaData[selectedMode].max_id, type, !sharedMediaData[selectedMode].cacheEndReached, classGuid);
|
||||||
}
|
}
|
||||||
@ -564,8 +597,12 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
if (documentsAdapter != null) {
|
if (documentsAdapter != null) {
|
||||||
documentsAdapter.notifyDataSetChanged();
|
documentsAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
} else if (selectedMode == 3 && type == 3) {
|
||||||
|
if (linksAdapter != null) {
|
||||||
|
linksAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (selectedMode == 1) {
|
if (selectedMode == 1 || selectedMode == 3) {
|
||||||
searchItem.setVisibility(!sharedMediaData[selectedMode].messages.isEmpty() && !searching ? View.VISIBLE : View.GONE);
|
searchItem.setVisibility(!sharedMediaData[selectedMode].messages.isEmpty() && !searching ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -587,7 +624,10 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
if (documentsAdapter != null) {
|
if (documentsAdapter != null) {
|
||||||
documentsAdapter.notifyDataSetChanged();
|
documentsAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
if (selectedMode == 1) {
|
if (linksAdapter != null) {
|
||||||
|
linksAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
if (selectedMode == 1 || selectedMode == 3) {
|
||||||
searchItem.setVisibility(!sharedMediaData[selectedMode].messages.isEmpty() && !searching ? View.VISIBLE : View.GONE);
|
searchItem.setVisibility(!sharedMediaData[selectedMode].messages.isEmpty() && !searching ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -617,7 +657,10 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
if (documentsAdapter != null) {
|
if (documentsAdapter != null) {
|
||||||
documentsAdapter.notifyDataSetChanged();
|
documentsAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
if (selectedMode == 1) {
|
if (linksAdapter != null) {
|
||||||
|
linksAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
if (selectedMode == 1 || selectedMode == 3) {
|
||||||
searchItem.setVisibility(!sharedMediaData[selectedMode].messages.isEmpty() && !searching ? View.VISIBLE : View.GONE);
|
searchItem.setVisibility(!sharedMediaData[selectedMode].messages.isEmpty() && !searching ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -641,6 +684,9 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
if (documentsAdapter != null) {
|
if (documentsAdapter != null) {
|
||||||
documentsAdapter.notifyDataSetChanged();
|
documentsAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
if (linksAdapter != null) {
|
||||||
|
linksAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
fixLayoutInternal();
|
fixLayoutInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,8 +774,13 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
private void switchToCurrentSelectedMode() {
|
private void switchToCurrentSelectedMode() {
|
||||||
if (searching && searchWas) {
|
if (searching && searchWas) {
|
||||||
if (listView != null) {
|
if (listView != null) {
|
||||||
listView.setAdapter(documentsSearchAdapter);
|
if (selectedMode == 1) {
|
||||||
documentsSearchAdapter.notifyDataSetChanged();
|
listView.setAdapter(documentsSearchAdapter);
|
||||||
|
documentsSearchAdapter.notifyDataSetChanged();
|
||||||
|
} else if (selectedMode == 3) {
|
||||||
|
listView.setAdapter(linksSearchAdapter);
|
||||||
|
linksSearchAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (emptyTextView != null) {
|
if (emptyTextView != null) {
|
||||||
emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult));
|
emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult));
|
||||||
@ -760,8 +811,8 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
dropDown.setText(LocaleController.getString("DocumentsTitle", R.string.DocumentsTitle));
|
dropDown.setText(LocaleController.getString("DocumentsTitle", R.string.DocumentsTitle));
|
||||||
emptyImageView.setImageResource(R.drawable.tip2);
|
emptyImageView.setImageResource(R.drawable.tip2);
|
||||||
emptyTextView.setText(LocaleController.getString("NoSharedFiles", R.string.NoSharedFiles));
|
emptyTextView.setText(LocaleController.getString("NoSharedFiles", R.string.NoSharedFiles));
|
||||||
searchItem.setVisibility(!sharedMediaData[1].messages.isEmpty() ? View.VISIBLE : View.GONE);
|
searchItem.setVisibility(!sharedMediaData[selectedMode].messages.isEmpty() ? View.VISIBLE : View.GONE);
|
||||||
if (!sharedMediaData[1].loading && !sharedMediaData[1].endReached && sharedMediaData[1].messages.isEmpty()) {
|
if (!sharedMediaData[selectedMode].loading && !sharedMediaData[selectedMode].endReached && sharedMediaData[selectedMode].messages.isEmpty()) {
|
||||||
sharedMediaData[selectedMode].loading = true;
|
sharedMediaData[selectedMode].loading = true;
|
||||||
SharedMediaQuery.loadMedia(dialog_id, 0, 50, 0, SharedMediaQuery.MEDIA_FILE, true, classGuid);
|
SharedMediaQuery.loadMedia(dialog_id, 0, 50, 0, SharedMediaQuery.MEDIA_FILE, true, classGuid);
|
||||||
}
|
}
|
||||||
@ -775,6 +826,26 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
listView.setEmptyView(emptyView);
|
listView.setEmptyView(emptyView);
|
||||||
}
|
}
|
||||||
listView.setPadding(0, 0, 0, AndroidUtilities.dp(4));
|
listView.setPadding(0, 0, 0, AndroidUtilities.dp(4));
|
||||||
|
} else if (selectedMode == 3) {
|
||||||
|
listView.setAdapter(linksAdapter);
|
||||||
|
dropDown.setText(LocaleController.getString("LinksTitle", R.string.LinksTitle));
|
||||||
|
emptyImageView.setImageResource(R.drawable.tip2);
|
||||||
|
emptyTextView.setText(LocaleController.getString("NoSharedLinks", R.string.NoSharedLinks));
|
||||||
|
searchItem.setVisibility(!sharedMediaData[3].messages.isEmpty() ? View.VISIBLE : View.GONE);
|
||||||
|
if (!sharedMediaData[selectedMode].loading && !sharedMediaData[selectedMode].endReached && sharedMediaData[selectedMode].messages.isEmpty()) {
|
||||||
|
sharedMediaData[selectedMode].loading = true;
|
||||||
|
SharedMediaQuery.loadMedia(dialog_id, 0, 50, 0, SharedMediaQuery.MEDIA_URL, false, classGuid);
|
||||||
|
}
|
||||||
|
listView.setVisibility(View.VISIBLE);
|
||||||
|
if (sharedMediaData[selectedMode].loading && sharedMediaData[selectedMode].messages.isEmpty()) {
|
||||||
|
progressView.setVisibility(View.VISIBLE);
|
||||||
|
listView.setEmptyView(null);
|
||||||
|
emptyView.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
progressView.setVisibility(View.GONE);
|
||||||
|
listView.setEmptyView(emptyView);
|
||||||
|
}
|
||||||
|
listView.setPadding(0, 0, 0, AndroidUtilities.dp(4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -905,6 +976,23 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
cell.updateFileExistIcon();
|
cell.updateFileExistIcon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (selectedMode == 3) {
|
||||||
|
try {
|
||||||
|
TLRPC.WebPage webPage = message.messageOwner.media.webpage;
|
||||||
|
if (Build.VERSION.SDK_INT >= 16 && webPage.embed_url != null && webPage.embed_url.length() != 0) {
|
||||||
|
BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity());
|
||||||
|
builder.setCustomView(new WebFrameLayout(getParentActivity(), builder.create(), webPage.title, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height));
|
||||||
|
builder.setUseFullWidth(true);
|
||||||
|
showDialog(builder.create());
|
||||||
|
} else {
|
||||||
|
Uri uri = Uri.parse(webPage.url);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
|
intent.putExtra(Browser.EXTRA_APPLICATION_ID, getParentActivity().getPackageName());
|
||||||
|
getParentActivity().startActivity(intent);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -945,6 +1033,100 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class SharedLinksAdapter extends BaseSectionsAdapter {
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
public SharedLinksAdapter(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int section, int position) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRowEnabled(int section, int row) {
|
||||||
|
return row != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSectionCount() {
|
||||||
|
return sharedMediaData[3].sections.size() + (sharedMediaData[3].sections.isEmpty() || sharedMediaData[3].endReached ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCountForSection(int section) {
|
||||||
|
if (section < sharedMediaData[3].sections.size()) {
|
||||||
|
return sharedMediaData[3].sectionArrays.get(sharedMediaData[3].sections.get(section)).size() + 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getSectionHeaderView(int section, View convertView, ViewGroup parent) {
|
||||||
|
if (convertView == null) {
|
||||||
|
convertView = new GreySectionCell(mContext);
|
||||||
|
}
|
||||||
|
if (section < sharedMediaData[3].sections.size()) {
|
||||||
|
String name = sharedMediaData[3].sections.get(section);
|
||||||
|
ArrayList<MessageObject> messageObjects = sharedMediaData[3].sectionArrays.get(name);
|
||||||
|
MessageObject messageObject = messageObjects.get(0);
|
||||||
|
((GreySectionCell) convertView).setText(LocaleController.formatterMonthYear.format((long) messageObject.messageOwner.date * 1000).toUpperCase());
|
||||||
|
}
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getItemView(int section, int position, View convertView, ViewGroup parent) {
|
||||||
|
if (section < sharedMediaData[3].sections.size()) {
|
||||||
|
String name = sharedMediaData[3].sections.get(section);
|
||||||
|
ArrayList<MessageObject> messageObjects = sharedMediaData[3].sectionArrays.get(name);
|
||||||
|
if (position == 0) {
|
||||||
|
if (convertView == null) {
|
||||||
|
convertView = new GreySectionCell(mContext);
|
||||||
|
}
|
||||||
|
MessageObject messageObject = messageObjects.get(0);
|
||||||
|
((GreySectionCell) convertView).setText(LocaleController.formatterMonthYear.format((long) messageObject.messageOwner.date * 1000).toUpperCase());
|
||||||
|
} else {
|
||||||
|
if (convertView == null) {
|
||||||
|
convertView = new SharedLinkCell(mContext);
|
||||||
|
}
|
||||||
|
SharedLinkCell sharedDocumentCell = (SharedLinkCell) convertView;
|
||||||
|
MessageObject messageObject = messageObjects.get(position - 1);
|
||||||
|
sharedDocumentCell.setLink(messageObject, position != messageObjects.size() || section == sharedMediaData[3].sections.size() - 1 && sharedMediaData[3].loading);
|
||||||
|
/*if (actionBar.isActionModeShowed()) {
|
||||||
|
sharedDocumentCell.setChecked(selectedFiles.containsKey(messageObject.getId()), !scrolling);
|
||||||
|
} else {
|
||||||
|
sharedDocumentCell.setChecked(false, !scrolling);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (convertView == null) {
|
||||||
|
convertView = new LoadingCell(mContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int section, int position) {
|
||||||
|
if (section < sharedMediaData[3].sections.size()) {
|
||||||
|
if (position == 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getViewTypeCount() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class SharedDocumentsAdapter extends BaseSectionsAdapter {
|
private class SharedDocumentsAdapter extends BaseSectionsAdapter {
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|
||||||
@ -1164,16 +1346,18 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DocumentsSearchAdapter extends BaseFragmentAdapter {
|
public class MediaSearchAdapter extends BaseFragmentAdapter {
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private ArrayList<MessageObject> searchResult = new ArrayList<>();
|
private ArrayList<MessageObject> searchResult = new ArrayList<>();
|
||||||
private Timer searchTimer;
|
private Timer searchTimer;
|
||||||
protected ArrayList<MessageObject> globalSearch = new ArrayList<>();
|
protected ArrayList<MessageObject> globalSearch = new ArrayList<>();
|
||||||
private long reqId = 0;
|
private long reqId = 0;
|
||||||
private int lastReqId;
|
private int lastReqId;
|
||||||
|
private int currentType;
|
||||||
|
|
||||||
public DocumentsSearchAdapter(Context context) {
|
public MediaSearchAdapter(Context context, int type) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
currentType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void queryServerSearch(final String query, final int max_id) {
|
public void queryServerSearch(final String query, final int max_id) {
|
||||||
@ -1195,7 +1379,11 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
req.offset = 0;
|
req.offset = 0;
|
||||||
req.limit = 50;
|
req.limit = 50;
|
||||||
req.max_id = max_id;
|
req.max_id = max_id;
|
||||||
req.filter = new TLRPC.TL_inputMessagesFilterDocument();
|
if (currentType == 1) {
|
||||||
|
req.filter = new TLRPC.TL_inputMessagesFilterDocument();
|
||||||
|
} else if (currentType == 3) {
|
||||||
|
req.filter = new TLRPC.TL_inputMessagesFilterUrl();
|
||||||
|
}
|
||||||
req.q = query;
|
req.q = query;
|
||||||
if (uid < 0) {
|
if (uid < 0) {
|
||||||
req.peer = new TLRPC.TL_inputPeerChat();
|
req.peer = new TLRPC.TL_inputPeerChat();
|
||||||
@ -1239,7 +1427,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
ConnectionsManager.getInstance().bindRequestToGuid(reqId, classGuid);
|
ConnectionsManager.getInstance().bindRequestToGuid(reqId, classGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void searchDocuments(final String query) {
|
public void search(final String query) {
|
||||||
try {
|
try {
|
||||||
if (searchTimer != null) {
|
if (searchTimer != null) {
|
||||||
searchTimer.cancel();
|
searchTimer.cancel();
|
||||||
@ -1271,49 +1459,55 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!sharedMediaData[1].messages.isEmpty()) {
|
if (!sharedMediaData[currentType].messages.isEmpty()) {
|
||||||
MessageObject messageObject = sharedMediaData[1].messages.get(sharedMediaData[1].messages.size() - 1);
|
if (currentType == 1) {
|
||||||
queryServerSearch(query, messageObject.getId());
|
MessageObject messageObject = sharedMediaData[currentType].messages.get(sharedMediaData[currentType].messages.size() - 1);
|
||||||
|
queryServerSearch(query, messageObject.getId());
|
||||||
|
} else if (currentType == 3) {
|
||||||
|
queryServerSearch(query, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final ArrayList<MessageObject> copy = new ArrayList<>();
|
if (currentType == 1) {
|
||||||
copy.addAll(sharedMediaData[1].messages);
|
final ArrayList<MessageObject> copy = new ArrayList<>();
|
||||||
Utilities.searchQueue.postRunnable(new Runnable() {
|
copy.addAll(sharedMediaData[1].messages);
|
||||||
@Override
|
Utilities.searchQueue.postRunnable(new Runnable() {
|
||||||
public void run() {
|
@Override
|
||||||
String search1 = query.trim().toLowerCase();
|
public void run() {
|
||||||
if (search1.length() == 0) {
|
String search1 = query.trim().toLowerCase();
|
||||||
updateSearchResults(new ArrayList<MessageObject>());
|
if (search1.length() == 0) {
|
||||||
return;
|
updateSearchResults(new ArrayList<MessageObject>());
|
||||||
}
|
return;
|
||||||
String search2 = LocaleController.getInstance().getTranslitString(search1);
|
}
|
||||||
if (search1.equals(search2) || search2.length() == 0) {
|
String search2 = LocaleController.getInstance().getTranslitString(search1);
|
||||||
search2 = null;
|
if (search1.equals(search2) || search2.length() == 0) {
|
||||||
}
|
search2 = null;
|
||||||
String search[] = new String[1 + (search2 != null ? 1 : 0)];
|
}
|
||||||
search[0] = search1;
|
String search[] = new String[1 + (search2 != null ? 1 : 0)];
|
||||||
if (search2 != null) {
|
search[0] = search1;
|
||||||
search[1] = search2;
|
if (search2 != null) {
|
||||||
}
|
search[1] = search2;
|
||||||
|
}
|
||||||
|
|
||||||
ArrayList<MessageObject> resultArray = new ArrayList<>();
|
ArrayList<MessageObject> resultArray = new ArrayList<>();
|
||||||
|
|
||||||
for (MessageObject messageObject : copy) {
|
for (MessageObject messageObject : copy) {
|
||||||
for (String q : search) {
|
for (String q : search) {
|
||||||
String name = messageObject.getDocumentName();
|
String name = messageObject.getDocumentName();
|
||||||
if (name == null || name.length() == 0) {
|
if (name == null || name.length() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
name = name.toLowerCase();
|
name = name.toLowerCase();
|
||||||
if (name.contains(q)) {
|
if (name.contains(q)) {
|
||||||
resultArray.add(messageObject);
|
resultArray.add(messageObject);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
updateSearchResults(resultArray);
|
updateSearchResults(resultArray);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1380,16 +1574,30 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int i, View view, ViewGroup viewGroup) {
|
public View getView(int i, View view, ViewGroup viewGroup) {
|
||||||
if (view == null) {
|
if (currentType == 1) {
|
||||||
view = new SharedDocumentCell(mContext);
|
if (view == null) {
|
||||||
}
|
view = new SharedDocumentCell(mContext);
|
||||||
SharedDocumentCell sharedDocumentCell = (SharedDocumentCell) view;
|
}
|
||||||
MessageObject messageObject = getItem(i);
|
SharedDocumentCell sharedDocumentCell = (SharedDocumentCell) view;
|
||||||
sharedDocumentCell.setDocument(messageObject, i != getCount() - 1);
|
MessageObject messageObject = getItem(i);
|
||||||
if (actionBar.isActionModeShowed()) {
|
sharedDocumentCell.setDocument(messageObject, i != getCount() - 1);
|
||||||
sharedDocumentCell.setChecked(selectedFiles.containsKey(messageObject.getId()), !scrolling);
|
if (actionBar.isActionModeShowed()) {
|
||||||
} else {
|
sharedDocumentCell.setChecked(selectedFiles.containsKey(messageObject.getId()), !scrolling);
|
||||||
sharedDocumentCell.setChecked(false, !scrolling);
|
} else {
|
||||||
|
sharedDocumentCell.setChecked(false, !scrolling);
|
||||||
|
}
|
||||||
|
} else if (currentType == 3) {
|
||||||
|
if (view == null) {
|
||||||
|
view = new SharedLinkCell(mContext);
|
||||||
|
}
|
||||||
|
SharedLinkCell sharedLinkCell = (SharedLinkCell) view;
|
||||||
|
MessageObject messageObject = getItem(i);
|
||||||
|
sharedLinkCell.setLink(messageObject, i != getCount() - 1);
|
||||||
|
/*if (actionBar.isActionModeShowed()) {
|
||||||
|
sharedDocumentCell.setChecked(selectedFiles.containsKey(messageObject.getId()), !scrolling);
|
||||||
|
} else {
|
||||||
|
sharedDocumentCell.setChecked(false, !scrolling);
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -780,6 +780,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen
|
|||||||
updateSearchInterface();
|
updateSearchInterface();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
jsonObjReq.setShouldCache(false);
|
||||||
jsonObjReq.setTag("search");
|
jsonObjReq.setTag("search");
|
||||||
requestQueue.add(jsonObjReq);
|
requestQueue.add(jsonObjReq);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -866,6 +867,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen
|
|||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
jsonObjReq.setShouldCache(false);
|
||||||
jsonObjReq.setTag("search");
|
jsonObjReq.setTag("search");
|
||||||
requestQueue.add(jsonObjReq);
|
requestQueue.add(jsonObjReq);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -14,10 +14,12 @@ import android.app.AlertDialog;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
@ -26,6 +28,7 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.Browser;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
@ -893,9 +896,17 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
|||||||
|
|
||||||
actionBar = new ActionBar(activity);
|
actionBar = new ActionBar(activity);
|
||||||
actionBar.setBackgroundColor(0x7F000000);
|
actionBar.setBackgroundColor(0x7F000000);
|
||||||
|
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
|
||||||
|
int def = themePrefs.getInt("themeColor", AndroidUtilities.defColor);
|
||||||
|
actionBar.setBackgroundColor(themePrefs.getInt("chatHeaderColor", def));
|
||||||
actionBar.setOccupyStatusBar(false);
|
actionBar.setOccupyStatusBar(false);
|
||||||
actionBar.setItemsBackground(R.drawable.bar_selector_white);
|
actionBar.setItemsBackground(R.drawable.bar_selector_white);
|
||||||
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
|
//actionBar.setBackButtonImage(R.drawable.ic_ab_back);
|
||||||
|
Drawable back = parentActivity.getResources().getDrawable(R.drawable.ic_ab_back);
|
||||||
|
int iconsColor = themePrefs.getInt("chatHeaderIconsColor", 0xffffffff);
|
||||||
|
back.setColorFilter(iconsColor, PorterDuff.Mode.MULTIPLY);
|
||||||
|
actionBar.setBackButtonDrawable(back);
|
||||||
|
actionBar.setTitleColor(iconsColor);
|
||||||
actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, 1, 1));
|
actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, 1, 1));
|
||||||
containerView.addView(actionBar, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
containerView.addView(actionBar, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||||
|
|
||||||
@ -1101,7 +1112,10 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
|||||||
|
|
||||||
ActionBarMenu menu = actionBar.createMenu();
|
ActionBarMenu menu = actionBar.createMenu();
|
||||||
|
|
||||||
menuItem = menu.addItem(0, R.drawable.ic_ab_other);
|
//menuItem = menu.addItem(0, R.drawable.ic_ab_other);
|
||||||
|
Drawable dots = parentActivity.getResources().getDrawable(R.drawable.ic_ab_other);
|
||||||
|
dots.setColorFilter(AndroidUtilities.getIntDef("chatHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY);
|
||||||
|
menuItem = menu.addItem(0, dots);
|
||||||
menuItem.addSubItem(gallery_menu_showall, LocaleController.getString("ShowAllMedia", R.string.ShowAllMedia), 0);
|
menuItem.addSubItem(gallery_menu_showall, LocaleController.getString("ShowAllMedia", R.string.ShowAllMedia), 0);
|
||||||
menuItem.addSubItem(gallery_menu_save, LocaleController.getString("SaveToGallery", R.string.SaveToGallery), 0);
|
menuItem.addSubItem(gallery_menu_save, LocaleController.getString("SaveToGallery", R.string.SaveToGallery), 0);
|
||||||
menuItem.addSubItem(gallery_menu_delete, LocaleController.getString("Delete", R.string.Delete), 0);
|
menuItem.addSubItem(gallery_menu_delete, LocaleController.getString("Delete", R.string.Delete), 0);
|
||||||
@ -1159,6 +1173,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
|||||||
File f = null;
|
File f = null;
|
||||||
|
|
||||||
if (currentMessageObject != null) {
|
if (currentMessageObject != null) {
|
||||||
|
if (currentMessageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||||
|
Uri uri = Uri.parse(currentMessageObject.messageOwner.media.webpage.url);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
|
intent.putExtra(Browser.EXTRA_APPLICATION_ID, parentActivity.getPackageName());
|
||||||
|
parentActivity.startActivity(intent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
f = FileLoader.getPathToMessage(currentMessageObject.messageOwner);
|
f = FileLoader.getPathToMessage(currentMessageObject.messageOwner);
|
||||||
} else if (currentFileLocation != null) {
|
} else if (currentFileLocation != null) {
|
||||||
f = FileLoader.getPathToAttach(currentFileLocation, avatarsUserId != 0);
|
f = FileLoader.getPathToAttach(currentFileLocation, avatarsUserId != 0);
|
||||||
@ -2020,7 +2041,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
|||||||
} else if (message.messageOwner.media != null) {
|
} else if (message.messageOwner.media != null) {
|
||||||
if (message.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
|
if (message.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||||
return file.volume_id + "_" + file.id + ".mp4";
|
return file.volume_id + "_" + file.id + ".mp4";
|
||||||
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
|
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || message.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||||
return file.volume_id + "_" + file.local_id + ".jpg";
|
return file.volume_id + "_" + file.local_id + ".jpg";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2076,7 +2097,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
|||||||
size[0] = -1;
|
size[0] = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && message.messageOwner.media.photo != null) {
|
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && message.messageOwner.media.photo != null || message.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && message.messageOwner.media.webpage != null) {
|
||||||
TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.photoThumbs, AndroidUtilities.getPhotoSize());
|
TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.photoThumbs, AndroidUtilities.getPhotoSize());
|
||||||
if (sizeFull != null) {
|
if (sizeFull != null) {
|
||||||
size[0] = sizeFull.size;
|
size[0] = sizeFull.size;
|
||||||
@ -2138,7 +2159,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
|||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
|
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || message.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||||
TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.photoThumbs, AndroidUtilities.getPhotoSize());
|
TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.photoThumbs, AndroidUtilities.getPhotoSize());
|
||||||
if (sizeFull != null) {
|
if (sizeFull != null) {
|
||||||
TLRPC.TL_inputFileLocation location = new TLRPC.TL_inputFileLocation();
|
TLRPC.TL_inputFileLocation location = new TLRPC.TL_inputFileLocation();
|
||||||
@ -2237,7 +2258,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
|||||||
|
|
||||||
if (messageObject != null && messages == null) {
|
if (messageObject != null && messages == null) {
|
||||||
imagesArr.add(messageObject);
|
imagesArr.add(messageObject);
|
||||||
if (messageObject.messageOwner.action == null || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionEmpty) {
|
if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) && (messageObject.messageOwner.action == null || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionEmpty)) {
|
||||||
needSearchImageInArr = true;
|
needSearchImageInArr = true;
|
||||||
imagesByIds.put(messageObject.getId(), messageObject);
|
imagesByIds.put(messageObject.getId(), messageObject);
|
||||||
if (messageObject.messageOwner.dialog_id != 0) {
|
if (messageObject.messageOwner.dialog_id != 0) {
|
||||||
@ -2397,6 +2418,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
|||||||
}
|
}
|
||||||
actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, (totalImagesCount - imagesArr.size()) + currentIndex + 1, totalImagesCount));
|
actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, (totalImagesCount - imagesArr.size()) + currentIndex + 1, totalImagesCount));
|
||||||
}
|
}
|
||||||
|
} else if (currentMessageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||||
|
actionBar.setTitle(LocaleController.getString("AttachPhoto", R.string.AttachPhoto));
|
||||||
}
|
}
|
||||||
if (currentMessageObject.messageOwner.ttl != 0) {
|
if (currentMessageObject.messageOwner.ttl != 0) {
|
||||||
menuItem.hideSubItem(gallery_menu_save);
|
menuItem.hideSubItem(gallery_menu_save);
|
||||||
|
@ -58,18 +58,6 @@ public class SecretPhotoViewer implements NotificationCenter.NotificationCenterD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FrameLayoutTouchListener extends FrameLayout {
|
|
||||||
public FrameLayoutTouchListener(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
FileLog.e("tmessages", event.toString());
|
|
||||||
return super.onTouchEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SecretDeleteTimer extends FrameLayout {
|
private class SecretDeleteTimer extends FrameLayout {
|
||||||
private String currentInfoString;
|
private String currentInfoString;
|
||||||
private int infoWidth;
|
private int infoWidth;
|
||||||
@ -147,7 +135,7 @@ public class SecretPhotoViewer implements NotificationCenter.NotificationCenterD
|
|||||||
|
|
||||||
private Activity parentActivity;
|
private Activity parentActivity;
|
||||||
private WindowManager.LayoutParams windowLayoutParams;
|
private WindowManager.LayoutParams windowLayoutParams;
|
||||||
private FrameLayoutTouchListener windowView;
|
private FrameLayout windowView;
|
||||||
private FrameLayoutDrawer containerView;
|
private FrameLayoutDrawer containerView;
|
||||||
private ImageReceiver centerImage = new ImageReceiver();
|
private ImageReceiver centerImage = new ImageReceiver();
|
||||||
private SecretDeleteTimer secretDeleteTimer;
|
private SecretDeleteTimer secretDeleteTimer;
|
||||||
@ -205,7 +193,7 @@ public class SecretPhotoViewer implements NotificationCenter.NotificationCenterD
|
|||||||
}
|
}
|
||||||
parentActivity = activity;
|
parentActivity = activity;
|
||||||
|
|
||||||
windowView = new FrameLayoutTouchListener(activity);
|
windowView = new FrameLayout(activity);
|
||||||
windowView.setBackgroundColor(0xff000000);
|
windowView.setBackgroundColor(0xff000000);
|
||||||
windowView.setFocusable(true);
|
windowView.setFocusable(true);
|
||||||
windowView.setFocusableInTouchMode(true);
|
windowView.setFocusableInTouchMode(true);
|
||||||
|
@ -316,7 +316,7 @@ public class ThemingDrawerActivity extends BaseFragment {
|
|||||||
commitInt("drawerNameColor", color);
|
commitInt("drawerNameColor", color);
|
||||||
}
|
}
|
||||||
|
|
||||||
},themePrefs.getInt("drawerNameColor", 0xffffffff), CENTER, 0, false);
|
},themePrefs.getInt("drawerNameColor", 0xffffffff), CENTER, 0, true);
|
||||||
colorDialog.show();
|
colorDialog.show();
|
||||||
} else if (i == phoneColorRow) {
|
} else if (i == phoneColorRow) {
|
||||||
if (getParentActivity() == null) {
|
if (getParentActivity() == null) {
|
||||||
@ -330,7 +330,7 @@ public class ThemingDrawerActivity extends BaseFragment {
|
|||||||
commitInt("drawerPhoneColor", color);
|
commitInt("drawerPhoneColor", color);
|
||||||
}
|
}
|
||||||
|
|
||||||
},themePrefs.getInt("drawerPhoneColor", AndroidUtilities.getIntDarkerColor("themeColor",-0x40)), CENTER, 0, false);
|
},themePrefs.getInt("drawerPhoneColor", AndroidUtilities.getIntDarkerColor("themeColor",-0x40)), CENTER, 0, true);
|
||||||
|
|
||||||
colorDialog.show();
|
colorDialog.show();
|
||||||
} else if (i == avatarRadiusRow) {
|
} else if (i == avatarRadiusRow) {
|
||||||
|
@ -274,7 +274,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
|||||||
compressVideo = (CheckBox) fragmentView.findViewById(R.id.compress_video);
|
compressVideo = (CheckBox) fragmentView.findViewById(R.id.compress_video);
|
||||||
compressVideo.setText(LocaleController.getString("CompressVideo", R.string.CompressVideo));
|
compressVideo.setText(LocaleController.getString("CompressVideo", R.string.CompressVideo));
|
||||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
||||||
//compressVideo.setVisibility(originalHeight != resultHeight || originalWidth != resultWidth ? View.VISIBLE : View.GONE);
|
compressVideo.setVisibility(originalHeight != resultHeight || originalWidth != resultWidth ? View.VISIBLE : View.GONE);
|
||||||
compressVideo.setChecked(preferences.getBoolean("compress_video", true));
|
compressVideo.setChecked(preferences.getBoolean("compress_video", true));
|
||||||
compressVideo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
compressVideo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
<string name="WillUnmuteIn">خلال %1$s</string>
|
<string name="WillUnmuteIn">خلال %1$s</string>
|
||||||
<string name="MuteDisable">تعطيل</string>
|
<string name="MuteDisable">تعطيل</string>
|
||||||
<string name="Hashtags">الأوسمة</string>
|
<string name="Hashtags">الأوسمة</string>
|
||||||
|
<string name="Recent">حديث</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="NewBroadcastList">رسالة جماعية جديدة</string>
|
<string name="NewBroadcastList">رسالة جماعية جديدة</string>
|
||||||
<string name="EnterListName">أدخل اسم القائمة</string>
|
<string name="EnterListName">أدخل اسم القائمة</string>
|
||||||
@ -391,9 +392,11 @@
|
|||||||
<string name="AutoLockDisabled">معطّل</string>
|
<string name="AutoLockDisabled">معطّل</string>
|
||||||
<!--media view-->
|
<!--media view-->
|
||||||
<string name="NoMedia">شارك المقاطع المرئية والصور في هذه المحادثة لتستطيع الوصول إليها من أية جهاز من أجهزتك</string>
|
<string name="NoMedia">شارك المقاطع المرئية والصور في هذه المحادثة لتستطيع الوصول إليها من أية جهاز من أجهزتك</string>
|
||||||
<string name="DocumentsTitle">ملفات</string>
|
<string name="DocumentsTitle">الملفات المشاركة</string>
|
||||||
<string name="SharedMediaTitle">الوسائط المشتركة</string>
|
<string name="SharedMediaTitle">الوسائط المشتركة</string>
|
||||||
|
<string name="LinksTitle">الروابط المشاركة</string>
|
||||||
<string name="NoSharedFiles">شارك الملفات والمستندات في هذه المحادثة لتستطيع الوصول إليها من أية جهاز من أجهزتك</string>
|
<string name="NoSharedFiles">شارك الملفات والمستندات في هذه المحادثة لتستطيع الوصول إليها من أية جهاز من أجهزتك</string>
|
||||||
|
<string name="NoSharedLinks">شارك الروابط في هذه المحادثة لتستطيع الوصول إليها من أية جهاز من أجهزتك</string>
|
||||||
<!--map view-->
|
<!--map view-->
|
||||||
<string name="Map">الخريطة</string>
|
<string name="Map">الخريطة</string>
|
||||||
<string name="Satellite">قمر صناعي</string>
|
<string name="Satellite">قمر صناعي</string>
|
||||||
@ -834,10 +837,10 @@
|
|||||||
<string name="formatterDay12H">h:mm a</string>
|
<string name="formatterDay12H">h:mm a</string>
|
||||||
<string name="formatDateAtTime">%1$s الساعة %2$s</string>
|
<string name="formatDateAtTime">%1$s الساعة %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">تم تحديث تيليجرام نسخة الأندرويد. الجديد في النسخة رقم 3.1:\n\n- بحث عن الرسائل داخل محادثات محددة. \n- إعادة تصميم كاملة لشاشة ارفاق الملفات. إرسال جهات اتصال وملفات صوتية مباشرة من خيار المرفقات. \n- تطوير لتشغيل الوسائط داخل التطبيق (يوتيوب, ڤيميو, ساوندكلاود وغيرها.),.\n\nللاستزادة، اطلع هنا:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">تم تحديث تيليجرام نسخة الاندرويد. الجديد في نسخة ٣.١.٢: \n\n- كلمات البحث الحديثة. \n- اضغط باستمرار لاستعراض الملصق قبل إرساله.</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+--><!--
|
||||||
<string name="updatePlusText"></string>
|
<string name="updatePlusText"></string>-->
|
||||||
<string name="TelegramForAndroid">بلاس مسنجر للأندرويد</string>
|
<string name="TelegramForAndroid">بلاس مسنجر للأندرويد</string>
|
||||||
<string name="Theming">الثيمات</string>
|
<string name="Theming">الثيمات</string>
|
||||||
<string name="colorHexInvalid">شفرة تعريف اللون غير صحيحه!</string>
|
<string name="colorHexInvalid">شفرة تعريف اللون غير صحيحه!</string>
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
<string name="WillUnmuteIn">In %1$s</string>
|
<string name="WillUnmuteIn">In %1$s</string>
|
||||||
<string name="MuteDisable">Dauerhaft Stumm</string>
|
<string name="MuteDisable">Dauerhaft Stumm</string>
|
||||||
<string name="Hashtags">HASHTAGS</string>
|
<string name="Hashtags">HASHTAGS</string>
|
||||||
|
<string name="Recent">LETZTE</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="NewBroadcastList">Neue Broadcast Liste</string>
|
<string name="NewBroadcastList">Neue Broadcast Liste</string>
|
||||||
<string name="EnterListName">Listenname</string>
|
<string name="EnterListName">Listenname</string>
|
||||||
@ -234,7 +235,7 @@
|
|||||||
<string name="EncryptionKey">Geheimer Schlüssel</string>
|
<string name="EncryptionKey">Geheimer Schlüssel</string>
|
||||||
<string name="MessageLifetime">Selbstzerstörungs-Timer</string>
|
<string name="MessageLifetime">Selbstzerstörungs-Timer</string>
|
||||||
<string name="ShortMessageLifetimeForever">Aus</string>
|
<string name="ShortMessageLifetimeForever">Aus</string>
|
||||||
<string name="EncryptionKeyDescription">Das ist eine Darstellung des Schlüssels für den Geheimen Chat mit <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Wenn dieses Bild auf <![CDATA[<b>]]>%2$s\s<![CDATA[</b>]]>s Telefon genau so aussieht, ist euer Chat zu 200%% sicher.<![CDATA[<br><br>]]>Erfahre mehr auf telegram.org</string>
|
<string name="EncryptionKeyDescription">Die Abbildung zeigt den aktuellen Schlüssel dieses geheimen Chats mit <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Wenn dieses Bild auf dem Gerät von <![CDATA[<b>]]>%2$s<![CDATA[</b>]]> genau so aussieht, ist euer Chat zu 200%% sicher.<![CDATA[<br><br>]]>Erfahre mehr auf telegram.org</string>
|
||||||
<string name="NumberUnknown">Unbekannt</string>
|
<string name="NumberUnknown">Unbekannt</string>
|
||||||
<string name="Info">Info</string>
|
<string name="Info">Info</string>
|
||||||
<string name="Phone">Telefon</string>
|
<string name="Phone">Telefon</string>
|
||||||
@ -391,9 +392,11 @@
|
|||||||
<string name="AutoLockDisabled">Deaktiviert</string>
|
<string name="AutoLockDisabled">Deaktiviert</string>
|
||||||
<!--media view-->
|
<!--media view-->
|
||||||
<string name="NoMedia">Die hier geteilten Bilder und Videos kannst du von jedem deiner Geräte aufrufen.</string>
|
<string name="NoMedia">Die hier geteilten Bilder und Videos kannst du von jedem deiner Geräte aufrufen.</string>
|
||||||
<string name="DocumentsTitle">Dateien</string>
|
<string name="DocumentsTitle">Geteilte Dateien</string>
|
||||||
<string name="SharedMediaTitle">Geteilte Medien</string>
|
<string name="SharedMediaTitle">Geteilte Medien</string>
|
||||||
|
<string name="LinksTitle">Geteilte Links</string>
|
||||||
<string name="NoSharedFiles">Die hier geteilten Dateien kannst du von jedem deiner Geräte aufrufen.</string>
|
<string name="NoSharedFiles">Die hier geteilten Dateien kannst du von jedem deiner Geräte aufrufen.</string>
|
||||||
|
<string name="NoSharedLinks">Die hier geteilten Links kannst du von jedem deiner Geräte aufrufen.</string>
|
||||||
<!--map view-->
|
<!--map view-->
|
||||||
<string name="Map">Karte</string>
|
<string name="Map">Karte</string>
|
||||||
<string name="Satellite">Satellit</string>
|
<string name="Satellite">Satellit</string>
|
||||||
@ -834,11 +837,11 @@
|
|||||||
<string name="formatterDay12H">h:mm a</string>
|
<string name="formatterDay12H">h:mm a</string>
|
||||||
<string name="formatDateAtTime">%1$s um %2$s</string>
|
<string name="formatDateAtTime">%1$s um %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Plus Messenger für Android wurde aktualisiert. Neu in Version 3.1:\n\n- Direkte Suche in Chats.\n- In Chats versteckt sich ein komplett neues Menü hinter der Büroklammer. Nun kann man dort auch Musik und Kontakte versenden.\n- In-App Medienwiedergabe für YouTube, Vimeo, SoundCloud, etc. optimiert und neuer Player für Audiodateien.\n\nMehr dazu unter:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">Plus Messenger für Android wurde aktualisiert. Neu in Version 3.1.2:\n\n- Die letzte Suche wird gespeichert\n- Stickervorschau: Sticker vor dem Senden antippen und halten</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+--><!--
|
||||||
<string name="updatePlusText">
|
<string name="updatePlusText">
|
||||||
\n\nNeu in 3.1.1.9:\n\n- Neue Sprechblase iOS hinzugefügt (Dank an Edwin Macalopu)\n- Neuer MOD Benutzernamen zusammen mit Mitgliedsnamen in Gruppen anzeigen\n- Zeigt Gruppe Admin im Gruppenprofil. Der Admin Benutzer hat ein eigenes Symbol\n- Neuer MOD Profilbild, Name und Telefonnummer im Hauptmenü zentrieren\n- Neuer MOD um Wiedergabe von Audio im Chat zu halten wird der Näherungssensor deaktiviert\n- Neuer MOD ändert Profilbild Farbe in Profilübersicht \n- Fehlerbeseitigung\n\n Prüfen und Anwenden von Themen für den Plus Messenger: https://play.google.com/store/apps/details?id=es.rafalense.themes</string>
|
\n\nNeu in 3.1.1.9:\n\n- Neue Sprechblase iOS hinzugefügt (Dank an Edwin Macalopu)\n- Neuer MOD Benutzernamen zusammen mit Mitgliedsnamen in Gruppen anzeigen\n- Zeigt Gruppe Admin im Gruppenprofil. Der Admin Benutzer hat ein eigenes Symbol\n- Neuer MOD Profilbild, Name und Telefonnummer im Hauptmenü zentrieren\n- Neuer MOD um Wiedergabe von Audio im Chat zu halten wird der Näherungssensor deaktiviert\n- Neuer MOD ändert Profilbild Farbe in Profilübersicht \n- Fehlerbeseitigung\n\n Prüfen und Anwenden von Themen für den Plus Messenger: https://play.google.com/store/apps/details?id=es.rafalense.themes</string>-->
|
||||||
<string name="TelegramForAndroid">Plus Messenger für Android</string>
|
<string name="TelegramForAndroid">Plus Messenger für Android</string>
|
||||||
<string name="Theming">Themen bearbeiten</string>
|
<string name="Theming">Themen bearbeiten</string>
|
||||||
<string name="colorHexInvalid">Ungültiger Hex-Code!</string>
|
<string name="colorHexInvalid">Ungültiger Hex-Code!</string>
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
<string name="WillUnmuteIn">En %1$s</string>
|
<string name="WillUnmuteIn">En %1$s</string>
|
||||||
<string name="MuteDisable">Desactivar</string>
|
<string name="MuteDisable">Desactivar</string>
|
||||||
<string name="Hashtags">HASHTAGS</string>
|
<string name="Hashtags">HASHTAGS</string>
|
||||||
|
<string name="Recent">RECIENTES</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="NewBroadcastList">Nueva difusión</string>
|
<string name="NewBroadcastList">Nueva difusión</string>
|
||||||
<string name="EnterListName">Nombre de la lista</string>
|
<string name="EnterListName">Nombre de la lista</string>
|
||||||
@ -393,7 +394,9 @@
|
|||||||
<string name="NoMedia">Comparte fotos y vídeos en este chat y accede a ellos desde cualquier dispositivo.</string>
|
<string name="NoMedia">Comparte fotos y vídeos en este chat y accede a ellos desde cualquier dispositivo.</string>
|
||||||
<string name="DocumentsTitle">Archivos</string>
|
<string name="DocumentsTitle">Archivos</string>
|
||||||
<string name="SharedMediaTitle">Multimedia</string>
|
<string name="SharedMediaTitle">Multimedia</string>
|
||||||
|
<string name="LinksTitle">Enlaces</string>
|
||||||
<string name="NoSharedFiles">Comparte archivos en este chat y accede a ellos desde cualquier dispositivo.</string>
|
<string name="NoSharedFiles">Comparte archivos en este chat y accede a ellos desde cualquier dispositivo.</string>
|
||||||
|
<string name="NoSharedLinks">Comparte enlaces en este chat y accede a ellos desde cualquiera de tus dispositivos.</string>
|
||||||
<!--map view-->
|
<!--map view-->
|
||||||
<string name="Map">Mapa</string>
|
<string name="Map">Mapa</string>
|
||||||
<string name="Satellite">Satélite</string>
|
<string name="Satellite">Satélite</string>
|
||||||
@ -834,10 +837,10 @@
|
|||||||
<string name="formatterDay12H">h:mm a</string>
|
<string name="formatterDay12H">h:mm a</string>
|
||||||
<string name="formatDateAtTime">%1$s a las %2$s</string>
|
<string name="formatDateAtTime">%1$s a las %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Plus Messenger para Android fue actualizada. Novedades en la versión 3.1:\n\n- Busca mensajes dentro de un chat en específico.\n- Menú para adjuntar completamente rediseñado. Envía contactos y archivos de audio directamente desde el menú para adjuntar.\n- Reproducción de multimedia dentro de la aplicación mejorada (YouTube, Vimeo, SoundCloud etc.), nuevo reproductor para archivos de audio largos.\n\nMás sobre esta actualización:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">Plus Messenger para Android fue actualizada. Novedades en la versión 3.1.2:\n\n- Búsquedas recientes\n- Mantén pulsado sobre un sticker para obtener una vista previa antes de enviarlo</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+-->
|
||||||
<string name="updatePlusText">\n\nNovedades en 3.1.1.9:\n\n- Añadidos nuevos bocadillos iOs (gracias a Edwin Macalopu)\n- Nuevo MOD para mostrar nombre de usuario junto con nombre de miembro en grupos\n- Se muestra admin en perfil de grupo\n- Nuevo MOD para centrar foto, nombre y número en menú de navegación\n- Nuevo MOD para no parar audio en chat desactivando actuación de sensor de proximidad\n- Nuevo MOD para cambiar color de iconos en pantalla perfil\n- Solución de errores\n\n- Revisa, descarga y aplica temas para Plus Messenger: https://play.google.com/store/apps/details?id=es.rafalense.themes</string>
|
<string name="updatePlusText">Novedades en 3.1.2.0:\n\n- Solución de errores</string>
|
||||||
<string name="TelegramForAndroid">Plus Messenger para Android</string>
|
<string name="TelegramForAndroid">Plus Messenger para Android</string>
|
||||||
<string name="Theming">Tematización</string>
|
<string name="Theming">Tematización</string>
|
||||||
<string name="colorHexInvalid">¡Color hexadecimal inválido!</string>
|
<string name="colorHexInvalid">¡Color hexadecimal inválido!</string>
|
||||||
|
@ -832,7 +832,7 @@
|
|||||||
<string name="formatDateAtTime">%1$s à %2$s</string>
|
<string name="formatDateAtTime">%1$s à %2$s</string>
|
||||||
<!--update text--><!--
|
<!--update text--><!--
|
||||||
<string name="updateText">Plus Messenger pour Android vient d\'être mis à jour. Nouveautés de la version 2.9: \n\n- Installez et partagez des paquets de stickers personnalisés comme celui-ci: this one: https://play.google.com/store/apps/details?id=es.rafalense.themes\n- Si vous êtes un artiste, créez vos paquets de stickers, en utilisant notre robot @stickers. \n\n- Utilisez Telegram avec Android Auto.</string>-->
|
<string name="updateText">Plus Messenger pour Android vient d\'être mis à jour. Nouveautés de la version 2.9: \n\n- Installez et partagez des paquets de stickers personnalisés comme celui-ci: this one: https://play.google.com/store/apps/details?id=es.rafalense.themes\n- Si vous êtes un artiste, créez vos paquets de stickers, en utilisant notre robot @stickers. \n\n- Utilisez Telegram avec Android Auto.</string>-->
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+-->
|
||||||
<string name="TelegramForAndroid">Plus Messenger pour Android</string>
|
<string name="TelegramForAndroid">Plus Messenger pour Android</string>
|
||||||
<string name="Theming">Thème</string>
|
<string name="Theming">Thème</string>
|
||||||
|
@ -515,9 +515,9 @@
|
|||||||
<string name="formatDateAtTime">%1$s पर %2$s</string>
|
<string name="formatDateAtTime">%1$s पर %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Plus Messenger for Android has been updated. New in Version 3.0:\n\n\n\n- Dedicated tabs for each one of your custom sticker sets in the sticker panel. Add custom stickers like https://telegram.me/addstickers/Animals\n- New bot API, free for everyone. If you\'re an engineer, create your own bots for games, services or integrations. Learn more at https://telegram.org/blog/bot-revolution\n https://play.google.com/store/apps/details?id=es.rafalense.themes</string>
|
<string name="updateText">Plus Messenger for Android has been updated. New in Version 3.0:\n\n\n\n- Dedicated tabs for each one of your custom sticker sets in the sticker panel. Add custom stickers like https://telegram.me/addstickers/Animals\n- New bot API, free for everyone. If you\'re an engineer, create your own bots for games, services or integrations. Learn more at https://telegram.org/blog/bot-revolution\n https://play.google.com/store/apps/details?id=es.rafalense.themes</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+--><!--
|
||||||
<string name="updatePlusText"></string>
|
<string name="updatePlusText"></string>-->
|
||||||
<string name="TelegramForAndroid">Android के लिए प्लस मैसेंजर</string>
|
<string name="TelegramForAndroid">Android के लिए प्लस मैसेंजर</string>
|
||||||
<string name="Theming">थीमिंग</string>
|
<string name="Theming">थीमिंग</string>
|
||||||
<string name="colorHexInvalid">रंग का हेक्स कोड गलत है!</string>
|
<string name="colorHexInvalid">रंग का हेक्स कोड गलत है!</string>
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
<string name="WillUnmuteIn">Tra %1$s</string>
|
<string name="WillUnmuteIn">Tra %1$s</string>
|
||||||
<string name="MuteDisable">Disabilita</string>
|
<string name="MuteDisable">Disabilita</string>
|
||||||
<string name="Hashtags">HASHTAG</string>
|
<string name="Hashtags">HASHTAG</string>
|
||||||
|
<string name="Recent">RECENTI</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="NewBroadcastList">Nuova lista broadcast</string>
|
<string name="NewBroadcastList">Nuova lista broadcast</string>
|
||||||
<string name="EnterListName">Immetti il nome della lista</string>
|
<string name="EnterListName">Immetti il nome della lista</string>
|
||||||
@ -301,7 +302,7 @@
|
|||||||
<string name="ContactJoined">Un contatto si è unito a Telegram</string>
|
<string name="ContactJoined">Un contatto si è unito a Telegram</string>
|
||||||
<string name="Pebble">PEBBLE</string>
|
<string name="Pebble">PEBBLE</string>
|
||||||
<string name="Language">Lingua</string>
|
<string name="Language">Lingua</string>
|
||||||
<string name="AskAQuestionInfo">Nota che il supporto di Telegram è fornito da volontari. Proviamo a rispondere non appena possibile, ma potrebbe volerci un pò.<![CDATA[<br><br>]]>Dai un\'occhiata alle <![CDATA[<a href=\"https://telegram.org/faq/it#domande-generali\">FAQdi Telegram</a>]]>: troverai risposte alla maggior parte delle domande e suggerimenti importanti per <![CDATA[<a href=\"https://telegram.org/faq/it#risoluzione-dei-problemi\">l\'individuazione del problema</a>]]></string>
|
<string name="AskAQuestionInfo">Nota che il supporto di Telegram è fornito da volontari. Proviamo a rispondere non appena possibile, ma potrebbe volerci un pò.<![CDATA[<br><br>]]>Dai un\'occhiata alle <![CDATA[<a href=\"https://telegram.org/faq/it#domande-generali\">FAQ di Telegram</a>]]>: troverai risposte alla maggior parte delle domande e suggerimenti importanti per <![CDATA[<a href=\"https://telegram.org/faq/it#risoluzione-dei-problemi\">l\'individuazione del problema</a>]]></string>
|
||||||
<string name="AskButton">Chiedi a un volontario</string>
|
<string name="AskButton">Chiedi a un volontario</string>
|
||||||
<string name="TelegramFaq">FAQ di Telegram</string>
|
<string name="TelegramFaq">FAQ di Telegram</string>
|
||||||
<string name="TelegramFaqUrl">https://telegram.org/faq/it</string>
|
<string name="TelegramFaqUrl">https://telegram.org/faq/it</string>
|
||||||
@ -391,9 +392,11 @@
|
|||||||
<string name="AutoLockDisabled">Disabilitato</string>
|
<string name="AutoLockDisabled">Disabilitato</string>
|
||||||
<!--media view-->
|
<!--media view-->
|
||||||
<string name="NoMedia">Condividi foto e video in questa chat e accedi ad essi da ogni tuo dispositivo.</string>
|
<string name="NoMedia">Condividi foto e video in questa chat e accedi ad essi da ogni tuo dispositivo.</string>
|
||||||
<string name="DocumentsTitle">File</string>
|
<string name="DocumentsTitle">File condivisi</string>
|
||||||
<string name="SharedMediaTitle">Media condivisi</string>
|
<string name="SharedMediaTitle">Media condivisi</string>
|
||||||
|
<string name="LinksTitle">Link condivisi</string>
|
||||||
<string name="NoSharedFiles">Condividi file e documenti in questa chat e accedi ad essi da ogni tuo dispositivo.</string>
|
<string name="NoSharedFiles">Condividi file e documenti in questa chat e accedi ad essi da ogni tuo dispositivo.</string>
|
||||||
|
<string name="NoSharedLinks">Condividi link in questa chat ed accedi ad essi da ogni tuo dispositivo.</string>
|
||||||
<!--map view-->
|
<!--map view-->
|
||||||
<string name="Map">Mappa</string>
|
<string name="Map">Mappa</string>
|
||||||
<string name="Satellite">Satellite</string>
|
<string name="Satellite">Satellite</string>
|
||||||
@ -834,11 +837,11 @@
|
|||||||
<string name="formatterDay12H">h:mm a</string>
|
<string name="formatterDay12H">h:mm a</string>
|
||||||
<string name="formatDateAtTime">%1$s alle %2$s</string>
|
<string name="formatDateAtTime">%1$s alle %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Plus Messenger per Android si è aggiornato. Nuovo nella versione 3.1:\n\n- Cerca messaggi all\'interno di una specifica chat.\n- Menu degli allegati completamente ridisegnato. Invia contatti e audio direttamente dal menu degli allegati.\n- Riproduzione in-app migliorata (YouTube, Vimeo, SoundCloud etc.), nuovo player per i file audio.\n\nMaggiori informazioni su questo aggiornamento:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">Plus Messenger per Android si è aggiornato. Nuovo nella versione 3.1.2:\n\n- Risultati recenti nella ricerca\n- Tieni premuto su uno sticker per visualizzare l\'anteprima prima di inviarlo</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+--><!--
|
||||||
<string name="updatePlusText">
|
<string name="updatePlusText">
|
||||||
\n\nNew in 3.1.1.9:\n\n- Nuove bolle in stile iOS aggiunte (tgrazie a Edwin Macalopu)\n- Nuova MOD per mostrare l\'username assieme al nome del partecipante del gruppo\n- Mostra l\'amministratore del gruppo nella schermata del profilo del gruppo. L\'amministratore ha un\'icona particolare\n- Nuova MOD per centrare l\'avatar, il nome ed il telefono nel menu di navigazione\n- Nuova MOD per continuare a riprodurre gli audio nelle chat disabilitndo l\'azione del sensore di prossimità\n- Nuova MOD per cambiare il colore delle icone nella schermata profilo\n- Bug fixes\n\nEsplora e scarica temi per Plus Messenger: https://play.google.com/store/apps/details?id=es.rafalense.themes</string>
|
\n\nNew in 3.1.1.9:\n\n- Nuove bolle in stile iOS aggiunte (tgrazie a Edwin Macalopu)\n- Nuova MOD per mostrare l\'username assieme al nome del partecipante del gruppo\n- Mostra l\'amministratore del gruppo nella schermata del profilo del gruppo. L\'amministratore ha un\'icona particolare\n- Nuova MOD per centrare l\'avatar, il nome ed il telefono nel menu di navigazione\n- Nuova MOD per continuare a riprodurre gli audio nelle chat disabilitndo l\'azione del sensore di prossimità\n- Nuova MOD per cambiare il colore delle icone nella schermata profilo\n- Bug fixes\n\nEsplora e scarica temi per Plus Messenger: https://play.google.com/store/apps/details?id=es.rafalense.themes</string>-->
|
||||||
<string name="TelegramForAndroid">Plus Messenger per Android</string>
|
<string name="TelegramForAndroid">Plus Messenger per Android</string>
|
||||||
<string name="Theming">Personalizzazione</string>
|
<string name="Theming">Personalizzazione</string>
|
||||||
<string name="colorHexInvalid">Codice del colore esadecimale non valido!</string>
|
<string name="colorHexInvalid">Codice del colore esadecimale non valido!</string>
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
<string name="WillUnmuteIn">%1$s 후</string>
|
<string name="WillUnmuteIn">%1$s 후</string>
|
||||||
<string name="MuteDisable">비활성화</string>
|
<string name="MuteDisable">비활성화</string>
|
||||||
<string name="Hashtags">해시태그</string>
|
<string name="Hashtags">해시태그</string>
|
||||||
|
<string name="Recent">최신</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="NewBroadcastList">새 단체 메시지 리스트</string>
|
<string name="NewBroadcastList">새 단체 메시지 리스트</string>
|
||||||
<string name="EnterListName">리스트 이름을 입력하세요</string>
|
<string name="EnterListName">리스트 이름을 입력하세요</string>
|
||||||
@ -391,9 +392,11 @@
|
|||||||
<string name="AutoLockDisabled">비활성화됨</string>
|
<string name="AutoLockDisabled">비활성화됨</string>
|
||||||
<!--media view-->
|
<!--media view-->
|
||||||
<string name="NoMedia">이 채팅방에서 사진이나 동영상을 공유하면 다른 기기에서도 보실 수 있습니다.</string>
|
<string name="NoMedia">이 채팅방에서 사진이나 동영상을 공유하면 다른 기기에서도 보실 수 있습니다.</string>
|
||||||
<string name="DocumentsTitle">파일</string>
|
<string name="DocumentsTitle">공유한 파일</string>
|
||||||
<string name="SharedMediaTitle">공유된 미디어</string>
|
<string name="SharedMediaTitle">공유된 미디어</string>
|
||||||
|
<string name="LinksTitle">공유한 링크</string>
|
||||||
<string name="NoSharedFiles">이 채팅방에서 파일이나 문서를 공유하면 다른 기기에서도 보실 수 있습니다.</string>
|
<string name="NoSharedFiles">이 채팅방에서 파일이나 문서를 공유하면 다른 기기에서도 보실 수 있습니다.</string>
|
||||||
|
<string name="NoSharedLinks">이 채팅방에서 파일이나 문서를 공유하면 다른 기기에서도 보실 수 있습니다.</string>
|
||||||
<!--map view-->
|
<!--map view-->
|
||||||
<string name="Map">지도</string>
|
<string name="Map">지도</string>
|
||||||
<string name="Satellite">위성</string>
|
<string name="Satellite">위성</string>
|
||||||
@ -834,6 +837,6 @@
|
|||||||
<string name="formatterDay12H">a h:mm</string>
|
<string name="formatterDay12H">a h:mm</string>
|
||||||
<string name="formatDateAtTime">%1$s %2$s</string>
|
<string name="formatDateAtTime">%1$s %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">텔레그램 안드로이드 버전이 업데이트 되었습니다. 새로운 버전은 3.1 입니다:\n\n- 특정 대화창에서 검색. \n- 첨부 메뉴 개선. 해당 메뉴에서 바로 연락처, 오디오를 전송 가능. \n- 인앱 미디어 재생 기능 향상 (YouTube, Vimeo, SoundCloud etc). 대용량 오디오 파일 별도 플레이어 기능. \n\nhttps://telegram.org/blog/search-and-media에서 자세한 사항을 알아보세요.</string>
|
<string name="updateText">텔레그램 안드로이드 버전이 업데이트 되었습니다. 새로운 버전은 3.1.2 입니다:\n\n- 최신 검색 결과\n- 스티커를 꾹 누를 경우 미리보기 기능</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
</resources>
|
</resources>
|
@ -59,6 +59,7 @@
|
|||||||
<string name="WillUnmuteIn">Over %1$s</string>
|
<string name="WillUnmuteIn">Over %1$s</string>
|
||||||
<string name="MuteDisable">Uitschakelen</string>
|
<string name="MuteDisable">Uitschakelen</string>
|
||||||
<string name="Hashtags">HASHTAGS</string>
|
<string name="Hashtags">HASHTAGS</string>
|
||||||
|
<string name="Recent">RECENT</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="NewBroadcastList">Nieuwe verzendlijst</string>
|
<string name="NewBroadcastList">Nieuwe verzendlijst</string>
|
||||||
<string name="EnterListName">Naam van lijst</string>
|
<string name="EnterListName">Naam van lijst</string>
|
||||||
@ -391,9 +392,11 @@
|
|||||||
<string name="AutoLockDisabled">Uitgeschakeld</string>
|
<string name="AutoLockDisabled">Uitgeschakeld</string>
|
||||||
<!--media view-->
|
<!--media view-->
|
||||||
<string name="NoMedia">Deel foto\'s en video\'s in deze chat om ze op al je apparaten te kunnen benaderen.</string>
|
<string name="NoMedia">Deel foto\'s en video\'s in deze chat om ze op al je apparaten te kunnen benaderen.</string>
|
||||||
<string name="DocumentsTitle">Bestanden</string>
|
<string name="DocumentsTitle">Gedeelde bestanden</string>
|
||||||
<string name="SharedMediaTitle">Gedeelde media</string>
|
<string name="SharedMediaTitle">Gedeelde media</string>
|
||||||
|
<string name="LinksTitle">Gedeelde links</string>
|
||||||
<string name="NoSharedFiles">Deel bestanden en documenten in deze chat om ze op al je apparaten te kunnen benaderen.</string>
|
<string name="NoSharedFiles">Deel bestanden en documenten in deze chat om ze op al je apparaten te kunnen benaderen.</string>
|
||||||
|
<string name="NoSharedLinks">Deel links in deze chat om ze op al je apparaten te kunnen benaderen.</string>
|
||||||
<!--map view-->
|
<!--map view-->
|
||||||
<string name="Map">Kaart</string>
|
<string name="Map">Kaart</string>
|
||||||
<string name="Satellite">Satelliet</string>
|
<string name="Satellite">Satelliet</string>
|
||||||
@ -834,10 +837,10 @@
|
|||||||
<string name="formatterDay12H">h:mm a</string>
|
<string name="formatterDay12H">h:mm a</string>
|
||||||
<string name="formatDateAtTime">%1$s om %2$s</string>
|
<string name="formatDateAtTime">%1$s om %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Plus Messenger voor Android is bijgewerkt. Nieuw in versie 3.1:\n\n- Zoek naar berichten in een specifieke chat.\n- Volledig opnieuw ontworpen bijlagemenu. Verstuur contacten en audiobestanden rechtstreeks vanuit het bijlagemenu.\n- Afspelen van media in de app verbeterd (YouTube, Vimeo, SoundCloud, etc.), nieuwe speler voor grote audiobestanden.\n\nMeer weten? Kijk op:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">Plus Messenger voor Android is bijgewerkt. Nieuw in versie 3.1.2:\n\n- Recente zoekresultaten\n- Stickers aantikken en vasthouden om een voorbeeld weer te geven voor het versturen.</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+--><!--
|
||||||
<string name="updatePlusText"></string>
|
<string name="updatePlusText"></string>-->
|
||||||
<string name="TelegramForAndroid">Plus Messenger voor Android</string>
|
<string name="TelegramForAndroid">Plus Messenger voor Android</string>
|
||||||
<string name="Theming">Uiterlijk Aanpassen</string>
|
<string name="Theming">Uiterlijk Aanpassen</string>
|
||||||
<string name="colorHexInvalid">Ongeldige hexadecimale kleurcode!</string>
|
<string name="colorHexInvalid">Ongeldige hexadecimale kleurcode!</string>
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
<string name="WillUnmuteIn">Em %1$s</string>
|
<string name="WillUnmuteIn">Em %1$s</string>
|
||||||
<string name="MuteDisable">Desativar</string>
|
<string name="MuteDisable">Desativar</string>
|
||||||
<string name="Hashtags">HASHTAGS</string>
|
<string name="Hashtags">HASHTAGS</string>
|
||||||
|
<string name="Recent">RECENTE</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="NewBroadcastList">Nova Lista de Transmissão</string>
|
<string name="NewBroadcastList">Nova Lista de Transmissão</string>
|
||||||
<string name="EnterListName">Digite o nome da lista</string>
|
<string name="EnterListName">Digite o nome da lista</string>
|
||||||
@ -391,9 +392,11 @@
|
|||||||
<string name="AutoLockDisabled">Desativado</string>
|
<string name="AutoLockDisabled">Desativado</string>
|
||||||
<!--media view-->
|
<!--media view-->
|
||||||
<string name="NoMedia">Compartilhar fotos e vídeos no chat e acessá-los em qualquer um de seus dispositivos.</string>
|
<string name="NoMedia">Compartilhar fotos e vídeos no chat e acessá-los em qualquer um de seus dispositivos.</string>
|
||||||
<string name="DocumentsTitle">Arquivos</string>
|
<string name="DocumentsTitle">Arquivos Compartilhados</string>
|
||||||
<string name="SharedMediaTitle">Mídia Compartilhada</string>
|
<string name="SharedMediaTitle">Mídia Compartilhada</string>
|
||||||
|
<string name="LinksTitle">Links Compartilhados</string>
|
||||||
<string name="NoSharedFiles">Compartilhar arquivos e documentos no chat e acessá-los de qualquer um de seus dispositivos.</string>
|
<string name="NoSharedFiles">Compartilhar arquivos e documentos no chat e acessá-los de qualquer um de seus dispositivos.</string>
|
||||||
|
<string name="NoSharedLinks">Compartilhe links nesse chat e os acesse de qualquer um de seus dispositivos</string>
|
||||||
<!--map view-->
|
<!--map view-->
|
||||||
<string name="Map">Mapa</string>
|
<string name="Map">Mapa</string>
|
||||||
<string name="Satellite">Satélite</string>
|
<string name="Satellite">Satélite</string>
|
||||||
@ -834,11 +837,11 @@
|
|||||||
<string name="formatterDay12H">h:mm a</string>
|
<string name="formatterDay12H">h:mm a</string>
|
||||||
<string name="formatDateAtTime">%1$s às %2$s</string>
|
<string name="formatDateAtTime">%1$s às %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Plus Messenger para Android foi atualizado. Novo na versão 3.1:\n\n- Busca por mensagens dentro de um chat específico.\n-Menu de anexo totalmente redesenhado. Envie contatos e arquivos de áudio diretamente do menu de anexo.\n- Reprodução melhorada de mídia dentro do aplicativo (YouTube, Vimeo, SoundCloud, etc.), novo player para grandes arquivos de áudio.\n\nMais sobre a atualização:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">Plus Messenger para Android acaba de ser atualizado. Novo na versão 3.1.2\n\n- Resultados das buscas recentes\n- Pressione e mantenha em um sticker para pré-visualizar antes do envio</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+--><!--
|
||||||
<string name="updatePlusText">
|
<string name="updatePlusText">
|
||||||
\n\nNew in 3.1.1.9:\n\n- New MOD to center avatar, name and phone in navigation menu\n- New MOD to don\'t stop audio in chat (disables proximity sensor action)\n-New MOD to change icons color in profile screen\n- Bug fixes</string>
|
\n\nNew in 3.1.1.9:\n\n- New MOD to center avatar, name and phone in navigation menu\n- New MOD to don\'t stop audio in chat (disables proximity sensor action)\n-New MOD to change icons color in profile screen\n- Bug fixes</string>-->
|
||||||
<string name="TelegramForAndroid">Plus Messenger para Android</string>
|
<string name="TelegramForAndroid">Plus Messenger para Android</string>
|
||||||
<string name="Theming">Personalização</string>
|
<string name="Theming">Personalização</string>
|
||||||
<string name="colorHexInvalid">Código de cor hexadecimal inválido!</string>
|
<string name="colorHexInvalid">Código de cor hexadecimal inválido!</string>
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
<string name="WillUnmuteIn">Em %1$s</string>
|
<string name="WillUnmuteIn">Em %1$s</string>
|
||||||
<string name="MuteDisable">Desativar</string>
|
<string name="MuteDisable">Desativar</string>
|
||||||
<string name="Hashtags">HASHTAGS</string>
|
<string name="Hashtags">HASHTAGS</string>
|
||||||
|
<string name="Recent">RECENTE</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="NewBroadcastList">Nova Lista de Transmissão</string>
|
<string name="NewBroadcastList">Nova Lista de Transmissão</string>
|
||||||
<string name="EnterListName">Digite o nome da lista</string>
|
<string name="EnterListName">Digite o nome da lista</string>
|
||||||
@ -391,9 +392,11 @@
|
|||||||
<string name="AutoLockDisabled">Desativado</string>
|
<string name="AutoLockDisabled">Desativado</string>
|
||||||
<!--media view-->
|
<!--media view-->
|
||||||
<string name="NoMedia">Compartilhar fotos e vídeos no chat e acessá-los em qualquer um de seus dispositivos.</string>
|
<string name="NoMedia">Compartilhar fotos e vídeos no chat e acessá-los em qualquer um de seus dispositivos.</string>
|
||||||
<string name="DocumentsTitle">Arquivos</string>
|
<string name="DocumentsTitle">Arquivos Compartilhados</string>
|
||||||
<string name="SharedMediaTitle">Mídia Compartilhada</string>
|
<string name="SharedMediaTitle">Mídia Compartilhada</string>
|
||||||
|
<string name="LinksTitle">Links Compartilhados</string>
|
||||||
<string name="NoSharedFiles">Compartilhar arquivos e documentos no chat e acessá-los de qualquer um de seus dispositivos.</string>
|
<string name="NoSharedFiles">Compartilhar arquivos e documentos no chat e acessá-los de qualquer um de seus dispositivos.</string>
|
||||||
|
<string name="NoSharedLinks">Compartilhe links nesse chat e os acesse de qualquer um de seus dispositivos</string>
|
||||||
<!--map view-->
|
<!--map view-->
|
||||||
<string name="Map">Mapa</string>
|
<string name="Map">Mapa</string>
|
||||||
<string name="Satellite">Satélite</string>
|
<string name="Satellite">Satélite</string>
|
||||||
@ -834,8 +837,8 @@
|
|||||||
<string name="formatterDay12H">h:mm a</string>
|
<string name="formatterDay12H">h:mm a</string>
|
||||||
<string name="formatDateAtTime">%1$s às %2$s</string>
|
<string name="formatDateAtTime">%1$s às %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Plus Messenger para Android foi atualizado. Novo na versão 3.1:\n\n- Busca por mensagens dentro de um chat específico.\n-Menu de anexo totalmente redesenhado. Envie contatos e arquivos de áudio diretamente do menu de anexo.\n- Reprodução melhorada de mídia dentro do aplicativo (YouTube, Vimeo, SoundCloud, etc.), novo player para grandes arquivos de áudio.\n\nMais sobre a atualização:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">Plus Messenger para Android acaba de ser atualizado. Novo na versão 3.1.2\n\n- Resultados das buscas recentes\n- Pressione e mantenha em um sticker para pré-visualizar antes do envio</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+-->
|
||||||
<string name="TelegramForAndroid">Plus Messenger para Android</string>
|
<string name="TelegramForAndroid">Plus Messenger para Android</string>
|
||||||
<string name="Theming">Temas</string>
|
<string name="Theming">Temas</string>
|
||||||
|
@ -832,7 +832,7 @@
|
|||||||
<string name="formatDateAtTime">%1$s в %2$s</string>
|
<string name="formatDateAtTime">%1$s в %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Plus Messenger для Android обновлён. Новое в версии 3.1:\n\n- Поиск сообщений внутри конкретного чата.\n- Полностью переработано меню вложений. Отправка контактов и аудиофайлов прямо из меню вложений.\n- Улучшено воспроизведение медиа в приложении (YouTube, Vimeo, SoundCloud и др.), новый плеер для больших аудиофайлов.\n\nБольше об этом обновлении:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">Plus Messenger для Android обновлён. Новое в версии 3.1:\n\n- Поиск сообщений внутри конкретного чата.\n- Полностью переработано меню вложений. Отправка контактов и аудиофайлов прямо из меню вложений.\n- Улучшено воспроизведение медиа в приложении (YouTube, Vimeo, SoundCloud и др.), новый плеер для больших аудиофайлов.\n\nБольше об этом обновлении:\nhttps://telegram.org/blog/search-and-media</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+-->
|
||||||
<string name="TelegramForAndroid">Plus Messenger для Android</string>
|
<string name="TelegramForAndroid">Plus Messenger для Android</string>
|
||||||
<string name="Theming">Кастомизация</string>
|
<string name="Theming">Кастомизация</string>
|
||||||
|
@ -461,10 +461,10 @@
|
|||||||
<string name="formatterDay24H">HH:mm</string>
|
<string name="formatterDay24H">HH:mm</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Plus Messenger için temalar indirin ve uygulayın. Hergün yeni temalar ekleniyor:\n https://play.google.com/store/apps/details?id=es.rafalense.themes</string>
|
<string name="updateText">Plus Messenger için temalar indirin ve uygulayın. Hergün yeni temalar ekleniyor:\n https://play.google.com/store/apps/details?id=es.rafalense.themes</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+--><!--
|
||||||
<string name="updatePlusText">
|
<string name="updatePlusText">
|
||||||
\n\n3.1.1.9\'daki Yenilikler\n\n- Yeni iOS baloncuğu eklendi (Edwin Macalopu\'ya teşekkürler)\n- Gruplarda kullanıcı adı iler beraber üye ismini birlikte gösteren yeni MOD eklendi\n- Grup profilinde admin gösterilir. Admin kendi ikonuna sahiptir\n- Sol menüde avatar,isim ve telefonu ortalamayı sağlayan yeni MOD eklendi\n- Sohbete yakınlık sensörü eylemlerini kapatmayı ve çalan sesleri devam ettirmeyi sağlayan yeni MOD eklendi \n- Profil ekranına ikon renklerini değiştirmeyi sağlayan yeni MOD eklendi\n- Hata düzeltmeleri \n\n Plus Messenger için temalar: https://play.google.com/store/apps/details?id=es.rafalense.themes</string>
|
\n\n3.1.1.9\'daki Yenilikler\n\n- Yeni iOS baloncuğu eklendi (Edwin Macalopu\'ya teşekkürler)\n- Gruplarda kullanıcı adı iler beraber üye ismini birlikte gösteren yeni MOD eklendi\n- Grup profilinde admin gösterilir. Admin kendi ikonuna sahiptir\n- Sol menüde avatar,isim ve telefonu ortalamayı sağlayan yeni MOD eklendi\n- Sohbete yakınlık sensörü eylemlerini kapatmayı ve çalan sesleri devam ettirmeyi sağlayan yeni MOD eklendi \n- Profil ekranına ikon renklerini değiştirmeyi sağlayan yeni MOD eklendi\n- Hata düzeltmeleri \n\n Plus Messenger için temalar: https://play.google.com/store/apps/details?id=es.rafalense.themes</string>-->
|
||||||
<string name="TelegramForAndroid">Android için Plus Messenger</string>
|
<string name="TelegramForAndroid">Android için Plus Messenger</string>
|
||||||
<string name="Theming">Tema</string>
|
<string name="Theming">Tema</string>
|
||||||
<string name="colorHexInvalid">Geçersiz renk hex kodu!</string>
|
<string name="colorHexInvalid">Geçersiz renk hex kodu!</string>
|
||||||
|
@ -804,7 +804,7 @@
|
|||||||
<string name="formatDateAtTime">%1$s 的 %2$s</string>
|
<string name="formatDateAtTime">%1$s 的 %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Android 版的 Plus Messenger 已更新。最新版本 3.1 的新增功能有:\n\n- 在特定聊天中搜索消息内容。\n- 全新设计的附件选择菜单。从附件选择菜单中直接发送联系人资料或语音文件。\n- 改进的程序内媒体播放功能 (YouTube, Vimoe, Soundcloud 等), 新播放器适用于大型语音文件。\n\n更多更新请查看:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">Android 版的 Plus Messenger 已更新。最新版本 3.1 的新增功能有:\n\n- 在特定聊天中搜索消息内容。\n- 全新设计的附件选择菜单。从附件选择菜单中直接发送联系人资料或语音文件。\n- 改进的程序内媒体播放功能 (YouTube, Vimoe, Soundcloud 等), 新播放器适用于大型语音文件。\n\n更多更新请查看:\nhttps://telegram.org/blog/search-and-media</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+--><!--
|
<!--Telegram+--><!--
|
||||||
<string name="updatePlusText">\n\n在 3.0.1.3 版的新功能:\n\n- 添加设置使用手机字体选项\n- 添加聊天/群组聊天内搜索聊天记录选项\n- 在设置/主题调整界面里添加标头颜色、标题颜色和标头图标颜色的设置\n- 添加主界面群组图标颜色的设置\n- 添加导航栏中头像大小的设置\n- 错误修复</string>-->
|
<string name="updatePlusText">\n\n在 3.0.1.3 版的新功能:\n\n- 添加设置使用手机字体选项\n- 添加聊天/群组聊天内搜索聊天记录选项\n- 在设置/主题调整界面里添加标头颜色、标题颜色和标头图标颜色的设置\n- 添加主界面群组图标颜色的设置\n- 添加导航栏中头像大小的设置\n- 错误修复</string>-->
|
||||||
<string name="TelegramForAndroid">Plus Messenger for Android</string>
|
<string name="TelegramForAndroid">Plus Messenger for Android</string>
|
||||||
|
@ -808,10 +808,10 @@
|
|||||||
<string name="formatDateAtTime">%1$s 於時間 %2$s</string>
|
<string name="formatDateAtTime">%1$s 於時間 %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Android 版的 Plus Messenger 已經更新。在版本 3.1 的新功能:\n\n- 在特定的聊天室裡搜尋訊息。\n- 完全重新設計的附件選單。從附件選單直接傳送「聯絡人」資訊和「音訊檔」。\n- 改進的程式內媒體播放( YouTube、Vimoe、SoundCloud 等 ),新的播放器適用於大型音訊檔。\n\n更多關於這次的更新:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">Android 版的 Plus Messenger 已經更新。在版本 3.1 的新功能:\n\n- 在特定的聊天室裡搜尋訊息。\n- 完全重新設計的附件選單。從附件選單直接傳送「聯絡人」資訊和「音訊檔」。\n- 改進的程式內媒體播放( YouTube、Vimoe、SoundCloud 等 ),新的播放器適用於大型音訊檔。\n\n更多關於這次的更新:\nhttps://telegram.org/blog/search-and-media</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+--><!--
|
||||||
<string name="updatePlusText">
|
<string name="updatePlusText">
|
||||||
\n\n在 3.1.1.9 版的新功能:\n\n- 新的模組在聊天畫面顯示擁有的大頭照\n- 加入新的泡泡邊緣 (感謝 Edwin Macalopu)\n- 錯誤修復</string>
|
\n\n在 3.1.1.9 版的新功能:\n\n- 新的模組在聊天畫面顯示擁有的大頭照\n- 加入新的泡泡邊緣 (感謝 Edwin Macalopu)\n- 錯誤修復</string>-->
|
||||||
<string name="TelegramForAndroid">適用於 Android 的 Plus Messenger</string>
|
<string name="TelegramForAndroid">適用於 Android 的 Plus Messenger</string>
|
||||||
<string name="Theming">自製佈景主題</string>
|
<string name="Theming">自製佈景主題</string>
|
||||||
<string name="colorHexInvalid">無效的十六進位顏色代碼!</string>
|
<string name="colorHexInvalid">無效的十六進位顏色代碼!</string>
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
<string name="WillUnmuteIn">In %1$s</string>
|
<string name="WillUnmuteIn">In %1$s</string>
|
||||||
<string name="MuteDisable">Disable</string>
|
<string name="MuteDisable">Disable</string>
|
||||||
<string name="Hashtags">HASHTAGS</string>
|
<string name="Hashtags">HASHTAGS</string>
|
||||||
|
<string name="Recent">RECENT</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="NewBroadcastList">New Broadcast List</string>
|
<string name="NewBroadcastList">New Broadcast List</string>
|
||||||
<string name="EnterListName">Enter list name</string>
|
<string name="EnterListName">Enter list name</string>
|
||||||
@ -390,9 +391,11 @@
|
|||||||
<string name="AutoLockDisabled">Disabled</string>
|
<string name="AutoLockDisabled">Disabled</string>
|
||||||
<!--media view-->
|
<!--media view-->
|
||||||
<string name="NoMedia">Share photos and videos in this chat and access them on any of your devices.</string>
|
<string name="NoMedia">Share photos and videos in this chat and access them on any of your devices.</string>
|
||||||
<string name="DocumentsTitle">Files</string>
|
<string name="DocumentsTitle">Shared Files</string>
|
||||||
<string name="SharedMediaTitle">Shared Media</string>
|
<string name="SharedMediaTitle">Shared Media</string>
|
||||||
|
<string name="LinksTitle">Shared Links</string>
|
||||||
<string name="NoSharedFiles">Share files and documents in this chat and access them on any of your devices.</string>
|
<string name="NoSharedFiles">Share files and documents in this chat and access them on any of your devices.</string>
|
||||||
|
<string name="NoSharedLinks">Share links in this chat and access them on any of your devices.</string>
|
||||||
<!--map view-->
|
<!--map view-->
|
||||||
<string name="Map">Map</string>
|
<string name="Map">Map</string>
|
||||||
<string name="Satellite">Satellite</string>
|
<string name="Satellite">Satellite</string>
|
||||||
@ -833,10 +836,10 @@
|
|||||||
<string name="formatterDay12H">h:mm a</string>
|
<string name="formatterDay12H">h:mm a</string>
|
||||||
<string name="formatDateAtTime">%1$s at %2$s</string>
|
<string name="formatDateAtTime">%1$s at %2$s</string>
|
||||||
<!--update text-->
|
<!--update text-->
|
||||||
<string name="updateText">Plus Messenger for Android has been updated. New in version 3.1:\n\n- Search for messages inside a specific chat.\n- Fully redesigned attachment menu. Send contacts and audio files straight from the attachment menu.\n- Improved in-app media playback (YouTube, Vimeo, SoundCloud etc.), new player for large audio files.\n\nMore about this update:\nhttps://telegram.org/blog/search-and-media</string>
|
<string name="updateText">Plus Messenger for Android has been updated. New in version 3.1.2:\n\n- Recent search results\n- Tap and hold sticker to preview before sending</string>
|
||||||
<string name="updateBuild">590</string>
|
<string name="updateBuild">591</string>
|
||||||
<!--Telegram+-->
|
<!--Telegram+-->
|
||||||
<string name="updatePlusText">\n\nNew in 3.1.1.9:\n\n- New bubble iOS added (thanks to Edwin Macalopu)\n- New MOD to show username together with member name in groups\n- Shows group admin in group profile. Admin user has its own icon\n- New MOD to center avatar, name and phone in navigation menu\n- New MOD to keep playing audio in chat disabling proximity sensor action\n- New MOD to change icons color in profile screen\n- Bug fixes\n\nCheck and apply themes for Plus Messenger: https://play.google.com/store/apps/details?id=es.rafalense.themes</string>
|
<string name="updatePlusText">\n\nNew in 3.1.2.0:\n\n- Bug fixes</string>
|
||||||
<string name="TelegramForAndroid">Plus Messenger for Android</string>
|
<string name="TelegramForAndroid">Plus Messenger for Android</string>
|
||||||
<string name="Theming">Theming</string>
|
<string name="Theming">Theming</string>
|
||||||
<string name="colorHexInvalid">Invalid color hex code!</string>
|
<string name="colorHexInvalid">Invalid color hex code!</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user