Commit 2b8304eb authored by DrKLO's avatar DrKLO

Update to 2.8.1

Thanks to https://github.com/DrKLO/Telegram/issues/738 for smart
notifications
parent f6655078
...@@ -13,11 +13,10 @@ repositories { ...@@ -13,11 +13,10 @@ repositories {
} }
dependencies { dependencies {
compile 'com.android.support:support-v4:22.0.+' compile 'com.android.support:support-v4:22.1.+'
compile 'com.google.android.gms:play-services:3.2.+' compile 'com.google.android.gms:play-services:3.2.+'
compile 'net.hockeyapp.android:HockeySDK:3.5.+' compile 'net.hockeyapp.android:HockeySDK:3.5.+'
compile 'com.googlecode.mp4parser:isoparser:1.0.+' compile 'com.googlecode.mp4parser:isoparser:1.0.+'
compile 'com.android.support:recyclerview-v7:+'
} }
android { android {
...@@ -82,7 +81,7 @@ android { ...@@ -82,7 +81,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
targetSdkVersion 22 targetSdkVersion 22
versionCode 492 versionCode 521
versionName "2.7.0" versionName "2.8.1"
} }
} }
...@@ -104,7 +104,7 @@ include $(BUILD_STATIC_LIBRARY) ...@@ -104,7 +104,7 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false LOCAL_PRELINK_MODULE := false
LOCAL_STATIC_LIBRARIES := webp sqlite LOCAL_STATIC_LIBRARIES := webp sqlite
LOCAL_MODULE := tmessages.7 LOCAL_MODULE := tmessages.8
LOCAL_CFLAGS := -w -std=gnu99 -O2 -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 LOCAL_CFLAGS := -w -std=gnu99 -O2 -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno
LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -ffast-math LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -ffast-math
......
...@@ -288,7 +288,7 @@ METHODDEF(void) my_error_exit(j_common_ptr cinfo) { ...@@ -288,7 +288,7 @@ METHODDEF(void) my_error_exit(j_common_ptr cinfo) {
longjmp(myerr->setjmp_buffer, 1); longjmp(myerr->setjmp_buffer, 1);
} }
JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jclass class, jobject bitmap, int radius) { JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jclass class, jobject bitmap, int radius, int unpin) {
if (!bitmap) { if (!bitmap) {
return; return;
} }
...@@ -312,7 +312,9 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jcl ...@@ -312,7 +312,9 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jcl
} else { } else {
fastBlurMore(info.width, info.height, info.stride, pixels, radius); fastBlurMore(info.width, info.height, info.stride, pixels, radius);
} }
if (unpin) {
AndroidBitmap_unlockPixels(env, bitmap); AndroidBitmap_unlockPixels(env, bitmap);
}
} }
JNIEXPORT void Java_org_telegram_messenger_Utilities_calcCDT(JNIEnv *env, jclass class, jobject hsvBuffer, int width, int height, jobject buffer) { JNIEXPORT void Java_org_telegram_messenger_Utilities_calcCDT(JNIEnv *env, jclass class, jobject hsvBuffer, int width, int height, jobject buffer) {
......
...@@ -45,10 +45,10 @@ import org.telegram.messenger.R; ...@@ -45,10 +45,10 @@ import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC; import org.telegram.messenger.TLRPC;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.ui.AnimationCompat.AnimatorListenerAdapterProxy; import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.ui.AnimationCompat.AnimatorSetProxy; import org.telegram.android.AnimationCompat.AnimatorSetProxy;
import org.telegram.ui.AnimationCompat.ObjectAnimatorProxy; import org.telegram.android.AnimationCompat.ObjectAnimatorProxy;
import org.telegram.ui.AnimationCompat.ViewProxy; import org.telegram.android.AnimationCompat.ViewProxy;
import org.telegram.ui.Components.ForegroundDetector; import org.telegram.ui.Components.ForegroundDetector;
import org.telegram.ui.Components.NumberPicker; import org.telegram.ui.Components.NumberPicker;
import org.telegram.ui.Components.TypefaceSpan; import org.telegram.ui.Components.TypefaceSpan;
...@@ -72,6 +72,7 @@ public class AndroidUtilities { ...@@ -72,6 +72,7 @@ public class AndroidUtilities {
public static Integer photoSize = null; public static Integer photoSize = null;
public static DisplayMetrics displayMetrics = new DisplayMetrics(); public static DisplayMetrics displayMetrics = new DisplayMetrics();
public static int leftBaseline; public static int leftBaseline;
public static boolean usingHardwareInput;
private static Boolean isTablet = null; private static Boolean isTablet = null;
static { static {
...@@ -227,21 +228,38 @@ public class AndroidUtilities { ...@@ -227,21 +228,38 @@ public class AndroidUtilities {
} }
public static int dp(float value) { public static int dp(float value) {
if (value == 0) {
return 0;
}
return (int)Math.ceil(density * value); return (int)Math.ceil(density * value);
} }
public static int compare(int lhs, int rhs) {
if (lhs == rhs) {
return 0;
} else if (lhs > rhs) {
return 1;
}
return -1;
}
public static float dpf2(float value) { public static float dpf2(float value) {
if (value == 0) {
return 0;
}
return density * value; return density * value;
} }
public static void checkDisplaySize() { public static void checkDisplaySize() {
try { try {
WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); Configuration configuration = ApplicationLoader.applicationContext.getResources().getConfiguration();
usingHardwareInput = configuration.keyboard != Configuration.KEYBOARD_NOKEYS && configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE);
if (manager != null) { if (manager != null) {
Display display = manager.getDefaultDisplay(); Display display = manager.getDefaultDisplay();
if (display != null) { if (display != null) {
display.getMetrics(displayMetrics); display.getMetrics(displayMetrics);
if(android.os.Build.VERSION.SDK_INT < 13) { if (android.os.Build.VERSION.SDK_INT < 13) {
displaySize.set(display.getWidth(), display.getHeight()); displaySize.set(display.getWidth(), display.getHeight());
} else { } else {
display.getSize(displaySize); display.getSize(displaySize);
...@@ -252,6 +270,38 @@ public class AndroidUtilities { ...@@ -252,6 +270,38 @@ public class AndroidUtilities {
} catch (Exception e) { } catch (Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
} }
/*
keyboardHidden
public static final int KEYBOARDHIDDEN_NO = 1
Constant for keyboardHidden, value corresponding to the keysexposed resource qualifier.
public static final int KEYBOARDHIDDEN_UNDEFINED = 0
Constant for keyboardHidden: a value indicating that no value has been set.
public static final int KEYBOARDHIDDEN_YES = 2
Constant for keyboardHidden, value corresponding to the keyshidden resource qualifier.
hardKeyboardHidden
public static final int HARDKEYBOARDHIDDEN_NO = 1
Constant for hardKeyboardHidden, value corresponding to the physical keyboard being exposed.
public static final int HARDKEYBOARDHIDDEN_UNDEFINED = 0
Constant for hardKeyboardHidden: a value indicating that no value has been set.
public static final int HARDKEYBOARDHIDDEN_YES = 2
Constant for hardKeyboardHidden, value corresponding to the physical keyboard being hidden.
keyboard
public static final int KEYBOARD_12KEY = 3
Constant for keyboard, value corresponding to the 12key resource qualifier.
public static final int KEYBOARD_NOKEYS = 1
Constant for keyboard, value corresponding to the nokeys resource qualifier.
public static final int KEYBOARD_QWERTY = 2
Constant for keyboard, value corresponding to the qwerty resource qualifier.
*/
} }
public static float getPixelsInCM(float cm, boolean isX) { public static float getPixelsInCM(float cm, boolean isX) {
...@@ -562,6 +612,9 @@ public class AndroidUtilities { ...@@ -562,6 +612,9 @@ public class AndroidUtilities {
if (start != -1) { if (start != -1) {
stringBuilder.replace(start, start + 3, ""); stringBuilder.replace(start, start + 3, "");
end = stringBuilder.indexOf("</b>"); end = stringBuilder.indexOf("</b>");
if (end == -1) {
end = stringBuilder.indexOf("<b>");
}
stringBuilder.replace(end, end + 4, ""); stringBuilder.replace(end, end + 4, "");
bolds.add(start); bolds.add(start);
bolds.add(end); bolds.add(end);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
public abstract class AnimatorListenerAdapter10 implements Animator10.AnimatorListener, Animator10.AnimatorPauseListener { public abstract class AnimatorListenerAdapter10 implements Animator10.AnimatorListener, Animator10.AnimatorPauseListener {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
public class FloatEvaluator implements TypeEvaluator<Number> { public class FloatEvaluator implements TypeEvaluator<Number> {
public Float evaluate(float fraction, Number startValue, Number endValue) { public Float evaluate(float fraction, Number startValue, Number endValue) {
......
...@@ -14,11 +14,11 @@ ...@@ -14,11 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import org.telegram.ui.Animation.Keyframe.FloatKeyframe; import org.telegram.android.Animation.Keyframe.FloatKeyframe;
import java.util.ArrayList; import java.util.ArrayList;
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
public abstract class FloatProperty10<T> extends Property<T, Float> { public abstract class FloatProperty10<T> extends Property<T, Float> {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
public class IntEvaluator implements TypeEvaluator<Integer> { public class IntEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) { public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
......
...@@ -14,11 +14,11 @@ ...@@ -14,11 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import org.telegram.ui.Animation.Keyframe.IntKeyframe; import org.telegram.android.Animation.Keyframe.IntKeyframe;
import java.util.ArrayList; import java.util.ArrayList;
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
public abstract class IntProperty<T> extends Property<T, Integer> { public abstract class IntProperty<T> extends Property<T, Integer> {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
......
...@@ -14,16 +14,16 @@ ...@@ -14,16 +14,16 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import android.util.Log; import android.util.Log;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import org.telegram.ui.Animation.Keyframe.IntKeyframe; import org.telegram.android.Animation.Keyframe.IntKeyframe;
import org.telegram.ui.Animation.Keyframe.FloatKeyframe; import org.telegram.android.Animation.Keyframe.FloatKeyframe;
import org.telegram.ui.Animation.Keyframe.ObjectKeyframe; import org.telegram.android.Animation.Keyframe.ObjectKeyframe;
class KeyframeSet { class KeyframeSet {
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
public class NoSuchPropertyException extends RuntimeException { public class NoSuchPropertyException extends RuntimeException {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import android.view.View; import android.view.View;
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
public abstract class Property<T, V> { public abstract class Property<T, V> {
......
...@@ -14,9 +14,8 @@ ...@@ -14,9 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
public interface TypeEvaluator<T> { public interface TypeEvaluator<T> {
T evaluate(float fraction, T startValue, T endValue); T evaluate(float fraction, T startValue, T endValue);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import android.os.Looper; import android.os.Looper;
import android.util.AndroidRuntimeException; import android.util.AndroidRuntimeException;
......
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package org.telegram.ui.Animation; package org.telegram.android.Animation;
import android.graphics.Camera; import android.graphics.Camera;
import android.graphics.Matrix; import android.graphics.Matrix;
......
...@@ -6,14 +6,14 @@ ...@@ -6,14 +6,14 @@
* Copyright Nikolai Kudashov, 2013-2014. * Copyright Nikolai Kudashov, 2013-2014.
*/ */
package org.telegram.ui.AnimationCompat; package org.telegram.android.AnimationCompat;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import org.telegram.ui.Animation.Animator10; import org.telegram.android.Animation.Animator10;
import org.telegram.ui.Animation.AnimatorListenerAdapter10; import org.telegram.android.Animation.AnimatorListenerAdapter10;
import org.telegram.ui.Animation.View10; import org.telegram.android.Animation.View10;
public class AnimatorListenerAdapterProxy { public class AnimatorListenerAdapterProxy {
protected Object animatorListenerAdapter; protected Object animatorListenerAdapter;
......
...@@ -6,17 +6,17 @@ ...@@ -6,17 +6,17 @@
* Copyright Nikolai Kudashov, 2013-2014. * Copyright Nikolai Kudashov, 2013-2014.
*/ */
package org.telegram.ui.AnimationCompat; package org.telegram.android.AnimationCompat;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import org.telegram.ui.Animation.Animator10; import org.telegram.android.Animation.Animator10;
import org.telegram.ui.Animation.AnimatorListenerAdapter10; import org.telegram.android.Animation.AnimatorListenerAdapter10;
import org.telegram.ui.Animation.AnimatorSet10; import org.telegram.android.Animation.AnimatorSet10;
import org.telegram.ui.Animation.View10; import org.telegram.android.Animation.View10;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.ArrayList; import java.util.ArrayList;
......
...@@ -6,15 +6,15 @@ ...@@ -6,15 +6,15 @@
* Copyright Nikolai Kudashov, 2013-2014. * Copyright Nikolai Kudashov, 2013-2014.
*/ */
package org.telegram.ui.AnimationCompat; package org.telegram.android.AnimationCompat;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import org.telegram.ui.Animation.AnimatorListenerAdapter10; import org.telegram.android.Animation.AnimatorListenerAdapter10;
import org.telegram.ui.Animation.ObjectAnimator10; import org.telegram.android.Animation.ObjectAnimator10;
import org.telegram.ui.Animation.View10; import org.telegram.android.Animation.View10;
public class ObjectAnimatorProxy { public class ObjectAnimatorProxy {
......
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
* Copyright Nikolai Kudashov, 2013-2014. * Copyright Nikolai Kudashov, 2013-2014.
*/ */
package org.telegram.ui.AnimationCompat; package org.telegram.android.AnimationCompat;
import android.view.View; import android.view.View;
import org.telegram.ui.Animation.View10; import org.telegram.android.Animation.View10;
public class ViewProxy { public class ViewProxy {
......
...@@ -14,6 +14,7 @@ import android.app.Activity; ...@@ -14,6 +14,7 @@ import android.app.Activity;
import android.content.ContentProviderOperation; import android.content.ContentProviderOperation;
import android.content.ContentProviderResult; import android.content.ContentProviderResult;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
...@@ -37,7 +38,6 @@ import java.util.ArrayList; ...@@ -37,7 +38,6 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class ContactsController { public class ContactsController {
...@@ -168,7 +168,7 @@ public class ContactsController { ...@@ -168,7 +168,7 @@ public class ContactsController {
if (!updatingInviteText && (inviteText == null || time + 86400 < (int)(System.currentTimeMillis() / 1000))) { if (!updatingInviteText && (inviteText == null || time + 86400 < (int)(System.currentTimeMillis() / 1000))) {
updatingInviteText = true; updatingInviteText = true;
TLRPC.TL_help_getInviteText req = new TLRPC.TL_help_getInviteText(); TLRPC.TL_help_getInviteText req = new TLRPC.TL_help_getInviteText();
req.lang_code = LocaleController.getLocaleString(Locale.getDefault()); req.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
if (req.lang_code == null || req.lang_code.length() == 0) { if (req.lang_code == null || req.lang_code.length() == 0) {
req.lang_code = "en"; req.lang_code = "en";
} }
...@@ -202,7 +202,19 @@ public class ContactsController { ...@@ -202,7 +202,19 @@ public class ContactsController {
public void checkAppAccount() { public void checkAppAccount() {
AccountManager am = AccountManager.get(ApplicationLoader.applicationContext); AccountManager am = AccountManager.get(ApplicationLoader.applicationContext);
Account[] accounts = am.getAccountsByType("org.telegram.account"); Account[] accounts;
try {
accounts = am.getAccountsByType("org.telegram.account");
if (accounts != null && accounts.length > 0) {
for (Account c : accounts) {
am.removeAccount(c, null, null);
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
accounts = am.getAccountsByType("org.telegram.messenger");
boolean recreateAccount = false; boolean recreateAccount = false;
if (UserConfig.isClientActivated()) { if (UserConfig.isClientActivated()) {
if (accounts.length == 1) { if (accounts.length == 1) {
...@@ -227,7 +239,7 @@ public class ContactsController { ...@@ -227,7 +239,7 @@ public class ContactsController {
} }
if (UserConfig.isClientActivated()) { if (UserConfig.isClientActivated()) {
try { try {
currentAccount = new Account(UserConfig.getCurrentUser().phone, "org.telegram.account"); currentAccount = new Account(UserConfig.getCurrentUser().phone, "org.telegram.messenger");
am.addAccountExplicitly(currentAccount, "", null); am.addAccountExplicitly(currentAccount, "", null);
} catch (Exception e) { } catch (Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
...@@ -239,7 +251,7 @@ public class ContactsController { ...@@ -239,7 +251,7 @@ public class ContactsController {
public void deleteAllAppAccounts() { public void deleteAllAppAccounts() {
try { try {
AccountManager am = AccountManager.get(ApplicationLoader.applicationContext); AccountManager am = AccountManager.get(ApplicationLoader.applicationContext);
Account[] accounts = am.getAccountsByType("org.telegram.account"); Account[] accounts = am.getAccountsByType("org.telegram.messenger");
for (Account c : accounts) { for (Account c : accounts) {
am.removeAccount(c, null, null); am.removeAccount(c, null, null);
} }
...@@ -1246,7 +1258,7 @@ public class ContactsController { ...@@ -1246,7 +1258,7 @@ public class ContactsController {
private void performWriteContactsToPhoneBook() { private void performWriteContactsToPhoneBook() {
final ArrayList<TLRPC.TL_contact> contactsArray = new ArrayList<>(); final ArrayList<TLRPC.TL_contact> contactsArray = new ArrayList<>();
contactsArray.addAll(contacts); contactsArray.addAll(contacts);
Utilities.photoBookQueue.postRunnable(new Runnable() { Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
performWriteContactsToPhoneBookInternal(contactsArray); performWriteContactsToPhoneBookInternal(contactsArray);
...@@ -1303,7 +1315,7 @@ public class ContactsController { ...@@ -1303,7 +1315,7 @@ public class ContactsController {
} }
for (final Integer uid : contactsTD) { for (final Integer uid : contactsTD) {
Utilities.photoBookQueue.postRunnable(new Runnable() { Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
deleteContactFromPhoneBook(uid); deleteContactFromPhoneBook(uid);
...@@ -1463,7 +1475,7 @@ public class ContactsController { ...@@ -1463,7 +1475,7 @@ public class ContactsController {
builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0); builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile"); builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile");
builder.withValue(ContactsContract.Data.DATA1, "+" + user.phone); builder.withValue(ContactsContract.Data.DATA1, user.id);
builder.withValue(ContactsContract.Data.DATA2, "Telegram Profile"); builder.withValue(ContactsContract.Data.DATA2, "Telegram Profile");
builder.withValue(ContactsContract.Data.DATA3, "+" + user.phone); builder.withValue(ContactsContract.Data.DATA3, "+" + user.phone);
builder.withValue(ContactsContract.Data.DATA4, user.id); builder.withValue(ContactsContract.Data.DATA4, user.id);
...@@ -1496,6 +1508,22 @@ public class ContactsController { ...@@ -1496,6 +1508,22 @@ public class ContactsController {
} }
} }
protected void markAsContacted(final String contactId) {
if (contactId == null) {
return;
}
Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override
public void run() {
Uri uri = Uri.parse(contactId);
ContentValues values = new ContentValues();
values.put(ContactsContract.Contacts.LAST_TIME_CONTACTED, System.currentTimeMillis());
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
cr.update(uri, values, null, null);
}
});
}
public void addContact(TLRPC.User user) { public void addContact(TLRPC.User user) {
if (user == null || user.phone == null) { if (user == null || user.phone == null) {
return; return;
...@@ -1533,7 +1561,7 @@ public class ContactsController { ...@@ -1533,7 +1561,7 @@ public class ContactsController {
// } // }
for (final TLRPC.User u : res.users) { for (final TLRPC.User u : res.users) {
Utilities.photoBookQueue.postRunnable(new Runnable() { Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
addContactToPhoneBook(u, true); addContactToPhoneBook(u, true);
...@@ -1546,7 +1574,7 @@ public class ContactsController { ...@@ -1546,7 +1574,7 @@ public class ContactsController {
MessagesStorage.getInstance().putContacts(arrayList, false); MessagesStorage.getInstance().putContacts(arrayList, false);
if (u.phone != null && u.phone.length() > 0) { if (u.phone != null && u.phone.length() > 0) {
String name = formatName(u.first_name, u.last_name); CharSequence name = formatName(u.first_name, u.last_name);
MessagesStorage.getInstance().applyPhoneBookUpdates(u.phone, ""); MessagesStorage.getInstance().applyPhoneBookUpdates(u.phone, "");
Contact contact = contactsBookSPhones.get(u.phone); Contact contact = contactsBookSPhones.get(u.phone);
if (contact != null) { if (contact != null) {
...@@ -1599,7 +1627,7 @@ public class ContactsController { ...@@ -1599,7 +1627,7 @@ public class ContactsController {
return; return;
} }
MessagesStorage.getInstance().deleteContacts(uids); MessagesStorage.getInstance().deleteContacts(uids);
Utilities.photoBookQueue.postRunnable(new Runnable() { Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
for (TLRPC.User user : users) { for (TLRPC.User user : users) {
...@@ -1610,7 +1638,7 @@ public class ContactsController { ...@@ -1610,7 +1638,7 @@ public class ContactsController {
for (TLRPC.User user : users) { for (TLRPC.User user : users) {
if (user.phone != null && user.phone.length() > 0) { if (user.phone != null && user.phone.length() > 0) {
String name = ContactsController.formatName(user.first_name, user.last_name); CharSequence name = ContactsController.formatName(user.first_name, user.last_name);
MessagesStorage.getInstance().applyPhoneBookUpdates(user.phone, ""); MessagesStorage.getInstance().applyPhoneBookUpdates(user.phone, "");
Contact contact = contactsBookSPhones.get(user.phone); Contact contact = contactsBookSPhones.get(user.phone);
if (contact != null) { if (contact != null) {
...@@ -1772,22 +1800,37 @@ public class ContactsController { ...@@ -1772,22 +1800,37 @@ public class ContactsController {
} }
public static String formatName(String firstName, String lastName) { public static String formatName(String firstName, String lastName) {
String result = ""; /*if ((firstName == null || firstName.length() == 0) && (lastName == null || lastName.length() == 0)) {
return LocaleController.getString("HiddenName", R.string.HiddenName);
}*/
if (firstName != null) {
firstName = firstName.trim();
}
if (lastName != null) {
lastName = lastName.trim();
}
StringBuilder result = new StringBuilder((firstName != null ? firstName.length() : 0) + (lastName != null ? lastName.length() : 0) + 1);
if (LocaleController.nameDisplayOrder == 1) { if (LocaleController.nameDisplayOrder == 1) {
result = firstName; if (firstName != null && firstName.length() > 0) {
if (result == null || result.length() == 0) { result.append(firstName);
result = lastName; if (lastName != null && lastName.length() > 0) {
} else if (result.length() != 0 && lastName != null && lastName.length() != 0) { result.append(" ");
result += " " + lastName; result.append(lastName);
}
} else if (lastName != null && lastName.length() > 0) {
result.append(lastName);
} }
} else { } else {
result = lastName; if (lastName != null && lastName.length() > 0) {
if (result == null || result.length() == 0) { result.append(lastName);
result = firstName; if (firstName != null && firstName.length() > 0) {
} else if (result.length() != 0 && firstName != null && firstName.length() != 0) { result.append(" ");
result += " " + firstName; result.append(firstName);
}
} else if (firstName != null && firstName.length() > 0) {
result.append(firstName);
} }
} }
return result.trim(); return result.toString();
} }
} }
...@@ -33,7 +33,8 @@ import org.telegram.messenger.ApplicationLoader; ...@@ -33,7 +33,8 @@ import org.telegram.messenger.ApplicationLoader;
public class Emoji { public class Emoji {
private static HashMap<Long, DrawableInfo> rects = new HashMap<>(); private static HashMap<Long, DrawableInfo> rects = new HashMap<>();
private static int drawImgSize, bigImgSize; private static int drawImgSize;
private static int bigImgSize;
private static boolean inited = false; private static boolean inited = false;
private static Paint placeholderPaint; private static Paint placeholderPaint;
private static Bitmap emojiBmp[] = new Bitmap[5]; private static Bitmap emojiBmp[] = new Bitmap[5];
...@@ -193,19 +194,19 @@ public class Emoji { ...@@ -193,19 +194,19 @@ public class Emoji {
static { static {
int emojiFullSize; int emojiFullSize;
if (AndroidUtilities.density <= 1.0f) { if (AndroidUtilities.density <= 1.0f) {
emojiFullSize = 30; emojiFullSize = 32;
} else if (AndroidUtilities.density <= 1.5f) { } else if (AndroidUtilities.density <= 1.5f) {
emojiFullSize = 45; emojiFullSize = 48;
} else if (AndroidUtilities.density <= 2.0f) { } else if (AndroidUtilities.density <= 2.0f) {
emojiFullSize = 60; emojiFullSize = 64;
} else { } else {
emojiFullSize = 90; emojiFullSize = 96;
} }
drawImgSize = AndroidUtilities.dp(20); drawImgSize = AndroidUtilities.dp(20);
if (AndroidUtilities.isTablet()) { if (AndroidUtilities.isTablet()) {
bigImgSize = AndroidUtilities.dp(40); bigImgSize = AndroidUtilities.dp(40);
} else { } else {
bigImgSize = AndroidUtilities.dp(30); bigImgSize = AndroidUtilities.dp(32);
} }
for (int j = 1; j < data.length; j++) { for (int j = 1; j < data.length; j++) {
...@@ -234,8 +235,26 @@ public class Emoji { ...@@ -234,8 +235,26 @@ public class Emoji {
scale = 3.0f; scale = 3.0f;
} }
String imageName = String.format(Locale.US, "emoji%.01fx_%d.jpg", scale, page); String imageName;
File imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName); File imageFile;
try {
imageName = String.format(Locale.US, "emoji%.01fx_%d.jpg", scale, page);
imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
if (imageFile.exists()) {
imageFile.delete();
}
imageName = String.format(Locale.US, "emoji%.01fx_a_%d.jpg", scale, page);
imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
if (imageFile.exists()) {
imageFile.delete();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
imageName = String.format(Locale.US, "v4_emoji%.01fx_%d.jpg", scale, page);
imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
if (!imageFile.exists()) { if (!imageFile.exists()) {
InputStream is = ApplicationLoader.applicationContext.getAssets().open("emoji/" + imageName); InputStream is = ApplicationLoader.applicationContext.getAssets().open("emoji/" + imageName);
Utilities.copyFile(is, imageFile); Utilities.copyFile(is, imageFile);
...@@ -253,7 +272,7 @@ public class Emoji { ...@@ -253,7 +272,7 @@ public class Emoji {
final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Utilities.loadBitmap(imageFile.getAbsolutePath(), bitmap, imageResize, width, height, stride); Utilities.loadBitmap(imageFile.getAbsolutePath(), bitmap, imageResize, width, height, stride);
imageName = String.format(Locale.US, "emoji%.01fx_a_%d.jpg", scale, page); imageName = String.format(Locale.US, "v4_emoji%.01fx_a_%d.jpg", scale, page);
imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName); imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
if (!imageFile.exists()) { if (!imageFile.exists()) {
InputStream is = ApplicationLoader.applicationContext.getAssets().open("emoji/" + imageName); InputStream is = ApplicationLoader.applicationContext.getAssets().open("emoji/" + imageName);
......
...@@ -309,6 +309,10 @@ public class LocaleController { ...@@ -309,6 +309,10 @@ public class LocaleController {
} }
} }
public Locale getSystemDefaultLocale() {
return systemDefaultLocale;
}
public static String getLocaleString(Locale locale) { public static String getLocaleString(Locale locale) {
if (locale == null) { if (locale == null) {
return "en"; return "en";
...@@ -607,11 +611,12 @@ public class LocaleController { ...@@ -607,11 +611,12 @@ public class LocaleController {
} }
public static String formatString(String key, int res, Object... args) { public static String formatString(String key, int res, Object... args) {
try {
String value = getInstance().localeValues.get(key); String value = getInstance().localeValues.get(key);
if (value == null) { if (value == null) {
value = ApplicationLoader.applicationContext.getString(res); value = ApplicationLoader.applicationContext.getString(res);
} }
try {
if (getInstance().currentLocale != null) { if (getInstance().currentLocale != null) {
return String.format(getInstance().currentLocale, value, args); return String.format(getInstance().currentLocale, value, args);
} else { } else {
......
...@@ -42,6 +42,7 @@ public class MessageObject { ...@@ -42,6 +42,7 @@ public class MessageObject {
public TLRPC.Message messageOwner; public TLRPC.Message messageOwner;
public CharSequence messageText; public CharSequence messageText;
public CharSequence linkDescription; public CharSequence linkDescription;
public CharSequence caption;
public MessageObject replyMessageObject; public MessageObject replyMessageObject;
public int type; public int type;
public int contentType; public int contentType;
...@@ -52,7 +53,7 @@ public class MessageObject { ...@@ -52,7 +53,7 @@ public class MessageObject {
public int audioProgressSec; public int audioProgressSec;
public ArrayList<TLRPC.PhotoSize> photoThumbs; public ArrayList<TLRPC.PhotoSize> photoThumbs;
private static TextPaint textPaint; public static TextPaint textPaint;
public int lastLineWidth; public int lastLineWidth;
public int textWidth; public int textWidth;
public int textHeight; public int textHeight;
...@@ -144,6 +145,13 @@ public class MessageObject { ...@@ -144,6 +145,13 @@ public class MessageObject {
whoUser = MessagesController.getInstance().getUser(message.action.user_id); whoUser = MessagesController.getInstance().getUser(message.action.user_id);
} }
if (whoUser != null && fromUser != null) { if (whoUser != null && fromUser != null) {
if (whoUser.id == fromUser.id) {
if (isOut()) {
messageText = LocaleController.getString("ActionAddUserSelf", R.string.ActionAddUserSelf).replace("un1", LocaleController.getString("FromYou", R.string.FromYou));
} else {
messageText = replaceWithLink(LocaleController.getString("ActionAddUserSelf", R.string.ActionAddUserSelf), "un1", fromUser);
}
} else {
if (isOut()) { if (isOut()) {
messageText = replaceWithLink(LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser), "un2", whoUser); messageText = replaceWithLink(LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser), "un2", whoUser);
} else if (message.action.user_id == UserConfig.getClientUserId()) { } else if (message.action.user_id == UserConfig.getClientUserId()) {
...@@ -152,9 +160,20 @@ public class MessageObject { ...@@ -152,9 +160,20 @@ public class MessageObject {
messageText = replaceWithLink(LocaleController.getString("ActionAddUser", R.string.ActionAddUser), "un2", whoUser); messageText = replaceWithLink(LocaleController.getString("ActionAddUser", R.string.ActionAddUser), "un2", whoUser);
messageText = replaceWithLink(messageText, "un1", fromUser); messageText = replaceWithLink(messageText, "un1", fromUser);
} }
}
} else { } else {
messageText = LocaleController.getString("ActionAddUser", R.string.ActionAddUser).replace("un2", "").replace("un1", ""); messageText = LocaleController.getString("ActionAddUser", R.string.ActionAddUser).replace("un2", "").replace("un1", "");
} }
} else if (message.action instanceof TLRPC.TL_messageActionChatJoinedByLink) {
if (fromUser != null) {
if (isOut()) {
messageText = LocaleController.getString("ActionInviteYou", R.string.ActionInviteYou);
} else {
messageText = replaceWithLink(LocaleController.getString("ActionInviteUser", R.string.ActionInviteUser), "un1", fromUser);
}
} else {
messageText = LocaleController.getString("ActionInviteUser", R.string.ActionInviteUser).replace("un1", "");
}
} else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) { } else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) {
if (isOut()) { if (isOut()) {
messageText = LocaleController.getString("ActionYouChangedPhoto", R.string.ActionYouChangedPhoto); messageText = LocaleController.getString("ActionYouChangedPhoto", R.string.ActionYouChangedPhoto);
...@@ -279,7 +298,7 @@ public class MessageObject { ...@@ -279,7 +298,7 @@ public class MessageObject {
messageText = LocaleController.getString("AttachPhoto", R.string.AttachPhoto); messageText = LocaleController.getString("AttachPhoto", R.string.AttachPhoto);
} else if (message.media instanceof TLRPC.TL_messageMediaVideo) { } else if (message.media instanceof TLRPC.TL_messageMediaVideo) {
messageText = LocaleController.getString("AttachVideo", R.string.AttachVideo); messageText = LocaleController.getString("AttachVideo", R.string.AttachVideo);
} else if (message.media instanceof TLRPC.TL_messageMediaGeo) { } else if (message.media instanceof TLRPC.TL_messageMediaGeo || message.media instanceof TLRPC.TL_messageMediaVenue) {
messageText = LocaleController.getString("AttachLocation", R.string.AttachLocation); messageText = LocaleController.getString("AttachLocation", R.string.AttachLocation);
} else if (message.media instanceof TLRPC.TL_messageMediaContact) { } else if (message.media instanceof TLRPC.TL_messageMediaContact) {
messageText = LocaleController.getString("AttachContact", R.string.AttachContact); messageText = LocaleController.getString("AttachContact", R.string.AttachContact);
...@@ -314,7 +333,7 @@ public class MessageObject { ...@@ -314,7 +333,7 @@ public class MessageObject {
contentType = type = 0; contentType = type = 0;
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) { } else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
contentType = type = 1; contentType = type = 1;
} else if (message.media instanceof TLRPC.TL_messageMediaGeo) { } else if (message.media instanceof TLRPC.TL_messageMediaGeo || message.media instanceof TLRPC.TL_messageMediaVenue) {
contentType = 1; contentType = 1;
type = 4; type = 4;
} else if (message.media instanceof TLRPC.TL_messageMediaVideo) { } else if (message.media instanceof TLRPC.TL_messageMediaVideo) {
...@@ -374,6 +393,7 @@ public class MessageObject { ...@@ -374,6 +393,7 @@ public class MessageObject {
monthKey = String.format("%d_%02d", dateYear, dateMonth); monthKey = String.format("%d_%02d", dateYear, dateMonth);
} }
generateCaption();
if (generateLayout) { if (generateLayout) {
generateLayout(); generateLayout();
} }
...@@ -569,6 +589,41 @@ public class MessageObject { ...@@ -569,6 +589,41 @@ public class MessageObject {
} }
} }
public void generateCaption() {
if (caption != null) {
return;
}
if (messageOwner.media != null && messageOwner.media.caption != null && messageOwner.media.caption.length() > 0) {
caption = Emoji.replaceEmoji(messageOwner.media.caption, textPaint.getFontMetricsInt(), AndroidUtilities.dp(20));
if (containsUrls(caption)) {
try {
Linkify.addLinks((Spannable) caption, Linkify.WEB_URLS);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
addUsernamesAndHashtags(caption);
}
}
}
private void addUsernamesAndHashtags(CharSequence charSequence) {
try {
Pattern pattern = Pattern.compile("(^|\\s)@[a-zA-Z\\d_]{5,32}|(^|\\s)#[\\w\\.]+");
Matcher matcher = pattern.matcher(charSequence);
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
if (charSequence.charAt(start) != '@' && charSequence.charAt(start) != '#') {
start++;
}
URLSpanNoUnderline url = new URLSpanNoUnderline(charSequence.subSequence(start, end).toString());
((Spannable) charSequence).setSpan(url, start, end, 0);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
private void generateLayout() { private void generateLayout() {
if (type != 0 || messageOwner.to_id == null || messageText == null || messageText.length() == 0) { if (type != 0 || messageOwner.to_id == null || messageText == null || messageText.length() == 0) {
return; return;
...@@ -579,27 +634,20 @@ public class MessageObject { ...@@ -579,27 +634,20 @@ public class MessageObject {
if (messageText instanceof Spannable && containsUrls(messageText)) { if (messageText instanceof Spannable && containsUrls(messageText)) {
if (messageText.length() < 100) { if (messageText.length() < 100) {
try {
Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS); Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
} else { } catch (Exception e) {
Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS); FileLog.e("tmessages", e);
} }
} else {
try { try {
Pattern pattern = Pattern.compile("(^|\\s)@[a-zA-Z\\d_]{5,32}|(^|\\s)#[\\w\\.]+"); Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS);
Matcher matcher = pattern.matcher(messageText);
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
if (messageText.charAt(start) != '@' && messageText.charAt(start) != '#') {
start++;
}
URLSpanNoUnderline url = new URLSpanNoUnderline(messageText.subSequence(start, end).toString());
((Spannable) messageText).setSpan(url, start, end, 0);
}
} catch (Exception e) { } catch (Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
} }
} }
addUsernamesAndHashtags(messageText);
}
int maxWidth; int maxWidth;
if (AndroidUtilities.isTablet()) { if (AndroidUtilities.isTablet()) {
...@@ -763,10 +811,33 @@ public class MessageObject { ...@@ -763,10 +811,33 @@ public class MessageObject {
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0; return (messageOwner.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0;
} }
public boolean isContentUnread() {
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_CONTENT_UNREAD) != 0;
}
public void setIsRead() { public void setIsRead() {
messageOwner.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD; messageOwner.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD;
} }
public int getUnradFlags() {
return getUnreadFlags(messageOwner);
}
public static int getUnreadFlags(TLRPC.Message message) {
int flags = 0;
if ((message.flags & TLRPC.MESSAGE_FLAG_UNREAD) == 0) {
flags |= 1;
}
if ((message.flags & TLRPC.MESSAGE_FLAG_CONTENT_UNREAD) == 0) {
flags |= 2;
}
return flags;
}
public void setContentIsRead() {
messageOwner.flags &= ~TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
}
public int getId() { public int getId() {
return messageOwner.id; return messageOwner.id;
} }
...@@ -782,18 +853,27 @@ public class MessageObject { ...@@ -782,18 +853,27 @@ public class MessageObject {
messageOwner.media instanceof TLRPC.TL_messageMediaVideo); messageOwner.media instanceof TLRPC.TL_messageMediaVideo);
} }
public static void setIsUnread(TLRPC.Message message, boolean unread) { public static void setUnreadFlags(TLRPC.Message message, int flag) {
if (unread) { if ((flag & 1) == 0) {
message.flags |= TLRPC.MESSAGE_FLAG_UNREAD; message.flags |= TLRPC.MESSAGE_FLAG_UNREAD;
} else { } else {
message.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD; message.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD;
} }
if ((flag & 2) == 0) {
message.flags |= TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
} else {
message.flags &= ~TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
}
} }
public static boolean isUnread(TLRPC.Message message) { public static boolean isUnread(TLRPC.Message message) {
return (message.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0; return (message.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0;
} }
public static boolean isContentUnread(TLRPC.Message message) {
return (message.flags & TLRPC.MESSAGE_FLAG_CONTENT_UNREAD) != 0;
}
public static boolean isOut(TLRPC.Message message) { public static boolean isOut(TLRPC.Message message) {
return (message.flags & TLRPC.MESSAGE_FLAG_OUT) != 0; return (message.flags & TLRPC.MESSAGE_FLAG_OUT) != 0;
} }
......
...@@ -23,7 +23,7 @@ import java.util.zip.ZipFile; ...@@ -23,7 +23,7 @@ import java.util.zip.ZipFile;
public class NativeLoader { public class NativeLoader {
private final static int LIB_VERSION = 7; private final static int LIB_VERSION = 8;
private final static String LIB_NAME = "tmessages." + LIB_VERSION; private final static String LIB_NAME = "tmessages." + LIB_VERSION;
private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so"; private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so";
private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so"; private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so";
......
...@@ -32,7 +32,7 @@ public class NotificationCenter { ...@@ -32,7 +32,7 @@ public class NotificationCenter {
public static final int mediaDidLoaded = totalEvents++; public static final int mediaDidLoaded = totalEvents++;
public static final int mediaCountDidLoaded = totalEvents++; public static final int mediaCountDidLoaded = totalEvents++;
public static final int encryptedChatUpdated = totalEvents++; public static final int encryptedChatUpdated = totalEvents++;
public static final int messagesReadedEncrypted = totalEvents++; public static final int messagesReadEncrypted = totalEvents++;
public static final int encryptedChatCreated = totalEvents++; public static final int encryptedChatCreated = totalEvents++;
public static final int userPhotosLoaded = totalEvents++; public static final int userPhotosLoaded = totalEvents++;
public static final int removeAllMessagesFromDialog = totalEvents++; public static final int removeAllMessagesFromDialog = totalEvents++;
...@@ -56,6 +56,9 @@ public class NotificationCenter { ...@@ -56,6 +56,9 @@ public class NotificationCenter {
public static final int newSessionReceived = totalEvents++; public static final int newSessionReceived = totalEvents++;
public static final int didReceivedWebpages = totalEvents++; public static final int didReceivedWebpages = totalEvents++;
public static final int didReceivedWebpagesInUpdates = totalEvents++; public static final int didReceivedWebpagesInUpdates = totalEvents++;
public static final int stickersDidLoaded = totalEvents++;
public static final int didReplacedPhotoInMemCache = totalEvents++;
public static final int messagesReadContent = totalEvents++;
public static final int httpFileDidLoaded = totalEvents++; public static final int httpFileDidLoaded = totalEvents++;
public static final int httpFileDidFailedLoad = totalEvents++; public static final int httpFileDidFailedLoad = totalEvents++;
......
...@@ -542,7 +542,7 @@ public class SecretChatHelper { ...@@ -542,7 +542,7 @@ public class SecretChatHelper {
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg"); File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg");
File cacheFile2 = FileLoader.getPathToAttach(size); File cacheFile2 = FileLoader.getPathToAttach(size);
cacheFile.renameTo(cacheFile2); cacheFile.renameTo(cacheFile2);
ImageLoader.getInstance().replaceImageInCache(fileName, fileName2); ImageLoader.getInstance().replaceImageInCache(fileName, fileName2, size.location);
ArrayList<TLRPC.Message> arr = new ArrayList<>(); ArrayList<TLRPC.Message> arr = new ArrayList<>();
arr.add(newMsg); arr.add(newMsg);
MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); MessagesStorage.getInstance().putMessages(arr, false, true, false, 0);
...@@ -557,7 +557,7 @@ public class SecretChatHelper { ...@@ -557,7 +557,7 @@ public class SecretChatHelper {
newMsg.media.video.w = video.w; newMsg.media.video.w = video.w;
newMsg.media.video.h = video.h; newMsg.media.video.h = video.h;
newMsg.media.video.date = video.date; newMsg.media.video.date = video.date;
newMsg.media.video.caption = ""; newMsg.media.caption = video.caption != null ? video.caption : "";
newMsg.media.video.user_id = video.user_id; newMsg.media.video.user_id = video.user_id;
newMsg.media.video.size = file.size; newMsg.media.video.size = file.size;
newMsg.media.video.id = file.id; newMsg.media.video.id = file.id;
...@@ -565,6 +565,7 @@ public class SecretChatHelper { ...@@ -565,6 +565,7 @@ public class SecretChatHelper {
newMsg.media.video.key = decryptedMessage.media.key; newMsg.media.video.key = decryptedMessage.media.key;
newMsg.media.video.iv = decryptedMessage.media.iv; newMsg.media.video.iv = decryptedMessage.media.iv;
newMsg.media.video.mime_type = video.mime_type; newMsg.media.video.mime_type = video.mime_type;
newMsg.media.video.caption = video.caption != null ? video.caption : "";
if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) {
File cacheFile = new File(newMsg.attachPath); File cacheFile = new File(newMsg.attachPath);
...@@ -893,10 +894,10 @@ public class SecretChatHelper { ...@@ -893,10 +894,10 @@ public class SecretChatHelper {
return null; return null;
} }
newMessage.media = new TLRPC.TL_messageMediaPhoto(); newMessage.media = new TLRPC.TL_messageMediaPhoto();
newMessage.media.caption = "";
newMessage.media.photo = new TLRPC.TL_photo(); newMessage.media.photo = new TLRPC.TL_photo();
newMessage.media.photo.user_id = newMessage.from_id; newMessage.media.photo.user_id = newMessage.from_id;
newMessage.media.photo.date = newMessage.date; newMessage.media.photo.date = newMessage.date;
newMessage.media.photo.caption = "";
newMessage.media.photo.geo = new TLRPC.TL_geoPointEmpty(); newMessage.media.photo.geo = new TLRPC.TL_geoPointEmpty();
if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) { if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
TLRPC.TL_photoCachedSize small = new TLRPC.TL_photoCachedSize(); TLRPC.TL_photoCachedSize small = new TLRPC.TL_photoCachedSize();
...@@ -926,6 +927,7 @@ public class SecretChatHelper { ...@@ -926,6 +927,7 @@ public class SecretChatHelper {
return null; return null;
} }
newMessage.media = new TLRPC.TL_messageMediaVideo(); newMessage.media = new TLRPC.TL_messageMediaVideo();
newMessage.media.caption = "";
newMessage.media.video = new TLRPC.TL_videoEncrypted(); newMessage.media.video = new TLRPC.TL_videoEncrypted();
if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) { if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
newMessage.media.video.thumb = new TLRPC.TL_photoCachedSize(); newMessage.media.video.thumb = new TLRPC.TL_photoCachedSize();
...@@ -943,7 +945,6 @@ public class SecretChatHelper { ...@@ -943,7 +945,6 @@ public class SecretChatHelper {
newMessage.media.video.w = decryptedMessage.media.w; newMessage.media.video.w = decryptedMessage.media.w;
newMessage.media.video.h = decryptedMessage.media.h; newMessage.media.video.h = decryptedMessage.media.h;
newMessage.media.video.date = date; newMessage.media.video.date = date;
newMessage.media.video.caption = "";
newMessage.media.video.user_id = from_id; newMessage.media.video.user_id = from_id;
newMessage.media.video.size = file.size; newMessage.media.video.size = file.size;
newMessage.media.video.id = file.id; newMessage.media.video.id = file.id;
...@@ -951,6 +952,7 @@ public class SecretChatHelper { ...@@ -951,6 +952,7 @@ public class SecretChatHelper {
newMessage.media.video.key = decryptedMessage.media.key; newMessage.media.video.key = decryptedMessage.media.key;
newMessage.media.video.iv = decryptedMessage.media.iv; newMessage.media.video.iv = decryptedMessage.media.iv;
newMessage.media.video.mime_type = decryptedMessage.media.mime_type; newMessage.media.video.mime_type = decryptedMessage.media.mime_type;
newMessage.media.video.caption = "";
if (newMessage.ttl != 0) { if (newMessage.ttl != 0) {
newMessage.ttl = Math.max(newMessage.media.video.duration + 1, newMessage.ttl); newMessage.ttl = Math.max(newMessage.media.video.duration + 1, newMessage.ttl);
} }
...@@ -1300,7 +1302,7 @@ public class SecretChatHelper { ...@@ -1300,7 +1302,7 @@ public class SecretChatHelper {
ByteBufferDesc is = BuffersStorage.getInstance().getFreeBuffer(message.bytes.length); ByteBufferDesc is = BuffersStorage.getInstance().getFreeBuffer(message.bytes.length);
is.writeRaw(message.bytes); is.writeRaw(message.bytes);
is.position(0); is.position(0);
long fingerprint = is.readInt64(); long fingerprint = is.readInt64(false);
byte[] keyToDecrypt = null; byte[] keyToDecrypt = null;
boolean new_key_used = false; boolean new_key_used = false;
if (chat.key_fingerprint == fingerprint) { if (chat.key_fingerprint == fingerprint) {
...@@ -1311,12 +1313,12 @@ public class SecretChatHelper { ...@@ -1311,12 +1313,12 @@ public class SecretChatHelper {
} }
if (keyToDecrypt != null) { if (keyToDecrypt != null) {
byte[] messageKey = is.readData(16); byte[] messageKey = is.readData(16, false);
MessageKeyData keyData = Utilities.generateMessageKeyData(keyToDecrypt, messageKey, false); MessageKeyData keyData = Utilities.generateMessageKeyData(keyToDecrypt, messageKey, false);
Utilities.aesIgeEncryption(is.buffer, keyData.aesKey, keyData.aesIv, false, false, 24, is.limit() - 24); Utilities.aesIgeEncryption(is.buffer, keyData.aesKey, keyData.aesIv, false, false, 24, is.limit() - 24);
int len = is.readInt32(); int len = is.readInt32(false);
if (len < 0 || len > is.limit() - 28) { if (len < 0 || len > is.limit() - 28) {
return null; return null;
} }
...@@ -1325,7 +1327,13 @@ public class SecretChatHelper { ...@@ -1325,7 +1327,13 @@ public class SecretChatHelper {
return null; return null;
} }
TLObject object = TLClassStore.Instance().TLdeserialize(is, is.readInt32()); TLObject object = null;
try {
object = TLClassStore.Instance().TLdeserialize(is, is.readInt32(true), true);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
BuffersStorage.getInstance().reuseFreeBuffer(is); BuffersStorage.getInstance().reuseFreeBuffer(is);
if (!new_key_used && AndroidUtilities.getPeerLayerVersion(chat.layer) >= 20) { if (!new_key_used && AndroidUtilities.getPeerLayerVersion(chat.layer) >= 20) {
chat.key_use_count_in++; chat.key_use_count_in++;
......
...@@ -21,7 +21,6 @@ import org.telegram.messenger.ByteBufferDesc; ...@@ -21,7 +21,6 @@ import org.telegram.messenger.ByteBufferDesc;
import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.RPCRequest; import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLClassStore;
import org.telegram.messenger.TLObject; import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC; import org.telegram.messenger.TLRPC;
...@@ -65,7 +64,7 @@ public class ReplyMessageQuery { ...@@ -65,7 +64,7 @@ public class ReplyMessageQuery {
while (cursor.next()) { while (cursor.next()) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.id = cursor.intValue(1); message.id = cursor.intValue(1);
message.date = cursor.intValue(2); message.date = cursor.intValue(2);
message.dialog_id = dialog_id; message.dialog_id = dialog_id;
......
...@@ -20,7 +20,6 @@ import org.telegram.messenger.ByteBufferDesc; ...@@ -20,7 +20,6 @@ import org.telegram.messenger.ByteBufferDesc;
import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.RPCRequest; import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLClassStore;
import org.telegram.messenger.TLObject; import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC; import org.telegram.messenger.TLRPC;
...@@ -178,7 +177,7 @@ public class SharedMediaQuery { ...@@ -178,7 +177,7 @@ public class SharedMediaQuery {
} }
final ArrayList<MessageObject> objects = new ArrayList<>(); final ArrayList<MessageObject> objects = new ArrayList<>();
for (TLRPC.Message message : res.messages) { for (TLRPC.Message message : res.messages) {
objects.add(new MessageObject(message, usersLocal, false)); objects.add(new MessageObject(message, usersLocal, true));
} }
AndroidUtilities.runOnUIThread(new Runnable() { AndroidUtilities.runOnUIThread(new Runnable() {
...@@ -324,7 +323,7 @@ public class SharedMediaQuery { ...@@ -324,7 +323,7 @@ public class SharedMediaQuery {
while (cursor.next()) { while (cursor.next()) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.id = cursor.intValue(1); message.id = cursor.intValue(1);
message.dialog_id = uid; message.dialog_id = uid;
if ((int)uid == 0) { if ((int)uid == 0) {
......
/*
* This is the source code of Telegram for Android v. 2.x
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.android.query;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.MessagesStorage;
import org.telegram.android.NotificationCenter;
import org.telegram.messenger.ByteBufferDesc;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.Utilities;
import java.util.ArrayList;
import java.util.HashMap;
public class StickersQuery {
private static String hash;
private static int loadDate;
private static ArrayList<TLRPC.Document> stickers = new ArrayList<>();
private static HashMap<String, ArrayList<TLRPC.Document>> allStickers = new HashMap<>();
private static boolean loadingStickers;
public static void checkStickers() {
if (!loadingStickers && (allStickers.isEmpty() || loadDate < (System.currentTimeMillis() / 1000 - 60 * 60))) {
loadStickers(true);
}
}
public static ArrayList<TLRPC.Document> getStickers() {
return stickers;
}
private static void loadStickers(boolean cache) {
if (loadingStickers) {
return;
}
loadingStickers = true;
if (cache) {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
TLRPC.messages_AllStickers result = null;
int date = 0;
try {
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, date FROM stickers WHERE 1");
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
result = TLRPC.messages_AllStickers.TLdeserialize(data, data.readInt32(false), false);
}
date = cursor.intValue(1);
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
}
cursor.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
processLoadedStickers(result, true, date);
}
});
} else {
TLRPC.TL_messages_getAllStickers req = new TLRPC.TL_messages_getAllStickers();
req.hash = hash;
if (req.hash == null) {
req.hash = "";
}
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(final TLObject response, final TLRPC.TL_error error) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
processLoadedStickers((TLRPC.messages_AllStickers) response, false, (int) (System.currentTimeMillis() / 1000));
}
});
}
});
}
}
private static void putStickersToCache(final TLRPC.TL_messages_allStickers stickers) {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO stickers VALUES(?, ?, ?)");
state.requery();
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(stickers.getObjectSize());
stickers.serializeToStream(data);
state.bindInteger(1, 1);
state.bindByteBuffer(2, data.buffer);
state.bindInteger(3, (int) (System.currentTimeMillis() / 1000));
state.step();
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
state.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
private static void processLoadedStickers(final TLRPC.messages_AllStickers res, final boolean cache, final int date) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadingStickers = false;
}
});
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
if ((res == null || date < (int) (System.currentTimeMillis() / 1000 - 60 * 60)) && cache) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadStickers(false);
}
});
if (res == null) {
return;
}
}
if (res instanceof TLRPC.TL_messages_allStickers) {
if (!cache) {
putStickersToCache((TLRPC.TL_messages_allStickers) res);
}
HashMap<Long, TLRPC.Document> documents = new HashMap<>();
for (TLRPC.Document document : res.documents) {
if (document == null) {
continue;
}
documents.put(document.id, document);
if (document.thumb != null && document.thumb.location != null) {
document.thumb.location.ext = "webp";
}
}
final HashMap<String, ArrayList<TLRPC.Document>> result = new HashMap<>();
for (TLRPC.TL_stickerPack stickerPack : res.packs) {
if (stickerPack != null && stickerPack.emoticon != null) {
stickerPack.emoticon = stickerPack.emoticon.replace("\uFE0F", "");
ArrayList<TLRPC.Document> arrayList = result.get(stickerPack.emoticon);
for (Long id : stickerPack.documents) {
TLRPC.Document document = documents.get(id);
if (document != null) {
if (arrayList == null) {
arrayList = new ArrayList<>();
result.put(stickerPack.emoticon, arrayList);
}
arrayList.add(document);
}
}
}
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
allStickers = result;
stickers = res.documents;
hash = res.hash;
loadDate = date;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded);
}
});
}
}
});
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment