mirror of
https://github.com/DrKLO/Telegram.git
synced 2024-12-22 22:45:18 +01:00
Different improvements
This commit is contained in:
parent
e3d2b9cece
commit
e5def002f7
25 changed files with 1222 additions and 343 deletions
|
@ -80,7 +80,7 @@ android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 8
|
minSdkVersion 8
|
||||||
targetSdkVersion 19
|
targetSdkVersion 19
|
||||||
versionCode 363
|
versionCode 371
|
||||||
versionName "1.9.5"
|
versionName "1.9.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -425,7 +425,7 @@ public class AndroidUtilities {
|
||||||
final NumberPicker numberPicker = new NumberPicker(context);
|
final NumberPicker numberPicker = new NumberPicker(context);
|
||||||
numberPicker.setMinValue(0);
|
numberPicker.setMinValue(0);
|
||||||
numberPicker.setMaxValue(20);
|
numberPicker.setMaxValue(20);
|
||||||
if (encryptedChat.ttl >= 0 && encryptedChat.ttl < 16) {
|
if (encryptedChat.ttl > 0 && encryptedChat.ttl < 16) {
|
||||||
numberPicker.setValue(encryptedChat.ttl);
|
numberPicker.setValue(encryptedChat.ttl);
|
||||||
} else if (encryptedChat.ttl == 30) {
|
} else if (encryptedChat.ttl == 30) {
|
||||||
numberPicker.setValue(16);
|
numberPicker.setValue(16);
|
||||||
|
@ -437,6 +437,8 @@ public class AndroidUtilities {
|
||||||
numberPicker.setValue(19);
|
numberPicker.setValue(19);
|
||||||
} else if (encryptedChat.ttl == 60 * 60 * 24 * 7) {
|
} else if (encryptedChat.ttl == 60 * 60 * 24 * 7) {
|
||||||
numberPicker.setValue(20);
|
numberPicker.setValue(20);
|
||||||
|
} else if (encryptedChat.ttl == 0) {
|
||||||
|
numberPicker.setValue(5);
|
||||||
}
|
}
|
||||||
numberPicker.setFormatter(new NumberPicker.Formatter() {
|
numberPicker.setFormatter(new NumberPicker.Formatter() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -479,7 +481,7 @@ public class AndroidUtilities {
|
||||||
encryptedChat.ttl = 60 * 60 * 24 * 7;
|
encryptedChat.ttl = 60 * 60 * 24 * 7;
|
||||||
}
|
}
|
||||||
if (oldValue != encryptedChat.ttl) {
|
if (oldValue != encryptedChat.ttl) {
|
||||||
SendMessagesHelper.getInstance().sendTTLMessage(encryptedChat);
|
SendMessagesHelper.getInstance().sendTTLMessage(encryptedChat, null);
|
||||||
MessagesStorage.getInstance().updateEncryptedChatTTL(encryptedChat);
|
MessagesStorage.getInstance().updateEncryptedChatTTL(encryptedChat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -791,7 +791,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
||||||
photoW = bmOptions.outWidth;
|
photoW = bmOptions.outWidth;
|
||||||
photoH = bmOptions.outHeight;
|
photoH = bmOptions.outHeight;
|
||||||
}
|
}
|
||||||
if (photoW == 0 || photoH == 0 || (photoW == width && photoH == height || photoH == width && photoW == height)) {
|
if (photoW <= 0 || photoH <= 0 || (photoW == width && photoH == height || photoH == width && photoW == height)) {
|
||||||
screenshotDates.add(date);
|
screenshotDates.add(date);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -834,7 +834,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (send) {
|
if (send) {
|
||||||
SendMessagesHelper.getInstance().sendScreenshotMessage(lastSecretChat, lastSecretChatVisibleMessages);
|
SendMessagesHelper.getInstance().sendScreenshotMessage(lastSecretChat, lastSecretChatVisibleMessages, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2200,6 +2200,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
||||||
|
|
||||||
File inputFile = new File(videoPath);
|
File inputFile = new File(videoPath);
|
||||||
if (!inputFile.canRead()) {
|
if (!inputFile.canRead()) {
|
||||||
|
didWriteData(messageObject, cacheFile, true, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2577,6 +2578,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
||||||
FileLog.e("tmessages", "time = " + (System.currentTimeMillis() - time));
|
FileLog.e("tmessages", "time = " + (System.currentTimeMillis() - time));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
didWriteData(messageObject, cacheFile, true, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
didWriteData(messageObject, cacheFile, true, error);
|
didWriteData(messageObject, cacheFile, true, error);
|
||||||
|
|
|
@ -232,7 +232,7 @@ public class MessageObject {
|
||||||
} else {
|
} else {
|
||||||
messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, "");
|
messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, "");
|
||||||
}
|
}
|
||||||
} else if (message.action instanceof TLRPC.TL_messageEcryptedAction) {
|
} else if (message.action instanceof TLRPC.TL_messageEncryptedAction) {
|
||||||
if (message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) {
|
if (message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) {
|
||||||
if (isFromMe()) {
|
if (isFromMe()) {
|
||||||
messageText = LocaleController.formatString("ActionTakeScreenshootYou", R.string.ActionTakeScreenshootYou);
|
messageText = LocaleController.formatString("ActionTakeScreenshootYou", R.string.ActionTakeScreenshootYou);
|
||||||
|
@ -243,6 +243,29 @@ public class MessageObject {
|
||||||
messageText = LocaleController.formatString("ActionTakeScreenshoot", R.string.ActionTakeScreenshoot).replace("un1", "");
|
messageText = LocaleController.formatString("ActionTakeScreenshoot", R.string.ActionTakeScreenshoot).replace("un1", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
|
||||||
|
TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL) message.action.encryptedAction;
|
||||||
|
if (action.ttl_seconds != 0) {
|
||||||
|
if (isFromMe()) {
|
||||||
|
messageText = LocaleController.formatString("MessageLifetimeChangedOutgoing", R.string.MessageLifetimeChangedOutgoing, AndroidUtilities.formatTTLString(action.ttl_seconds));
|
||||||
|
} else {
|
||||||
|
if (fromUser != null) {
|
||||||
|
messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, fromUser.first_name, AndroidUtilities.formatTTLString(action.ttl_seconds));
|
||||||
|
} else {
|
||||||
|
messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, "", AndroidUtilities.formatTTLString(action.ttl_seconds));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isFromMe()) {
|
||||||
|
messageText = LocaleController.getString("MessageLifetimeYouRemoved", R.string.MessageLifetimeYouRemoved);
|
||||||
|
} else {
|
||||||
|
if (fromUser != null) {
|
||||||
|
messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, fromUser.first_name);
|
||||||
|
} else {
|
||||||
|
messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (message.action instanceof TLRPC.TL_messageActionCreatedBroadcastList) {
|
} else if (message.action instanceof TLRPC.TL_messageActionCreatedBroadcastList) {
|
||||||
messageText = LocaleController.formatString("YouCreatedBroadcastList", R.string.YouCreatedBroadcastList);
|
messageText = LocaleController.formatString("YouCreatedBroadcastList", R.string.YouCreatedBroadcastList);
|
||||||
|
@ -301,6 +324,14 @@ public class MessageObject {
|
||||||
} else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto || message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
|
} else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto || message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
|
||||||
contentType = 4;
|
contentType = 4;
|
||||||
type = 11;
|
type = 11;
|
||||||
|
} else if (message.action instanceof TLRPC.TL_messageEncryptedAction) {
|
||||||
|
if (message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
|
||||||
|
contentType = 4;
|
||||||
|
type = 10;
|
||||||
|
} else {
|
||||||
|
contentType = -1;
|
||||||
|
type = -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
contentType = 4;
|
contentType = 4;
|
||||||
type = 10;
|
type = 10;
|
||||||
|
|
|
@ -980,7 +980,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDeleted, messages);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDeleted, messages);
|
||||||
|
|
||||||
if (randoms != null && encryptedChat != null && !randoms.isEmpty()) {
|
if (randoms != null && encryptedChat != null && !randoms.isEmpty()) {
|
||||||
SendMessagesHelper.getInstance().sendMessagesDeleteMessage(randoms, encryptedChat);
|
SendMessagesHelper.getInstance().sendMessagesDeleteMessage(encryptedChat, randoms, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<Integer> toSend = new ArrayList<Integer>();
|
ArrayList<Integer> toSend = new ArrayList<Integer>();
|
||||||
|
@ -1071,7 +1071,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (onlyHistory) {
|
if (onlyHistory) {
|
||||||
SendMessagesHelper.getInstance().sendClearHistoryMessage(getEncryptedChat(high_id));
|
SendMessagesHelper.getInstance().sendClearHistoryMessage(getEncryptedChat(high_id), null);
|
||||||
} else {
|
} else {
|
||||||
declineSecretChat(high_id);
|
declineSecretChat(high_id);
|
||||||
}
|
}
|
||||||
|
@ -1643,6 +1643,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
putChats(dialogsRes.chats, isCache);
|
putChats(dialogsRes.chats, isCache);
|
||||||
if (encChats != null) {
|
if (encChats != null) {
|
||||||
for (TLRPC.EncryptedChat encryptedChat : encChats) {
|
for (TLRPC.EncryptedChat encryptedChat : encChats) {
|
||||||
|
if (encryptedChat instanceof TLRPC.TL_encryptedChat && AndroidUtilities.getMyLayerVersion(encryptedChat.layer) < SendMessagesHelper.CURRENT_SECRET_CHAT_LAYER) {
|
||||||
|
SendMessagesHelper.getInstance().sendNotifyLayerMessage(encryptedChat, null);
|
||||||
|
}
|
||||||
putEncryptedChat(encryptedChat, true);
|
putEncryptedChat(encryptedChat, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1707,7 +1710,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markMessageAsRead(final long dialog_id, final long random_id) {
|
public void markMessageAsRead(final long dialog_id, final long random_id, int ttl) {
|
||||||
if (random_id == 0 || dialog_id == 0) {
|
if (random_id == 0 || dialog_id == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1722,12 +1725,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
}
|
}
|
||||||
ArrayList<Long> random_ids = new ArrayList<Long>();
|
ArrayList<Long> random_ids = new ArrayList<Long>();
|
||||||
random_ids.add(random_id);
|
random_ids.add(random_id);
|
||||||
SendMessagesHelper.getInstance().sendMessagesReadMessage(random_ids, chat);
|
SendMessagesHelper.getInstance().sendMessagesReadMessage(chat, random_ids, null);
|
||||||
if (chat.ttl > 0) {
|
if (ttl > 0) {
|
||||||
int time = ConnectionsManager.getInstance().getCurrentTime();
|
int time = ConnectionsManager.getInstance().getCurrentTime();
|
||||||
MessagesStorage.getInstance().createTaskForSecretChat(chat.id, time, time, 0, random_ids);
|
MessagesStorage.getInstance().createTaskForSecretChat(chat.id, time, time, 0, random_ids);
|
||||||
}
|
}
|
||||||
//TODO resend request
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markDialogAsRead(final long dialog_id, final int max_id, final int max_positive_id, final int offset, final int max_date, final boolean was, final boolean popup) {
|
public void markDialogAsRead(final long dialog_id, final int max_id, final int max_positive_id, final int offset, final int max_date, final boolean was, final boolean popup) {
|
||||||
|
@ -3558,7 +3560,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
|
|
||||||
public TLRPC.Message decryptMessage(TLRPC.EncryptedMessage message) {
|
public TLRPC.Message decryptMessage(TLRPC.EncryptedMessage message) {
|
||||||
final TLRPC.EncryptedChat chat = getEncryptedChatDB(message.chat_id);
|
final TLRPC.EncryptedChat chat = getEncryptedChatDB(message.chat_id);
|
||||||
if (chat == null) {
|
if (chat == null || chat instanceof TLRPC.TL_encryptedChatDiscarded) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
ByteBufferDesc is = BuffersStorage.getInstance().getFreeBuffer(message.bytes.length);
|
ByteBufferDesc is = BuffersStorage.getInstance().getFreeBuffer(message.bytes.length);
|
||||||
|
@ -3582,13 +3584,38 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
|
|
||||||
if (object instanceof TLRPC.TL_decryptedMessageLayer) {
|
if (object instanceof TLRPC.TL_decryptedMessageLayer) {
|
||||||
final TLRPC.TL_decryptedMessageLayer layer = (TLRPC.TL_decryptedMessageLayer)object;
|
final TLRPC.TL_decryptedMessageLayer layer = (TLRPC.TL_decryptedMessageLayer)object;
|
||||||
|
if (chat.seq_in == 0 && chat.seq_out == 0) {
|
||||||
|
if (chat.admin_id == UserConfig.getClientUserId()) {
|
||||||
|
chat.seq_out = 1;
|
||||||
|
} else {
|
||||||
|
chat.seq_in = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (chat.seq_in != layer.out_seq_no && chat.seq_in != layer.out_seq_no - 2) {
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
chat.seq_in = layer.out_seq_no;
|
final TLRPC.TL_encryptedChatDiscarded newChat = new TLRPC.TL_encryptedChatDiscarded();
|
||||||
MessagesStorage.getInstance().updateEncryptedChatSeq(chat);
|
newChat.id = chat.id;
|
||||||
|
newChat.user_id = chat.user_id;
|
||||||
|
newChat.auth_key = chat.auth_key;
|
||||||
|
newChat.seq_in = chat.seq_in;
|
||||||
|
newChat.seq_out = chat.seq_out;
|
||||||
|
MessagesStorage.getInstance().updateEncryptedChat(newChat);
|
||||||
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
putEncryptedChat(newChat, false);
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
declineSecretChat(chat.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
chat.seq_in = layer.out_seq_no;
|
||||||
|
MessagesStorage.getInstance().updateEncryptedChatSeq(chat);
|
||||||
object = layer.message;
|
object = layer.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3597,8 +3624,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
TLRPC.TL_message newMessage = null;
|
TLRPC.TL_message newMessage = null;
|
||||||
if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) {
|
if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) {
|
||||||
newMessage = new TLRPC.TL_message_secret();
|
newMessage = new TLRPC.TL_message_secret();
|
||||||
|
newMessage.ttl = decryptedMessage.ttl;
|
||||||
} else {
|
} else {
|
||||||
newMessage = new TLRPC.TL_message();
|
newMessage = new TLRPC.TL_message();
|
||||||
|
newMessage.ttl = chat.ttl;
|
||||||
}
|
}
|
||||||
newMessage.message = decryptedMessage.message;
|
newMessage.message = decryptedMessage.message;
|
||||||
newMessage.date = message.date;
|
newMessage.date = message.date;
|
||||||
|
@ -3610,7 +3639,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
newMessage.to_id.user_id = UserConfig.getClientUserId();
|
newMessage.to_id.user_id = UserConfig.getClientUserId();
|
||||||
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD;
|
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD;
|
||||||
newMessage.dialog_id = ((long)chat.id) << 32;
|
newMessage.dialog_id = ((long)chat.id) << 32;
|
||||||
newMessage.ttl = chat.ttl;
|
|
||||||
if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) {
|
if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) {
|
||||||
newMessage.media = new TLRPC.TL_messageMediaEmpty();
|
newMessage.media = new TLRPC.TL_messageMediaEmpty();
|
||||||
} else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaContact) {
|
} else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaContact) {
|
||||||
|
@ -3751,13 +3779,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL || serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) {
|
if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL || serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) {
|
||||||
TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService();
|
TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService();
|
||||||
if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
|
if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
|
||||||
newMessage.action = new TLRPC.TL_messageActionTTLChange();
|
newMessage.action = new TLRPC.TL_messageEncryptedAction();
|
||||||
if (serviceMessage.action.ttl_seconds < 0 || serviceMessage.action.ttl_seconds > 60 * 60 * 24 * 365) {
|
if (serviceMessage.action.ttl_seconds < 0 || serviceMessage.action.ttl_seconds > 60 * 60 * 24 * 365) {
|
||||||
serviceMessage.action.ttl_seconds = 60 * 60 * 24 * 365;
|
serviceMessage.action.ttl_seconds = 60 * 60 * 24 * 365;
|
||||||
}
|
}
|
||||||
newMessage.action.ttl = chat.ttl = serviceMessage.action.ttl_seconds;
|
chat.ttl = serviceMessage.action.ttl_seconds;
|
||||||
|
newMessage.action.encryptedAction = serviceMessage.action;
|
||||||
|
MessagesStorage.getInstance().updateEncryptedChatTTL(chat);
|
||||||
} else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) {
|
} else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) {
|
||||||
newMessage.action = new TLRPC.TL_messageEcryptedAction();
|
newMessage.action = new TLRPC.TL_messageEncryptedAction();
|
||||||
newMessage.action.encryptedAction = serviceMessage.action;
|
newMessage.action.encryptedAction = serviceMessage.action;
|
||||||
}
|
}
|
||||||
newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
|
newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
|
||||||
|
@ -3768,7 +3798,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
newMessage.to_id = new TLRPC.TL_peerUser();
|
newMessage.to_id = new TLRPC.TL_peerUser();
|
||||||
newMessage.to_id.user_id = UserConfig.getClientUserId();
|
newMessage.to_id.user_id = UserConfig.getClientUserId();
|
||||||
newMessage.dialog_id = ((long)chat.id) << 32;
|
newMessage.dialog_id = ((long)chat.id) << 32;
|
||||||
MessagesStorage.getInstance().updateEncryptedChatTTL(chat);
|
|
||||||
return newMessage;
|
return newMessage;
|
||||||
} else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionFlushHistory) {
|
} else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionFlushHistory) {
|
||||||
final long did = ((long)chat.id) << 32;
|
final long did = ((long)chat.id) << 32;
|
||||||
|
@ -3818,7 +3847,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
chat.layer = AndroidUtilities.setPeerLayerVersion(chat.layer, serviceMessage.action.layer);
|
chat.layer = AndroidUtilities.setPeerLayerVersion(chat.layer, serviceMessage.action.layer);
|
||||||
MessagesStorage.getInstance().updateEncryptedChatLayer(chat);
|
MessagesStorage.getInstance().updateEncryptedChatLayer(chat);
|
||||||
if (currentPeerLayer < 17) {
|
if (currentPeerLayer < 17) {
|
||||||
SendMessagesHelper.getInstance().sendNotifyLayerMessage(chat);
|
SendMessagesHelper.getInstance().sendNotifyLayerMessage(chat, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -3878,7 +3907,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
public void run() {
|
public void run() {
|
||||||
putEncryptedChat(encryptedChat, false);
|
putEncryptedChat(encryptedChat, false);
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, encryptedChat);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, encryptedChat);
|
||||||
SendMessagesHelper.getInstance().sendNotifyLayerMessage(encryptedChat);
|
SendMessagesHelper.getInstance().sendNotifyLayerMessage(encryptedChat, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -4003,7 +4032,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
public void run() {
|
public void run() {
|
||||||
putEncryptedChat(newChat, false);
|
putEncryptedChat(newChat, false);
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat);
|
||||||
SendMessagesHelper.getInstance().sendNotifyLayerMessage(newChat);
|
SendMessagesHelper.getInstance().sendNotifyLayerMessage(newChat, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,7 @@ public class MessagesStorage {
|
||||||
database.executeFast("CREATE TABLE download_queue(uid INTEGER, type INTEGER, date INTEGER, data BLOB, PRIMARY KEY (uid, type));").stepThis().dispose();
|
database.executeFast("CREATE TABLE download_queue(uid INTEGER, type INTEGER, date INTEGER, data BLOB, PRIMARY KEY (uid, type));").stepThis().dispose();
|
||||||
database.executeFast("CREATE TABLE dialog_settings(did INTEGER PRIMARY KEY, flags INTEGER);").stepThis().dispose();
|
database.executeFast("CREATE TABLE dialog_settings(did INTEGER PRIMARY KEY, flags INTEGER);").stepThis().dispose();
|
||||||
database.executeFast("CREATE TABLE messages_seq(mid INTEGER PRIMARY KEY, seq_in INTEGER, seq_out INTEGER);").stepThis().dispose();
|
database.executeFast("CREATE TABLE messages_seq(mid INTEGER PRIMARY KEY, seq_in INTEGER, seq_out INTEGER);").stepThis().dispose();
|
||||||
|
|
||||||
//database.executeFast("CREATE TABLE attach_data(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
|
//database.executeFast("CREATE TABLE attach_data(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
|
||||||
|
|
||||||
database.executeFast("CREATE TABLE user_contacts_v6(uid INTEGER PRIMARY KEY, fname TEXT, sname TEXT)").stepThis().dispose();
|
database.executeFast("CREATE TABLE user_contacts_v6(uid INTEGER PRIMARY KEY, fname TEXT, sname TEXT)").stepThis().dispose();
|
||||||
|
@ -137,6 +138,9 @@ public class MessagesStorage {
|
||||||
database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages ON messages(mid, out);").stepThis().dispose();
|
database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages ON messages(mid, out);").stepThis().dispose();
|
||||||
database.executeFast("CREATE INDEX IF NOT EXISTS task_idx_messages ON messages(uid, out, read_state, ttl, date, send_state);").stepThis().dispose();
|
database.executeFast("CREATE INDEX IF NOT EXISTS task_idx_messages ON messages(uid, out, read_state, ttl, date, send_state);").stepThis().dispose();
|
||||||
database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages ON messages(mid, send_state, date) WHERE mid < 0 AND send_state = 1;").stepThis().dispose();
|
database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages ON messages(mid, send_state, date) WHERE mid < 0 AND send_state = 1;").stepThis().dispose();
|
||||||
|
|
||||||
|
database.executeFast("CREATE INDEX IF NOT EXISTS seq_idx_messages_seq ON messages_seq(seq_in, seq_out);").stepThis().dispose();
|
||||||
|
|
||||||
database.executeFast("PRAGMA user_version = 7").stepThis().dispose();
|
database.executeFast("PRAGMA user_version = 7").stepThis().dispose();
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -292,6 +296,7 @@ public class MessagesStorage {
|
||||||
}
|
}
|
||||||
if (version == 6 && version < 7) {
|
if (version == 6 && version < 7) {
|
||||||
database.executeFast("CREATE TABLE IF NOT EXISTS messages_seq(mid INTEGER PRIMARY KEY, seq_in INTEGER, seq_out INTEGER);").stepThis().dispose();
|
database.executeFast("CREATE TABLE IF NOT EXISTS messages_seq(mid INTEGER PRIMARY KEY, seq_in INTEGER, seq_out INTEGER);").stepThis().dispose();
|
||||||
|
database.executeFast("CREATE INDEX IF NOT EXISTS seq_idx_messages_seq ON messages_seq(seq_in, seq_out);").stepThis().dispose();
|
||||||
database.executeFast("ALTER TABLE enc_chats ADD COLUMN layer INTEGER default 0").stepThis().dispose();
|
database.executeFast("ALTER TABLE enc_chats ADD COLUMN layer INTEGER default 0").stepThis().dispose();
|
||||||
database.executeFast("ALTER TABLE enc_chats ADD COLUMN seq_in INTEGER default 0").stepThis().dispose();
|
database.executeFast("ALTER TABLE enc_chats ADD COLUMN seq_in INTEGER default 0").stepThis().dispose();
|
||||||
database.executeFast("ALTER TABLE enc_chats ADD COLUMN seq_out INTEGER default 0").stepThis().dispose();
|
database.executeFast("ALTER TABLE enc_chats ADD COLUMN seq_out INTEGER default 0").stepThis().dispose();
|
||||||
|
@ -1559,9 +1564,9 @@ public class MessagesStorage {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (max_id != 0) {
|
if (max_id != 0) {
|
||||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media WHERE uid = %d AND mid > %d ORDER BY mid ASC LIMIT %d", uid, max_id, count));
|
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, r.random_id FROM media as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d ORDER BY m.mid ASC LIMIT %d", uid, max_id, count));
|
||||||
} else {
|
} else {
|
||||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media WHERE uid = %d ORDER BY mid ASC LIMIT %d,%d", uid, offset, count));
|
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, r.random_id FROM media as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d ORDER BY m.mid ASC LIMIT %d,%d", uid, offset, count));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1571,6 +1576,9 @@ public class MessagesStorage {
|
||||||
TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
|
TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
|
||||||
message.id = cursor.intValue(1);
|
message.id = cursor.intValue(1);
|
||||||
message.dialog_id = uid;
|
message.dialog_id = uid;
|
||||||
|
if ((int)uid == 0) {
|
||||||
|
message.random_id = cursor.longValue(2);
|
||||||
|
}
|
||||||
res.messages.add(message);
|
res.messages.add(message);
|
||||||
fromUser.add(message.from_id);
|
fromUser.add(message.from_id);
|
||||||
}
|
}
|
||||||
|
@ -1659,7 +1667,7 @@ public class MessagesStorage {
|
||||||
ArrayList<Integer> chatIds = new ArrayList<Integer>();
|
ArrayList<Integer> chatIds = new ArrayList<Integer>();
|
||||||
ArrayList<Integer> broadcastIds = new ArrayList<Integer>();
|
ArrayList<Integer> broadcastIds = new ArrayList<Integer>();
|
||||||
ArrayList<Integer> encryptedChatIds = new ArrayList<Integer>();
|
ArrayList<Integer> encryptedChatIds = new ArrayList<Integer>();
|
||||||
SQLiteCursor cursor = database.queryFinalized("SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.uid FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.mid < 0 AND m.send_state = 1 ORDER BY m.mid DESC LIMIT " + count);
|
SQLiteCursor cursor = database.queryFinalized("SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.uid, s.seq_in, s.seq_out FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid LEFT JOIN messages_seq as s ON m.mid = s.mid WHERE m.mid < 0 AND m.send_state = 1 ORDER BY m.mid DESC LIMIT " + count);
|
||||||
while (cursor.next()) {
|
while (cursor.next()) {
|
||||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1));
|
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1));
|
||||||
if (data != null && cursor.byteBufferValue(1, data.buffer) != 0) {
|
if (data != null && cursor.byteBufferValue(1, data.buffer) != 0) {
|
||||||
|
@ -1671,6 +1679,8 @@ public class MessagesStorage {
|
||||||
message.random_id = cursor.longValue(5);
|
message.random_id = cursor.longValue(5);
|
||||||
}
|
}
|
||||||
message.dialog_id = cursor.longValue(6);
|
message.dialog_id = cursor.longValue(6);
|
||||||
|
message.seq_in = cursor.intValue(7);
|
||||||
|
message.seq_out = cursor.intValue(8);
|
||||||
messages.add(message);
|
messages.add(message);
|
||||||
|
|
||||||
int lower_id = (int)message.dialog_id;
|
int lower_id = (int)message.dialog_id;
|
||||||
|
@ -2629,10 +2639,19 @@ public class MessagesStorage {
|
||||||
|
|
||||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(message.getObjectSize());
|
ByteBufferDesc data = buffersStorage.getFreeBuffer(message.getObjectSize());
|
||||||
message.serializeToStream(data);
|
message.serializeToStream(data);
|
||||||
|
|
||||||
|
boolean updateDialog = true;
|
||||||
|
if (message.action != null && message.action instanceof TLRPC.TL_messageEncryptedAction && !(message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL || message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages)) {
|
||||||
|
updateDialog = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateDialog) {
|
||||||
TLRPC.Message lastMessage = messagesMap.get(dialog_id);
|
TLRPC.Message lastMessage = messagesMap.get(dialog_id);
|
||||||
if (lastMessage == null || message.date > lastMessage.date) {
|
if (lastMessage == null || message.date > lastMessage.date) {
|
||||||
messagesMap.put(dialog_id, message);
|
messagesMap.put(dialog_id, message);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state.bindInteger(1, messageId);
|
state.bindInteger(1, messageId);
|
||||||
state.bindLong(2, dialog_id);
|
state.bindLong(2, dialog_id);
|
||||||
state.bindInteger(3, (MessageObject.isUnread(message) ? 0 : 1));
|
state.bindInteger(3, (MessageObject.isUnread(message) ? 0 : 1));
|
||||||
|
@ -2820,6 +2839,25 @@ public class MessagesStorage {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMessageSeq(final int mid, final int seq_in, final int seq_out) {
|
||||||
|
storageQueue.postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages_seq VALUES(?, ?, ?)");
|
||||||
|
state.requery();
|
||||||
|
state.bindInteger(1, mid);
|
||||||
|
state.bindInteger(2, seq_in);
|
||||||
|
state.bindInteger(3, seq_out);
|
||||||
|
state.step();
|
||||||
|
state.dispose();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private Integer updateMessageStateAndIdInternal(long random_id, Integer _oldId, int newId, int date) {
|
private Integer updateMessageStateAndIdInternal(long random_id, Integer _oldId, int newId, int date) {
|
||||||
if (_oldId != null && _oldId == newId && date != 0) {
|
if (_oldId != null && _oldId == newId && date != 0) {
|
||||||
SQLitePreparedStatement state = null;
|
SQLitePreparedStatement state = null;
|
||||||
|
@ -2835,6 +2873,7 @@ public class MessagesStorage {
|
||||||
state.dispose();
|
state.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newId;
|
return newId;
|
||||||
} else {
|
} else {
|
||||||
Integer oldId = _oldId;
|
Integer oldId = _oldId;
|
||||||
|
@ -2875,6 +2914,7 @@ public class MessagesStorage {
|
||||||
} finally {
|
} finally {
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
state.dispose();
|
state.dispose();
|
||||||
|
state = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2888,6 +2928,7 @@ public class MessagesStorage {
|
||||||
} finally {
|
} finally {
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
state.dispose();
|
state.dispose();
|
||||||
|
state = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2901,6 +2942,7 @@ public class MessagesStorage {
|
||||||
} finally {
|
} finally {
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
state.dispose();
|
state.dispose();
|
||||||
|
state = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3113,10 +3155,63 @@ public class MessagesStorage {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
String ids = TextUtils.join(",", messages);
|
String ids = TextUtils.join(",", messages);
|
||||||
|
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, data FROM messages WHERE mid IN(%s)", ids));
|
||||||
|
ArrayList<File> filesToDelete = new ArrayList<File>();
|
||||||
|
try {
|
||||||
|
while (cursor.next()) {
|
||||||
|
long did = cursor.longValue(0);
|
||||||
|
if ((int)did != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1));
|
||||||
|
if (data != null && cursor.byteBufferValue(1, data.buffer) != 0) {
|
||||||
|
TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
|
||||||
|
if (message == null || message.media == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (message.media instanceof TLRPC.TL_messageMediaAudio) {
|
||||||
|
File file = FileLoader.getPathToAttach(message.media.audio);
|
||||||
|
if (file != null && file.toString().length() > 0) {
|
||||||
|
filesToDelete.add(file);
|
||||||
|
}
|
||||||
|
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||||
|
for (TLRPC.PhotoSize photoSize : message.media.photo.sizes) {
|
||||||
|
File file = FileLoader.getPathToAttach(photoSize);
|
||||||
|
if (file != null && file.toString().length() > 0) {
|
||||||
|
filesToDelete.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (message.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||||
|
File file = FileLoader.getPathToAttach(message.media.video);
|
||||||
|
if (file != null && file.toString().length() > 0) {
|
||||||
|
filesToDelete.add(file);
|
||||||
|
}
|
||||||
|
file = FileLoader.getPathToAttach(message.media.video.thumb);
|
||||||
|
if (file != null && file.toString().length() > 0) {
|
||||||
|
filesToDelete.add(file);
|
||||||
|
}
|
||||||
|
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
|
||||||
|
File file = FileLoader.getPathToAttach(message.media.document);
|
||||||
|
if (file != null && file.toString().length() > 0) {
|
||||||
|
filesToDelete.add(file);
|
||||||
|
}
|
||||||
|
file = FileLoader.getPathToAttach(message.media.document.thumb);
|
||||||
|
if (file != null && file.toString().length() > 0) {
|
||||||
|
filesToDelete.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffersStorage.reuseFreeBuffer(data);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
cursor.dispose();
|
||||||
|
FileLoader.getInstance().deleteFiles(filesToDelete);
|
||||||
database.executeFast(String.format(Locale.US, "DELETE FROM messages WHERE mid IN(%s)", ids)).stepThis().dispose();
|
database.executeFast(String.format(Locale.US, "DELETE FROM messages WHERE mid IN(%s)", ids)).stepThis().dispose();
|
||||||
|
database.executeFast(String.format(Locale.US, "DELETE FROM messages_seq WHERE mid IN(%s)", ids)).stepThis().dispose();
|
||||||
database.executeFast(String.format(Locale.US, "DELETE FROM media WHERE mid IN(%s)", ids)).stepThis().dispose();
|
database.executeFast(String.format(Locale.US, "DELETE FROM media WHERE mid IN(%s)", ids)).stepThis().dispose();
|
||||||
database.executeFast("DELETE FROM media_counts WHERE 1").stepThis().dispose();
|
database.executeFast("DELETE FROM media_counts WHERE 1").stepThis().dispose();
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,18 +113,18 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
if (file != null && media != null) {
|
if (file != null && media != null) {
|
||||||
if (message.type == 0) {
|
if (message.type == 0) {
|
||||||
media.file = file;
|
media.file = file;
|
||||||
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
|
||||||
} else if (message.type == 1) {
|
} else if (message.type == 1) {
|
||||||
if (media.file == null) {
|
if (media.file == null) {
|
||||||
media.file = file;
|
media.file = file;
|
||||||
if (media.thumb == null && message.location != null) {
|
if (media.thumb == null && message.location != null) {
|
||||||
performSendDelayedMessage(message);
|
performSendDelayedMessage(message);
|
||||||
} else {
|
} else {
|
||||||
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
media.thumb = file;
|
media.thumb = file;
|
||||||
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
|
||||||
}
|
}
|
||||||
} else if (message.type == 2) {
|
} else if (message.type == 2) {
|
||||||
if (media.file == null) {
|
if (media.file == null) {
|
||||||
|
@ -132,22 +132,22 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
if (media.thumb == null && message.location != null) {
|
if (media.thumb == null && message.location != null) {
|
||||||
performSendDelayedMessage(message);
|
performSendDelayedMessage(message);
|
||||||
} else {
|
} else {
|
||||||
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
media.thumb = file;
|
media.thumb = file;
|
||||||
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
|
||||||
}
|
}
|
||||||
} else if (message.type == 3) {
|
} else if (message.type == 3) {
|
||||||
media.file = file;
|
media.file = file;
|
||||||
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
|
||||||
}
|
}
|
||||||
arr.remove(a);
|
arr.remove(a);
|
||||||
a--;
|
a--;
|
||||||
} else if (encryptedFile != null && message.sendEncryptedRequest != null) {
|
} else if (encryptedFile != null && message.sendEncryptedRequest != null) {
|
||||||
message.sendEncryptedRequest.media.key = encryptedFile.key;
|
message.sendEncryptedRequest.media.key = encryptedFile.key;
|
||||||
message.sendEncryptedRequest.media.iv = encryptedFile.iv;
|
message.sendEncryptedRequest.media.iv = encryptedFile.iv;
|
||||||
performSendEncryptedRequest(message.sendEncryptedRequest, message.obj, message.encryptedChat, encryptedFile, message.originalPath, null);
|
performSendEncryptedRequest(message.sendEncryptedRequest, message.obj.messageOwner, message.encryptedChat, encryptedFile, message.originalPath);
|
||||||
arr.remove(a);
|
arr.remove(a);
|
||||||
a--;
|
a--;
|
||||||
}
|
}
|
||||||
|
@ -288,6 +288,35 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
if (messageObject.messageOwner.id >= 0) {
|
if (messageObject.messageOwner.id >= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (messageObject.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction) {
|
||||||
|
int enc_id = (int) (messageObject.getDialogId() >> 32);
|
||||||
|
TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat(enc_id);
|
||||||
|
if (encryptedChat == null) {
|
||||||
|
MessagesStorage.getInstance().markMessageAsSendError(messageObject.messageOwner.id);
|
||||||
|
messageObject.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, messageObject.messageOwner.id);
|
||||||
|
processSentMessage(messageObject.messageOwner.id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
|
||||||
|
sendTTLMessage(encryptedChat, messageObject.messageOwner);
|
||||||
|
} else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionDeleteMessages) {
|
||||||
|
sendMessagesDeleteMessage(encryptedChat, null, messageObject.messageOwner);
|
||||||
|
} else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionFlushHistory) {
|
||||||
|
sendClearHistoryMessage(encryptedChat, messageObject.messageOwner);
|
||||||
|
} else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionNotifyLayer) {
|
||||||
|
sendNotifyLayerMessage(encryptedChat, messageObject.messageOwner);
|
||||||
|
} else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionReadMessages) {
|
||||||
|
sendMessagesReadMessage(encryptedChat, null, messageObject.messageOwner);
|
||||||
|
} else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) {
|
||||||
|
sendScreenshotMessage(encryptedChat, null, messageObject.messageOwner);
|
||||||
|
} else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionTyping) {
|
||||||
|
|
||||||
|
} else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionResend) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (unsent) {
|
if (unsent) {
|
||||||
unsentMessages.put(messageObject.messageOwner.id, messageObject);
|
unsentMessages.put(messageObject.messageOwner.id, messageObject);
|
||||||
}
|
}
|
||||||
|
@ -623,13 +652,13 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend.message = message;
|
reqSend.message = message;
|
||||||
reqSend.contacts = sendToPeers;
|
reqSend.contacts = sendToPeers;
|
||||||
reqSend.media = new TLRPC.TL_inputMediaEmpty();
|
reqSend.media = new TLRPC.TL_inputMediaEmpty();
|
||||||
performSendMessageRequest(reqSend, newMsgObj, null);
|
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||||
} else {
|
} else {
|
||||||
TLRPC.TL_messages_sendMessage reqSend = new TLRPC.TL_messages_sendMessage();
|
TLRPC.TL_messages_sendMessage reqSend = new TLRPC.TL_messages_sendMessage();
|
||||||
reqSend.message = message;
|
reqSend.message = message;
|
||||||
reqSend.peer = sendToPeer;
|
reqSend.peer = sendToPeer;
|
||||||
reqSend.random_id = newMsg.random_id;
|
reqSend.random_id = newMsg.random_id;
|
||||||
performSendMessageRequest(reqSend, newMsgObj, null);
|
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TLRPC.TL_decryptedMessage reqSend;
|
TLRPC.TL_decryptedMessage reqSend;
|
||||||
|
@ -644,7 +673,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend.random_id = newMsg.random_id;
|
reqSend.random_id = newMsg.random_id;
|
||||||
reqSend.message = message;
|
reqSend.message = message;
|
||||||
reqSend.media = new TLRPC.TL_decryptedMessageMediaEmpty();
|
reqSend.media = new TLRPC.TL_decryptedMessageMediaEmpty();
|
||||||
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, null, null, null);
|
performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null);
|
||||||
}
|
}
|
||||||
} else if (type >= 1 && type <= 3 || type >= 5 && type <= 8) {
|
} else if (type >= 1 && type <= 3 || type >= 5 && type <= 8) {
|
||||||
if (encryptedChat == null) {
|
if (encryptedChat == null) {
|
||||||
|
@ -761,32 +790,32 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend = request;
|
reqSend = request;
|
||||||
}
|
}
|
||||||
if (type == 1) {
|
if (type == 1) {
|
||||||
performSendMessageRequest(reqSend, newMsgObj, null);
|
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||||
} else if (type == 2) {
|
} else if (type == 2) {
|
||||||
if (photo.access_hash == 0) {
|
if (photo.access_hash == 0) {
|
||||||
performSendDelayedMessage(delayedMessage);
|
performSendDelayedMessage(delayedMessage);
|
||||||
} else {
|
} else {
|
||||||
performSendMessageRequest(reqSend, newMsgObj, null);
|
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||||
}
|
}
|
||||||
} else if (type == 3) {
|
} else if (type == 3) {
|
||||||
if (video.access_hash == 0) {
|
if (video.access_hash == 0) {
|
||||||
performSendDelayedMessage(delayedMessage);
|
performSendDelayedMessage(delayedMessage);
|
||||||
} else {
|
} else {
|
||||||
performSendMessageRequest(reqSend, newMsgObj, null);
|
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||||
}
|
}
|
||||||
} else if (type == 6) {
|
} else if (type == 6) {
|
||||||
performSendMessageRequest(reqSend, newMsgObj, null);
|
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||||
} else if (type == 7) {
|
} else if (type == 7) {
|
||||||
if (document.access_hash == 0) {
|
if (document.access_hash == 0) {
|
||||||
performSendDelayedMessage(delayedMessage);
|
performSendDelayedMessage(delayedMessage);
|
||||||
} else {
|
} else {
|
||||||
performSendMessageRequest(reqSend, newMsgObj, null);
|
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||||
}
|
}
|
||||||
} else if (type == 8) {
|
} else if (type == 8) {
|
||||||
if (audio.access_hash == 0) {
|
if (audio.access_hash == 0) {
|
||||||
performSendDelayedMessage(delayedMessage);
|
performSendDelayedMessage(delayedMessage);
|
||||||
} else {
|
} else {
|
||||||
performSendMessageRequest(reqSend, newMsgObj, null);
|
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -805,7 +834,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend.media = new TLRPC.TL_decryptedMessageMediaGeoPoint();
|
reqSend.media = new TLRPC.TL_decryptedMessageMediaGeoPoint();
|
||||||
reqSend.media.lat = lat;
|
reqSend.media.lat = lat;
|
||||||
reqSend.media._long = lon;
|
reqSend.media._long = lon;
|
||||||
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, null, null, null);
|
performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null);
|
||||||
} else if (type == 2) {
|
} else if (type == 2) {
|
||||||
TLRPC.PhotoSize small = photo.sizes.get(0);
|
TLRPC.PhotoSize small = photo.sizes.get(0);
|
||||||
TLRPC.PhotoSize big = photo.sizes.get(photo.sizes.size() - 1);
|
TLRPC.PhotoSize big = photo.sizes.get(photo.sizes.size() - 1);
|
||||||
|
@ -831,7 +860,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
encryptedFile.access_hash = big.location.secret;
|
encryptedFile.access_hash = big.location.secret;
|
||||||
reqSend.media.key = big.location.key;
|
reqSend.media.key = big.location.key;
|
||||||
reqSend.media.iv = big.location.iv;
|
reqSend.media.iv = big.location.iv;
|
||||||
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, encryptedFile, null, null);
|
performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null);
|
||||||
}
|
}
|
||||||
} else if (type == 3) {
|
} else if (type == 3) {
|
||||||
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
|
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
|
||||||
|
@ -862,7 +891,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
encryptedFile.access_hash = video.access_hash;
|
encryptedFile.access_hash = video.access_hash;
|
||||||
reqSend.media.key = video.key;
|
reqSend.media.key = video.key;
|
||||||
reqSend.media.iv = video.iv;
|
reqSend.media.iv = video.iv;
|
||||||
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, encryptedFile, null, null);
|
performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null);
|
||||||
}
|
}
|
||||||
} else if (type == 6) {
|
} else if (type == 6) {
|
||||||
reqSend.media = new TLRPC.TL_decryptedMessageMediaContact();
|
reqSend.media = new TLRPC.TL_decryptedMessageMediaContact();
|
||||||
|
@ -870,7 +899,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend.media.first_name = user.first_name;
|
reqSend.media.first_name = user.first_name;
|
||||||
reqSend.media.last_name = user.last_name;
|
reqSend.media.last_name = user.last_name;
|
||||||
reqSend.media.user_id = user.id;
|
reqSend.media.user_id = user.id;
|
||||||
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, null, null, null);
|
performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null);
|
||||||
} else if (type == 7) {
|
} else if (type == 7) {
|
||||||
reqSend.media = new TLRPC.TL_decryptedMessageMediaDocument();
|
reqSend.media = new TLRPC.TL_decryptedMessageMediaDocument();
|
||||||
reqSend.media.size = document.size;
|
reqSend.media.size = document.size;
|
||||||
|
@ -900,7 +929,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
encryptedFile.access_hash = document.access_hash;
|
encryptedFile.access_hash = document.access_hash;
|
||||||
reqSend.media.key = document.key;
|
reqSend.media.key = document.key;
|
||||||
reqSend.media.iv = document.iv;
|
reqSend.media.iv = document.iv;
|
||||||
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, encryptedFile, null, null);
|
performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null);
|
||||||
}
|
}
|
||||||
} else if (type == 8) {
|
} else if (type == 8) {
|
||||||
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
|
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
|
||||||
|
@ -930,7 +959,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
} else {
|
} else {
|
||||||
reqSend.id = msgObj.messageOwner.fwd_msg_id;
|
reqSend.id = msgObj.messageOwner.fwd_msg_id;
|
||||||
}
|
}
|
||||||
performSendMessageRequest(reqSend, newMsgObj, null);
|
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
|
@ -1046,26 +1075,26 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performSendMessageRequest(final TLObject req, final MessageObject newMsgObj, final String originalPath) {
|
private void performSendMessageRequest(final TLObject req, final TLRPC.Message newMsgObj, final String originalPath) {
|
||||||
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
|
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
|
||||||
@Override
|
@Override
|
||||||
public void run(TLObject response, TLRPC.TL_error error) {
|
public void run(TLObject response, TLRPC.TL_error error) {
|
||||||
if (error == null) {
|
if (error == null) {
|
||||||
final int oldId = newMsgObj.messageOwner.id;
|
final int oldId = newMsgObj.id;
|
||||||
final boolean isBroadcast = req instanceof TLRPC.TL_messages_sendBroadcast;
|
final boolean isBroadcast = req instanceof TLRPC.TL_messages_sendBroadcast;
|
||||||
final ArrayList<TLRPC.Message> sentMessages = new ArrayList<TLRPC.Message>();
|
final ArrayList<TLRPC.Message> sentMessages = new ArrayList<TLRPC.Message>();
|
||||||
final String attachPath = newMsgObj.messageOwner.attachPath;
|
final String attachPath = newMsgObj.attachPath;
|
||||||
|
|
||||||
if (response instanceof TLRPC.messages_SentMessage) {
|
if (response instanceof TLRPC.messages_SentMessage) {
|
||||||
TLRPC.messages_SentMessage res = (TLRPC.messages_SentMessage) response;
|
TLRPC.messages_SentMessage res = (TLRPC.messages_SentMessage) response;
|
||||||
newMsgObj.messageOwner.id = res.id;
|
newMsgObj.id = res.id;
|
||||||
newMsgObj.messageOwner.date = res.date;
|
newMsgObj.date = res.date;
|
||||||
MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, res.date);
|
MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, res.date);
|
||||||
} else if (response instanceof TLRPC.messages_StatedMessage) {
|
} else if (response instanceof TLRPC.messages_StatedMessage) {
|
||||||
TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage) response;
|
TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage) response;
|
||||||
sentMessages.add(res.message);
|
sentMessages.add(res.message);
|
||||||
newMsgObj.messageOwner.id = res.message.id;
|
newMsgObj.id = res.message.id;
|
||||||
processSentMessage(newMsgObj.messageOwner, res.message, null, null, originalPath);
|
processSentMessage(newMsgObj, res.message, null, null, originalPath);
|
||||||
MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, res.message.date);
|
MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, res.message.date);
|
||||||
} else if (response instanceof TLRPC.messages_StatedMessages) {
|
} else if (response instanceof TLRPC.messages_StatedMessages) {
|
||||||
TLRPC.messages_StatedMessages res = (TLRPC.messages_StatedMessages) response;
|
TLRPC.messages_StatedMessages res = (TLRPC.messages_StatedMessages) response;
|
||||||
|
@ -1073,27 +1102,27 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
sentMessages.addAll(res.messages);
|
sentMessages.addAll(res.messages);
|
||||||
TLRPC.Message message = res.messages.get(0);
|
TLRPC.Message message = res.messages.get(0);
|
||||||
if (!isBroadcast) {
|
if (!isBroadcast) {
|
||||||
newMsgObj.messageOwner.id = message.id;
|
newMsgObj.id = message.id;
|
||||||
}
|
}
|
||||||
processSentMessage(newMsgObj.messageOwner, message, null, null, originalPath);
|
processSentMessage(newMsgObj, message, null, null, originalPath);
|
||||||
}
|
}
|
||||||
MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, -1);
|
MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, -1);
|
||||||
}
|
}
|
||||||
MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() {
|
MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
MessagesStorage.getInstance().updateMessageStateAndId(newMsgObj.messageOwner.random_id, oldId, (isBroadcast ? oldId : newMsgObj.messageOwner.id), 0, false);
|
MessagesStorage.getInstance().updateMessageStateAndId(newMsgObj.random_id, oldId, (isBroadcast ? oldId : newMsgObj.id), 0, false);
|
||||||
MessagesStorage.getInstance().putMessages(sentMessages, true, false, isBroadcast, 0);
|
MessagesStorage.getInstance().putMessages(sentMessages, true, false, isBroadcast, 0);
|
||||||
if (isBroadcast) {
|
if (isBroadcast) {
|
||||||
ArrayList<TLRPC.Message> currentMessage = new ArrayList<TLRPC.Message>();
|
ArrayList<TLRPC.Message> currentMessage = new ArrayList<TLRPC.Message>();
|
||||||
currentMessage.add(newMsgObj.messageOwner);
|
currentMessage.add(newMsgObj);
|
||||||
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
|
newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
|
||||||
MessagesStorage.getInstance().putMessages(currentMessage, true, false, false, 0);
|
MessagesStorage.getInstance().putMessages(currentMessage, true, false, false, 0);
|
||||||
}
|
}
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
|
newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
|
||||||
if (isBroadcast) {
|
if (isBroadcast) {
|
||||||
for (TLRPC.Message message : sentMessages) {
|
for (TLRPC.Message message : sentMessages) {
|
||||||
ArrayList<MessageObject> arr = new ArrayList<MessageObject>();
|
ArrayList<MessageObject> arr = new ArrayList<MessageObject>();
|
||||||
|
@ -1103,25 +1132,25 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
}
|
}
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
||||||
}
|
}
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, (isBroadcast ? oldId : newMsgObj.messageOwner.id), newMsgObj);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, (isBroadcast ? oldId : newMsgObj.id), newMsgObj);
|
||||||
processSentMessage(oldId);
|
processSentMessage(oldId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (newMsgObj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
|
if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||||
stopVideoService(attachPath);
|
stopVideoService(attachPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.messageOwner.id);
|
MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.id);
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.messageOwner.id);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.id);
|
||||||
processSentMessage(newMsgObj.messageOwner.id);
|
processSentMessage(newMsgObj.id);
|
||||||
if (newMsgObj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
|
if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||||
stopVideoService(newMsgObj.messageOwner.attachPath);
|
stopVideoService(newMsgObj.attachPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1130,11 +1159,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
}, (req instanceof TLRPC.TL_messages_forwardMessages ? null : new RPCRequest.RPCQuickAckDelegate() {
|
}, (req instanceof TLRPC.TL_messages_forwardMessages ? null : new RPCRequest.RPCQuickAckDelegate() {
|
||||||
@Override
|
@Override
|
||||||
public void quickAck() {
|
public void quickAck() {
|
||||||
final int msg_id = newMsgObj.messageOwner.id;
|
final int msg_id = newMsgObj.id;
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
|
newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByAck, msg_id);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByAck, msg_id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1142,7 +1171,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
}), true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassCanCompress, ConnectionsManager.DEFAULT_DATACENTER_ID);
|
}), true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassCanCompress, ConnectionsManager.DEFAULT_DATACENTER_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performSendEncryptedRequest(final TLRPC.DecryptedMessage req, final MessageObject newMsgObj, final TLRPC.EncryptedChat chat, final TLRPC.InputEncryptedFile encryptedFile, final String originalPath, final Runnable callback) {
|
private void performSendEncryptedRequest(final TLRPC.DecryptedMessage req, final TLRPC.Message newMsgObj, final TLRPC.EncryptedChat chat, final TLRPC.InputEncryptedFile encryptedFile, final String originalPath) {
|
||||||
if (req == null || chat.auth_key == null || chat instanceof TLRPC.TL_encryptedChatRequested || chat instanceof TLRPC.TL_encryptedChatWaiting) {
|
if (req == null || chat.auth_key == null || chat instanceof TLRPC.TL_encryptedChatRequested || chat instanceof TLRPC.TL_encryptedChatWaiting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1150,15 +1179,33 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) {
|
if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) {
|
||||||
TLRPC.TL_decryptedMessageLayer layer = new TLRPC.TL_decryptedMessageLayer();
|
TLRPC.TL_decryptedMessageLayer layer = new TLRPC.TL_decryptedMessageLayer();
|
||||||
layer.layer = CURRENT_SECRET_CHAT_LAYER;
|
layer.layer = CURRENT_SECRET_CHAT_LAYER;
|
||||||
layer.in_seq_no = chat.seq_in;
|
|
||||||
layer.out_seq_no = chat.seq_out;
|
|
||||||
layer.message = req;
|
layer.message = req;
|
||||||
layer.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
layer.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
||||||
Utilities.random.nextBytes(layer.random_bytes);
|
Utilities.random.nextBytes(layer.random_bytes);
|
||||||
toEncryptObject = layer;
|
toEncryptObject = layer;
|
||||||
|
|
||||||
|
if (chat.seq_in == 0 && chat.seq_out == 0) {
|
||||||
|
if (chat.admin_id == UserConfig.getClientUserId()) {
|
||||||
|
chat.seq_out = 1;
|
||||||
|
} else {
|
||||||
|
chat.seq_in = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newMsgObj.seq_in == 0 && newMsgObj.seq_out == 0) {
|
||||||
|
layer.in_seq_no = chat.seq_in;
|
||||||
|
layer.out_seq_no = chat.seq_out;
|
||||||
chat.seq_out += 2;
|
chat.seq_out += 2;
|
||||||
MessagesStorage.getInstance().updateEncryptedChatSeq(chat);
|
MessagesStorage.getInstance().updateEncryptedChatSeq(chat);
|
||||||
|
if (newMsgObj != null) {
|
||||||
|
newMsgObj.seq_in = layer.in_seq_no;
|
||||||
|
newMsgObj.seq_out = layer.out_seq_no;
|
||||||
|
MessagesStorage.getInstance().setMessageSeq(newMsgObj.id, newMsgObj.seq_in, newMsgObj.seq_out);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
layer.in_seq_no = newMsgObj.seq_in;
|
||||||
|
layer.out_seq_no = newMsgObj.seq_out;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toEncryptObject = req;
|
toEncryptObject = req;
|
||||||
}
|
}
|
||||||
|
@ -1199,6 +1246,15 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
TLObject reqToSend = null;
|
TLObject reqToSend = null;
|
||||||
|
|
||||||
if (encryptedFile == null) {
|
if (encryptedFile == null) {
|
||||||
|
if (req instanceof TLRPC.TL_decryptedMessageService) {
|
||||||
|
TLRPC.TL_messages_sendEncryptedService req2 = new TLRPC.TL_messages_sendEncryptedService();
|
||||||
|
req2.data = data;
|
||||||
|
req2.random_id = req.random_id;
|
||||||
|
req2.peer = new TLRPC.TL_inputEncryptedChat();
|
||||||
|
req2.peer.chat_id = chat.id;
|
||||||
|
req2.peer.access_hash = chat.access_hash;
|
||||||
|
reqToSend = req2;
|
||||||
|
} else {
|
||||||
TLRPC.TL_messages_sendEncrypted req2 = new TLRPC.TL_messages_sendEncrypted();
|
TLRPC.TL_messages_sendEncrypted req2 = new TLRPC.TL_messages_sendEncrypted();
|
||||||
req2.data = data;
|
req2.data = data;
|
||||||
req2.random_id = req.random_id;
|
req2.random_id = req.random_id;
|
||||||
|
@ -1206,6 +1262,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
req2.peer.chat_id = chat.id;
|
req2.peer.chat_id = chat.id;
|
||||||
req2.peer.access_hash = chat.access_hash;
|
req2.peer.access_hash = chat.access_hash;
|
||||||
reqToSend = req2;
|
reqToSend = req2;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
TLRPC.TL_messages_sendEncryptedFile req2 = new TLRPC.TL_messages_sendEncryptedFile();
|
TLRPC.TL_messages_sendEncryptedFile req2 = new TLRPC.TL_messages_sendEncryptedFile();
|
||||||
req2.data = data;
|
req2.data = data;
|
||||||
|
@ -1219,28 +1276,47 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
ConnectionsManager.getInstance().performRpc(reqToSend, new RPCRequest.RPCRequestDelegate() {
|
ConnectionsManager.getInstance().performRpc(reqToSend, new RPCRequest.RPCRequestDelegate() {
|
||||||
@Override
|
@Override
|
||||||
public void run(TLObject response, TLRPC.TL_error error) {
|
public void run(TLObject response, TLRPC.TL_error error) {
|
||||||
if (error == null && callback != null) {
|
if (error == null) {
|
||||||
callback.run();
|
if (req.action instanceof TLRPC.TL_decryptedMessageActionNotifyLayer) {
|
||||||
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
TLRPC.EncryptedChat currentChat = MessagesController.getInstance().getEncryptedChat(chat.id);
|
||||||
|
sendingNotifyLayer.remove((Integer)currentChat.id);
|
||||||
|
currentChat.layer = AndroidUtilities.setMyLayerVersion(currentChat.layer, CURRENT_SECRET_CHAT_LAYER);
|
||||||
|
MessagesStorage.getInstance().updateEncryptedChatLayer(currentChat);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (newMsgObj != null) {
|
if (newMsgObj != null) {
|
||||||
if (error == null) {
|
if (error == null) {
|
||||||
final String attachPath = newMsgObj.messageOwner.attachPath;
|
final String attachPath = newMsgObj.attachPath;
|
||||||
final TLRPC.messages_SentEncryptedMessage res = (TLRPC.messages_SentEncryptedMessage) response;
|
final TLRPC.messages_SentEncryptedMessage res = (TLRPC.messages_SentEncryptedMessage) response;
|
||||||
newMsgObj.messageOwner.date = res.date;
|
if (newMsgObj.action instanceof TLRPC.TL_messageEncryptedAction) {
|
||||||
|
if (newMsgObj.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || newMsgObj.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
|
||||||
|
newMsgObj.date = res.date;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (res.file instanceof TLRPC.TL_encryptedFile) {
|
if (res.file instanceof TLRPC.TL_encryptedFile) {
|
||||||
processSentMessage(newMsgObj.messageOwner, null, res.file, req, originalPath);
|
processSentMessage(newMsgObj, null, res.file, req, originalPath);
|
||||||
}
|
}
|
||||||
MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() {
|
MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
MessagesStorage.getInstance().updateMessageStateAndId(newMsgObj.messageOwner.random_id, newMsgObj.messageOwner.id, newMsgObj.messageOwner.id, res.date, false);
|
if (newMsgObj.action instanceof TLRPC.TL_messageEncryptedAction) {
|
||||||
|
if (!(newMsgObj.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || newMsgObj.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL)) {
|
||||||
|
res.date = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MessagesStorage.getInstance().updateMessageStateAndId(newMsgObj.random_id, newMsgObj.id, newMsgObj.id, res.date, false);
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
|
newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, newMsgObj.messageOwner.id, newMsgObj.messageOwner.id, newMsgObj);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, newMsgObj.id, newMsgObj.id, newMsgObj);
|
||||||
processSentMessage(newMsgObj.messageOwner.id);
|
processSentMessage(newMsgObj.id);
|
||||||
if (newMsgObj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
|
if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||||
stopVideoService(attachPath);
|
stopVideoService(attachPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1248,15 +1324,15 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.messageOwner.id);
|
MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.id);
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.messageOwner.id);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.id);
|
||||||
processSentMessage(newMsgObj.messageOwner.id);
|
processSentMessage(newMsgObj.id);
|
||||||
if (newMsgObj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
|
if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||||
stopVideoService(newMsgObj.messageOwner.attachPath);
|
stopVideoService(newMsgObj.attachPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1492,7 +1568,38 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessagesReadMessage(ArrayList<Long> random_ids, TLRPC.EncryptedChat encryptedChat) {
|
private TLRPC.TL_messageService createServiceSecretMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.DecryptedMessageAction decryptedMessage) {
|
||||||
|
TLRPC.TL_messageService newMsg = new TLRPC.TL_messageService();
|
||||||
|
|
||||||
|
newMsg.action = new TLRPC.TL_messageEncryptedAction();
|
||||||
|
newMsg.action.encryptedAction = decryptedMessage;
|
||||||
|
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
||||||
|
newMsg.from_id = UserConfig.getClientUserId();
|
||||||
|
newMsg.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_OUT;
|
||||||
|
newMsg.dialog_id = ((long)encryptedChat.id) << 32;
|
||||||
|
newMsg.to_id = new TLRPC.TL_peerUser();
|
||||||
|
newMsg.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
|
||||||
|
if (encryptedChat.participant_id == UserConfig.getClientUserId()) {
|
||||||
|
newMsg.to_id.user_id = encryptedChat.admin_id;
|
||||||
|
} else {
|
||||||
|
newMsg.to_id.user_id = encryptedChat.participant_id;
|
||||||
|
}
|
||||||
|
if (decryptedMessage instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || decryptedMessage instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
|
||||||
|
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
|
||||||
|
} else {
|
||||||
|
newMsg.date = 0;
|
||||||
|
}
|
||||||
|
newMsg.random_id = getNextRandomId();
|
||||||
|
UserConfig.saveConfig(false);
|
||||||
|
|
||||||
|
ArrayList<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
|
||||||
|
arr.add(newMsg);
|
||||||
|
MessagesStorage.getInstance().putMessages(arr, false, true, true, 0);
|
||||||
|
|
||||||
|
return newMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessagesReadMessage(TLRPC.EncryptedChat encryptedChat, ArrayList<Long> random_ids, TLRPC.Message resendMessage) {
|
||||||
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1504,13 +1611,23 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
||||||
Utilities.random.nextBytes(reqSend.random_bytes);
|
Utilities.random.nextBytes(reqSend.random_bytes);
|
||||||
}
|
}
|
||||||
reqSend.random_id = getNextRandomId();
|
|
||||||
|
TLRPC.Message message = null;
|
||||||
|
|
||||||
|
if (resendMessage != null) {
|
||||||
|
message = resendMessage;
|
||||||
|
reqSend.action = message.action.encryptedAction;
|
||||||
|
} else {
|
||||||
reqSend.action = new TLRPC.TL_decryptedMessageActionReadMessages();
|
reqSend.action = new TLRPC.TL_decryptedMessageActionReadMessages();
|
||||||
reqSend.action.random_ids = random_ids;
|
reqSend.action.random_ids = random_ids;
|
||||||
performSendEncryptedRequest(reqSend, null, encryptedChat, null, null, null);
|
message = createServiceSecretMessage(encryptedChat, reqSend.action);
|
||||||
|
}
|
||||||
|
reqSend.random_id = message.random_id;
|
||||||
|
|
||||||
|
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessagesDeleteMessage(ArrayList<Long> random_ids, TLRPC.EncryptedChat encryptedChat) {
|
public void sendMessagesDeleteMessage(TLRPC.EncryptedChat encryptedChat, ArrayList<Long> random_ids, TLRPC.Message resendMessage) {
|
||||||
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1522,13 +1639,23 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
||||||
Utilities.random.nextBytes(reqSend.random_bytes);
|
Utilities.random.nextBytes(reqSend.random_bytes);
|
||||||
}
|
}
|
||||||
reqSend.random_id = getNextRandomId();
|
|
||||||
|
TLRPC.Message message = null;
|
||||||
|
|
||||||
|
if (resendMessage != null) {
|
||||||
|
message = resendMessage;
|
||||||
|
reqSend.action = message.action.encryptedAction;
|
||||||
|
} else {
|
||||||
reqSend.action = new TLRPC.TL_decryptedMessageActionDeleteMessages();
|
reqSend.action = new TLRPC.TL_decryptedMessageActionDeleteMessages();
|
||||||
reqSend.action.random_ids = random_ids;
|
reqSend.action.random_ids = random_ids;
|
||||||
performSendEncryptedRequest(reqSend, null, encryptedChat, null, null, null);
|
message = createServiceSecretMessage(encryptedChat, reqSend.action);
|
||||||
|
}
|
||||||
|
reqSend.random_id = message.random_id;
|
||||||
|
|
||||||
|
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendClearHistoryMessage(TLRPC.EncryptedChat encryptedChat) {
|
public void sendClearHistoryMessage(TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) {
|
||||||
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1540,12 +1667,22 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
||||||
Utilities.random.nextBytes(reqSend.random_bytes);
|
Utilities.random.nextBytes(reqSend.random_bytes);
|
||||||
}
|
}
|
||||||
reqSend.random_id = getNextRandomId();
|
|
||||||
|
TLRPC.Message message = null;
|
||||||
|
|
||||||
|
if (resendMessage != null) {
|
||||||
|
message = resendMessage;
|
||||||
|
reqSend.action = message.action.encryptedAction;
|
||||||
|
} else {
|
||||||
reqSend.action = new TLRPC.TL_decryptedMessageActionFlushHistory();
|
reqSend.action = new TLRPC.TL_decryptedMessageActionFlushHistory();
|
||||||
performSendEncryptedRequest(reqSend, null, encryptedChat, null, null, null);
|
message = createServiceSecretMessage(encryptedChat, reqSend.action);
|
||||||
|
}
|
||||||
|
reqSend.random_id = message.random_id;
|
||||||
|
|
||||||
|
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendNotifyLayerMessage(final TLRPC.EncryptedChat encryptedChat) {
|
public void sendNotifyLayerMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) {
|
||||||
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1561,57 +1698,26 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
||||||
Utilities.random.nextBytes(reqSend.random_bytes);
|
Utilities.random.nextBytes(reqSend.random_bytes);
|
||||||
}
|
}
|
||||||
reqSend.random_id = getNextRandomId();
|
|
||||||
|
TLRPC.Message message = null;
|
||||||
|
|
||||||
|
if (resendMessage != null) {
|
||||||
|
message = resendMessage;
|
||||||
|
reqSend.action = message.action.encryptedAction;
|
||||||
|
} else {
|
||||||
reqSend.action = new TLRPC.TL_decryptedMessageActionNotifyLayer();
|
reqSend.action = new TLRPC.TL_decryptedMessageActionNotifyLayer();
|
||||||
reqSend.action.layer = CURRENT_SECRET_CHAT_LAYER;
|
reqSend.action.layer = CURRENT_SECRET_CHAT_LAYER;
|
||||||
Runnable callback = new Runnable() {
|
message = createServiceSecretMessage(encryptedChat, reqSend.action);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
TLRPC.EncryptedChat chat = MessagesController.getInstance().getEncryptedChat(encryptedChat.id);
|
|
||||||
sendingNotifyLayer.remove((Integer)chat.id);
|
|
||||||
chat.layer = AndroidUtilities.setMyLayerVersion(chat.layer, CURRENT_SECRET_CHAT_LAYER);
|
|
||||||
MessagesStorage.getInstance().updateEncryptedChatLayer(chat);
|
|
||||||
}
|
}
|
||||||
});
|
reqSend.random_id = message.random_id;
|
||||||
}
|
|
||||||
};
|
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
|
||||||
performSendEncryptedRequest(reqSend, null, encryptedChat, null, null, callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendTTLMessage(TLRPC.EncryptedChat encryptedChat) {
|
public void sendTTLMessage(TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) {
|
||||||
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TLRPC.TL_messageService newMsg = new TLRPC.TL_messageService();
|
|
||||||
|
|
||||||
newMsg.action = new TLRPC.TL_messageActionTTLChange();
|
|
||||||
newMsg.action.ttl = encryptedChat.ttl;
|
|
||||||
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
|
||||||
newMsg.from_id = UserConfig.getClientUserId();
|
|
||||||
newMsg.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_OUT;
|
|
||||||
newMsg.dialog_id = ((long)encryptedChat.id) << 32;
|
|
||||||
newMsg.to_id = new TLRPC.TL_peerUser();
|
|
||||||
if (encryptedChat.participant_id == UserConfig.getClientUserId()) {
|
|
||||||
newMsg.to_id.user_id = encryptedChat.admin_id;
|
|
||||||
} else {
|
|
||||||
newMsg.to_id.user_id = encryptedChat.participant_id;
|
|
||||||
}
|
|
||||||
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
|
|
||||||
newMsg.random_id = getNextRandomId();
|
|
||||||
UserConfig.saveConfig(false);
|
|
||||||
final MessageObject newMsgObj = new MessageObject(newMsg, null);
|
|
||||||
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
|
|
||||||
|
|
||||||
final ArrayList<MessageObject> objArr = new ArrayList<MessageObject>();
|
|
||||||
objArr.add(newMsgObj);
|
|
||||||
ArrayList<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
|
|
||||||
arr.add(newMsg);
|
|
||||||
MessagesStorage.getInstance().putMessages(arr, false, true, false, 0);
|
|
||||||
MessagesController.getInstance().updateInterfaceWithMessages(newMsg.dialog_id, objArr);
|
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
|
||||||
|
|
||||||
TLRPC.TL_decryptedMessageService reqSend = null;
|
TLRPC.TL_decryptedMessageService reqSend = null;
|
||||||
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
|
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
|
||||||
|
@ -1621,49 +1727,34 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
||||||
Utilities.random.nextBytes(reqSend.random_bytes);
|
Utilities.random.nextBytes(reqSend.random_bytes);
|
||||||
}
|
}
|
||||||
reqSend.random_id = newMsg.random_id;
|
|
||||||
|
TLRPC.Message message = null;
|
||||||
|
|
||||||
|
if (resendMessage != null) {
|
||||||
|
message = resendMessage;
|
||||||
|
reqSend.action = message.action.encryptedAction;
|
||||||
|
} else {
|
||||||
reqSend.action = new TLRPC.TL_decryptedMessageActionSetMessageTTL();
|
reqSend.action = new TLRPC.TL_decryptedMessageActionSetMessageTTL();
|
||||||
reqSend.action.ttl_seconds = encryptedChat.ttl;
|
reqSend.action.ttl_seconds = encryptedChat.ttl;
|
||||||
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, null, null, null);
|
message = createServiceSecretMessage(encryptedChat, reqSend.action);
|
||||||
|
|
||||||
|
MessageObject newMsgObj = new MessageObject(message, null);
|
||||||
|
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
|
||||||
|
ArrayList<MessageObject> objArr = new ArrayList<MessageObject>();
|
||||||
|
objArr.add(newMsgObj);
|
||||||
|
MessagesController.getInstance().updateInterfaceWithMessages(message.dialog_id, objArr);
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
||||||
|
}
|
||||||
|
reqSend.random_id = message.random_id;
|
||||||
|
|
||||||
|
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendScreenshotMessage(TLRPC.EncryptedChat encryptedChat, ArrayList<Long> random_ids) {
|
public void sendScreenshotMessage(TLRPC.EncryptedChat encryptedChat, ArrayList<Long> random_ids, TLRPC.Message resendMessage) {
|
||||||
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TLRPC.TL_decryptedMessageActionScreenshotMessages action = new TLRPC.TL_decryptedMessageActionScreenshotMessages();
|
|
||||||
action.random_ids = random_ids;
|
|
||||||
|
|
||||||
TLRPC.TL_messageService newMsg = new TLRPC.TL_messageService();
|
|
||||||
|
|
||||||
newMsg.action = new TLRPC.TL_messageEcryptedAction();
|
|
||||||
newMsg.action.encryptedAction = action;
|
|
||||||
|
|
||||||
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
|
||||||
newMsg.from_id = UserConfig.getClientUserId();
|
|
||||||
newMsg.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_OUT;
|
|
||||||
newMsg.dialog_id = ((long)encryptedChat.id) << 32;
|
|
||||||
newMsg.to_id = new TLRPC.TL_peerUser();
|
|
||||||
if (encryptedChat.participant_id == UserConfig.getClientUserId()) {
|
|
||||||
newMsg.to_id.user_id = encryptedChat.admin_id;
|
|
||||||
} else {
|
|
||||||
newMsg.to_id.user_id = encryptedChat.participant_id;
|
|
||||||
}
|
|
||||||
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
|
|
||||||
newMsg.random_id = getNextRandomId();
|
|
||||||
UserConfig.saveConfig(false);
|
|
||||||
final MessageObject newMsgObj = new MessageObject(newMsg, null);
|
|
||||||
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
|
|
||||||
|
|
||||||
final ArrayList<MessageObject> objArr = new ArrayList<MessageObject>();
|
|
||||||
objArr.add(newMsgObj);
|
|
||||||
ArrayList<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
|
|
||||||
arr.add(newMsg);
|
|
||||||
MessagesStorage.getInstance().putMessages(arr, false, true, false, 0);
|
|
||||||
MessagesController.getInstance().updateInterfaceWithMessages(newMsg.dialog_id, objArr);
|
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
|
||||||
|
|
||||||
TLRPC.TL_decryptedMessageService reqSend = null;
|
TLRPC.TL_decryptedMessageService reqSend = null;
|
||||||
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
|
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
|
||||||
reqSend = new TLRPC.TL_decryptedMessageService();
|
reqSend = new TLRPC.TL_decryptedMessageService();
|
||||||
|
@ -1672,9 +1763,27 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
|
||||||
Utilities.random.nextBytes(reqSend.random_bytes);
|
Utilities.random.nextBytes(reqSend.random_bytes);
|
||||||
}
|
}
|
||||||
reqSend.random_id = newMsg.random_id;
|
|
||||||
reqSend.action = action;
|
TLRPC.Message message = null;
|
||||||
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, null, null, null);
|
|
||||||
|
if (resendMessage != null) {
|
||||||
|
message = resendMessage;
|
||||||
|
reqSend.action = message.action.encryptedAction;
|
||||||
|
} else {
|
||||||
|
reqSend.action = new TLRPC.TL_decryptedMessageActionScreenshotMessages();
|
||||||
|
reqSend.action.random_ids = random_ids;
|
||||||
|
message = createServiceSecretMessage(encryptedChat, reqSend.action);
|
||||||
|
|
||||||
|
MessageObject newMsgObj = new MessageObject(message, null);
|
||||||
|
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
|
||||||
|
ArrayList<MessageObject> objArr = new ArrayList<MessageObject>();
|
||||||
|
objArr.add(newMsgObj);
|
||||||
|
MessagesController.getInstance().updateInterfaceWithMessages(message.dialog_id, objArr);
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
||||||
|
}
|
||||||
|
reqSend.random_id = message.random_id;
|
||||||
|
|
||||||
|
performSendEncryptedRequest(reqSend, message, encryptedChat, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putToDelayedMessages(String location, DelayedMessage message) {
|
private void putToDelayedMessages(String location, DelayedMessage message) {
|
||||||
|
@ -1695,7 +1804,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkUnsentMessages() {
|
public void checkUnsentMessages() {
|
||||||
MessagesStorage.getInstance().getUnsentMessages(10);
|
MessagesStorage.getInstance().getUnsentMessages(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processUnsentMessages(final ArrayList<TLRPC.Message> messages, final ArrayList<TLRPC.User> users, final ArrayList<TLRPC.Chat> chats, final ArrayList<TLRPC.EncryptedChat> encryptedChats) {
|
protected void processUnsentMessages(final ArrayList<TLRPC.Message> messages, final ArrayList<TLRPC.User> users, final ArrayList<TLRPC.Chat> chats, final ArrayList<TLRPC.EncryptedChat> encryptedChats) {
|
||||||
|
|
|
@ -704,4 +704,26 @@ public class FileLoader {
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteFiles(final ArrayList<File> files) {
|
||||||
|
if (files == null || files.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fileLoaderQueue.postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (File file : files) {
|
||||||
|
if (file.exists()) {
|
||||||
|
try {
|
||||||
|
if (!file.delete()) {
|
||||||
|
file.deleteOnExit();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,7 +370,7 @@ public class TLClassStore {
|
||||||
classStore.put(TLRPC.TL_userRequest_old.constructor, TLRPC.TL_userRequest_old.class);
|
classStore.put(TLRPC.TL_userRequest_old.constructor, TLRPC.TL_userRequest_old.class);
|
||||||
classStore.put(TLRPC.TL_userForeign_old.constructor, TLRPC.TL_userForeign_old.class);
|
classStore.put(TLRPC.TL_userForeign_old.constructor, TLRPC.TL_userForeign_old.class);
|
||||||
classStore.put(TLRPC.TL_userDeleted_old.constructor, TLRPC.TL_userDeleted_old.class);
|
classStore.put(TLRPC.TL_userDeleted_old.constructor, TLRPC.TL_userDeleted_old.class);
|
||||||
classStore.put(TLRPC.TL_messageEcryptedAction.constructor, TLRPC.TL_messageEcryptedAction.class);
|
classStore.put(TLRPC.TL_messageEncryptedAction.constructor, TLRPC.TL_messageEncryptedAction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TLClassStore store = null;
|
static TLClassStore store = null;
|
||||||
|
|
|
@ -8429,32 +8429,37 @@ public class TLRPC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//manually created
|
||||||
|
|
||||||
public static class TL_messages_sendEncryptedService extends TLObject {
|
public static class TL_messages_sendEncryptedService extends TLObject {
|
||||||
public static int constructor = 0x32d439a4;
|
public static int constructor = 0x32d439a4;
|
||||||
|
|
||||||
public TL_inputEncryptedChat peer;
|
public TL_inputEncryptedChat peer;
|
||||||
public long random_id;
|
public long random_id;
|
||||||
public byte[] data;
|
public ByteBufferDesc data;
|
||||||
|
|
||||||
public Class responseClass () {
|
public Class responseClass () {
|
||||||
return messages_SentEncryptedMessage.class;
|
return messages_SentEncryptedMessage.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readParams(AbsSerializedData stream) {
|
|
||||||
peer = (TL_inputEncryptedChat)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
|
||||||
random_id = stream.readInt64();
|
|
||||||
data = stream.readByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void serializeToStream(AbsSerializedData stream) {
|
public void serializeToStream(AbsSerializedData stream) {
|
||||||
stream.writeInt32(constructor);
|
stream.writeInt32(constructor);
|
||||||
peer.serializeToStream(stream);
|
peer.serializeToStream(stream);
|
||||||
stream.writeInt64(random_id);
|
stream.writeInt64(random_id);
|
||||||
stream.writeByteArray(data);
|
stream.writeByteBuffer(data);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//manually created
|
@Override
|
||||||
|
public void freeResources() {
|
||||||
|
if (disableFree) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data != null) {
|
||||||
|
BuffersStorage.getInstance().reuseFreeBuffer(data);
|
||||||
|
data = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class TL_userDeleted_old extends TL_userDeleted {
|
public static class TL_userDeleted_old extends TL_userDeleted {
|
||||||
public static int constructor = 0xb29ad7cc;
|
public static int constructor = 0xb29ad7cc;
|
||||||
|
@ -8990,6 +8995,8 @@ public class TLRPC {
|
||||||
public int ttl;
|
public int ttl;
|
||||||
public int destroyTime;
|
public int destroyTime;
|
||||||
public int layer;
|
public int layer;
|
||||||
|
public int seq_in;
|
||||||
|
public int seq_out;
|
||||||
public VideoEditedInfo videoEditedInfo = null;
|
public VideoEditedInfo videoEditedInfo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9993,7 +10000,7 @@ public class TLRPC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TL_messageEcryptedAction extends MessageAction {
|
public static class TL_messageEncryptedAction extends MessageAction {
|
||||||
public static int constructor = 0x555555F7;
|
public static int constructor = 0x555555F7;
|
||||||
|
|
||||||
public void readParams(AbsSerializedData stream) {
|
public void readParams(AbsSerializedData stream) {
|
||||||
|
|
|
@ -43,6 +43,7 @@ public class ChatMessageCell extends ChatBaseCell {
|
||||||
y -= textY;
|
y -= textY;
|
||||||
int blockNum = Math.max(0, y / currentMessageObject.blockHeight);
|
int blockNum = Math.max(0, y / currentMessageObject.blockHeight);
|
||||||
if (blockNum < currentMessageObject.textLayoutBlocks.size()) {
|
if (blockNum < currentMessageObject.textLayoutBlocks.size()) {
|
||||||
|
try {
|
||||||
MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(blockNum);
|
MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(blockNum);
|
||||||
x -= textX - (int)Math.ceil(block.textXOffset);
|
x -= textX - (int)Math.ceil(block.textXOffset);
|
||||||
y -= block.textYOffset;
|
y -= block.textYOffset;
|
||||||
|
@ -74,6 +75,10 @@ public class ChatMessageCell extends ChatBaseCell {
|
||||||
} else {
|
} else {
|
||||||
pressedLink = null;
|
pressedLink = null;
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
pressedLink = null;
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pressedLink = null;
|
pressedLink = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,7 +387,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
typingDotsDrawable.setIsChat(currentChat != null);
|
typingDotsDrawable.setIsChat(currentChat != null);
|
||||||
|
|
||||||
if (currentEncryptedChat != null && AndroidUtilities.getMyLayerVersion(currentEncryptedChat.layer) != SendMessagesHelper.CURRENT_SECRET_CHAT_LAYER) {
|
if (currentEncryptedChat != null && AndroidUtilities.getMyLayerVersion(currentEncryptedChat.layer) != SendMessagesHelper.CURRENT_SECRET_CHAT_LAYER) {
|
||||||
SendMessagesHelper.getInstance().sendNotifyLayerMessage(currentEncryptedChat);
|
SendMessagesHelper.getInstance().sendNotifyLayerMessage(currentEncryptedChat, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -651,7 +651,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
|
|
||||||
actionModeViews.clear();
|
actionModeViews.clear();
|
||||||
|
|
||||||
ActionBarMenu actionMode = actionBarLayer.createActionMode();
|
final ActionBarMenu actionMode = actionBarLayer.createActionMode();
|
||||||
actionModeViews.add(actionMode.addItem(-2, R.drawable.ic_ab_done_gray, R.drawable.bar_selector_mode));
|
actionModeViews.add(actionMode.addItem(-2, R.drawable.ic_ab_done_gray, R.drawable.bar_selector_mode));
|
||||||
|
|
||||||
FrameLayout layout = new FrameLayout(actionMode.getContext());
|
FrameLayout layout = new FrameLayout(actionMode.getContext());
|
||||||
|
@ -822,6 +822,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
chatListView.setOnInterceptTouchEventListener(new LayoutListView.OnInterceptTouchEventListener() {
|
chatListView.setOnInterceptTouchEventListener(new LayoutListView.OnInterceptTouchEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||||
|
if (actionBarLayer.isActionModeShowed()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
int x = (int)event.getX();
|
int x = (int)event.getX();
|
||||||
int y = (int)event.getY();
|
int y = (int)event.getY();
|
||||||
|
@ -880,14 +883,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
if (openSecretPhotoRunnable != null || SecretPhotoViewer.getInstance().isVisible()) {
|
if (openSecretPhotoRunnable != null || SecretPhotoViewer.getInstance().isVisible()) {
|
||||||
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_POINTER_UP) {
|
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_POINTER_UP) {
|
||||||
if (openSecretPhotoRunnable != null) {
|
|
||||||
AndroidUtilities.CancelRunOnUIThread(openSecretPhotoRunnable);
|
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
chatListView.setOnItemClickListener(onItemClickListener);
|
chatListView.setOnItemClickListener(onItemClickListener);
|
||||||
}
|
}
|
||||||
}, 150);
|
}, 150);
|
||||||
|
if (openSecretPhotoRunnable != null) {
|
||||||
|
AndroidUtilities.CancelRunOnUIThread(openSecretPhotoRunnable);
|
||||||
openSecretPhotoRunnable = null;
|
openSecretPhotoRunnable = null;
|
||||||
try {
|
try {
|
||||||
Toast.makeText(v.getContext(), LocaleController.getString("PhotoTip", R.string.PhotoTip), Toast.LENGTH_SHORT).show();
|
Toast.makeText(v.getContext(), LocaleController.getString("PhotoTip", R.string.PhotoTip), Toast.LENGTH_SHORT).show();
|
||||||
|
@ -899,14 +902,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
chatListView.setOnItemClickListener(onItemClickListener);
|
|
||||||
chatListView.setOnItemLongClickListener(onItemLongClickListener);
|
chatListView.setOnItemLongClickListener(onItemLongClickListener);
|
||||||
chatListView.setLongClickable(true);
|
chatListView.setLongClickable(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
SecretPhotoViewer.getInstance().closePhoto();
|
SecretPhotoViewer.getInstance().closePhoto();
|
||||||
} else {
|
|
||||||
chatListView.setOnItemClickListener(onItemClickListener);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event.getAction() != MotionEvent.ACTION_DOWN) {
|
} else if (event.getAction() != MotionEvent.ACTION_DOWN) {
|
||||||
|
@ -1043,7 +1043,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
if (messageObject == null || messageObject.isOut() || !messageObject.isSecretMedia() || messageObject.messageOwner.destroyTime != 0) {
|
if (messageObject == null || messageObject.isOut() || !messageObject.isSecretMedia() || messageObject.messageOwner.destroyTime != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MessagesController.getInstance().markMessageAsRead(dialog_id, messageObject.messageOwner.random_id);
|
MessagesController.getInstance().markMessageAsRead(dialog_id, messageObject.messageOwner.random_id, messageObject.messageOwner.ttl);
|
||||||
messageObject.messageOwner.destroyTime = messageObject.messageOwner.ttl + ConnectionsManager.getInstance().getCurrentTime();
|
messageObject.messageOwner.destroyTime = messageObject.messageOwner.ttl + ConnectionsManager.getInstance().getCurrentTime();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1290,11 +1290,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
} else {
|
} else {
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
} else if (messageObject.type == 10 || messageObject.type == 11 || messageObject.isSending()) {
|
} else if (messageObject.type == 10 || messageObject.type == 11) {
|
||||||
if (messageObject.messageOwner.id == 0) {
|
if (messageObject.isSending()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) {
|
if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) {
|
||||||
if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo ||
|
if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo ||
|
||||||
|
@ -1502,10 +1503,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
SendMessagesHelper.prepareSendingVideo(videoPath, estimatedSize, estimatedDuration, resultWidth, resultHeight, videoEditedInfo, dialog_id);
|
SendMessagesHelper.prepareSendingVideo(videoPath, estimatedSize, estimatedDuration, resultWidth, resultHeight, videoEditedInfo, dialog_id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (parentLayout == null || !parentLayout.presentFragment(fragment, removeLast, true, true)) {
|
|
||||||
|
if (parentLayout == null || !fragment.onFragmentCreate()) {
|
||||||
SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id);
|
SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
parentLayout.presentFragment(fragment, removeLast, true, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1686,6 +1689,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
if (minDate == 0 || obj.messageOwner.date < minDate) {
|
if (minDate == 0 || obj.messageOwner.date < minDate) {
|
||||||
minDate = obj.messageOwner.date;
|
minDate = obj.messageOwner.date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (obj.type < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!obj.isOut() && obj.isUnread()) {
|
if (!obj.isOut() && obj.isUnread()) {
|
||||||
wasUnread = true;
|
wasUnread = true;
|
||||||
}
|
}
|
||||||
|
@ -1876,9 +1884,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
ArrayList<MessageObject> arr = (ArrayList<MessageObject>)args[1];
|
ArrayList<MessageObject> arr = (ArrayList<MessageObject>)args[1];
|
||||||
|
|
||||||
if (currentEncryptedChat != null && arr.size() == 1) {
|
if (currentEncryptedChat != null && arr.size() == 1) {
|
||||||
MessageObject messageObject = arr.get(0);
|
MessageObject obj = arr.get(0);
|
||||||
|
|
||||||
if (messageObject.isOut() && messageObject.messageOwner.action instanceof TLRPC.TL_messageActionTTLChange && getParentActivity() != null && AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) < 17 && currentEncryptedChat.ttl > 0 && currentEncryptedChat.ttl <= 60) {
|
if (currentEncryptedChat != null && obj.isOut() && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction &&
|
||||||
|
obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL && getParentActivity() != null) {
|
||||||
|
TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL)obj.messageOwner.action.encryptedAction;
|
||||||
|
if (AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) < 17 && currentEncryptedChat.ttl > 0 && currentEncryptedChat.ttl <= 60) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
|
||||||
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
|
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
|
||||||
builder.setPositiveButton(R.string.OK, null);
|
builder.setPositiveButton(R.string.OK, null);
|
||||||
|
@ -1886,6 +1897,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
showAlertDialog(builder);
|
showAlertDialog(builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!unread_end_reached) {
|
if (!unread_end_reached) {
|
||||||
int currentMaxDate = Integer.MIN_VALUE;
|
int currentMaxDate = Integer.MIN_VALUE;
|
||||||
|
@ -1896,8 +1908,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
boolean currentMarkAsRead = false;
|
boolean currentMarkAsRead = false;
|
||||||
|
|
||||||
for (MessageObject obj : arr) {
|
for (MessageObject obj : arr) {
|
||||||
if (currentEncryptedChat != null && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageActionTTLChange && timerButton != null) {
|
if (currentEncryptedChat != null && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction &&
|
||||||
timerButton.setTime(obj.messageOwner.action.ttl);
|
obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL && timerButton != null) {
|
||||||
|
TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL)obj.messageOwner.action.encryptedAction;
|
||||||
|
timerButton.setTime(action.ttl_seconds);
|
||||||
}
|
}
|
||||||
if (obj.isOut() && obj.isSending()) {
|
if (obj.isOut() && obj.isSending()) {
|
||||||
scrollToLastMessage();
|
scrollToLastMessage();
|
||||||
|
@ -1938,8 +1952,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
boolean markAsRead = false;
|
boolean markAsRead = false;
|
||||||
int oldCount = messages.size();
|
int oldCount = messages.size();
|
||||||
for (MessageObject obj : arr) {
|
for (MessageObject obj : arr) {
|
||||||
if (currentEncryptedChat != null && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageActionTTLChange && timerButton != null) {
|
if (currentEncryptedChat != null && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction &&
|
||||||
timerButton.setTime(obj.messageOwner.action.ttl);
|
obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL && timerButton != null) {
|
||||||
|
TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL)obj.messageOwner.action.encryptedAction;
|
||||||
|
timerButton.setTime(action.ttl_seconds);
|
||||||
}
|
}
|
||||||
if (messagesDict.containsKey(obj.messageOwner.id)) {
|
if (messagesDict.containsKey(obj.messageOwner.id)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -2108,9 +2124,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
MessageObject obj = messagesDict.get(msgId);
|
MessageObject obj = messagesDict.get(msgId);
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
Integer newMsgId = (Integer)args[1];
|
Integer newMsgId = (Integer)args[1];
|
||||||
MessageObject newMsgObj = (MessageObject)args[2];
|
TLRPC.Message newMsgObj = (TLRPC.Message)args[2];
|
||||||
if (newMsgObj != null) {
|
if (newMsgObj != null) {
|
||||||
obj.messageOwner.media = newMsgObj.messageOwner.media;
|
obj.messageOwner.media = newMsgObj.media;
|
||||||
obj.generateThumbs(true, 1);
|
obj.generateThumbs(true, 1);
|
||||||
}
|
}
|
||||||
messagesDict.remove(msgId);
|
messagesDict.remove(msgId);
|
||||||
|
|
|
@ -657,7 +657,16 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
||||||
if (obj.isSent()) {
|
if (obj.isSent()) {
|
||||||
ArrayList<Integer> arr = new ArrayList<Integer>();
|
ArrayList<Integer> arr = new ArrayList<Integer>();
|
||||||
arr.add(obj.messageOwner.id);
|
arr.add(obj.messageOwner.id);
|
||||||
MessagesController.getInstance().deleteMessages(arr, null, null);
|
|
||||||
|
ArrayList<Long> random_ids = null;
|
||||||
|
TLRPC.EncryptedChat encryptedChat = null;
|
||||||
|
if ((int)obj.getDialogId() == 0 && obj.messageOwner.random_id != 0) {
|
||||||
|
random_ids = new ArrayList<Long>();
|
||||||
|
random_ids.add(obj.messageOwner.random_id);
|
||||||
|
encryptedChat = MessagesController.getInstance().getEncryptedChat((int)(obj.getDialogId() >> 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
MessagesController.getInstance().deleteMessages(arr, random_ids, encryptedChat);
|
||||||
closePhoto(false);
|
closePhoto(false);
|
||||||
}
|
}
|
||||||
} else if (!avatarsArr.isEmpty()) {
|
} else if (!avatarsArr.isEmpty()) {
|
||||||
|
|
|
@ -71,10 +71,8 @@ public class SettingsChangeUsernameActivity extends BaseFragment {
|
||||||
doneButton.setOnClickListener(new View.OnClickListener() {
|
doneButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (firstNameField.getText().length() != 0) {
|
|
||||||
saveName();
|
saveName();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
cancelButton.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase());
|
cancelButton.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase());
|
||||||
|
|
|
@ -58,6 +58,7 @@ import java.util.List;
|
||||||
@TargetApi(16)
|
@TargetApi(16)
|
||||||
public class VideoEditorActivity extends BaseFragment implements TextureView.SurfaceTextureListener {
|
public class VideoEditorActivity extends BaseFragment implements TextureView.SurfaceTextureListener {
|
||||||
|
|
||||||
|
private boolean created = false;
|
||||||
private MediaPlayer videoPlayer = null;
|
private MediaPlayer videoPlayer = null;
|
||||||
private VideoTimelineView videoTimelineView = null;
|
private VideoTimelineView videoTimelineView = null;
|
||||||
private View videoContainerView = null;
|
private View videoContainerView = null;
|
||||||
|
@ -161,6 +162,9 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onFragmentCreate() {
|
public boolean onFragmentCreate() {
|
||||||
|
if (created) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (videoPath == null || !processOpenVideo()) {
|
if (videoPath == null || !processOpenVideo()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -191,6 +195,8 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
created = true;
|
||||||
|
|
||||||
return super.onFragmentCreate();
|
return super.onFragmentCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ import android.view.ViewConfiguration;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.Scroller;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.telegram.messenger.R;
|
import org.telegram.messenger.R;
|
||||||
|
@ -726,6 +725,28 @@ public class NumberPicker extends LinearLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
|
||||||
|
int result = size;
|
||||||
|
int specMode = MeasureSpec.getMode(measureSpec);
|
||||||
|
int specSize = MeasureSpec.getSize(measureSpec);
|
||||||
|
switch (specMode) {
|
||||||
|
case MeasureSpec.UNSPECIFIED:
|
||||||
|
result = size;
|
||||||
|
break;
|
||||||
|
case MeasureSpec.AT_MOST:
|
||||||
|
if (specSize < size) {
|
||||||
|
result = specSize | 16777216;
|
||||||
|
} else {
|
||||||
|
result = size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MeasureSpec.EXACTLY:
|
||||||
|
result = specSize;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result | (childMeasuredState & (-16777216));
|
||||||
|
}
|
||||||
|
|
||||||
private void initializeSelectorWheelIndices() {
|
private void initializeSelectorWheelIndices() {
|
||||||
mSelectorIndexToStringCache.clear();
|
mSelectorIndexToStringCache.clear();
|
||||||
int[] selectorIndices = mSelectorIndices;
|
int[] selectorIndices = mSelectorIndices;
|
||||||
|
|
502
TMessagesProj/src/main/java/org/telegram/ui/Views/Scroller.java
Normal file
502
TMessagesProj/src/main/java/org/telegram/ui/Views/Scroller.java
Normal file
|
@ -0,0 +1,502 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.telegram.ui.Views;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.hardware.SensorManager;
|
||||||
|
import android.util.FloatMath;
|
||||||
|
import android.view.ViewConfiguration;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class encapsulates scrolling. The duration of the scroll
|
||||||
|
* can be passed in the constructor and specifies the maximum time that
|
||||||
|
* the scrolling animation should take. Past this time, the scrolling is
|
||||||
|
* automatically moved to its final stage and computeScrollOffset()
|
||||||
|
* will always return false to indicate that scrolling is over.
|
||||||
|
*/
|
||||||
|
public class Scroller {
|
||||||
|
private int mMode;
|
||||||
|
|
||||||
|
private int mStartX;
|
||||||
|
private int mStartY;
|
||||||
|
private int mFinalX;
|
||||||
|
private int mFinalY;
|
||||||
|
|
||||||
|
private int mMinX;
|
||||||
|
private int mMaxX;
|
||||||
|
private int mMinY;
|
||||||
|
private int mMaxY;
|
||||||
|
|
||||||
|
private int mCurrX;
|
||||||
|
private int mCurrY;
|
||||||
|
private long mStartTime;
|
||||||
|
private int mDuration;
|
||||||
|
private float mDurationReciprocal;
|
||||||
|
private float mDeltaX;
|
||||||
|
private float mDeltaY;
|
||||||
|
private boolean mFinished;
|
||||||
|
private Interpolator mInterpolator;
|
||||||
|
private boolean mFlywheel;
|
||||||
|
|
||||||
|
private float mVelocity;
|
||||||
|
|
||||||
|
private static final int DEFAULT_DURATION = 250;
|
||||||
|
private static final int SCROLL_MODE = 0;
|
||||||
|
private static final int FLING_MODE = 1;
|
||||||
|
|
||||||
|
private static float DECELERATION_RATE = (float) (Math.log(0.75) / Math.log(0.9));
|
||||||
|
private static float START_TENSION = 0.4f; // Tension at start: (0.4 * total T, 1.0 * Distance)
|
||||||
|
private static float END_TENSION = 1.0f - START_TENSION;
|
||||||
|
private static final int NB_SAMPLES = 100;
|
||||||
|
private static final float[] SPLINE = new float[NB_SAMPLES + 1];
|
||||||
|
|
||||||
|
private float mDeceleration;
|
||||||
|
private final float mPpi;
|
||||||
|
|
||||||
|
static {
|
||||||
|
float x_min = 0.0f;
|
||||||
|
for (int i = 0; i <= NB_SAMPLES; i++) {
|
||||||
|
final float t = (float) i / NB_SAMPLES;
|
||||||
|
float x_max = 1.0f;
|
||||||
|
float x, tx, coef;
|
||||||
|
while (true) {
|
||||||
|
x = x_min + (x_max - x_min) / 2.0f;
|
||||||
|
coef = 3.0f * x * (1.0f - x);
|
||||||
|
tx = coef * ((1.0f - x) * START_TENSION + x * END_TENSION) + x * x * x;
|
||||||
|
if (Math.abs(tx - t) < 1E-5) break;
|
||||||
|
if (tx > t) x_max = x;
|
||||||
|
else x_min = x;
|
||||||
|
}
|
||||||
|
final float d = coef + x * x * x;
|
||||||
|
SPLINE[i] = d;
|
||||||
|
}
|
||||||
|
SPLINE[NB_SAMPLES] = 1.0f;
|
||||||
|
|
||||||
|
// This controls the viscous fluid effect (how much of it)
|
||||||
|
sViscousFluidScale = 8.0f;
|
||||||
|
// must be set to 1.0 (used in viscousFluid())
|
||||||
|
sViscousFluidNormalize = 1.0f;
|
||||||
|
sViscousFluidNormalize = 1.0f / viscousFluid(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float sViscousFluidScale;
|
||||||
|
private static float sViscousFluidNormalize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Scroller with the default duration and interpolator.
|
||||||
|
*/
|
||||||
|
public Scroller(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Scroller with the specified interpolator. If the interpolator is
|
||||||
|
* null, the default (viscous) interpolator will be used. "Flywheel" behavior will
|
||||||
|
* be in effect for apps targeting Honeycomb or newer.
|
||||||
|
*/
|
||||||
|
public Scroller(Context context, Interpolator interpolator) {
|
||||||
|
this(context, interpolator, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Scroller with the specified interpolator. If the interpolator is
|
||||||
|
* null, the default (viscous) interpolator will be used. Specify whether or
|
||||||
|
* not to support progressive "flywheel" behavior in flinging.
|
||||||
|
*/
|
||||||
|
public Scroller(Context context, Interpolator interpolator, boolean flywheel) {
|
||||||
|
mFinished = true;
|
||||||
|
mInterpolator = interpolator;
|
||||||
|
mPpi = context.getResources().getDisplayMetrics().density * 160.0f;
|
||||||
|
mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction());
|
||||||
|
mFlywheel = flywheel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount of friction applied to flings. The default value
|
||||||
|
* is {@link android.view.ViewConfiguration#getScrollFriction}.
|
||||||
|
*
|
||||||
|
* @param friction A scalar dimension-less value representing the coefficient of
|
||||||
|
* friction.
|
||||||
|
*/
|
||||||
|
public final void setFriction(float friction) {
|
||||||
|
mDeceleration = computeDeceleration(friction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float computeDeceleration(float friction) {
|
||||||
|
return SensorManager.GRAVITY_EARTH // g (m/s^2)
|
||||||
|
* 39.37f // inch/meter
|
||||||
|
* mPpi // pixels per inch
|
||||||
|
* friction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Returns whether the scroller has finished scrolling.
|
||||||
|
*
|
||||||
|
* @return True if the scroller has finished scrolling, false otherwise.
|
||||||
|
*/
|
||||||
|
public final boolean isFinished() {
|
||||||
|
return mFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force the finished field to a particular value.
|
||||||
|
*
|
||||||
|
* @param finished The new finished value.
|
||||||
|
*/
|
||||||
|
public final void forceFinished(boolean finished) {
|
||||||
|
mFinished = finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns how long the scroll event will take, in milliseconds.
|
||||||
|
*
|
||||||
|
* @return The duration of the scroll in milliseconds.
|
||||||
|
*/
|
||||||
|
public final int getDuration() {
|
||||||
|
return mDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current X offset in the scroll.
|
||||||
|
*
|
||||||
|
* @return The new X offset as an absolute distance from the origin.
|
||||||
|
*/
|
||||||
|
public final int getCurrX() {
|
||||||
|
return mCurrX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current Y offset in the scroll.
|
||||||
|
*
|
||||||
|
* @return The new Y offset as an absolute distance from the origin.
|
||||||
|
*/
|
||||||
|
public final int getCurrY() {
|
||||||
|
return mCurrY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current velocity.
|
||||||
|
*
|
||||||
|
* @return The original velocity less the deceleration. Result may be
|
||||||
|
* negative.
|
||||||
|
*/
|
||||||
|
public float getCurrVelocity() {
|
||||||
|
return mVelocity - mDeceleration * timePassed() / 2000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the start X offset in the scroll.
|
||||||
|
*
|
||||||
|
* @return The start X offset as an absolute distance from the origin.
|
||||||
|
*/
|
||||||
|
public final int getStartX() {
|
||||||
|
return mStartX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the start Y offset in the scroll.
|
||||||
|
*
|
||||||
|
* @return The start Y offset as an absolute distance from the origin.
|
||||||
|
*/
|
||||||
|
public final int getStartY() {
|
||||||
|
return mStartY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns where the scroll will end. Valid only for "fling" scrolls.
|
||||||
|
*
|
||||||
|
* @return The final X offset as an absolute distance from the origin.
|
||||||
|
*/
|
||||||
|
public final int getFinalX() {
|
||||||
|
return mFinalX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns where the scroll will end. Valid only for "fling" scrolls.
|
||||||
|
*
|
||||||
|
* @return The final Y offset as an absolute distance from the origin.
|
||||||
|
*/
|
||||||
|
public final int getFinalY() {
|
||||||
|
return mFinalY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this when you want to know the new location. If it returns true,
|
||||||
|
* the animation is not yet finished. loc will be altered to provide the
|
||||||
|
* new location.
|
||||||
|
*/
|
||||||
|
public boolean computeScrollOffset() {
|
||||||
|
if (mFinished) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
|
||||||
|
|
||||||
|
if (timePassed < mDuration) {
|
||||||
|
switch (mMode) {
|
||||||
|
case SCROLL_MODE:
|
||||||
|
float x = timePassed * mDurationReciprocal;
|
||||||
|
|
||||||
|
if (mInterpolator == null)
|
||||||
|
x = viscousFluid(x);
|
||||||
|
else
|
||||||
|
x = mInterpolator.getInterpolation(x);
|
||||||
|
|
||||||
|
mCurrX = mStartX + Math.round(x * mDeltaX);
|
||||||
|
mCurrY = mStartY + Math.round(x * mDeltaY);
|
||||||
|
break;
|
||||||
|
case FLING_MODE:
|
||||||
|
final float t = (float) timePassed / mDuration;
|
||||||
|
final int index = (int) (NB_SAMPLES * t);
|
||||||
|
final float t_inf = (float) index / NB_SAMPLES;
|
||||||
|
final float t_sup = (float) (index + 1) / NB_SAMPLES;
|
||||||
|
final float d_inf = SPLINE[index];
|
||||||
|
final float d_sup = SPLINE[index + 1];
|
||||||
|
final float distanceCoef = d_inf + (t - t_inf) / (t_sup - t_inf) * (d_sup - d_inf);
|
||||||
|
|
||||||
|
mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX));
|
||||||
|
// Pin to mMinX <= mCurrX <= mMaxX
|
||||||
|
mCurrX = Math.min(mCurrX, mMaxX);
|
||||||
|
mCurrX = Math.max(mCurrX, mMinX);
|
||||||
|
|
||||||
|
mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY));
|
||||||
|
// Pin to mMinY <= mCurrY <= mMaxY
|
||||||
|
mCurrY = Math.min(mCurrY, mMaxY);
|
||||||
|
mCurrY = Math.max(mCurrY, mMinY);
|
||||||
|
|
||||||
|
if (mCurrX == mFinalX && mCurrY == mFinalY) {
|
||||||
|
mFinished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mCurrX = mFinalX;
|
||||||
|
mCurrY = mFinalY;
|
||||||
|
mFinished = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start scrolling by providing a starting point and the distance to travel.
|
||||||
|
* The scroll will use the default value of 250 milliseconds for the
|
||||||
|
* duration.
|
||||||
|
*
|
||||||
|
* @param startX Starting horizontal scroll offset in pixels. Positive
|
||||||
|
* numbers will scroll the content to the left.
|
||||||
|
* @param startY Starting vertical scroll offset in pixels. Positive numbers
|
||||||
|
* will scroll the content up.
|
||||||
|
* @param dx Horizontal distance to travel. Positive numbers will scroll the
|
||||||
|
* content to the left.
|
||||||
|
* @param dy Vertical distance to travel. Positive numbers will scroll the
|
||||||
|
* content up.
|
||||||
|
*/
|
||||||
|
public void startScroll(int startX, int startY, int dx, int dy) {
|
||||||
|
startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start scrolling by providing a starting point and the distance to travel.
|
||||||
|
*
|
||||||
|
* @param startX Starting horizontal scroll offset in pixels. Positive
|
||||||
|
* numbers will scroll the content to the left.
|
||||||
|
* @param startY Starting vertical scroll offset in pixels. Positive numbers
|
||||||
|
* will scroll the content up.
|
||||||
|
* @param dx Horizontal distance to travel. Positive numbers will scroll the
|
||||||
|
* content to the left.
|
||||||
|
* @param dy Vertical distance to travel. Positive numbers will scroll the
|
||||||
|
* content up.
|
||||||
|
* @param duration Duration of the scroll in milliseconds.
|
||||||
|
*/
|
||||||
|
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
|
||||||
|
mMode = SCROLL_MODE;
|
||||||
|
mFinished = false;
|
||||||
|
mDuration = duration;
|
||||||
|
mStartTime = AnimationUtils.currentAnimationTimeMillis();
|
||||||
|
mStartX = startX;
|
||||||
|
mStartY = startY;
|
||||||
|
mFinalX = startX + dx;
|
||||||
|
mFinalY = startY + dy;
|
||||||
|
mDeltaX = dx;
|
||||||
|
mDeltaY = dy;
|
||||||
|
mDurationReciprocal = 1.0f / (float) mDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start scrolling based on a fling gesture. The distance travelled will
|
||||||
|
* depend on the initial velocity of the fling.
|
||||||
|
*
|
||||||
|
* @param startX Starting point of the scroll (X)
|
||||||
|
* @param startY Starting point of the scroll (Y)
|
||||||
|
* @param velocityX Initial velocity of the fling (X) measured in pixels per
|
||||||
|
* second.
|
||||||
|
* @param velocityY Initial velocity of the fling (Y) measured in pixels per
|
||||||
|
* second
|
||||||
|
* @param minX Minimum X value. The scroller will not scroll past this
|
||||||
|
* point.
|
||||||
|
* @param maxX Maximum X value. The scroller will not scroll past this
|
||||||
|
* point.
|
||||||
|
* @param minY Minimum Y value. The scroller will not scroll past this
|
||||||
|
* point.
|
||||||
|
* @param maxY Maximum Y value. The scroller will not scroll past this
|
||||||
|
* point.
|
||||||
|
*/
|
||||||
|
public void fling(int startX, int startY, int velocityX, int velocityY,
|
||||||
|
int minX, int maxX, int minY, int maxY) {
|
||||||
|
// Continue a scroll or fling in progress
|
||||||
|
if (mFlywheel && !mFinished) {
|
||||||
|
float oldVel = getCurrVelocity();
|
||||||
|
|
||||||
|
float dx = (float) (mFinalX - mStartX);
|
||||||
|
float dy = (float) (mFinalY - mStartY);
|
||||||
|
float hyp = FloatMath.sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
|
float ndx = dx / hyp;
|
||||||
|
float ndy = dy / hyp;
|
||||||
|
|
||||||
|
float oldVelocityX = ndx * oldVel;
|
||||||
|
float oldVelocityY = ndy * oldVel;
|
||||||
|
if (Math.signum(velocityX) == Math.signum(oldVelocityX) &&
|
||||||
|
Math.signum(velocityY) == Math.signum(oldVelocityY)) {
|
||||||
|
velocityX += oldVelocityX;
|
||||||
|
velocityY += oldVelocityY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mMode = FLING_MODE;
|
||||||
|
mFinished = false;
|
||||||
|
|
||||||
|
float velocity = FloatMath.sqrt(velocityX * velocityX + velocityY * velocityY);
|
||||||
|
|
||||||
|
mVelocity = velocity;
|
||||||
|
float ALPHA = 800;
|
||||||
|
final double l = Math.log(START_TENSION * velocity / ALPHA);
|
||||||
|
mDuration = (int) (1000.0 * Math.exp(l / (DECELERATION_RATE - 1.0)));
|
||||||
|
mStartTime = AnimationUtils.currentAnimationTimeMillis();
|
||||||
|
mStartX = startX;
|
||||||
|
mStartY = startY;
|
||||||
|
|
||||||
|
float coeffX = velocity == 0 ? 1.0f : velocityX / velocity;
|
||||||
|
float coeffY = velocity == 0 ? 1.0f : velocityY / velocity;
|
||||||
|
|
||||||
|
int totalDistance =
|
||||||
|
(int) (ALPHA * Math.exp(DECELERATION_RATE / (DECELERATION_RATE - 1.0) * l));
|
||||||
|
|
||||||
|
mMinX = minX;
|
||||||
|
mMaxX = maxX;
|
||||||
|
mMinY = minY;
|
||||||
|
mMaxY = maxY;
|
||||||
|
|
||||||
|
mFinalX = startX + Math.round(totalDistance * coeffX);
|
||||||
|
// Pin to mMinX <= mFinalX <= mMaxX
|
||||||
|
mFinalX = Math.min(mFinalX, mMaxX);
|
||||||
|
mFinalX = Math.max(mFinalX, mMinX);
|
||||||
|
|
||||||
|
mFinalY = startY + Math.round(totalDistance * coeffY);
|
||||||
|
// Pin to mMinY <= mFinalY <= mMaxY
|
||||||
|
mFinalY = Math.min(mFinalY, mMaxY);
|
||||||
|
mFinalY = Math.max(mFinalY, mMinY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float viscousFluid(float x)
|
||||||
|
{
|
||||||
|
x *= sViscousFluidScale;
|
||||||
|
if (x < 1.0f) {
|
||||||
|
x -= (1.0f - (float)Math.exp(-x));
|
||||||
|
} else {
|
||||||
|
float start = 0.36787944117f; // 1/e == exp(-1)
|
||||||
|
x = 1.0f - (float)Math.exp(1.0f - x);
|
||||||
|
x = start + x * (1.0f - start);
|
||||||
|
}
|
||||||
|
x *= sViscousFluidNormalize;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the animation. Contrary to {@link #forceFinished(boolean)},
|
||||||
|
* aborting the animating cause the scroller to move to the final x and y
|
||||||
|
* position
|
||||||
|
*
|
||||||
|
* @see #forceFinished(boolean)
|
||||||
|
*/
|
||||||
|
public void abortAnimation() {
|
||||||
|
mCurrX = mFinalX;
|
||||||
|
mCurrY = mFinalY;
|
||||||
|
mFinished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend the scroll animation. This allows a running animation to scroll
|
||||||
|
* further and longer, when used with {@link #setFinalX(int)} or {@link #setFinalY(int)}.
|
||||||
|
*
|
||||||
|
* @param extend Additional time to scroll in milliseconds.
|
||||||
|
* @see #setFinalX(int)
|
||||||
|
* @see #setFinalY(int)
|
||||||
|
*/
|
||||||
|
public void extendDuration(int extend) {
|
||||||
|
int passed = timePassed();
|
||||||
|
mDuration = passed + extend;
|
||||||
|
mDurationReciprocal = 1.0f / mDuration;
|
||||||
|
mFinished = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the time elapsed since the beginning of the scrolling.
|
||||||
|
*
|
||||||
|
* @return The elapsed time in milliseconds.
|
||||||
|
*/
|
||||||
|
public int timePassed() {
|
||||||
|
return (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the final position (X) for this scroller.
|
||||||
|
*
|
||||||
|
* @param newX The new X offset as an absolute distance from the origin.
|
||||||
|
* @see #extendDuration(int)
|
||||||
|
* @see #setFinalY(int)
|
||||||
|
*/
|
||||||
|
public void setFinalX(int newX) {
|
||||||
|
mFinalX = newX;
|
||||||
|
mDeltaX = mFinalX - mStartX;
|
||||||
|
mFinished = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the final position (Y) for this scroller.
|
||||||
|
*
|
||||||
|
* @param newY The new Y offset as an absolute distance from the origin.
|
||||||
|
* @see #extendDuration(int)
|
||||||
|
* @see #setFinalX(int)
|
||||||
|
*/
|
||||||
|
public void setFinalY(int newY) {
|
||||||
|
mFinalY = newY;
|
||||||
|
mDeltaY = mFinalY - mStartY;
|
||||||
|
mFinished = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isScrollingInDirection(float xvel, float yvel) {
|
||||||
|
return !mFinished && Math.signum(xvel) == Math.signum(mFinalX - mStartX) &&
|
||||||
|
Math.signum(yvel) == Math.signum(mFinalY - mStartY);
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,6 +51,7 @@
|
||||||
<string name="DeleteChat">حذف وخروج</string>
|
<string name="DeleteChat">حذف وخروج</string>
|
||||||
<string name="HiddenName">الاسم مخفي</string>
|
<string name="HiddenName">الاسم مخفي</string>
|
||||||
<string name="SelectChat">اختر محادثة</string>
|
<string name="SelectChat">اختر محادثة</string>
|
||||||
|
<string name="PhotoTip">إضغط بإستمرار على المستخدم العرض</string>
|
||||||
<string name="CompatibilityChat">%1$s يستخدم إصدار قديم من تيليجرام، لذلك، الصور السرية ستظهر في وضع الموافقة.\n\nعندما يقوم %2$s بتحديث تيليجرام، الصور التي بها عداد دقيقة أو أقل ستعمل بطريقة \"الاستمرار بالضغط للإستعراض\"، وسيتم إخبارك عندما يلتقط المستقبل صورة من شاشته.</string>
|
<string name="CompatibilityChat">%1$s يستخدم إصدار قديم من تيليجرام، لذلك، الصور السرية ستظهر في وضع الموافقة.\n\nعندما يقوم %2$s بتحديث تيليجرام، الصور التي بها عداد دقيقة أو أقل ستعمل بطريقة \"الاستمرار بالضغط للإستعراض\"، وسيتم إخبارك عندما يلتقط المستقبل صورة من شاشته.</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="BroadcastList">قائمة الرسالة الجماعية</string>
|
<string name="BroadcastList">قائمة الرسالة الجماعية</string>
|
||||||
|
@ -201,6 +202,7 @@
|
||||||
<string name="NumberUnknown">غير معروف</string>
|
<string name="NumberUnknown">غير معروف</string>
|
||||||
<string name="Info">معلومات</string>
|
<string name="Info">معلومات</string>
|
||||||
<string name="Phone">هاتف</string>
|
<string name="Phone">هاتف</string>
|
||||||
|
<!--usernames-->
|
||||||
<string name="Username">اسم مستخدم</string>
|
<string name="Username">اسم مستخدم</string>
|
||||||
<string name="UsernamePlaceholder">معرّفك</string>
|
<string name="UsernamePlaceholder">معرّفك</string>
|
||||||
<string name="UsernameInUse">المعذرة، اسم المستخدم تم اختياره مسبقًا.</string>
|
<string name="UsernameInUse">المعذرة، اسم المستخدم تم اختياره مسبقًا.</string>
|
||||||
|
@ -211,8 +213,8 @@
|
||||||
<string name="UsernameHelp">يمكنك اختيار اسم مستخدم في <![CDATA[<b>]]>تيليجرام<![CDATA[</b>]]>. إذا قمت بذلك، سيستطيع الناس إيجادك باستخدام الاسم المستخدم والتواصل معك من دون معرفة رقمك.<![CDATA[<br><br>]]>يمكنك استخدام <![CDATA[<b>]]>حروف اللغة الإنجليزية<![CDATA[</b>]]>, <![CDATA[<b>]]>وأرقامها<![CDATA[</b>]]> و كذلك الخط. لا بد من استخدام <![CDATA[<b>]]>٥<![CDATA[</b>]]> حروف على الأقل.</string>
|
<string name="UsernameHelp">يمكنك اختيار اسم مستخدم في <![CDATA[<b>]]>تيليجرام<![CDATA[</b>]]>. إذا قمت بذلك، سيستطيع الناس إيجادك باستخدام الاسم المستخدم والتواصل معك من دون معرفة رقمك.<![CDATA[<br><br>]]>يمكنك استخدام <![CDATA[<b>]]>حروف اللغة الإنجليزية<![CDATA[</b>]]>, <![CDATA[<b>]]>وأرقامها<![CDATA[</b>]]> و كذلك الخط. لا بد من استخدام <![CDATA[<b>]]>٥<![CDATA[</b>]]> حروف على الأقل.</string>
|
||||||
<string name="UsernameChecking">جاري مراجعة اسم المستخدم...</string>
|
<string name="UsernameChecking">جاري مراجعة اسم المستخدم...</string>
|
||||||
<string name="UsernameAvailable">%1$s متاح.</string>
|
<string name="UsernameAvailable">%1$s متاح.</string>
|
||||||
<string name="UsernameEmpty">None</string>
|
<string name="UsernameEmpty">لا يوجد</string>
|
||||||
<string name="ErrorOccurred">An error occurred</string>
|
<string name="ErrorOccurred">حدث خطأ.</string>
|
||||||
<!--settings view-->
|
<!--settings view-->
|
||||||
<string name="ResetNotificationsText">تم تعيين كافة الإشعارات افتراضيا</string>
|
<string name="ResetNotificationsText">تم تعيين كافة الإشعارات افتراضيا</string>
|
||||||
<string name="TextSize">حجم نص الرسائل</string>
|
<string name="TextSize">حجم نص الرسائل</string>
|
||||||
|
@ -384,6 +386,7 @@
|
||||||
<string name="ForwardFromMyName">أعد الإرسال باستخدام اسمي</string>
|
<string name="ForwardFromMyName">أعد الإرسال باستخدام اسمي</string>
|
||||||
<string name="SendMessagesToGroup">هل ترغب في إرسال رسالة إلى %1$s؟</string>
|
<string name="SendMessagesToGroup">هل ترغب في إرسال رسالة إلى %1$s؟</string>
|
||||||
<string name="ForwardMessagesToGroup">؟%1$s هل تريد إعادة توجيه الرسائل إلى</string>
|
<string name="ForwardMessagesToGroup">؟%1$s هل تريد إعادة توجيه الرسائل إلى</string>
|
||||||
|
<string name="FeatureUnavailable">.Sorry, this feature is currently not available in your country</string>
|
||||||
<!--Intro view-->
|
<!--Intro view-->
|
||||||
<string name="Page1Title">تيليجرام</string>
|
<string name="Page1Title">تيليجرام</string>
|
||||||
<string name="Page2Title">سريع</string>
|
<string name="Page2Title">سريع</string>
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
<string name="DeleteChat">Löschen und beenden</string>
|
<string name="DeleteChat">Löschen und beenden</string>
|
||||||
<string name="HiddenName">Versteckter Name</string>
|
<string name="HiddenName">Versteckter Name</string>
|
||||||
<string name="SelectChat">Chat auswählen</string>
|
<string name="SelectChat">Chat auswählen</string>
|
||||||
|
<string name="PhotoTip">Tippen und Halten</string>
|
||||||
<string name="CompatibilityChat">%1$s benutzt eine ältere Version von Telegram, sodass Fotos in Geheimen Chats im Kompatibilitätsmodus angezeigt werden.\n\nSobald %2$s Telegram aktualisiert, werden Fotos mit Timern von 1 Minute und kürzer per \"Tippen und Halten\" angezeigt. Du wirst benachrichtigt, sobald dein Chatpartner ein Bildschirmfoto macht.</string>
|
<string name="CompatibilityChat">%1$s benutzt eine ältere Version von Telegram, sodass Fotos in Geheimen Chats im Kompatibilitätsmodus angezeigt werden.\n\nSobald %2$s Telegram aktualisiert, werden Fotos mit Timern von 1 Minute und kürzer per \"Tippen und Halten\" angezeigt. Du wirst benachrichtigt, sobald dein Chatpartner ein Bildschirmfoto macht.</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="BroadcastList">Broadcast Liste</string>
|
<string name="BroadcastList">Broadcast Liste</string>
|
||||||
|
@ -201,6 +202,7 @@
|
||||||
<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>
|
||||||
|
<!--usernames-->
|
||||||
<string name="Username">Benutzername</string>
|
<string name="Username">Benutzername</string>
|
||||||
<string name="UsernamePlaceholder">Dein Benutzername</string>
|
<string name="UsernamePlaceholder">Dein Benutzername</string>
|
||||||
<string name="UsernameInUse">Leider ist dieser Benutzername vergeben.</string>
|
<string name="UsernameInUse">Leider ist dieser Benutzername vergeben.</string>
|
||||||
|
@ -208,11 +210,11 @@
|
||||||
<string name="UsernameInvalidShort">Ein Benutzername benötigt mindestens 5 Zeichen.</string>
|
<string name="UsernameInvalidShort">Ein Benutzername benötigt mindestens 5 Zeichen.</string>
|
||||||
<string name="UsernameInvalidLong">Ein Benutzername darf maximal 32 Zeichen haben.</string>
|
<string name="UsernameInvalidLong">Ein Benutzername darf maximal 32 Zeichen haben.</string>
|
||||||
<string name="UsernameInvalidStartNumber">Benutzernamen dürfen leider nicht mit einer Zahl anfangen.</string>
|
<string name="UsernameInvalidStartNumber">Benutzernamen dürfen leider nicht mit einer Zahl anfangen.</string>
|
||||||
<string name="UsernameHelp">Wähle einen Benutzernamen, wenn du von anderen bei<![CDATA[<b>]]>Telegram<![CDATA[</b>]]>gefunden werden willst – ohne, dass sie deine Nummer kennen müssen.<![CDATA[<br><br>]]>Erlaubt sind <![CDATA[<b>]]>a–z<![CDATA[<b>]]>, <![CDATA[<b>]]>0–9<![CDATA[<b>]]> und Unterstriche. Die Mindestlänge beträgt <![CDATA[<b>]]>5<![CDATA[<b>]]> Zeichen.</string>
|
<string name="UsernameHelp">Wähle einen Benutzernamen, wenn du von anderen bei<![CDATA[<b>]]>Telegram<![CDATA[</b>]]>gefunden werden willst — ohne, dass sie deine Nummer kennen müssen.<![CDATA[<br><br>]]>Erlaubt sind <![CDATA[<b>]]>a-z<![CDATA[<b>]]>, <![CDATA[<b>]]>0-9<![CDATA[<b>]]> und Unterstriche. Die Mindestlänge beträgt <![CDATA[<b>]]>5<![CDATA[<b>]]> Zeichen.</string>
|
||||||
<string name="UsernameChecking">Prüfe Benutzername...</string>
|
<string name="UsernameChecking">Prüfe Benutzername...</string>
|
||||||
<string name="UsernameAvailable">%1$s ist verfügbar.</string>
|
<string name="UsernameAvailable">%1$s ist verfügbar.</string>
|
||||||
<string name="UsernameEmpty">None</string>
|
<string name="UsernameEmpty">Keiner</string>
|
||||||
<string name="ErrorOccurred">An error occurred</string>
|
<string name="ErrorOccurred">Es ist ein Fehler aufgetreten.</string>
|
||||||
<!--settings view-->
|
<!--settings view-->
|
||||||
<string name="ResetNotificationsText">Alle Einstellungen für Mitteilungen zurücksetzen</string>
|
<string name="ResetNotificationsText">Alle Einstellungen für Mitteilungen zurücksetzen</string>
|
||||||
<string name="TextSize">Textgröße für Nachrichten</string>
|
<string name="TextSize">Textgröße für Nachrichten</string>
|
||||||
|
@ -384,6 +386,7 @@
|
||||||
<string name="ForwardFromMyName">mit meinem Namen weiterleiten</string>
|
<string name="ForwardFromMyName">mit meinem Namen weiterleiten</string>
|
||||||
<string name="SendMessagesToGroup">Nachricht an %1$s senden?</string>
|
<string name="SendMessagesToGroup">Nachricht an %1$s senden?</string>
|
||||||
<string name="ForwardMessagesToGroup">Weiterleiten an %1$s?</string>
|
<string name="ForwardMessagesToGroup">Weiterleiten an %1$s?</string>
|
||||||
|
<string name="FeatureUnavailable">Sorry, this feature is currently not available in your country.</string>
|
||||||
<!--Intro view-->
|
<!--Intro view-->
|
||||||
<string name="Page1Title">Telegram</string>
|
<string name="Page1Title">Telegram</string>
|
||||||
<string name="Page2Title">Schnell</string>
|
<string name="Page2Title">Schnell</string>
|
||||||
|
|
|
@ -22,10 +22,10 @@
|
||||||
<string name="DidNotGetTheCode">¿No recibiste el código?</string>
|
<string name="DidNotGetTheCode">¿No recibiste el código?</string>
|
||||||
<!--signup view-->
|
<!--signup view-->
|
||||||
<string name="YourName">Tu nombre</string>
|
<string name="YourName">Tu nombre</string>
|
||||||
<string name="RegisterText">Ingresa tu nombre y apellido</string>
|
<string name="RegisterText">Ingresa tu nombre y apellidos</string>
|
||||||
<!--<string name="RegisterText">Set up your name and picture</string>-->
|
<!--<string name="RegisterText">Set up your name and picture</string>-->
|
||||||
<string name="FirstName">Nombre (requerido)</string>
|
<string name="FirstName">Nombre (requerido)</string>
|
||||||
<string name="LastName">Apellido (opcional)</string>
|
<string name="LastName">Apellidos (opcional)</string>
|
||||||
<string name="CancelRegistration">Cancelar registro</string>
|
<string name="CancelRegistration">Cancelar registro</string>
|
||||||
<!--chats view-->
|
<!--chats view-->
|
||||||
<string name="Chats">Chats</string>
|
<string name="Chats">Chats</string>
|
||||||
|
@ -51,6 +51,7 @@
|
||||||
<string name="DeleteChat">Eliminar y salir</string>
|
<string name="DeleteChat">Eliminar y salir</string>
|
||||||
<string name="HiddenName">Nombre oculto</string>
|
<string name="HiddenName">Nombre oculto</string>
|
||||||
<string name="SelectChat">Elige el chat</string>
|
<string name="SelectChat">Elige el chat</string>
|
||||||
|
<string name="PhotoTip">Mantén pulsado para ver</string>
|
||||||
<string name="CompatibilityChat">%1$s usa una versión antigua de Telegram, así que las fotos secretas serán mostradas en un modo de compatibilidad.\n\nCuando %2$s actualice Telegram, las fotos con autodestrucción de 1 minuto o menos funcionarán con el modo \'Mantén pulsado para ver\', y te notificaremos siempre que la otra parte haga una captura de pantalla.</string>
|
<string name="CompatibilityChat">%1$s usa una versión antigua de Telegram, así que las fotos secretas serán mostradas en un modo de compatibilidad.\n\nCuando %2$s actualice Telegram, las fotos con autodestrucción de 1 minuto o menos funcionarán con el modo \'Mantén pulsado para ver\', y te notificaremos siempre que la otra parte haga una captura de pantalla.</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="BroadcastList">Lista de difusión</string>
|
<string name="BroadcastList">Lista de difusión</string>
|
||||||
|
@ -201,6 +202,7 @@
|
||||||
<string name="NumberUnknown">Desconocido</string>
|
<string name="NumberUnknown">Desconocido</string>
|
||||||
<string name="Info">INFORMACIÓN</string>
|
<string name="Info">INFORMACIÓN</string>
|
||||||
<string name="Phone">Teléfono</string>
|
<string name="Phone">Teléfono</string>
|
||||||
|
<!--usernames-->
|
||||||
<string name="Username">Apodo</string>
|
<string name="Username">Apodo</string>
|
||||||
<string name="UsernamePlaceholder">Tu apodo</string>
|
<string name="UsernamePlaceholder">Tu apodo</string>
|
||||||
<string name="UsernameInUse">Lo siento, este apodo ya está ocupado.</string>
|
<string name="UsernameInUse">Lo siento, este apodo ya está ocupado.</string>
|
||||||
|
@ -211,8 +213,8 @@
|
||||||
<string name="UsernameHelp">Puedes elegir un apodo en <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. Si lo haces, otras personas te podrán encontrar por ese apodo y contactarte sin saber tu número de teléfono.<![CDATA[<br><br>]]>Puedes usar <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> y guiones bajos. La longitud mínima es de <![CDATA[<b>]]>5<![CDATA[</b>]]> caracteres.</string>
|
<string name="UsernameHelp">Puedes elegir un apodo en <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. Si lo haces, otras personas te podrán encontrar por ese apodo y contactarte sin saber tu número de teléfono.<![CDATA[<br><br>]]>Puedes usar <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> y guiones bajos. La longitud mínima es de <![CDATA[<b>]]>5<![CDATA[</b>]]> caracteres.</string>
|
||||||
<string name="UsernameChecking">Verificando apodo...</string>
|
<string name="UsernameChecking">Verificando apodo...</string>
|
||||||
<string name="UsernameAvailable">%1$s está disponible.</string>
|
<string name="UsernameAvailable">%1$s está disponible.</string>
|
||||||
<string name="UsernameEmpty">None</string>
|
<string name="UsernameEmpty">Ninguno</string>
|
||||||
<string name="ErrorOccurred">An error occurred</string>
|
<string name="ErrorOccurred">Ocurrió un error.</string>
|
||||||
<!--settings view-->
|
<!--settings view-->
|
||||||
<string name="ResetNotificationsText">Restablecer las notificaciones</string>
|
<string name="ResetNotificationsText">Restablecer las notificaciones</string>
|
||||||
<string name="TextSize">Tamaño del texto</string>
|
<string name="TextSize">Tamaño del texto</string>
|
||||||
|
@ -238,7 +240,7 @@
|
||||||
<string name="BlockedUsers">Usuarios bloqueados</string>
|
<string name="BlockedUsers">Usuarios bloqueados</string>
|
||||||
<string name="SaveIncomingPhotos">Guardar fotos entrantes</string>
|
<string name="SaveIncomingPhotos">Guardar fotos entrantes</string>
|
||||||
<string name="LogOut">Cerrar sesión</string>
|
<string name="LogOut">Cerrar sesión</string>
|
||||||
<string name="YourFirstNameAndLastName">TU NOMBRE Y APELLIDO</string>
|
<string name="YourFirstNameAndLastName">TU NOMBRE Y APELLIDOS</string>
|
||||||
<string name="NoSound">Sin sonido</string>
|
<string name="NoSound">Sin sonido</string>
|
||||||
<string name="Default">Por defecto</string>
|
<string name="Default">Por defecto</string>
|
||||||
<string name="Support">SOPORTE</string>
|
<string name="Support">SOPORTE</string>
|
||||||
|
@ -264,7 +266,7 @@
|
||||||
<string name="ImportContacts">Importar contactos</string>
|
<string name="ImportContacts">Importar contactos</string>
|
||||||
<string name="WiFiOnly">Sólo vía Wi-Fi</string>
|
<string name="WiFiOnly">Sólo vía Wi-Fi</string>
|
||||||
<string name="SortFirstName">Nombre</string>
|
<string name="SortFirstName">Nombre</string>
|
||||||
<string name="SortLastName">Apellido</string>
|
<string name="SortLastName">Apellidos</string>
|
||||||
<string name="LedColor">Color del LED</string>
|
<string name="LedColor">Color del LED</string>
|
||||||
<string name="PopupNotification">Notificaciones emergentes</string>
|
<string name="PopupNotification">Notificaciones emergentes</string>
|
||||||
<string name="NoPopup">Desactivadas</string>
|
<string name="NoPopup">Desactivadas</string>
|
||||||
|
@ -360,7 +362,7 @@
|
||||||
<string name="FloodWait">Muchos intentos. Por favor, inténtalo más tarde.</string>
|
<string name="FloodWait">Muchos intentos. Por favor, inténtalo más tarde.</string>
|
||||||
<string name="InvalidCode">Código inválido</string>
|
<string name="InvalidCode">Código inválido</string>
|
||||||
<string name="InvalidFirstName">Nombre inválido</string>
|
<string name="InvalidFirstName">Nombre inválido</string>
|
||||||
<string name="InvalidLastName">Apellido inválido</string>
|
<string name="InvalidLastName">Apellidos inválidos</string>
|
||||||
<string name="Loading">Cargando...</string>
|
<string name="Loading">Cargando...</string>
|
||||||
<string name="NoPlayerInstalled">No tienes reproductor de vídeo. Por favor, instala uno para continuar.</string>
|
<string name="NoPlayerInstalled">No tienes reproductor de vídeo. Por favor, instala uno para continuar.</string>
|
||||||
<string name="NoMailInstalled">Por favor, envíanos un correo electrónico a sms@telegram.org y cuéntanos tu problema.</string>
|
<string name="NoMailInstalled">Por favor, envíanos un correo electrónico a sms@telegram.org y cuéntanos tu problema.</string>
|
||||||
|
@ -384,6 +386,7 @@
|
||||||
<string name="ForwardFromMyName">reenviar desde mi nombre</string>
|
<string name="ForwardFromMyName">reenviar desde mi nombre</string>
|
||||||
<string name="SendMessagesToGroup">¿Enviar mensajes a %1$s?</string>
|
<string name="SendMessagesToGroup">¿Enviar mensajes a %1$s?</string>
|
||||||
<string name="ForwardMessagesToGroup">¿Reenviar mensajes a %1$s?</string>
|
<string name="ForwardMessagesToGroup">¿Reenviar mensajes a %1$s?</string>
|
||||||
|
<string name="FeatureUnavailable">Sorry, this feature is currently not available in your country.</string>
|
||||||
<!--Intro view-->
|
<!--Intro view-->
|
||||||
<string name="Page1Title">Telegram</string>
|
<string name="Page1Title">Telegram</string>
|
||||||
<string name="Page2Title">Rápida</string>
|
<string name="Page2Title">Rápida</string>
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
<string name="DeleteChat">Elimina ed esci</string>
|
<string name="DeleteChat">Elimina ed esci</string>
|
||||||
<string name="HiddenName">Nome nascosto</string>
|
<string name="HiddenName">Nome nascosto</string>
|
||||||
<string name="SelectChat">Seleziona chat</string>
|
<string name="SelectChat">Seleziona chat</string>
|
||||||
|
<string name="PhotoTip">Tieni premuto per vedere</string>
|
||||||
<string name="CompatibilityChat">%1$s sta usando una versione vecchia di Telegram, quindi le foto segrete verranno visualizzate in modalità di compatibilità.\n\nUna volta che %2$s avrà aggiornato Telegram, le foto con il timer minore di 1 minuto funzioneranno in modalità \'Tieni premuto per vedere\' , e verrai notificato ogni volta che l\'altro esegue uno screenshot.</string>
|
<string name="CompatibilityChat">%1$s sta usando una versione vecchia di Telegram, quindi le foto segrete verranno visualizzate in modalità di compatibilità.\n\nUna volta che %2$s avrà aggiornato Telegram, le foto con il timer minore di 1 minuto funzioneranno in modalità \'Tieni premuto per vedere\' , e verrai notificato ogni volta che l\'altro esegue uno screenshot.</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="BroadcastList">Lista broadcast</string>
|
<string name="BroadcastList">Lista broadcast</string>
|
||||||
|
@ -201,6 +202,7 @@
|
||||||
<string name="NumberUnknown">Sconosciuto</string>
|
<string name="NumberUnknown">Sconosciuto</string>
|
||||||
<string name="Info">INFO</string>
|
<string name="Info">INFO</string>
|
||||||
<string name="Phone">Telefono</string>
|
<string name="Phone">Telefono</string>
|
||||||
|
<!--usernames-->
|
||||||
<string name="Username">Nome utente</string>
|
<string name="Username">Nome utente</string>
|
||||||
<string name="UsernamePlaceholder">Il tuo Nome Utente</string>
|
<string name="UsernamePlaceholder">Il tuo Nome Utente</string>
|
||||||
<string name="UsernameInUse">Nome utente già preso.</string>
|
<string name="UsernameInUse">Nome utente già preso.</string>
|
||||||
|
@ -211,8 +213,8 @@
|
||||||
<string name="UsernameHelp">Puoi scegliere un nome utente su <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. Se lo fai, le altre persone potranno trovarti tramite questo nome utente e contattarti senza conoscere il tuo numero di telefono.<![CDATA[<br><br>]]>Puoi usare <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> e underscore. La lunghezza minima è di <![CDATA[<b>]]>5<![CDATA[</b>]]> caratteri.</string>
|
<string name="UsernameHelp">Puoi scegliere un nome utente su <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. Se lo fai, le altre persone potranno trovarti tramite questo nome utente e contattarti senza conoscere il tuo numero di telefono.<![CDATA[<br><br>]]>Puoi usare <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> e underscore. La lunghezza minima è di <![CDATA[<b>]]>5<![CDATA[</b>]]> caratteri.</string>
|
||||||
<string name="UsernameChecking">Controllando il nome utente...</string>
|
<string name="UsernameChecking">Controllando il nome utente...</string>
|
||||||
<string name="UsernameAvailable">%1$s è disponibile.</string>
|
<string name="UsernameAvailable">%1$s è disponibile.</string>
|
||||||
<string name="UsernameEmpty">None</string>
|
<string name="UsernameEmpty">Nessuno</string>
|
||||||
<string name="ErrorOccurred">An error occurred</string>
|
<string name="ErrorOccurred">Si è verificato un errore.</string>
|
||||||
<!--settings view-->
|
<!--settings view-->
|
||||||
<string name="ResetNotificationsText">Ripristina tutte le impostazioni di notifica predefinite</string>
|
<string name="ResetNotificationsText">Ripristina tutte le impostazioni di notifica predefinite</string>
|
||||||
<string name="TextSize">Dimensione testo messaggi</string>
|
<string name="TextSize">Dimensione testo messaggi</string>
|
||||||
|
@ -384,6 +386,7 @@
|
||||||
<string name="ForwardFromMyName">inoltra dal mio nome</string>
|
<string name="ForwardFromMyName">inoltra dal mio nome</string>
|
||||||
<string name="SendMessagesToGroup">Inviare messaggi a %1$s?</string>
|
<string name="SendMessagesToGroup">Inviare messaggi a %1$s?</string>
|
||||||
<string name="ForwardMessagesToGroup">Inoltra messaggi a %1$s?</string>
|
<string name="ForwardMessagesToGroup">Inoltra messaggi a %1$s?</string>
|
||||||
|
<string name="FeatureUnavailable">Ci spiace, questa funzione non è disponibile nel tuo paese.</string>
|
||||||
<!--Intro view-->
|
<!--Intro view-->
|
||||||
<string name="Page1Title">Telegram</string>
|
<string name="Page1Title">Telegram</string>
|
||||||
<string name="Page2Title">Veloce</string>
|
<string name="Page2Title">Veloce</string>
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<string name="NoResult">결과 없음</string>
|
<string name="NoResult">결과 없음</string>
|
||||||
<string name="NoChats">채팅방이 없습니다...</string>
|
<string name="NoChats">채팅방이 없습니다...</string>
|
||||||
<string name="NoChatsHelp">대화를 시작하려면 우측 상단의\n초대하기 버튼을 누르거나\n메뉴 버튼을 눌러 보세요.</string>
|
<string name="NoChatsHelp">대화를 시작하려면 우측 상단의\n초대하기 버튼을 누르거나\n메뉴 버튼을 눌러 보세요.</string>
|
||||||
<string name="WaitingForNetwork">네트워크 연결을 기다리는 중...</string>
|
<string name="WaitingForNetwork">대기 중...</string>
|
||||||
<string name="Connecting">연결 중...</string>
|
<string name="Connecting">연결 중...</string>
|
||||||
<string name="Updating">업데이트 중...</string>
|
<string name="Updating">업데이트 중...</string>
|
||||||
<string name="NewSecretChat">비밀대화 시작</string>
|
<string name="NewSecretChat">비밀대화 시작</string>
|
||||||
|
@ -51,6 +51,8 @@
|
||||||
<string name="DeleteChat">채팅방 나가기</string>
|
<string name="DeleteChat">채팅방 나가기</string>
|
||||||
<string name="HiddenName">숨긴 이름</string>
|
<string name="HiddenName">숨긴 이름</string>
|
||||||
<string name="SelectChat">채팅방 선택</string>
|
<string name="SelectChat">채팅방 선택</string>
|
||||||
|
<string name="PhotoTip">꾹 눌러서 보기</string>
|
||||||
|
<string name="CompatibilityChat">%1$s님의 텔레그램 버전이 낮아 비밀 사진을 호환성 모드로 표시합니다.\n\n%2$s님이 텔레그램을 업데이트하고 나면, 자동삭제 시간이 1분 이하인 사진은 \"탭하고 누르고 있어야 보임\" 상태가 되며, 상대방이 화면을 캡처할 때 마다 알림을 받습니다.</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="BroadcastList">단체 메시지 리스트</string>
|
<string name="BroadcastList">단체 메시지 리스트</string>
|
||||||
<string name="NewBroadcastList">새 단체 메시지 리스트</string>
|
<string name="NewBroadcastList">새 단체 메시지 리스트</string>
|
||||||
|
@ -160,7 +162,7 @@
|
||||||
<string name="LastSeen">마지막 접속: </string>
|
<string name="LastSeen">마지막 접속: </string>
|
||||||
<string name="LastSeenDate">마지막 접속: </string>
|
<string name="LastSeenDate">마지막 접속: </string>
|
||||||
<string name="InviteFriends">친구 초대</string>
|
<string name="InviteFriends">친구 초대</string>
|
||||||
<string name="GlobalSearch">GLOBAL SEARCH</string>
|
<string name="GlobalSearch">전체 검색</string>
|
||||||
<!--group create view-->
|
<!--group create view-->
|
||||||
<string name="SendMessageTo">메시지 보내기...</string>
|
<string name="SendMessageTo">메시지 보내기...</string>
|
||||||
<string name="EnterGroupNamePlaceholder">그룹 이름 입력</string>
|
<string name="EnterGroupNamePlaceholder">그룹 이름 입력</string>
|
||||||
|
@ -197,21 +199,22 @@
|
||||||
<string name="MessageLifetime">자동삭제 타이머</string>
|
<string name="MessageLifetime">자동삭제 타이머</string>
|
||||||
<string name="ShortMessageLifetimeForever">해제</string>
|
<string name="ShortMessageLifetimeForever">해제</string>
|
||||||
<string name="EncryptionKeyDescription">이 이미지는 <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>님과의 비밀대화에 사용 중인 암호화 키의 모습입니다.<![CDATA[<br><br>]]>이 이미지가 <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>님의 암호화 키와 똑같다면 대화는 200%% 안전합니다.<![CDATA[<br><br>]]>더 자세한 사항은 telegram.org 를 참고해 주세요.</string>
|
<string name="EncryptionKeyDescription">이 이미지는 <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>님과의 비밀대화에 사용 중인 암호화 키의 모습입니다.<![CDATA[<br><br>]]>이 이미지가 <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>님의 암호화 키와 똑같다면 대화는 200%% 안전합니다.<![CDATA[<br><br>]]>더 자세한 사항은 telegram.org 를 참고해 주세요.</string>
|
||||||
<string name="NumberUnknown">Unknown</string>
|
<string name="NumberUnknown">알 수 없음</string>
|
||||||
<string name="Info">INFO</string>
|
<string name="Info">정보</string>
|
||||||
<string name="Phone">전화번호</string>
|
<string name="Phone">전화번호</string>
|
||||||
<string name="Username">Username</string>
|
<!--usernames-->
|
||||||
<string name="UsernamePlaceholder">Your Username</string>
|
<string name="Username">아이디</string>
|
||||||
<string name="UsernameInUse">Sorry, this username is already taken.</string>
|
<string name="UsernamePlaceholder">아이디</string>
|
||||||
<string name="UsernameInvalid">Sorry, this username is invalid.</string>
|
<string name="UsernameInUse">이미 사용 중인 아이디입니다.</string>
|
||||||
<string name="UsernameInvalidShort">A username must have at least 5 characters.</string>
|
<string name="UsernameInvalid">올바른 아이디를 입력하세요.</string>
|
||||||
<string name="UsernameInvalidLong">A username must have maximum 32 characters.</string>
|
<string name="UsernameInvalidShort">아이디는 최소 다섯 글자 이상 입력해야 합니다.</string>
|
||||||
<string name="UsernameInvalidStartNumber">Sorry, a username can\'t start with a number.</string>
|
<string name="UsernameInvalidLong">아이디는 최대 32자까지만 가능합니다.</string>
|
||||||
<string name="UsernameHelp">You can choose a username on <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. If you do, other people will be able to find you by this username and contact you without knowing your phone number.<![CDATA[<br><br>]]>You can use <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> and underscores. Minimum length is <![CDATA[<b>]]>5<![CDATA[</b>]]> characters.</string>
|
<string name="UsernameInvalidStartNumber">아이디는 숫자로 시작할 수 없습니다.</string>
|
||||||
<string name="UsernameChecking">Checking username...</string>
|
<string name="UsernameHelp">텔레그램 아이디를 설정할 수 있습니다. 아이디를 설정하면 회원님의 전화번호를 몰라도 아이디로 회원님을 찾아 대화를 나눌 수 있습니다.<![CDATA[<br><br>]]>아이디는 영문, 밑줄, 숫자로 (<![CDATA[<b>]]>a~z<![CDATA[</b>]]>, <![CDATA[<b>]]>_<![CDATA[</b>]]>, <![CDATA[<b>]]>0~9<![CDATA[</b>]]>) <![CDATA[<b>]]>다섯 글자<![CDATA[</b>]]> 이상으로 설정해 주세요.</string>
|
||||||
<string name="UsernameAvailable">%1$s is available.</string>
|
<string name="UsernameChecking">아이디 확인 중...</string>
|
||||||
<string name="UsernameEmpty">None</string>
|
<string name="UsernameAvailable">%1$s: 사용 가능합니다.</string>
|
||||||
<string name="ErrorOccurred">An error occurred</string>
|
<string name="UsernameEmpty">없음</string>
|
||||||
|
<string name="ErrorOccurred">오류가 발생했습니다.</string>
|
||||||
<!--settings view-->
|
<!--settings view-->
|
||||||
<string name="ResetNotificationsText">모든 알림 설정이 초기화되었습니다</string>
|
<string name="ResetNotificationsText">모든 알림 설정이 초기화되었습니다</string>
|
||||||
<string name="TextSize">채팅 글자 크기</string>
|
<string name="TextSize">채팅 글자 크기</string>
|
||||||
|
@ -383,6 +386,7 @@
|
||||||
<string name="ForwardFromMyName">내 이름으로 전달</string>
|
<string name="ForwardFromMyName">내 이름으로 전달</string>
|
||||||
<string name="SendMessagesToGroup">%1$s 그룹에 메시지를 보낼까요?</string>
|
<string name="SendMessagesToGroup">%1$s 그룹에 메시지를 보낼까요?</string>
|
||||||
<string name="ForwardMessagesToGroup">%1$s 그룹에 메시지를 전달할까요?</string>
|
<string name="ForwardMessagesToGroup">%1$s 그룹에 메시지를 전달할까요?</string>
|
||||||
|
<string name="FeatureUnavailable">이 기능은 회원님의 국가에서는 사용할 수 없습니다.</string>
|
||||||
<!--Intro view-->
|
<!--Intro view-->
|
||||||
<string name="Page1Title">텔레그램</string>
|
<string name="Page1Title">텔레그램</string>
|
||||||
<string name="Page2Title">눈부신 속도</string>
|
<string name="Page2Title">눈부신 속도</string>
|
||||||
|
@ -436,36 +440,36 @@
|
||||||
<string name="FromContacts_few">채팅방 %1$d개에서</string>
|
<string name="FromContacts_few">채팅방 %1$d개에서</string>
|
||||||
<string name="FromContacts_many">채팅방 %1$d개에서</string>
|
<string name="FromContacts_many">채팅방 %1$d개에서</string>
|
||||||
<string name="FromContacts_other">채팅방 %1$d개에서</string>
|
<string name="FromContacts_other">채팅방 %1$d개에서</string>
|
||||||
<string name="Seconds_zero">%1$d seconds</string>
|
<string name="Seconds_zero">%1$d초</string>
|
||||||
<string name="Seconds_one">%1$d second</string>
|
<string name="Seconds_one">%1$d초</string>
|
||||||
<string name="Seconds_two">%1$d seconds</string>
|
<string name="Seconds_two">%1$d초</string>
|
||||||
<string name="Seconds_few">%1$d seconds</string>
|
<string name="Seconds_few">%1$d초</string>
|
||||||
<string name="Seconds_many">%1$d seconds</string>
|
<string name="Seconds_many">%1$d초</string>
|
||||||
<string name="Seconds_other">%1$d seconds</string>
|
<string name="Seconds_other">%1$d초</string>
|
||||||
<string name="Minutes_zero">%1$d minutes</string>
|
<string name="Minutes_zero">%1$d분</string>
|
||||||
<string name="Minutes_one">%1$d minute</string>
|
<string name="Minutes_one">%1$d분</string>
|
||||||
<string name="Minutes_two">%1$d minutes</string>
|
<string name="Minutes_two">%1$d분</string>
|
||||||
<string name="Minutes_few">%1$d minutes</string>
|
<string name="Minutes_few">%1$d분</string>
|
||||||
<string name="Minutes_many">%1$d minutes</string>
|
<string name="Minutes_many">%1$d분</string>
|
||||||
<string name="Minutes_other">%1$d minutes</string>
|
<string name="Minutes_other">%1$d분</string>
|
||||||
<string name="Hours_zero">%1$d hours</string>
|
<string name="Hours_zero">%1$d시간</string>
|
||||||
<string name="Hours_one">%1$d hour</string>
|
<string name="Hours_one">%1$d시간</string>
|
||||||
<string name="Hours_two">%1$d hours</string>
|
<string name="Hours_two">%1$d시간</string>
|
||||||
<string name="Hours_few">%1$d hours</string>
|
<string name="Hours_few">%1$d시간</string>
|
||||||
<string name="Hours_many">%1$d hours</string>
|
<string name="Hours_many">%1$d시간</string>
|
||||||
<string name="Hours_other">%1$d hours</string>
|
<string name="Hours_other">%1$d시간</string>
|
||||||
<string name="Days_zero">%1$d days</string>
|
<string name="Days_zero">%1$d일</string>
|
||||||
<string name="Days_one">%1$d day</string>
|
<string name="Days_one">%1$d일</string>
|
||||||
<string name="Days_two">%1$d days</string>
|
<string name="Days_two">%1$d일</string>
|
||||||
<string name="Days_few">%1$d days</string>
|
<string name="Days_few">%1$d일</string>
|
||||||
<string name="Days_many">%1$d days</string>
|
<string name="Days_many">%1$d일</string>
|
||||||
<string name="Days_other">%1$d days</string>
|
<string name="Days_other">%1$d일</string>
|
||||||
<string name="Weeks_zero">%1$d weeks</string>
|
<string name="Weeks_zero">%1$d주</string>
|
||||||
<string name="Weeks_one">%1$d week</string>
|
<string name="Weeks_one">%1$d주</string>
|
||||||
<string name="Weeks_two">%1$d weeks</string>
|
<string name="Weeks_two">%1$d주</string>
|
||||||
<string name="Weeks_few">%1$d weeks</string>
|
<string name="Weeks_few">%1$d주</string>
|
||||||
<string name="Weeks_many">%1$d weeks</string>
|
<string name="Weeks_many">%1$d주</string>
|
||||||
<string name="Weeks_other">%1$d weeks</string>
|
<string name="Weeks_other">%1$d주</string>
|
||||||
<!--date formatters-->
|
<!--date formatters-->
|
||||||
<string name="formatterMonth">M\'월\' d\'일\'</string>
|
<string name="formatterMonth">M\'월\' d\'일\'</string>
|
||||||
<string name="formatterYear">yyyy.MM.dd.</string>
|
<string name="formatterYear">yyyy.MM.dd.</string>
|
||||||
|
|
|
@ -51,7 +51,8 @@
|
||||||
<string name="DeleteChat">Verwijderen en verlaten</string>
|
<string name="DeleteChat">Verwijderen en verlaten</string>
|
||||||
<string name="HiddenName">Verborgen naam</string>
|
<string name="HiddenName">Verborgen naam</string>
|
||||||
<string name="SelectChat">Kies een gesprek</string>
|
<string name="SelectChat">Kies een gesprek</string>
|
||||||
<string name="CompatibilityChat">%1$s gebruikt een oudere versie van Telegram, dus worden geheime foto\'s weergegeven in de compatibiliteitsmodus.\n\nZodra %2$s Telegram update werken foto\'s met timers voor 1 minuut of minder in de \'Houd ingedrukt om te bekijken\'-modus en krijg je een bericht wanneer de andere partij een schermafbeelding maakt.</string>
|
<string name="PhotoTip">Druk en houd ingedrukt</string>
|
||||||
|
<string name="CompatibilityChat">%1$s gebruikt een oudere versie van Telegram, dus worden geheime foto\'s weergegeven in de compatibiliteitsmodus.\n\nZodra %2$s Telegram updatet werken foto\'s met timers voor 1 minuut of minder in de \'Druk en houd ingedrukt\'-modus en krijg je een bericht wanneer de andere partij een schermafbeelding maakt.</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="BroadcastList">Verzendlijst</string>
|
<string name="BroadcastList">Verzendlijst</string>
|
||||||
<string name="NewBroadcastList">Nieuwe verzendlijst</string>
|
<string name="NewBroadcastList">Nieuwe verzendlijst</string>
|
||||||
|
@ -201,6 +202,7 @@
|
||||||
<string name="NumberUnknown">Onbekend</string>
|
<string name="NumberUnknown">Onbekend</string>
|
||||||
<string name="Info">INFORMATIE</string>
|
<string name="Info">INFORMATIE</string>
|
||||||
<string name="Phone">Telefoon</string>
|
<string name="Phone">Telefoon</string>
|
||||||
|
<!--usernames-->
|
||||||
<string name="Username">Gebruikersnaam</string>
|
<string name="Username">Gebruikersnaam</string>
|
||||||
<string name="UsernamePlaceholder">Kies een naam</string>
|
<string name="UsernamePlaceholder">Kies een naam</string>
|
||||||
<string name="UsernameInUse">Sorry, deze gebruikersnaam is al bezet.</string>
|
<string name="UsernameInUse">Sorry, deze gebruikersnaam is al bezet.</string>
|
||||||
|
@ -211,8 +213,8 @@
|
||||||
<string name="UsernameHelp">Je kan een gebruikersnaam kiezen voor <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. Hiermee kunnen anderen je vinden en contact met je opnemen zonder je telefoonnummer te weten.<![CDATA[<br><br>]]>Je mag <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> en liggend streepje gebruiken. De minimale lengte is <![CDATA[<b>]]>5<![CDATA[</b>]]> tekens.</string>
|
<string name="UsernameHelp">Je kan een gebruikersnaam kiezen voor <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. Hiermee kunnen anderen je vinden en contact met je opnemen zonder je telefoonnummer te weten.<![CDATA[<br><br>]]>Je mag <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> en liggend streepje gebruiken. De minimale lengte is <![CDATA[<b>]]>5<![CDATA[</b>]]> tekens.</string>
|
||||||
<string name="UsernameChecking">Gebruikersnaam controleren.</string>
|
<string name="UsernameChecking">Gebruikersnaam controleren.</string>
|
||||||
<string name="UsernameAvailable">%1$s is beschikbaar.</string>
|
<string name="UsernameAvailable">%1$s is beschikbaar.</string>
|
||||||
<string name="UsernameEmpty">None</string>
|
<string name="UsernameEmpty">Geen</string>
|
||||||
<string name="ErrorOccurred">An error occurred</string>
|
<string name="ErrorOccurred">Er is een fout opgetreden.</string>
|
||||||
<!--settings view-->
|
<!--settings view-->
|
||||||
<string name="ResetNotificationsText">Alle meldingsinstellingen herstellen</string>
|
<string name="ResetNotificationsText">Alle meldingsinstellingen herstellen</string>
|
||||||
<string name="TextSize">Tekstgrootte berichten</string>
|
<string name="TextSize">Tekstgrootte berichten</string>
|
||||||
|
@ -384,6 +386,7 @@
|
||||||
<string name="ForwardFromMyName">doorsturen via mijn eigen naam</string>
|
<string name="ForwardFromMyName">doorsturen via mijn eigen naam</string>
|
||||||
<string name="SendMessagesToGroup">Berichten naar %1$s verzenden?</string>
|
<string name="SendMessagesToGroup">Berichten naar %1$s verzenden?</string>
|
||||||
<string name="ForwardMessagesToGroup">Berichten naar %1$s doorsturen?</string>
|
<string name="ForwardMessagesToGroup">Berichten naar %1$s doorsturen?</string>
|
||||||
|
<string name="FeatureUnavailable">Sorry, deze functie is momenteel niet beschikbaar in jouw land.</string>
|
||||||
<!--Intro view-->
|
<!--Intro view-->
|
||||||
<string name="Page1Title">Telegram</string>
|
<string name="Page1Title">Telegram</string>
|
||||||
<string name="Page2Title">Snel</string>
|
<string name="Page2Title">Snel</string>
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
<string name="DeleteChat">Apagar e sair</string>
|
<string name="DeleteChat">Apagar e sair</string>
|
||||||
<string name="HiddenName">Nome oculto</string>
|
<string name="HiddenName">Nome oculto</string>
|
||||||
<string name="SelectChat">Selecione uma Conversa</string>
|
<string name="SelectChat">Selecione uma Conversa</string>
|
||||||
|
<string name="PhotoTip">Toque e segure para ver</string>
|
||||||
<string name="CompatibilityChat">%1$s está usando uma versão mais antiga do Telegram, por isso fotos secretas serão mostradas em modo de compatibilidade.\n\nAssim que %2$s atualize o Telegram, fotos com timers de 1 minuto ou menos passarão a funcionar no modo ‘Toque e segure para ver’, e você será notificado caso a outra pessoa salve a tela.</string>
|
<string name="CompatibilityChat">%1$s está usando uma versão mais antiga do Telegram, por isso fotos secretas serão mostradas em modo de compatibilidade.\n\nAssim que %2$s atualize o Telegram, fotos com timers de 1 minuto ou menos passarão a funcionar no modo ‘Toque e segure para ver’, e você será notificado caso a outra pessoa salve a tela.</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="BroadcastList">Lista de Broadcast</string>
|
<string name="BroadcastList">Lista de Broadcast</string>
|
||||||
|
@ -201,6 +202,7 @@
|
||||||
<string name="NumberUnknown">Desconhecido</string>
|
<string name="NumberUnknown">Desconhecido</string>
|
||||||
<string name="Info">INFO</string>
|
<string name="Info">INFO</string>
|
||||||
<string name="Phone">Telefone</string>
|
<string name="Phone">Telefone</string>
|
||||||
|
<!--usernames-->
|
||||||
<string name="Username">Nome de Usuário</string>
|
<string name="Username">Nome de Usuário</string>
|
||||||
<string name="UsernamePlaceholder">Seu nome de usuário</string>
|
<string name="UsernamePlaceholder">Seu nome de usuário</string>
|
||||||
<string name="UsernameInUse">Desculpe, este usuário já existe.</string>
|
<string name="UsernameInUse">Desculpe, este usuário já existe.</string>
|
||||||
|
@ -211,8 +213,8 @@
|
||||||
<string name="UsernameHelp">Você pode escolher um nome de usuário no <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. Assim, outras pessoas poderão te encontrar pelo nome de usuário e entrar em contato sem precisar saber seu telefone. <![CDATA[<br><br>]]>Você pode usar <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> e underline. O tamanho mínimo é <![CDATA[<b>]]>5<![CDATA[</b>]]> caracteres.</string>
|
<string name="UsernameHelp">Você pode escolher um nome de usuário no <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. Assim, outras pessoas poderão te encontrar pelo nome de usuário e entrar em contato sem precisar saber seu telefone. <![CDATA[<br><br>]]>Você pode usar <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> e underline. O tamanho mínimo é <![CDATA[<b>]]>5<![CDATA[</b>]]> caracteres.</string>
|
||||||
<string name="UsernameChecking">Verificando nome de usuário...</string>
|
<string name="UsernameChecking">Verificando nome de usuário...</string>
|
||||||
<string name="UsernameAvailable">%1$s está disponível.</string>
|
<string name="UsernameAvailable">%1$s está disponível.</string>
|
||||||
<string name="UsernameEmpty">None</string>
|
<string name="UsernameEmpty">Nenhum</string>
|
||||||
<string name="ErrorOccurred">An error occurred</string>
|
<string name="ErrorOccurred">Ocorreu um erro.</string>
|
||||||
<!--settings view-->
|
<!--settings view-->
|
||||||
<string name="ResetNotificationsText">Restaurar todas as configurações de notificação</string>
|
<string name="ResetNotificationsText">Restaurar todas as configurações de notificação</string>
|
||||||
<string name="TextSize">Tamanho do texto nas mensagens</string>
|
<string name="TextSize">Tamanho do texto nas mensagens</string>
|
||||||
|
@ -384,6 +386,7 @@
|
||||||
<string name="ForwardFromMyName">encaminhar pelo meu nome</string>
|
<string name="ForwardFromMyName">encaminhar pelo meu nome</string>
|
||||||
<string name="SendMessagesToGroup">Enviar mensagens para %1$s?</string>
|
<string name="SendMessagesToGroup">Enviar mensagens para %1$s?</string>
|
||||||
<string name="ForwardMessagesToGroup">Encaminhar mensagem para %1$s?</string>
|
<string name="ForwardMessagesToGroup">Encaminhar mensagem para %1$s?</string>
|
||||||
|
<string name="FeatureUnavailable">Sorry, this feature is currently not available in your country.</string>
|
||||||
<!--Intro view-->
|
<!--Intro view-->
|
||||||
<string name="Page1Title">Telegram</string>
|
<string name="Page1Title">Telegram</string>
|
||||||
<string name="Page2Title">Rápido</string>
|
<string name="Page2Title">Rápido</string>
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
<string name="DeleteChat">Apagar e sair</string>
|
<string name="DeleteChat">Apagar e sair</string>
|
||||||
<string name="HiddenName">Nome oculto</string>
|
<string name="HiddenName">Nome oculto</string>
|
||||||
<string name="SelectChat">Selecione uma Conversa</string>
|
<string name="SelectChat">Selecione uma Conversa</string>
|
||||||
|
<string name="PhotoTip">Toque e segure para ver</string>
|
||||||
<string name="CompatibilityChat">%1$s está usando uma versão mais antiga do Telegram, por isso fotos secretas serão mostradas em modo de compatibilidade.\n\nAssim que %2$s atualize o Telegram, fotos com timers de 1 minuto ou menos passarão a funcionar no modo ‘Toque e segure para ver’, e você será notificado caso a outra pessoa salve a tela.</string>
|
<string name="CompatibilityChat">%1$s está usando uma versão mais antiga do Telegram, por isso fotos secretas serão mostradas em modo de compatibilidade.\n\nAssim que %2$s atualize o Telegram, fotos com timers de 1 minuto ou menos passarão a funcionar no modo ‘Toque e segure para ver’, e você será notificado caso a outra pessoa salve a tela.</string>
|
||||||
<!--broadcasts-->
|
<!--broadcasts-->
|
||||||
<string name="BroadcastList">Lista de Broadcast</string>
|
<string name="BroadcastList">Lista de Broadcast</string>
|
||||||
|
@ -201,6 +202,7 @@
|
||||||
<string name="NumberUnknown">Desconhecido</string>
|
<string name="NumberUnknown">Desconhecido</string>
|
||||||
<string name="Info">INFO</string>
|
<string name="Info">INFO</string>
|
||||||
<string name="Phone">Telefone</string>
|
<string name="Phone">Telefone</string>
|
||||||
|
<!--usernames-->
|
||||||
<string name="Username">Nome de Usuário</string>
|
<string name="Username">Nome de Usuário</string>
|
||||||
<string name="UsernamePlaceholder">Seu nome de usuário</string>
|
<string name="UsernamePlaceholder">Seu nome de usuário</string>
|
||||||
<string name="UsernameInUse">Desculpe, este usuário já existe.</string>
|
<string name="UsernameInUse">Desculpe, este usuário já existe.</string>
|
||||||
|
@ -211,8 +213,8 @@
|
||||||
<string name="UsernameHelp">Você pode escolher um nome de usuário no <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. Assim, outras pessoas poderão te encontrar pelo nome de usuário e entrar em contato sem precisar saber seu telefone. <![CDATA[<br><br>]]>Você pode usar <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> e underline. O tamanho mínimo é <![CDATA[<b>]]>5<![CDATA[</b>]]> caracteres.</string>
|
<string name="UsernameHelp">Você pode escolher um nome de usuário no <![CDATA[<b>]]>Telegram<![CDATA[</b>]]>. Assim, outras pessoas poderão te encontrar pelo nome de usuário e entrar em contato sem precisar saber seu telefone. <![CDATA[<br><br>]]>Você pode usar <![CDATA[<b>]]>a–z<![CDATA[</b>]]>, <![CDATA[<b>]]>0–9<![CDATA[</b>]]> e underline. O tamanho mínimo é <![CDATA[<b>]]>5<![CDATA[</b>]]> caracteres.</string>
|
||||||
<string name="UsernameChecking">Verificando nome de usuário...</string>
|
<string name="UsernameChecking">Verificando nome de usuário...</string>
|
||||||
<string name="UsernameAvailable">%1$s está disponível.</string>
|
<string name="UsernameAvailable">%1$s está disponível.</string>
|
||||||
<string name="UsernameEmpty">None</string>
|
<string name="UsernameEmpty">Nenhum</string>
|
||||||
<string name="ErrorOccurred">An error occurred</string>
|
<string name="ErrorOccurred">Ocorreu um erro.</string>
|
||||||
<!--settings view-->
|
<!--settings view-->
|
||||||
<string name="ResetNotificationsText">Restaurar todas as configurações de notificação</string>
|
<string name="ResetNotificationsText">Restaurar todas as configurações de notificação</string>
|
||||||
<string name="TextSize">Tamanho do texto nas mensagens</string>
|
<string name="TextSize">Tamanho do texto nas mensagens</string>
|
||||||
|
@ -384,6 +386,7 @@
|
||||||
<string name="ForwardFromMyName">encaminhar pelo meu nome</string>
|
<string name="ForwardFromMyName">encaminhar pelo meu nome</string>
|
||||||
<string name="SendMessagesToGroup">Enviar mensagens para %1$s?</string>
|
<string name="SendMessagesToGroup">Enviar mensagens para %1$s?</string>
|
||||||
<string name="ForwardMessagesToGroup">Encaminhar mensagem para %1$s?</string>
|
<string name="ForwardMessagesToGroup">Encaminhar mensagem para %1$s?</string>
|
||||||
|
<string name="FeatureUnavailable">Sorry, this feature is currently not available in your country.</string>
|
||||||
<!--Intro view-->
|
<!--Intro view-->
|
||||||
<string name="Page1Title">Telegram</string>
|
<string name="Page1Title">Telegram</string>
|
||||||
<string name="Page2Title">Rápido</string>
|
<string name="Page2Title">Rápido</string>
|
||||||
|
|
Loading…
Reference in a new issue