Update to 1.3.26 (184)

https://github.com/DrKLO/Telegram/pull/216
Bug fixes
This commit is contained in:
DrKLO 2014-03-05 20:42:10 +04:00
parent 2518d0e91f
commit ddd022ef6f
9 changed files with 205 additions and 159 deletions

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.telegram.messenger"
android:versionCode="182"
android:versionCode="184"
android:versionName="1.3.26">
<supports-screens android:anyDensity="true"

View file

@ -8,23 +8,23 @@
package org.telegram.messenger;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.ArrayList;
public class BuffersStorage {
public static BuffersStorage Instance = new BuffersStorage();
private final ConcurrentLinkedQueue<ByteBufferDesc> freeBuffers128;
private final ConcurrentLinkedQueue<ByteBufferDesc> freeBuffers1024;
private final ConcurrentLinkedQueue<ByteBufferDesc> freeBuffers4096;
private final ConcurrentLinkedQueue<ByteBufferDesc> freeBuffers16384;
private final ConcurrentLinkedQueue<ByteBufferDesc> freeBuffers32768;
private final ArrayList<ByteBufferDesc> freeBuffers128;
private final ArrayList<ByteBufferDesc> freeBuffers1024;
private final ArrayList<ByteBufferDesc> freeBuffers4096;
private final ArrayList<ByteBufferDesc> freeBuffers16384;
private final ArrayList<ByteBufferDesc> freeBuffers32768;
public BuffersStorage() {
freeBuffers128 = new ConcurrentLinkedQueue<ByteBufferDesc>();
freeBuffers1024 = new ConcurrentLinkedQueue<ByteBufferDesc>();
freeBuffers4096 = new ConcurrentLinkedQueue<ByteBufferDesc>();
freeBuffers16384 = new ConcurrentLinkedQueue<ByteBufferDesc>();
freeBuffers32768 = new ConcurrentLinkedQueue<ByteBufferDesc>();
freeBuffers128 = new ArrayList<ByteBufferDesc>();
freeBuffers1024 = new ArrayList<ByteBufferDesc>();
freeBuffers4096 = new ArrayList<ByteBufferDesc>();
freeBuffers16384 = new ArrayList<ByteBufferDesc>();
freeBuffers32768 = new ArrayList<ByteBufferDesc>();
for (int a = 0; a < 5; a++) {
freeBuffers128.add(new ByteBufferDesc(128));
@ -47,7 +47,10 @@ public class BuffersStorage {
ByteBufferDesc buffer = null;
if (size <= 128) {
synchronized (freeBuffers128) {
buffer = freeBuffers128.poll();
if (freeBuffers128.size() > 0) {
buffer = freeBuffers128.get(0);
freeBuffers128.remove(0);
}
}
if (buffer == null) {
buffer = new ByteBufferDesc(128);
@ -55,7 +58,10 @@ public class BuffersStorage {
}
} else if (size <= 1024 + 200) {
synchronized (freeBuffers1024) {
buffer = freeBuffers1024.poll();
if (freeBuffers1024.size() > 0) {
buffer = freeBuffers1024.get(0);
freeBuffers1024.remove(0);
}
}
if (buffer == null) {
buffer = new ByteBufferDesc(1024 + 200);
@ -63,7 +69,10 @@ public class BuffersStorage {
}
} else if (size <= 4096 + 200) {
synchronized (freeBuffers4096) {
buffer = freeBuffers4096.poll();
if (freeBuffers4096.size() > 0) {
buffer = freeBuffers4096.get(0);
freeBuffers4096.remove(0);
}
}
if (buffer == null) {
buffer = new ByteBufferDesc(4096 + 200);
@ -71,7 +80,10 @@ public class BuffersStorage {
}
} else if (size <= 16384 + 200) {
synchronized (freeBuffers16384) {
buffer = freeBuffers16384.poll();
if (freeBuffers16384.size() > 0) {
buffer = freeBuffers16384.get(0);
freeBuffers16384.remove(0);
}
}
if (buffer == null) {
buffer = new ByteBufferDesc(16384 + 200);
@ -79,7 +91,10 @@ public class BuffersStorage {
}
} else if (size <= 40000) {
synchronized (freeBuffers32768) {
buffer = freeBuffers32768.poll();
if (freeBuffers32768.size() > 0) {
buffer = freeBuffers32768.get(0);
freeBuffers32768.remove(0);
}
}
if (buffer == null) {
buffer = new ByteBufferDesc(40000);
@ -98,37 +113,22 @@ public class BuffersStorage {
}
if (buffer.buffer.capacity() == 128) {
synchronized (freeBuffers128) {
if (freeBuffers128.contains(buffer)) {
throw new RuntimeException("already containing buffer! 0");
}
freeBuffers128.add(buffer);
}
} else if (buffer.buffer.capacity() == 1024 + 200) {
synchronized (freeBuffers1024) {
if (freeBuffers1024.contains(buffer)) {
throw new RuntimeException("already containing buffer! 1");
}
freeBuffers1024.add(buffer);
}
} else if (buffer.buffer.capacity() == 4096 + 200) {
synchronized (freeBuffers4096) {
if (freeBuffers4096.contains(buffer)) {
throw new RuntimeException("already containing buffer! 2");
}
freeBuffers4096.add(buffer);
}
} else if (buffer.buffer.capacity() == 16384 + 200) {
synchronized (freeBuffers16384) {
if (freeBuffers16384.contains(buffer)) {
throw new RuntimeException("already containing buffer! 3");
}
freeBuffers16384.add(buffer);
}
} else if (buffer.buffer.capacity() == 40000) {
synchronized (freeBuffers32768) {
if (freeBuffers32768.contains(buffer)) {
throw new RuntimeException("already containing buffer! 4");
}
freeBuffers32768.add(buffer);
}
}

View file

@ -919,20 +919,16 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
final ArrayList<Integer> unauthorizedDatacenterIds = new ArrayList<Integer>();
int currentTime = (int)(System.currentTimeMillis() / 1000);
for (RPCRequest request : runningRequests) {
for (int i = 0; i < runningRequests.size(); i++) {
RPCRequest request = runningRequests.get(i);
if (updatingDcSettings && datacenters.size() > 1 && request.rawRequest instanceof TLRPC.TL_help_getConfig) {
if (updatingDcStartTime < currentTime - 60) {
updatingDcStartTime = currentTime;
ArrayList<Datacenter> allDc = new ArrayList<Datacenter>(datacenters.values());
for (int a = 0; a < allDc.size(); a++) {
Datacenter dc = allDc.get(a);
if (dc.datacenterId == request.runningDatacenterId) {
allDc.remove(a);
break;
}
}
Datacenter newDc = allDc.get(Math.abs(MessagesController.random.nextInt()) % allDc.size());
request.runningDatacenterId = newDc.datacenterId;
FileLog.e("tmessages", "move TL_help_getConfig to requestQueue");
requestQueue.add(request);
runningRequests.remove(i);
i--;
continue;
}
}

View file

@ -501,16 +501,16 @@ public class ContactsController {
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
if (ConnectionsManager.DEBUG_VERSION) {
FileLog.e("tmessages", "need delete contacts");
for (HashMap.Entry<Integer, Contact> c : contactHashMap.entrySet()) {
Contact contact = c.getValue();
FileLog.e("tmessages", "delete contact " + contact.first_name + " " + contact.last_name);
for (String phone : contact.phones) {
FileLog.e("tmessages", phone);
}
}
}
// if (ConnectionsManager.DEBUG_VERSION) {
// FileLog.e("tmessages", "need delete contacts");
// for (HashMap.Entry<Integer, Contact> c : contactHashMap.entrySet()) {
// Contact contact = c.getValue();
// FileLog.e("tmessages", "delete contact " + contact.first_name + " " + contact.last_name);
// for (String phone : contact.phones) {
// FileLog.e("tmessages", phone);
// }
// }
// }
final ArrayList<TLRPC.User> toDelete = new ArrayList<TLRPC.User>();
if (contactHashMap != null && !contactHashMap.isEmpty()) {
@ -577,12 +577,12 @@ public class ContactsController {
if (request) {
if (!toImport.isEmpty()) {
if (ConnectionsManager.DEBUG_VERSION) {
FileLog.e("tmessages", "start import contacts");
for (TLRPC.TL_inputPhoneContact contact : toImport) {
FileLog.e("tmessages", "add contact " + contact.first_name + " " + contact.last_name + " " + contact.phone);
}
}
// if (ConnectionsManager.DEBUG_VERSION) {
// FileLog.e("tmessages", "start import contacts");
// for (TLRPC.TL_inputPhoneContact contact : toImport) {
// FileLog.e("tmessages", "add contact " + contact.first_name + " " + contact.last_name + " " + contact.phone);
// }
// }
final int count = (int)Math.ceil(toImport.size() / 500.0f);
for (int a = 0; a < count; a++) {
ArrayList<TLRPC.TL_inputPhoneContact> finalToImport = new ArrayList<TLRPC.TL_inputPhoneContact>();
@ -598,15 +598,6 @@ public class ContactsController {
FileLog.e("tmessages", "contacts imported");
if (isLastQuery && !contactsMap.isEmpty()) {
MessagesStorage.Instance.putCachedPhoneBook(contactsMap);
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
contactsBookSPhones = contactsBookShort;
contactsBook = contactsMap;
contactsSyncInProgress = false;
contactsBookLoaded = true;
}
});
}
TLRPC.TL_contacts_importedContacts res = (TLRPC.TL_contacts_importedContacts)response;
MessagesStorage.Instance.putUsersAndChats(res.users, null, true, true);
@ -620,6 +611,24 @@ public class ContactsController {
} else {
FileLog.e("tmessages", "import contacts error " + error.text);
}
if (isLastQuery) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
contactsBookSPhones = contactsBookShort;
contactsBook = contactsMap;
contactsSyncInProgress = false;
contactsBookLoaded = true;
if (first) {
contactsLoaded = true;
}
if (!delayedContactsUpdate.isEmpty() && contactsLoaded && contactsBookLoaded) {
applyContactsUpdates(delayedContactsUpdate, null, null, null);
delayedContactsUpdate.clear();
}
}
});
}
}
}, null, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassCanCompress);
}
@ -631,6 +640,13 @@ public class ContactsController {
contactsBook = contactsMap;
contactsSyncInProgress = false;
contactsBookLoaded = true;
if (first) {
contactsLoaded = true;
}
if (!delayedContactsUpdate.isEmpty() && contactsLoaded && contactsBookLoaded) {
applyContactsUpdates(delayedContactsUpdate, null, null, null);
delayedContactsUpdate.clear();
}
}
});
Utilities.RunOnUIThread(new Runnable() {
@ -649,6 +665,13 @@ public class ContactsController {
contactsBook = contactsMap;
contactsSyncInProgress = false;
contactsBookLoaded = true;
if (first) {
contactsLoaded = true;
}
if (!delayedContactsUpdate.isEmpty() && contactsLoaded && contactsBookLoaded) {
applyContactsUpdates(delayedContactsUpdate, null, null, null);
delayedContactsUpdate.clear();
}
}
});
if (!contactsMap.isEmpty()) {

View file

@ -4418,18 +4418,20 @@ public class MessagesController implements NotificationCenter.NotificationCenter
private void updateInterfaceWithMessages(long uid, ArrayList<MessageObject> messages) {
MessageObject lastMessage = null;
int lastDate = 0;
TLRPC.TL_dialog dialog = dialogs_dict.get(uid);
boolean isEncryptedChat = ((int)uid) == 0;
NotificationCenter.Instance.postNotificationName(didReceivedNewMessages, uid, messages);
for (MessageObject message : messages) {
if (lastMessage == null || message.messageOwner.date > lastDate) {
if (lastMessage == null || (!isEncryptedChat && message.messageOwner.id > lastMessage.messageOwner.id || isEncryptedChat && message.messageOwner.id < lastMessage.messageOwner.id) || message.messageOwner.date > lastMessage.messageOwner.date) {
lastMessage = message;
lastDate = message.messageOwner.date;
}
}
boolean changed = false;
if (dialog == null) {
dialog = new TLRPC.TL_dialog();
dialog.id = uid;
@ -4439,33 +4441,37 @@ public class MessagesController implements NotificationCenter.NotificationCenter
dialogs_dict.put(uid, dialog);
dialogs.add(dialog);
dialogMessage.put(lastMessage.messageOwner.id, lastMessage);
changed = true;
} else {
dialogMessage.remove(dialog.top_message);
if (dialog.top_message > 0 && lastMessage.messageOwner.id > 0 && lastMessage.messageOwner.id > dialog.top_message ||
dialog.top_message < 0 && lastMessage.messageOwner.id < 0 && lastMessage.messageOwner.id < dialog.top_message ||
dialog.last_message_date < lastMessage.messageOwner.date) {
dialogMessage.remove(dialog.top_message);
dialog.top_message = lastMessage.messageOwner.id;
dialog.last_message_date = lastMessage.messageOwner.date;
dialogMessage.put(lastMessage.messageOwner.id, lastMessage);
changed = true;
}
}
dialogsServerOnly.clear();
Collections.sort(dialogs, new Comparator<TLRPC.TL_dialog>() {
@Override
public int compare(TLRPC.TL_dialog tl_dialog, TLRPC.TL_dialog tl_dialog2) {
if (tl_dialog.last_message_date == tl_dialog2.last_message_date) {
return 0;
} else if (tl_dialog.last_message_date < tl_dialog2.last_message_date) {
return 1;
} else {
return -1;
if (changed) {
dialogsServerOnly.clear();
Collections.sort(dialogs, new Comparator<TLRPC.TL_dialog>() {
@Override
public int compare(TLRPC.TL_dialog tl_dialog, TLRPC.TL_dialog tl_dialog2) {
if (tl_dialog.last_message_date == tl_dialog2.last_message_date) {
return 0;
} else if (tl_dialog.last_message_date < tl_dialog2.last_message_date) {
return 1;
} else {
return -1;
}
}
});
for (TLRPC.TL_dialog d : dialogs) {
if ((int)d.id != 0) {
dialogsServerOnly.add(d);
}
}
});
for (TLRPC.TL_dialog d : dialogs) {
if ((int)d.id != 0) {
dialogsServerOnly.add(d);
}
}
}

View file

@ -439,7 +439,7 @@ public class TcpConnection extends PyroClientAdapter {
}
if (currentPacketLength % 4 != 0 || currentPacketLength > 2 * 1024 * 1024) {
//FileLog.e("tmessages", "Invalid packet length");
FileLog.e("tmessages", "Invalid packet length");
reconnect();
return;
}

View file

@ -48,6 +48,8 @@ public class LoginActivityPhoneView extends SlideView implements AdapterView.OnI
private EditText phoneField;
private TextView countryButton;
private int countryState = 0;
private ArrayList<String> countriesArray = new ArrayList<String>();
private HashMap<String, String> countriesMap = new HashMap<String, String>();
private HashMap<String, String> codesMap = new HashMap<String, String>();
@ -104,17 +106,29 @@ public class LoginActivityPhoneView extends SlideView implements AdapterView.OnI
ignoreOnTextChange = true;
String text = PhoneFormat.stripExceptNumbers(codeField.getText().toString());
codeField.setText(text);
String country = codesMap.get(text);
if (country != null) {
int index = countriesArray.indexOf(country);
if (index != -1) {
ignoreSelection = true;
countryButton.setText(countriesArray.get(index));
if (text.length() == 0) {
countryButton.setText(R.string.ChooseCountry);
countryState = 1;
} else {
String country = codesMap.get(text);
if (country != null) {
int index = countriesArray.indexOf(country);
if (index != -1) {
ignoreSelection = true;
countryButton.setText(countriesArray.get(index));
updatePhoneField();
updatePhoneField();
countryState = 0;
} else {
countryButton.setText(R.string.WrongCountry);
countryState = 2;
}
} else {
countryButton.setText(R.string.WrongCountry);
countryState = 2;
}
codeField.setSelection(codeField.getText().length());
}
codeField.setSelection(codeField.getText().length());
}
});
codeField.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@ -198,56 +212,50 @@ public class LoginActivityPhoneView extends SlideView implements AdapterView.OnI
}
});
boolean codeProceed = false;
String country = null;
if (!codeProceed) {
String country = "RU";
try {
TelephonyManager telephonyManager = (TelephonyManager)ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
country = telephonyManager.getSimCountryIso().toUpperCase();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (country == null || country.length() == 0) {
try {
Locale current = ApplicationLoader.applicationContext.getResources().getConfiguration().locale;
country = current.getCountry().toUpperCase();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
if (country == null || country.length() == 0) {
country = "RU";
}
String countryName = languageMap.get(country);
if (countryName == null) {
countryName = "Russia";
}
int index = countriesArray.indexOf(countryName);
if (index != -1) {
codeField.setText(countriesMap.get(countryName));
try {
TelephonyManager telephonyManager = (TelephonyManager)ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
country = telephonyManager.getSimCountryIso().toUpperCase();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (country != null) {
String countryName = languageMap.get(country);
if (countryName != null) {
int index = countriesArray.indexOf(countryName);
if (index != -1) {
codeField.setText(countriesMap.get(countryName));
countryState = 0;
}
}
}
if (codeField.length() == 0) {
countryButton.setText(R.string.ChooseCountry);
countryState = 1;
}
}
if (codeField.length() != 0) {
Utilities.showKeyboard(phoneField);
phoneField.requestFocus();
phoneField.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if (i == EditorInfo.IME_ACTION_NEXT) {
delegate.onNextAction();
return true;
}
return false;
}
});
} else {
Utilities.showKeyboard(codeField);
codeField.requestFocus();
}
phoneField.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if (i == EditorInfo.IME_ACTION_NEXT) {
delegate.onNextAction();
return true;
}
return false;
}
});
}
public void selectCountry(String name) {
@ -301,6 +309,13 @@ public class LoginActivityPhoneView extends SlideView implements AdapterView.OnI
@Override
public void onNextPressed() {
if (countryState == 1) {
delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.ChooseCountry));
return;
} else if (countryState == 2) {
delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.WrongCountry));
return;
}
if (codeField.length() == 0 || phoneField.length() == 0) {
delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidPhoneNumber));
return;

View file

@ -232,6 +232,12 @@ public class PhotoCropActivity extends BaseFragment {
int x = (int)(percX * imageToCrop.getWidth());
int y = (int)(percY * imageToCrop.getHeight());
int size = (int)(percSize * imageToCrop.getWidth());
if (x + size > imageToCrop.getWidth()) {
size = imageToCrop.getWidth() - x;
}
if (y + size > imageToCrop.getHeight()) {
size = imageToCrop.getHeight() - y;
}
try {
return Bitmap.createBitmap(imageToCrop, x, y, size, size);
} catch (Exception e) {

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- -->
<!--Translated by Telegram Team, corrected by Florian Keller-->
<resources>
<string name="AppName">Telegram</string>
@ -48,7 +48,7 @@
<string name="EncryptedChatStartedOutgoing">%s joined your secret chat.</string>
<string name="EncryptedChatStartedIncoming">You joined the secret chat.</string>
<string name="ClearHistory">Clear History</string>
<string name="DeleteChat">Delete and Exit</string>
<string name="DeleteChat">Delete and exit</string>
<string name="HiddenName">Hidden Name</string>
<string name="SelectChat">Select Chat</string>
@ -60,7 +60,7 @@
<string name="NoFiles">No files yet...</string>
<string name="FileUploadLimit">File size shouldn\'t be greater than %1$s</string>
<string name="NotMounted">Storage not mounted</string>
<string name="UsbActive">Usb transfer active</string>
<string name="UsbActive">USB transfer active</string>
<string name="InternalStorage">Internal Storage</string>
<string name="ExternalStorage">External Storage</string>
<string name="SystemRoot">System Root</string>
@ -102,9 +102,9 @@
<string name="EncryptedDescription4">Do not allow forwarding</string>
<string name="OneNewMessage">%1$d new message</string>
<string name="FewNewMessages">%1$d new messages</string>
<string name="YouWereKicked">You were kicked from this group</string>
<string name="YouWereKicked">You were removed from this group</string>
<string name="YouLeft">You left this group</string>
<string name="DeleteThisGroup">Delete this Group</string>
<string name="DeleteThisGroup">Delete this group</string>
<string name="SlideToCancel">SLIDE TO CANCEL</string>
<!--notification-->
@ -126,7 +126,7 @@
<string name="NotificationMessagePhoto">%1$s sent you a photo</string>
<string name="NotificationMessageVideo">%1$s sent you a video</string>
<string name="NotificationMessageContact">%1$s shared a contact with you</string>
<string name="NotificationMessageMap">%1$s sent you a map</string>
<string name="NotificationMessageMap">%1$s sent you a location</string>
<string name="NotificationMessageDocument">%1$s sent you a document</string>
<string name="NotificationMessageAudio">%1$s sent you an audio</string>
<string name="NotificationMessageGroupText">%1$s @ %2$s: %3$s</string>
@ -134,15 +134,15 @@
<string name="NotificationMessageGroupPhoto">%1$s sent a photo to the group %2$s</string>
<string name="NotificationMessageGroupVideo">%1$s sent a video to the group %2$s</string>
<string name="NotificationMessageGroupContact">%1$s shared a contact in the group %2$s</string>
<string name="NotificationMessageGroupMap">%1$s sent a map to the group %2$s</string>
<string name="NotificationMessageGroupMap">%1$s sent a location to the group %2$s</string>
<string name="NotificationMessageGroupDocument">%1$s sent a document to the group %2$s</string>
<string name="NotificationMessageGroupAudio">%1$s sent an audio to the group %2$s</string>
<string name="NotificationInvitedToGroup">%1$s invited you to the group %2$s</string>
<string name="NotificationEditedGroupName">%1$s edited the group\'s %2$s name</string>
<string name="NotificationEditedGroupPhoto">%1$s edited the group\'s %2$s photo</string>
<string name="NotificationGroupAddMember">%1$s invited %3$s to the group %2$s</string>
<string name="NotificationGroupKickMember">%1$s kicked %3$s from the group %2$s</string>
<string name="NotificationGroupKickYou">%1$s kicked you from the group %2$s</string>
<string name="NotificationGroupKickMember">%1$s removed %3$s from the group %2$s</string>
<string name="NotificationGroupKickYou">%1$s removed you from the group %2$s</string>
<string name="NotificationGroupLeftMember">%1$s has left the group %2$s</string>
<string name="NotificationContactJoined">%1$s joined Telegram!</string>
<string name="NotificationUnrecognizedDevice">%1$s,\nWe detected a login into your account from a new device on %2$s\n\nDevice: %3$s\nLocation: %4$s\n\nIf this wasnt you, you can go to Settings Terminate all sessions.\n\nThanks,\nThe Telegram Team</string>
@ -178,7 +178,7 @@
<string name="AddMember">Add member</string>
<string name="DeleteAndExit">Delete and leave group</string>
<string name="Notifications">Notifications</string>
<string name="KickFromGroup">Kick from group</string>
<string name="KickFromGroup">Remove from group</string>
<!--contact info view-->
<string name="ShareContact">Share</string>
@ -290,21 +290,21 @@
<string name="OK">OK</string>
<!--messages-->
<string name="ActionKickUser">un1 kicked un2</string>
<string name="ActionKickUser">un1 removed un2</string>
<string name="ActionLeftUser">un1 left group</string>
<string name="ActionAddUser">un1 added un2</string>
<string name="ActionRemovedPhoto">un1 removed group photo</string>
<string name="ActionChangedPhoto">un1 changed group photo</string>
<string name="ActionChangedTitle">un1 changed group name to un2</string>
<string name="ActionRemovedPhoto">un1 removed the group photo</string>
<string name="ActionChangedPhoto">un1 changed the group photo</string>
<string name="ActionChangedTitle">un1 changed the group name to un2</string>
<string name="ActionCreateGroup">un1 created the group</string>
<string name="ActionYouKickUser">You kicked un2</string>
<string name="ActionYouKickUser">You removed un2</string>
<string name="ActionYouLeftUser">You left group</string>
<string name="ActionYouAddUser">You added un2</string>
<string name="ActionYouRemovedPhoto">You removed group photo</string>
<string name="ActionYouChangedPhoto">You changed group photo</string>
<string name="ActionYouChangedTitle">You changed group name to un2</string>
<string name="ActionYouRemovedPhoto">You removed the group photo</string>
<string name="ActionYouChangedPhoto">You changed the group photo</string>
<string name="ActionYouChangedTitle">You changed the group name to un2</string>
<string name="ActionYouCreateGroup">You created the group</string>
<string name="ActionKickUserYou">un1 kicked you</string>
<string name="ActionKickUserYou">un1 removed you</string>
<string name="ActionAddUserYou">un1 added you</string>
<string name="UnsuppotedMedia">This message is not supported on your version of Telegram.</string>
<string name="AttachPhoto">Photo</string>