diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index bbfc4d219..0fac4cf04 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -80,7 +80,7 @@ android { defaultConfig { minSdkVersion 8 targetSdkVersion 19 - versionCode 326 - versionName "1.8.3" + versionCode 327 + versionName "1.9.0" } } diff --git a/TMessagesProj/jni/Android.mk b/TMessagesProj/jni/Android.mk index 87fffeb51..7ed09eb22 100755 --- a/TMessagesProj/jni/Android.mk +++ b/TMessagesProj/jni/Android.mk @@ -3,12 +3,12 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_PRELINK_MODULE := false LOCAL_MODULE := tmessages -LOCAL_CFLAGS := -w -std=gnu99 -O2 -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -DLOG_DISABLED +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 += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT LOCAL_CPPFLAGS := -DBSD=1 -ffast-math -O2 -funroll-loops #LOCAL_LDLIBS := -llog -LOCAL_LDLIBS := -ljnigraphics +LOCAL_LDLIBS := -ljnigraphics -llog LOCAL_SRC_FILES := \ ./opus/src/opus.c \ @@ -227,6 +227,46 @@ LOCAL_SRC_FILES += \ ./libjpeg/jquant2.c \ ./libjpeg/jutils.c +LOCAL_SRC_FILES += \ +./libyuv/source/compare_common.cc \ +./libyuv/source/compare_neon.cc \ +./libyuv/source/compare_posix.cc \ +./libyuv/source/compare_win.cc \ +./libyuv/source/compare.cc \ +./libyuv/source/convert_argb.cc \ +./libyuv/source/convert_from_argb.cc \ +./libyuv/source/convert_from.cc \ +./libyuv/source/convert_jpeg.cc \ +./libyuv/source/convert_to_argb.cc \ +./libyuv/source/convert_to_i420.cc \ +./libyuv/source/convert.cc \ +./libyuv/source/cpu_id.cc \ +./libyuv/source/format_conversion.cc \ +./libyuv/source/mjpeg_decoder.cc \ +./libyuv/source/mjpeg_validate.cc \ +./libyuv/source/planar_functions.cc \ +./libyuv/source/rotate_argb.cc \ +./libyuv/source/rotate_mips.cc \ +./libyuv/source/rotate_neon.cc \ +./libyuv/source/rotate_neon64.cc \ +./libyuv/source/rotate.cc \ +./libyuv/source/row_any.cc \ +./libyuv/source/row_common.cc \ +./libyuv/source/row_mips.cc \ +./libyuv/source/row_neon.cc \ +./libyuv/source/row_neon64.cc \ +./libyuv/source/row_posix.cc \ +./libyuv/source/row_win.cc \ +./libyuv/source/scale_argb.cc \ +./libyuv/source/scale_common.cc \ +./libyuv/source/scale_mips.cc \ +./libyuv/source/scale_neon.cc \ +./libyuv/source/scale_neon64.cc \ +./libyuv/source/scale_posix.cc \ +./libyuv/source/scale_win.cc \ +./libyuv/source/scale.cc \ +./libyuv/source/video_common.cc + LOCAL_SRC_FILES += \ ./jni.c \ ./sqlite_cursor.c \ @@ -237,6 +277,7 @@ LOCAL_SRC_FILES += \ ./gif.c \ ./utils.c \ ./image.c \ +./video.c \ ./fake.c include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/TMessagesProj/jni/fake.c b/TMessagesProj/jni/fake.c index bd08db5a1..0af425568 100644 --- a/TMessagesProj/jni/fake.c +++ b/TMessagesProj/jni/fake.c @@ -2,5 +2,5 @@ void fakeFunction() { printf("some androids has buggy native loader, so i should check size of libs in java to know that native library is correct. So each changed native library should has diffrent size in different app versions. This function will increase lib size for few bytes :)"); - printf("bla blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla"); + printf(""); } diff --git a/TMessagesProj/jni/utils.h b/TMessagesProj/jni/utils.h index 34805a1d7..f17ae9025 100644 --- a/TMessagesProj/jni/utils.h +++ b/TMessagesProj/jni/utils.h @@ -4,7 +4,7 @@ #include #include -#define LOG_TAG "tmessages_native" +#define LOG_TAG "tmessages" #ifndef LOG_DISABLED #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) diff --git a/TMessagesProj/jni/video.c b/TMessagesProj/jni/video.c new file mode 100644 index 000000000..17771111c --- /dev/null +++ b/TMessagesProj/jni/video.c @@ -0,0 +1,94 @@ +#include +#include +#include + +enum COLOR_FORMATTYPE { + COLOR_FormatMonochrome = 1, + COLOR_Format8bitRGB332 = 2, + COLOR_Format12bitRGB444 = 3, + COLOR_Format16bitARGB4444 = 4, + COLOR_Format16bitARGB1555 = 5, + COLOR_Format16bitRGB565 = 6, + COLOR_Format16bitBGR565 = 7, + COLOR_Format18bitRGB666 = 8, + COLOR_Format18bitARGB1665 = 9, + COLOR_Format19bitARGB1666 = 10, + COLOR_Format24bitRGB888 = 11, + COLOR_Format24bitBGR888 = 12, + COLOR_Format24bitARGB1887 = 13, + COLOR_Format25bitARGB1888 = 14, + COLOR_Format32bitBGRA8888 = 15, + COLOR_Format32bitARGB8888 = 16, + COLOR_FormatYUV411Planar = 17, + COLOR_FormatYUV411PackedPlanar = 18, + COLOR_FormatYUV420Planar = 19, + COLOR_FormatYUV420PackedPlanar = 20, + COLOR_FormatYUV420SemiPlanar = 21, + COLOR_FormatYUV422Planar = 22, + COLOR_FormatYUV422PackedPlanar = 23, + COLOR_FormatYUV422SemiPlanar = 24, + COLOR_FormatYCbYCr = 25, + COLOR_FormatYCrYCb = 26, + COLOR_FormatCbYCrY = 27, + COLOR_FormatCrYCbY = 28, + COLOR_FormatYUV444Interleaved = 29, + COLOR_FormatRawBayer8bit = 30, + COLOR_FormatRawBayer10bit = 31, + COLOR_FormatRawBayer8bitcompressed = 32, + COLOR_FormatL2 = 33, + COLOR_FormatL4 = 34, + COLOR_FormatL8 = 35, + COLOR_FormatL16 = 36, + COLOR_FormatL24 = 37, + COLOR_FormatL32 = 38, + COLOR_FormatYUV420PackedSemiPlanar = 39, + COLOR_FormatYUV422PackedSemiPlanar = 40, + COLOR_Format18BitBGR666 = 41, + COLOR_Format24BitARGB6666 = 42, + COLOR_Format24BitABGR6666 = 43, + + COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100, + COLOR_FormatSurface = 0x7F000789, + COLOR_QCOM_FormatYUV420SemiPlanar = 0x7fa30c00 +}; + +int isSemiPlanarYUV(int colorFormat) { + switch (colorFormat) { + case COLOR_FormatYUV420Planar: + case COLOR_FormatYUV420PackedPlanar: + return 0; + case COLOR_FormatYUV420SemiPlanar: + case COLOR_FormatYUV420PackedSemiPlanar: + case COLOR_TI_FormatYUV420PackedSemiPlanar: + return 1; + default: + return 0; + } +} + +JNIEXPORT int Java_org_telegram_messenger_Utilities_convertVideoFrame(JNIEnv *env, jclass class, jobject src, jobject dest, int destFormat, int width, int height, int padding) { + if (!src || !dest || !destFormat) { + return 0; + } + + jbyte *srcBuff = (*env)->GetDirectBufferAddress(env, src); + jbyte *destBuff = (*env)->GetDirectBufferAddress(env, dest); + + int half_width = (width + 1) / 2; + int half_height = (height + 1) / 2; + + if (!isSemiPlanarYUV(destFormat)) { + ARGBToI420(srcBuff, width * 4, + destBuff, width, + destBuff + width * height + half_width * half_height + padding * 5 / 4, half_width, + destBuff + width * height + padding, half_width, + width, height); + } else { + ARGBToNV21(srcBuff, width * 4, + destBuff, width, + destBuff + width * height + padding, half_width * 2, + width, height); + } + + return 1; +} diff --git a/TMessagesProj/libs/armeabi-v7a/libtmessages.so b/TMessagesProj/libs/armeabi-v7a/libtmessages.so index 07aee65fe..96100725e 100755 Binary files a/TMessagesProj/libs/armeabi-v7a/libtmessages.so and b/TMessagesProj/libs/armeabi-v7a/libtmessages.so differ diff --git a/TMessagesProj/libs/armeabi/libtmessages.so b/TMessagesProj/libs/armeabi/libtmessages.so index 422cd9445..74b229f10 100755 Binary files a/TMessagesProj/libs/armeabi/libtmessages.so and b/TMessagesProj/libs/armeabi/libtmessages.so differ diff --git a/TMessagesProj/libs/x86/libtmessages.so b/TMessagesProj/libs/x86/libtmessages.so index 05025a396..041687e31 100755 Binary files a/TMessagesProj/libs/x86/libtmessages.so and b/TMessagesProj/libs/x86/libtmessages.so differ diff --git a/TMessagesProj/src/main/AndroidManifest.xml b/TMessagesProj/src/main/AndroidManifest.xml index 8792d4131..d8ee6d5e8 100644 --- a/TMessagesProj/src/main/AndroidManifest.xml +++ b/TMessagesProj/src/main/AndroidManifest.xml @@ -98,8 +98,7 @@ + android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> typefaceCache = new Hashtable(); @@ -39,13 +42,44 @@ public class AndroidUtilities { public static float density = 1; public static Point displaySize = new Point(); + public static int[] arrColors = {0xffee4928, 0xff41a903, 0xffe09602, 0xff0f94ed, 0xff8f3bf7, 0xfffc4380, 0xff00a1c4, 0xffeb7002}; + public static int[] arrUsersAvatars = { + R.drawable.user_red, + R.drawable.user_green, + R.drawable.user_yellow, + R.drawable.user_blue, + R.drawable.user_violet, + R.drawable.user_pink, + R.drawable.user_aqua, + R.drawable.user_orange}; + + public static int[] arrGroupsAvatars = { + R.drawable.group_red, + R.drawable.group_green, + R.drawable.group_yellow, + R.drawable.group_blue, + R.drawable.group_violet, + R.drawable.group_pink, + R.drawable.group_aqua, + R.drawable.group_orange}; + + public static int[] arrBroadcastAvatars = { + R.drawable.broadcast_red, + R.drawable.broadcast_green, + R.drawable.broadcast_yellow, + R.drawable.broadcast_blue, + R.drawable.broadcast_violet, + R.drawable.broadcast_pink, + R.drawable.broadcast_aqua, + R.drawable.broadcast_orange}; + static { density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; checkDisplaySize(); } public static void lockOrientation(Activity activity) { - if (prevOrientation != -10) { + if (activity == null || prevOrientation != -10) { return; } try { @@ -103,6 +137,9 @@ public class AndroidUtilities { } public static void unlockOrientation(Activity activity) { + if (activity == null) { + return; + } try { if (prevOrientation != -10) { activity.setRequestedOrientation(prevOrientation); @@ -229,4 +266,60 @@ public class AndroidUtilities { public static void RunOnUIThread(Runnable runnable) { ApplicationLoader.applicationHandler.post(runnable); } + + public static boolean isTablet() { + return (ApplicationLoader.applicationContext.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; + } + + public static int getColorIndex(int id) { + int[] arr; + if (id >= 0) { + arr = arrUsersAvatars; + } else { + arr = arrGroupsAvatars; + } + try { + String str; + if (id >= 0) { + str = String.format(Locale.US, "%d%d", id, UserConfig.getClientUserId()); + } else { + str = String.format(Locale.US, "%d", id); + } + if (str.length() > 15) { + str = str.substring(0, 15); + } + java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); + byte[] digest = md.digest(str.getBytes()); + int b = digest[Math.abs(id % 16)]; + if (b < 0) { + b += 256; + } + return Math.abs(b) % arr.length; + } catch (Exception e) { + FileLog.e("tmessages", e); + } + return id % arr.length; + } + + public static int getColorForId(int id) { + if (id / 1000 == 333) { + return 0xff0f94ed; + } + return arrColors[getColorIndex(id)]; + } + + public static int getUserAvatarForId(int id) { + if (id / 1000 == 333 || id / 1000 == 777) { + return R.drawable.telegram_avatar; + } + return arrUsersAvatars[getColorIndex(id)]; + } + + public static int getGroupAvatarForId(int id) { + return arrGroupsAvatars[getColorIndex(-Math.abs(id))]; + } + + public static int getBroadcastAvatarForId(int id) { + return arrBroadcastAvatars[getColorIndex(-Math.abs(id))]; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java index b8680e45d..cd6cd1385 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java @@ -17,6 +17,7 @@ import android.database.Cursor; import android.net.Uri; import android.provider.BaseColumns; import android.provider.ContactsContract; +import android.provider.Settings; import android.util.SparseArray; import org.telegram.PhoneFormat.PhoneFormat; @@ -48,6 +49,7 @@ public class ContactsController { private boolean contactsBookLoaded = false; private String lastContactsVersions = ""; private ArrayList delayedContactsUpdate = new ArrayList(); + public int nameDisplayOrder = 1; public static class Contact { public int id; @@ -99,6 +101,14 @@ public class ContactsController { return localInstance; } + public ContactsController() { + try { + nameDisplayOrder = Settings.System.getInt(ApplicationLoader.applicationContext.getContentResolver(), "android.contacts.DISPLAY_ORDER"); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + public void cleanup() { contactsBook.clear(); contactsBookSPhones.clear(); @@ -1465,7 +1475,7 @@ public class ContactsController { MessagesStorage.getInstance().putContacts(arrayList, false); if (u.phone != null && u.phone.length() > 0) { - String name = Utilities.formatName(u.first_name, u.last_name); + String name = formatName(u.first_name, u.last_name); MessagesStorage.getInstance().applyPhoneBookUpdates(u.phone, ""); Contact contact = contactsBookSPhones.get(u.phone); if (contact != null) { @@ -1529,7 +1539,7 @@ public class ContactsController { for (TLRPC.User user : users) { if (user.phone != null && user.phone.length() > 0) { - String name = Utilities.formatName(user.first_name, user.last_name); + String name = ContactsController.formatName(user.first_name, user.last_name); MessagesStorage.getInstance().applyPhoneBookUpdates(user.phone, ""); Contact contact = contactsBookSPhones.get(user.phone); if (contact != null) { @@ -1563,4 +1573,24 @@ public class ContactsController { } }, true, RPCRequest.RPCRequestClassGeneric); } + + public static String formatName(String firstName, String lastName) { + String result = null; + if (ContactsController.getInstance().nameDisplayOrder == 1) { + result = firstName; + if (result == null || result.length() == 0) { + result = lastName; + } else if (result.length() != 0 && lastName != null && lastName.length() != 0) { + result += " " + lastName; + } + } else { + result = lastName; + if (result == null || result.length() == 0) { + result = firstName; + } else if (result.length() != 0 && firstName != null && firstName.length() != 0) { + result += " " + firstName; + } + } + return result.trim(); + } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/Emoji.java b/TMessagesProj/src/main/java/org/telegram/android/Emoji.java index b35ade3fa..6093f75f8 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/Emoji.java +++ b/TMessagesProj/src/main/java/org/telegram/android/Emoji.java @@ -214,7 +214,11 @@ public class Emoji { emojiFullSize = 90; } drawImgSize = AndroidUtilities.dp(20); - bigImgSize = AndroidUtilities.dp(30); + if (AndroidUtilities.isTablet()) { + bigImgSize = AndroidUtilities.dp(40); + } else { + bigImgSize = AndroidUtilities.dp(30); + } for (int j = 1; j < data.length; j++) { for (int i = 0; i < data[j].length; i++) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java index 6ccc2bdbb..9dff025bc 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java @@ -91,7 +91,7 @@ public class MessageObject { messageText = LocaleController.getString("ActionYouCreateGroup", R.string.ActionYouCreateGroup); } else { if (fromUser != null) { - messageText = LocaleController.getString("ActionCreateGroup", R.string.ActionCreateGroup).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.getString("ActionCreateGroup", R.string.ActionCreateGroup).replace("un1", ContactsController.formatName(fromUser.first_name, fromUser.last_name)); } else { messageText = LocaleController.getString("ActionCreateGroup", R.string.ActionCreateGroup).replace("un1", ""); } @@ -102,7 +102,7 @@ public class MessageObject { messageText = LocaleController.getString("ActionYouLeftUser", R.string.ActionYouLeftUser); } else { if (fromUser != null) { - messageText = LocaleController.getString("ActionLeftUser", R.string.ActionLeftUser).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.getString("ActionLeftUser", R.string.ActionLeftUser).replace("un1", ContactsController.formatName(fromUser.first_name, fromUser.last_name)); } else { messageText = LocaleController.getString("ActionLeftUser", R.string.ActionLeftUser).replace("un1", ""); } @@ -117,11 +117,11 @@ public class MessageObject { } if (who != null && fromUser != null) { if (isFromMe()) { - messageText = LocaleController.getString("ActionYouKickUser", R.string.ActionYouKickUser).replace("un2", Utilities.formatName(who.first_name, who.last_name)); + messageText = LocaleController.getString("ActionYouKickUser", R.string.ActionYouKickUser).replace("un2", ContactsController.formatName(who.first_name, who.last_name)); } else if (message.action.user_id == UserConfig.getClientUserId()) { - messageText = LocaleController.getString("ActionKickUserYou", R.string.ActionKickUserYou).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.getString("ActionKickUserYou", R.string.ActionKickUserYou).replace("un1", ContactsController.formatName(fromUser.first_name, fromUser.last_name)); } else { - messageText = LocaleController.getString("ActionKickUser", R.string.ActionKickUser).replace("un2", Utilities.formatName(who.first_name, who.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.getString("ActionKickUser", R.string.ActionKickUser).replace("un2", ContactsController.formatName(who.first_name, who.last_name)).replace("un1", ContactsController.formatName(fromUser.first_name, fromUser.last_name)); } } else { messageText = LocaleController.getString("ActionKickUser", R.string.ActionKickUser).replace("un2", "").replace("un1", ""); @@ -137,11 +137,11 @@ public class MessageObject { } if (whoUser != null && fromUser != null) { if (isFromMe()) { - messageText = LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser).replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)); + messageText = LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser).replace("un2", ContactsController.formatName(whoUser.first_name, whoUser.last_name)); } else if (message.action.user_id == UserConfig.getClientUserId()) { - messageText = LocaleController.getString("ActionAddUserYou", R.string.ActionAddUserYou).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.getString("ActionAddUserYou", R.string.ActionAddUserYou).replace("un1", ContactsController.formatName(fromUser.first_name, fromUser.last_name)); } else { - messageText = LocaleController.getString("ActionAddUser", R.string.ActionAddUser).replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.getString("ActionAddUser", R.string.ActionAddUser).replace("un2", ContactsController.formatName(whoUser.first_name, whoUser.last_name)).replace("un1", ContactsController.formatName(fromUser.first_name, fromUser.last_name)); } } else { messageText = LocaleController.getString("ActionAddUser", R.string.ActionAddUser).replace("un2", "").replace("un1", ""); @@ -151,7 +151,7 @@ public class MessageObject { messageText = LocaleController.getString("ActionYouChangedPhoto", R.string.ActionYouChangedPhoto); } else { if (fromUser != null) { - messageText = LocaleController.getString("ActionChangedPhoto", R.string.ActionChangedPhoto).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.getString("ActionChangedPhoto", R.string.ActionChangedPhoto).replace("un1", ContactsController.formatName(fromUser.first_name, fromUser.last_name)); } else { messageText = LocaleController.getString("ActionChangedPhoto", R.string.ActionChangedPhoto).replace("un1", ""); } @@ -161,7 +161,7 @@ public class MessageObject { messageText = LocaleController.getString("ActionYouChangedTitle", R.string.ActionYouChangedTitle).replace("un2", message.action.title); } else { if (fromUser != null) { - messageText = LocaleController.getString("ActionChangedTitle", R.string.ActionChangedTitle).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)).replace("un2", message.action.title); + messageText = LocaleController.getString("ActionChangedTitle", R.string.ActionChangedTitle).replace("un1", ContactsController.formatName(fromUser.first_name, fromUser.last_name)).replace("un2", message.action.title); } else { messageText = LocaleController.getString("ActionChangedTitle", R.string.ActionChangedTitle).replace("un1", "").replace("un2", message.action.title); } @@ -171,7 +171,7 @@ public class MessageObject { messageText = LocaleController.getString("ActionYouRemovedPhoto", R.string.ActionYouRemovedPhoto); } else { if (fromUser != null) { - messageText = LocaleController.getString("ActionRemovedPhoto", R.string.ActionRemovedPhoto).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.getString("ActionRemovedPhoto", R.string.ActionRemovedPhoto).replace("un1", ContactsController.formatName(fromUser.first_name, fromUser.last_name)); } else { messageText = LocaleController.getString("ActionRemovedPhoto", R.string.ActionRemovedPhoto).replace("un1", ""); } @@ -232,13 +232,13 @@ public class MessageObject { messageText = LocaleController.formatString("NotificationUnrecognizedDevice", R.string.NotificationUnrecognizedDevice, name, date, message.action.title, message.action.address); } else if (message.action instanceof TLRPC.TL_messageActionUserJoined) { if (fromUser != null) { - messageText = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, ContactsController.formatName(fromUser.first_name, fromUser.last_name)); } else { messageText = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, ""); } } else if (message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { if (fromUser != null) { - messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, ContactsController.formatName(fromUser.first_name, fromUser.last_name)); } else { messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, ""); } @@ -443,10 +443,23 @@ public class MessageObject { } int maxWidth; - if (messageOwner.to_id.chat_id != 0) { - maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(122); + if (AndroidUtilities.isTablet()) { + int min = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y); + int leftWidth = min / 100 * 35; + if (leftWidth < AndroidUtilities.dp(320)) { + leftWidth = AndroidUtilities.dp(320); + } + if (messageOwner.to_id.chat_id != 0) { + maxWidth = min - leftWidth - AndroidUtilities.dp(122); + } else { + maxWidth = min - leftWidth - AndroidUtilities.dp(80); + } } else { - maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(80); + if (messageOwner.to_id.chat_id != 0) { + maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(122); + } else { + maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(80); + } } StaticLayout textLayout = null; @@ -485,12 +498,17 @@ public class MessageObject { CharSequence str = messageText.subSequence(startCharacter, endCharacter); block.textLayout = new StaticLayout(str, textPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); block.textYOffset = textLayout.getLineTop(linesOffset); - if (a != blocksCount - 1) { + if (a != 0) { + blockHeight = Math.min(blockHeight, (int)(block.textYOffset - prevOffset)); + } + prevOffset = block.textYOffset; + /*if (a != blocksCount - 1) { + int height = block.textLayout.getHeight(); blockHeight = Math.min(blockHeight, block.textLayout.getHeight()); prevOffset = block.textYOffset; } else { blockHeight = Math.min(blockHeight, (int)(block.textYOffset - prevOffset)); - } + }*/ } catch (Exception e) { FileLog.e("tmessages", e); continue; diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java index 9d584f6f9..072e92da0 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java @@ -143,7 +143,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); maxGroupCount = preferences.getInt("maxGroupCount", 200); maxBroadcastCount = preferences.getInt("maxBroadcastCount", 100); - fontSize = preferences.getInt("fons_size", 16); + fontSize = preferences.getInt("fons_size", AndroidUtilities.isTablet() ? 18 : 16); } public void updateConfig(final TLRPC.TL_config config) { @@ -1175,7 +1175,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (label.length() != 0) { label += ", "; } - label += Utilities.formatName(user.first_name, user.last_name); + label += ContactsController.formatName(user.first_name, user.last_name); count++; } if (count == 2) { @@ -3462,9 +3462,23 @@ public class MessagesController implements NotificationCenter.NotificationCenter changed = true; } } else { + boolean change = false; 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) { + dialog.top_message < 0 && lastMessage.messageOwner.id < 0 && lastMessage.messageOwner.id < dialog.top_message) { + change = true; + } else { + MessageObject currentDialogMessage = dialogMessage.get(dialog.top_message); + if (currentDialogMessage != null) { + if (currentDialogMessage.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING && lastMessage.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) { + change = true; + } else if (dialog.last_message_date < lastMessage.messageOwner.date || dialog.last_message_date == lastMessage.messageOwner.date && lastMessage.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) { + change = true; + } + } else { + change = true; + } + } + if (change) { dialogMessage.remove(dialog.top_message); dialog.top_message = lastMessage.messageOwner.id; if (!isBroadcast) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java index 47b0e3dfc..42120c533 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java @@ -1253,7 +1253,7 @@ public class MessagesStorage { if (user.status != null) { user.status.expires = cursor.intValue(7); } - resultArrayNames.add(Html.fromHtml("" + Utilities.formatName(user.first_name, user.last_name) + "")); + resultArrayNames.add(Html.fromHtml("" + ContactsController.formatName(user.first_name, user.last_name) + "")); resultArray.add(chat); encUsers.add(user); } diff --git a/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java b/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java index 04e039b2d..4e66ae6f2 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java @@ -24,9 +24,9 @@ import java.util.zip.ZipFile; public class NativeLoader { private static final long sizes[] = new long[] { - 811664, //armeabi - 864932, //armeabi-v7a - 1262644, //x86 + 946908, //armeabi + 1028848, //armeabi-v7a + 1603780, //x86 0, //mips }; diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java index f45b7bb93..26a3083b0 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java @@ -38,6 +38,7 @@ public class NotificationCenter { public static final int notificationsSettingsUpdated = 26; public static final int pushMessagesUpdated = 27; public static final int blockedUsersDidLoaded = 28; + public static final int openedChatChanged = 29; public static final int wallpapersDidLoaded = 171; public static final int closeOtherAppActivities = 702; @@ -67,7 +68,7 @@ public class NotificationCenter { final private HashMap removeAfterBroadcast = new HashMap(); final private HashMap addAfterBroadcast = new HashMap(); - private boolean broadcasting = false; + private int broadcasting = 0; private static volatile NotificationCenter Instance = null; public static NotificationCenter getInstance() { @@ -89,32 +90,34 @@ public class NotificationCenter { public void postNotificationName(int id, Object... args) { synchronized (observers) { - broadcasting = true; + broadcasting++; ArrayList objects = observers.get(id); if (objects != null) { for (Object obj : objects) { ((NotificationCenterDelegate)obj).didReceivedNotification(id, args); } } - broadcasting = false; - if (!removeAfterBroadcast.isEmpty()) { - for (HashMap.Entry entry : removeAfterBroadcast.entrySet()) { - removeObserver(entry.getValue(), entry.getKey()); + broadcasting--; + if (broadcasting == 0) { + if (!removeAfterBroadcast.isEmpty()) { + for (HashMap.Entry entry : removeAfterBroadcast.entrySet()) { + removeObserver(entry.getValue(), entry.getKey()); + } + removeAfterBroadcast.clear(); } - removeAfterBroadcast.clear(); - } - if (!addAfterBroadcast.isEmpty()) { - for (HashMap.Entry entry : addAfterBroadcast.entrySet()) { - addObserver(entry.getValue(), entry.getKey()); + if (!addAfterBroadcast.isEmpty()) { + for (HashMap.Entry entry : addAfterBroadcast.entrySet()) { + addObserver(entry.getValue(), entry.getKey()); + } + addAfterBroadcast.clear(); } - addAfterBroadcast.clear(); } } } public void addObserver(Object observer, int id) { synchronized (observers) { - if (broadcasting) { + if (broadcasting != 0) { addAfterBroadcast.put(id, observer); return; } @@ -131,7 +134,7 @@ public class NotificationCenter { public void removeObserver(Object observer, int id) { synchronized (observers) { - if (broadcasting) { + if (broadcasting != 0) { removeAfterBroadcast.put(id, observer); return; } diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java index b5777a760..597a2660a 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java @@ -30,7 +30,6 @@ import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; -import org.telegram.messenger.Utilities; import org.telegram.ui.ApplicationLoader; import org.telegram.ui.LaunchActivity; import org.telegram.ui.PopupNotificationActivity; @@ -126,9 +125,9 @@ public class NotificationsController { if (preferences.getBoolean("EnablePreviewAll", true)) { if (messageObject.messageOwner instanceof TLRPC.TL_messageService) { if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserJoined) { - msg = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, Utilities.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, ContactsController.formatName(user.first_name, user.last_name)); } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { - msg = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, Utilities.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, ContactsController.formatName(user.first_name, user.last_name)); } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) { String date = String.format("%s %s %s", LocaleController.formatterYear.format(((long)messageObject.messageOwner.date) * 1000), LocaleController.getString("OtherAt", R.string.OtherAt), LocaleController.formatterDay.format(((long)messageObject.messageOwner.date) * 1000)); msg = LocaleController.formatString("NotificationUnrecognizedDevice", R.string.NotificationUnrecognizedDevice, UserConfig.getCurrentUser().first_name, date, messageObject.messageOwner.action.title, messageObject.messageOwner.action.address); @@ -136,26 +135,26 @@ public class NotificationsController { } else { if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty) { if (messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) { - msg = LocaleController.formatString("NotificationMessageText", R.string.NotificationMessageText, Utilities.formatName(user.first_name, user.last_name), messageObject.messageOwner.message); + msg = LocaleController.formatString("NotificationMessageText", R.string.NotificationMessageText, ContactsController.formatName(user.first_name, user.last_name), messageObject.messageOwner.message); } else { - msg = LocaleController.formatString("NotificationMessageNoText", R.string.NotificationMessageNoText, Utilities.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageNoText", R.string.NotificationMessageNoText, ContactsController.formatName(user.first_name, user.last_name)); } } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { - msg = LocaleController.formatString("NotificationMessagePhoto", R.string.NotificationMessagePhoto, Utilities.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessagePhoto", R.string.NotificationMessagePhoto, ContactsController.formatName(user.first_name, user.last_name)); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { - msg = LocaleController.formatString("NotificationMessageVideo", R.string.NotificationMessageVideo, Utilities.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageVideo", R.string.NotificationMessageVideo, ContactsController.formatName(user.first_name, user.last_name)); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaContact) { - msg = LocaleController.formatString("NotificationMessageContact", R.string.NotificationMessageContact, Utilities.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageContact", R.string.NotificationMessageContact, ContactsController.formatName(user.first_name, user.last_name)); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) { - msg = LocaleController.formatString("NotificationMessageMap", R.string.NotificationMessageMap, Utilities.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageMap", R.string.NotificationMessageMap, ContactsController.formatName(user.first_name, user.last_name)); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { - msg = LocaleController.formatString("NotificationMessageDocument", R.string.NotificationMessageDocument, Utilities.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageDocument", R.string.NotificationMessageDocument, ContactsController.formatName(user.first_name, user.last_name)); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaAudio) { - msg = LocaleController.formatString("NotificationMessageAudio", R.string.NotificationMessageAudio, Utilities.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageAudio", R.string.NotificationMessageAudio, ContactsController.formatName(user.first_name, user.last_name)); } } } else { - msg = LocaleController.formatString("NotificationMessageNoText", R.string.NotificationMessageNoText, Utilities.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageNoText", R.string.NotificationMessageNoText, ContactsController.formatName(user.first_name, user.last_name)); } } else if (chat_id != 0) { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE); @@ -163,29 +162,29 @@ public class NotificationsController { if (messageObject.messageOwner instanceof TLRPC.TL_messageService) { if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser) { if (messageObject.messageOwner.action.user_id == UserConfig.getClientUserId()) { - msg = LocaleController.formatString("NotificationInvitedToGroup", R.string.NotificationInvitedToGroup, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationInvitedToGroup", R.string.NotificationInvitedToGroup, ContactsController.formatName(user.first_name, user.last_name), chat.title); } else { TLRPC.User u2 = MessagesController.getInstance().getUser(messageObject.messageOwner.action.user_id); if (u2 == null) { return null; } - msg = LocaleController.formatString("NotificationGroupAddMember", R.string.NotificationGroupAddMember, Utilities.formatName(user.first_name, user.last_name), chat.title, Utilities.formatName(u2.first_name, u2.last_name)); + msg = LocaleController.formatString("NotificationGroupAddMember", R.string.NotificationGroupAddMember, ContactsController.formatName(user.first_name, user.last_name), chat.title, ContactsController.formatName(u2.first_name, u2.last_name)); } } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditTitle) { - msg = LocaleController.formatString("NotificationEditedGroupName", R.string.NotificationEditedGroupName, Utilities.formatName(user.first_name, user.last_name), messageObject.messageOwner.action.title); + msg = LocaleController.formatString("NotificationEditedGroupName", R.string.NotificationEditedGroupName, ContactsController.formatName(user.first_name, user.last_name), messageObject.messageOwner.action.title); } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeletePhoto) { - msg = LocaleController.formatString("NotificationEditedGroupPhoto", R.string.NotificationEditedGroupPhoto, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationEditedGroupPhoto", R.string.NotificationEditedGroupPhoto, ContactsController.formatName(user.first_name, user.last_name), chat.title); } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser) { if (messageObject.messageOwner.action.user_id == UserConfig.getClientUserId()) { - msg = LocaleController.formatString("NotificationGroupKickYou", R.string.NotificationGroupKickYou, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationGroupKickYou", R.string.NotificationGroupKickYou, ContactsController.formatName(user.first_name, user.last_name), chat.title); } else if (messageObject.messageOwner.action.user_id == user.id) { - msg = LocaleController.formatString("NotificationGroupLeftMember", R.string.NotificationGroupLeftMember, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationGroupLeftMember", R.string.NotificationGroupLeftMember, ContactsController.formatName(user.first_name, user.last_name), chat.title); } else { TLRPC.User u2 = MessagesController.getInstance().getUser(messageObject.messageOwner.action.user_id); if (u2 == null) { return null; } - msg = LocaleController.formatString("NotificationGroupKickMember", R.string.NotificationGroupKickMember, Utilities.formatName(user.first_name, user.last_name), chat.title, Utilities.formatName(u2.first_name, u2.last_name)); + msg = LocaleController.formatString("NotificationGroupKickMember", R.string.NotificationGroupKickMember, ContactsController.formatName(user.first_name, user.last_name), chat.title, ContactsController.formatName(u2.first_name, u2.last_name)); } } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatCreate) { msg = messageObject.messageText.toString(); @@ -193,26 +192,26 @@ public class NotificationsController { } else { if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty) { if (messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) { - msg = LocaleController.formatString("NotificationMessageGroupText", R.string.NotificationMessageGroupText, Utilities.formatName(user.first_name, user.last_name), chat.title, messageObject.messageOwner.message); + msg = LocaleController.formatString("NotificationMessageGroupText", R.string.NotificationMessageGroupText, ContactsController.formatName(user.first_name, user.last_name), chat.title, messageObject.messageOwner.message); } else { - msg = LocaleController.formatString("NotificationMessageGroupNoText", R.string.NotificationMessageGroupNoText, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupNoText", R.string.NotificationMessageGroupNoText, ContactsController.formatName(user.first_name, user.last_name), chat.title); } } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { - msg = LocaleController.formatString("NotificationMessageGroupPhoto", R.string.NotificationMessageGroupPhoto, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupPhoto", R.string.NotificationMessageGroupPhoto, ContactsController.formatName(user.first_name, user.last_name), chat.title); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { - msg = LocaleController.formatString("NotificationMessageGroupVideo", R.string.NotificationMessageGroupVideo, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupVideo", R.string.NotificationMessageGroupVideo, ContactsController.formatName(user.first_name, user.last_name), chat.title); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaContact) { - msg = LocaleController.formatString("NotificationMessageGroupContact", R.string.NotificationMessageGroupContact, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupContact", R.string.NotificationMessageGroupContact, ContactsController.formatName(user.first_name, user.last_name), chat.title); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) { - msg = LocaleController.formatString("NotificationMessageGroupMap", R.string.NotificationMessageGroupMap, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupMap", R.string.NotificationMessageGroupMap, ContactsController.formatName(user.first_name, user.last_name), chat.title); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { - msg = LocaleController.formatString("NotificationMessageGroupDocument", R.string.NotificationMessageGroupDocument, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupDocument", R.string.NotificationMessageGroupDocument, ContactsController.formatName(user.first_name, user.last_name), chat.title); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaAudio) { - msg = LocaleController.formatString("NotificationMessageGroupAudio", R.string.NotificationMessageGroupAudio, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupAudio", R.string.NotificationMessageGroupAudio, ContactsController.formatName(user.first_name, user.last_name), chat.title); } } } else { - msg = LocaleController.formatString("NotificationMessageGroupNoText", R.string.NotificationMessageGroupNoText, Utilities.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupNoText", R.string.NotificationMessageGroupNoText, ContactsController.formatName(user.first_name, user.last_name), chat.title); } } } else { @@ -358,7 +357,7 @@ public class NotificationsController { if (chat != null) { name = chat.title; } else { - name = Utilities.formatName(user.first_name, user.last_name); + name = ContactsController.formatName(user.first_name, user.last_name); } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java index 762143016..33318a4fc 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java @@ -28,6 +28,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter private TLRPC.ChatParticipants currentChatInfo = null; private HashMap> delayedMessages = new HashMap>(); + private HashMap unsentMessages = new HashMap(); private class DelayedMessage { public TLObject sendRequest; @@ -153,6 +154,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter arr.remove(a); a--; NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, obj.obj.messageOwner.id); + processSentMessage(obj.obj.messageOwner.id); } } if (arr.isEmpty()) { @@ -191,14 +193,25 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter MessagesController.getInstance().deleteMessages(messages, null, null); } - public boolean retrySendMessage(MessageObject messageObject) { + public boolean retrySendMessage(MessageObject messageObject, boolean unsent) { if (messageObject.messageOwner.id >= 0) { return false; } + if (unsent) { + unsentMessages.put(messageObject.messageOwner.id, messageObject); + } sendMessage(messageObject); return true; } + private void processSentMessage(int id) { + int prevSize = unsentMessages.size(); + unsentMessages.remove(id); + if (prevSize != 0 && unsentMessages.size() == 0) { + checkUnsentMessages(); + } + } + public void processForwardFromMyName(MessageObject messageObject, long did) { if (messageObject == null) { return; @@ -271,7 +284,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } private void sendMessage(String message, double lat, double lon, TLRPC.TL_photo photo, TLRPC.TL_video video, MessageObject msgObj, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, String originalPath, long peer, boolean retry) { - TLRPC.Message newMsg = null; int type = -1; if (retry) { @@ -394,12 +406,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter newMsg.local_id = newMsg.id = UserConfig.getNewMessageId(); newMsg.from_id = UserConfig.getClientUserId(); newMsg.out = true; - newMsg.date = ConnectionsManager.getInstance().getCurrentTime(); UserConfig.saveConfig(false); } if (newMsg.random_id == 0) { newMsg.random_id = getNextRandomId(); } + newMsg.date = ConnectionsManager.getInstance().getCurrentTime(); newMsg.unread = true; newMsg.dialog_id = peer; int lower_id = (int) peer; @@ -410,6 +422,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (lower_id != 0) { if (high_id == 1) { if (currentChatInfo == null) { + processSentMessage(newMsg.id); return; } sendToPeers = new ArrayList(); @@ -434,6 +447,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter TLRPC.User sendToUser = MessagesController.getInstance().getUser(lower_id); if (sendToUser == null) { + processSentMessage(newMsg.id); return; } if (sendToUser instanceof TLRPC.TL_userForeign || sendToUser instanceof TLRPC.TL_userRequest) { @@ -767,6 +781,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.messageOwner.id); newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.messageOwner.id); + processSentMessage(newMsgObj.messageOwner.id); } } @@ -855,11 +870,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter final boolean isBroadcast = req instanceof TLRPC.TL_messages_sendBroadcast; final ArrayList sentMessages = new ArrayList(); - if (response instanceof TLRPC.TL_messages_sentMessage) { + if (response instanceof TLRPC.messages_SentMessage) { TLRPC.TL_messages_sentMessage res = (TLRPC.TL_messages_sentMessage) response; newMsgObj.messageOwner.id = res.id; newMsgObj.messageOwner.date = res.date; MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, res.date); + //TODO link check } else if (response instanceof TLRPC.messages_StatedMessage) { TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage) response; sentMessages.add(res.message); @@ -903,6 +919,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); } NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, (isBroadcast ? oldId : newMsgObj.messageOwner.id), newMsgObj); + processSentMessage(oldId); } }); } @@ -914,6 +931,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter public void run() { newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.messageOwner.id); + processSentMessage(newMsgObj.messageOwner.id); } }); } @@ -1009,6 +1027,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter public void run() { newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, newMsgObj.messageOwner.id, newMsgObj.messageOwner.id, newMsgObj); + processSentMessage(newMsgObj.messageOwner.id); } }); } @@ -1020,6 +1039,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter public void run() { newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.messageOwner.id); + processSentMessage(newMsgObj.messageOwner.id); } }); } @@ -1370,7 +1390,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter MessagesController.getInstance().putEncryptedChats(encryptedChats, true); for (TLRPC.Message message : messages) { MessageObject messageObject = new MessageObject(message, null, 0); - retrySendMessage(messageObject); + retrySendMessage(messageObject, true); } } }); diff --git a/TMessagesProj/src/main/java/org/telegram/android/video/MP4Builder.java b/TMessagesProj/src/main/java/org/telegram/android/video/MP4Builder.java index fb8d70102..a04e8d4c4 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/video/MP4Builder.java +++ b/TMessagesProj/src/main/java/org/telegram/android/video/MP4Builder.java @@ -87,7 +87,7 @@ public class MP4Builder { fos.flush(); } - public void writeSampleData(int trackIndex, ByteBuffer byteBuf, MediaCodec.BufferInfo bufferInfo) throws Exception { + public boolean writeSampleData(int trackIndex, ByteBuffer byteBuf, MediaCodec.BufferInfo bufferInfo) throws Exception { if (writeNewMdat) { mdat.setContentSize(0); mdat.getBox(fc); @@ -111,16 +111,18 @@ public class MP4Builder { currentMp4Movie.addSample(trackIndex, dataOffset, bufferInfo); byteBuf.position(bufferInfo.offset); byteBuf.limit(bufferInfo.offset + bufferInfo.size); + fc.write(byteBuf); dataOffset += bufferInfo.size; if (flush) { fos.flush(); } + return flush; } - public int addTrack(MediaFormat mediaFormat, boolean isVideo) throws Exception { - return currentMp4Movie.addTrack(mediaFormat, isVideo); + public int addTrack(MediaFormat mediaFormat, boolean isAudio) throws Exception { + return currentMp4Movie.addTrack(mediaFormat, isAudio); } public void finishMovie(boolean error) throws Exception { diff --git a/TMessagesProj/src/main/java/org/telegram/android/video/Mp4Movie.java b/TMessagesProj/src/main/java/org/telegram/android/video/Mp4Movie.java index 4492bc312..5fea2eb3d 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/video/Mp4Movie.java +++ b/TMessagesProj/src/main/java/org/telegram/android/video/Mp4Movie.java @@ -74,8 +74,8 @@ public class Mp4Movie { track.addSample(offset, bufferInfo); } - public int addTrack(MediaFormat mediaFormat, boolean isVideo) throws Exception { - tracks.add(new Track(tracks.size(), mediaFormat, isVideo)); + public int addTrack(MediaFormat mediaFormat, boolean isAudio) throws Exception { + tracks.add(new Track(tracks.size(), mediaFormat, isAudio)); return tracks.size() - 1; } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/video/OutputSurface.java b/TMessagesProj/src/main/java/org/telegram/android/video/OutputSurface.java index 6511d9608..d01b7225a 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/video/OutputSurface.java +++ b/TMessagesProj/src/main/java/org/telegram/android/video/OutputSurface.java @@ -18,32 +18,44 @@ package org.telegram.android.video; import android.annotation.TargetApi; import android.graphics.SurfaceTexture; -import android.opengl.EGL14; +import android.opengl.GLES20; import android.view.Surface; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.egl.EGLSurface; -@TargetApi(17) +@TargetApi(16) public class OutputSurface implements SurfaceTexture.OnFrameAvailableListener { private static final int EGL_OPENGL_ES2_BIT = 4; + private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; private EGL10 mEGL; - private EGLDisplay mEGLDisplay; - private EGLContext mEGLContext; - private EGLSurface mEGLSurface; + private EGLDisplay mEGLDisplay = null; + private EGLContext mEGLContext = null; + private EGLSurface mEGLSurface = null; private SurfaceTexture mSurfaceTexture; private Surface mSurface; private final Object mFrameSyncObject = new Object(); private boolean mFrameAvailable; private TextureRenderer mTextureRender; + private int mWidth; + private int mHeight; + private ByteBuffer mPixelBuf; public OutputSurface(int width, int height) { if (width <= 0 || height <= 0) { throw new IllegalArgumentException(); } + mWidth = width; + mHeight = height; + mPixelBuf = ByteBuffer.allocateDirect(mWidth * mHeight * 4); + mPixelBuf.order(ByteOrder.LITTLE_ENDIAN); eglSetup(width, height); makeCurrent(); setup(); @@ -64,28 +76,35 @@ public class OutputSurface implements SurfaceTexture.OnFrameAvailableListener { private void eglSetup(int width, int height) { mEGL = (EGL10) EGLContext.getEGL(); mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); + + if (mEGLDisplay == EGL10.EGL_NO_DISPLAY) { + throw new RuntimeException("unable to get EGL10 display"); + } + if (!mEGL.eglInitialize(mEGLDisplay, null)) { + mEGLDisplay = null; throw new RuntimeException("unable to initialize EGL10"); } + int[] attribList = { EGL10.EGL_RED_SIZE, 8, EGL10.EGL_GREEN_SIZE, 8, EGL10.EGL_BLUE_SIZE, 8, + EGL10.EGL_ALPHA_SIZE, 8, EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT, EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] numConfigs = new int[1]; - if (!mEGL.eglChooseConfig(mEGLDisplay, attribList, configs, 1, numConfigs)) { + if (!mEGL.eglChooseConfig(mEGLDisplay, attribList, configs, configs.length, numConfigs)) { throw new RuntimeException("unable to find RGB888+pbuffer EGL config"); } int[] attrib_list = { - EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; - mEGLContext = mEGL.eglCreateContext(mEGLDisplay, configs[0], EGL10.EGL_NO_CONTEXT, - attrib_list); + mEGLContext = mEGL.eglCreateContext(mEGLDisplay, configs[0], EGL10.EGL_NO_CONTEXT, attrib_list); checkEglError("eglCreateContext"); if (mEGLContext == null) { throw new RuntimeException("null context"); @@ -139,7 +158,7 @@ public class OutputSurface implements SurfaceTexture.OnFrameAvailableListener { } public void awaitNewImage() { - final int TIMEOUT_MS = 500; + final int TIMEOUT_MS = 2500; synchronized (mFrameSyncObject) { while (!mFrameAvailable) { try { @@ -157,8 +176,8 @@ public class OutputSurface implements SurfaceTexture.OnFrameAvailableListener { mSurfaceTexture.updateTexImage(); } - public void drawImage() { - mTextureRender.drawFrame(mSurfaceTexture); + public void drawImage(boolean invert) { + mTextureRender.drawFrame(mSurfaceTexture, invert); } @Override @@ -172,6 +191,12 @@ public class OutputSurface implements SurfaceTexture.OnFrameAvailableListener { } } + public ByteBuffer getFrame() { + mPixelBuf.rewind(); + GLES20.glReadPixels(0, 0, mWidth, mHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPixelBuf); + return mPixelBuf; + } + private void checkEglError(String msg) { if (mEGL.eglGetError() != EGL10.EGL_SUCCESS) { throw new RuntimeException("EGL error encountered (see log)"); diff --git a/TMessagesProj/src/main/java/org/telegram/android/video/TextureRenderer.java b/TMessagesProj/src/main/java/org/telegram/android/video/TextureRenderer.java index 7b09eeb36..550ced58c 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/video/TextureRenderer.java +++ b/TMessagesProj/src/main/java/org/telegram/android/video/TextureRenderer.java @@ -26,38 +26,41 @@ import android.opengl.GLES11Ext; import android.opengl.GLES20; import android.opengl.Matrix; -@TargetApi(17) +@TargetApi(16) public class TextureRenderer { + private static final int FLOAT_SIZE_BYTES = 4; private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; private static final float[] mTriangleVerticesData = { - // X, Y, Z, U, V -1.0f, -1.0f, 0, 0.f, 0.f, 1.0f, -1.0f, 0, 1.f, 0.f, -1.0f, 1.0f, 0, 0.f, 1.f, 1.0f, 1.0f, 0, 1.f, 1.f, }; private FloatBuffer mTriangleVertices; + private static final String VERTEX_SHADER = "uniform mat4 uMVPMatrix;\n" + - "uniform mat4 uSTMatrix;\n" + - "attribute vec4 aPosition;\n" + - "attribute vec4 aTextureCoord;\n" + - "varying vec2 vTextureCoord;\n" + - "void main() {\n" + - " gl_Position = uMVPMatrix * aPosition;\n" + - " vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" + - "}\n"; + "uniform mat4 uSTMatrix;\n" + + "attribute vec4 aPosition;\n" + + "attribute vec4 aTextureCoord;\n" + + "varying vec2 vTextureCoord;\n" + + "void main() {\n" + + " gl_Position = uMVPMatrix * aPosition;\n" + + " vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" + + "}\n"; + private static final String FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n" + - "precision mediump float;\n" + // highp here doesn't seem to matter - "varying vec2 vTextureCoord;\n" + - "uniform samplerExternalOES sTexture;\n" + - "void main() {\n" + - " gl_FragColor = texture2D(sTexture, vTextureCoord);\n" + - "}\n"; + "precision mediump float;\n" + + "varying vec2 vTextureCoord;\n" + + "uniform samplerExternalOES sTexture;\n" + + "void main() {\n" + + " gl_FragColor = texture2D(sTexture, vTextureCoord);\n" + + "}\n"; + private float[] mMVPMatrix = new float[16]; private float[] mSTMatrix = new float[16]; private int mProgram; @@ -77,11 +80,15 @@ public class TextureRenderer { return mTextureID; } - public void drawFrame(SurfaceTexture st) { + public void drawFrame(SurfaceTexture st, boolean invert) { checkGlError("onDrawFrame start"); st.getTransformMatrix(mSTMatrix); - GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f); - GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); + + if (invert) { + mSTMatrix[5] = -mSTMatrix[5]; + mSTMatrix[13] = 1.0f - mSTMatrix[13]; + } + GLES20.glUseProgram(mProgram); checkGlError("glUseProgram"); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); @@ -96,9 +103,8 @@ public class TextureRenderer { checkGlError("glVertexAttribPointer maTextureHandle"); GLES20.glEnableVertexAttribArray(maTextureHandle); checkGlError("glEnableVertexAttribArray maTextureHandle"); - Matrix.setIdentityM(mMVPMatrix, 0); - GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0); + GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); checkGlError("glDrawArrays"); GLES20.glFinish(); @@ -139,6 +145,8 @@ public class TextureRenderer { GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); checkGlError("glTexParameter"); + + Matrix.setIdentityM(mMVPMatrix, 0); } public void changeFragmentShader(String fragmentShader) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/video/Track.java b/TMessagesProj/src/main/java/org/telegram/android/video/Track.java index b2eabafdf..3131a00ce 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/video/Track.java +++ b/TMessagesProj/src/main/java/org/telegram/android/video/Track.java @@ -67,9 +67,9 @@ public class Track { samplingFrequencyIndexMap.put(8000, 0xb); } - public Track(int id, MediaFormat format, boolean isVideo) throws Exception { + public Track(int id, MediaFormat format, boolean isAudio) throws Exception { trackId = id; - if (isVideo) { + if (!isAudio) { sampleDurations.add((long)3015); duration = 3015; width = format.getInteger(MediaFormat.KEY_WIDTH); @@ -79,46 +79,62 @@ public class Track { handler = "vide"; headerBox = new VideoMediaHeaderBox(); sampleDescriptionBox = new SampleDescriptionBox(); - VisualSampleEntry visualSampleEntry = new VisualSampleEntry("avc1"); - visualSampleEntry.setDataReferenceIndex(1); - visualSampleEntry.setDepth(24); - visualSampleEntry.setFrameCount(1); - visualSampleEntry.setHorizresolution(72); - visualSampleEntry.setVertresolution(72); - visualSampleEntry.setWidth(width); - visualSampleEntry.setHeight(height); + String mime = format.getString(MediaFormat.KEY_MIME); + if (mime.equals("video/avc")) { + VisualSampleEntry visualSampleEntry = new VisualSampleEntry("avc1"); + visualSampleEntry.setDataReferenceIndex(1); + visualSampleEntry.setDepth(24); + visualSampleEntry.setFrameCount(1); + visualSampleEntry.setHorizresolution(72); + visualSampleEntry.setVertresolution(72); + visualSampleEntry.setWidth(width); + visualSampleEntry.setHeight(height); - AvcConfigurationBox avcConfigurationBox = new AvcConfigurationBox(); + AvcConfigurationBox avcConfigurationBox = new AvcConfigurationBox(); - ArrayList spsArray = new ArrayList(); - ByteBuffer spsBuff = format.getByteBuffer("csd-0"); - spsBuff.position(4); - byte[] spsBytes = new byte[spsBuff.remaining()]; - spsBuff.get(spsBytes); - spsArray.add(spsBytes); + if (format.getByteBuffer("csd-0") != null) { + ArrayList spsArray = new ArrayList(); + ByteBuffer spsBuff = format.getByteBuffer("csd-0"); + spsBuff.position(4); + byte[] spsBytes = new byte[spsBuff.remaining()]; + spsBuff.get(spsBytes); + spsArray.add(spsBytes); - ArrayList ppsArray = new ArrayList(); - ByteBuffer ppsBuff = format.getByteBuffer("csd-1"); - ppsBuff.position(4); - byte[] ppsBytes = new byte[ppsBuff.remaining()]; - ppsBuff.get(ppsBytes); - ppsArray.add(ppsBytes); - //ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(spsBytes); - //SeqParameterSet seqParameterSet = SeqParameterSet.read(byteArrayInputStream); + ArrayList ppsArray = new ArrayList(); + ByteBuffer ppsBuff = format.getByteBuffer("csd-1"); + ppsBuff.position(4); + byte[] ppsBytes = new byte[ppsBuff.remaining()]; + ppsBuff.get(ppsBytes); + ppsArray.add(ppsBytes); + avcConfigurationBox.setSequenceParameterSets(spsArray); + avcConfigurationBox.setPictureParameterSets(ppsArray); + } + //ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(spsBytes); + //SeqParameterSet seqParameterSet = SeqParameterSet.read(byteArrayInputStream); - avcConfigurationBox.setSequenceParameterSets(spsArray); - avcConfigurationBox.setPictureParameterSets(ppsArray); - avcConfigurationBox.setAvcLevelIndication(13); - avcConfigurationBox.setAvcProfileIndication(100); - avcConfigurationBox.setBitDepthLumaMinus8(-1); - avcConfigurationBox.setBitDepthChromaMinus8(-1); - avcConfigurationBox.setChromaFormat(-1); - avcConfigurationBox.setConfigurationVersion(1); - avcConfigurationBox.setLengthSizeMinusOne(3); - avcConfigurationBox.setProfileCompatibility(0); + avcConfigurationBox.setAvcLevelIndication(13); + avcConfigurationBox.setAvcProfileIndication(100); + avcConfigurationBox.setBitDepthLumaMinus8(-1); + avcConfigurationBox.setBitDepthChromaMinus8(-1); + avcConfigurationBox.setChromaFormat(-1); + avcConfigurationBox.setConfigurationVersion(1); + avcConfigurationBox.setLengthSizeMinusOne(3); + avcConfigurationBox.setProfileCompatibility(0); - visualSampleEntry.addBox(avcConfigurationBox); - sampleDescriptionBox.addBox(visualSampleEntry); + visualSampleEntry.addBox(avcConfigurationBox); + sampleDescriptionBox.addBox(visualSampleEntry); + } else if (mime.equals("video/mp4v")) { + VisualSampleEntry visualSampleEntry = new VisualSampleEntry("mp4v"); + visualSampleEntry.setDataReferenceIndex(1); + visualSampleEntry.setDepth(24); + visualSampleEntry.setFrameCount(1); + visualSampleEntry.setHorizresolution(72); + visualSampleEntry.setVertresolution(72); + visualSampleEntry.setWidth(width); + visualSampleEntry.setHeight(height); + + sampleDescriptionBox.addBox(visualSampleEntry); + } } else { sampleDurations.add((long)1024); duration = 1024; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java index 1f18873e4..2fd5369f9 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java @@ -9,6 +9,7 @@ package org.telegram.messenger; import java.io.File; +import java.util.HashMap; import java.util.LinkedList; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Semaphore; @@ -37,6 +38,7 @@ public class FileLoader { private ConcurrentHashMap uploadOperationPathsEnc = new ConcurrentHashMap(); private ConcurrentHashMap loadOperationPaths = new ConcurrentHashMap(); private ConcurrentHashMap fileProgresses = new ConcurrentHashMap(); + private HashMap uploadSizes = new HashMap(); private FileLoaderDelegate delegate = null; @@ -70,6 +72,7 @@ public class FileLoader { } else { operation = uploadOperationPathsEnc.get(location); } + uploadSizes.remove(location); if (operation != null) { uploadOperationQueue.remove(operation); uploadSmallOperationQueue.remove(operation); @@ -95,6 +98,8 @@ public class FileLoader { } if (operation != null) { operation.checkNewDataAvailable(finalSize); + } else if (finalSize != 0) { + uploadSizes.put(location, finalSize); } } }); @@ -117,7 +122,15 @@ public class FileLoader { return; } } - FileUploadOperation operation = new FileUploadOperation(location, encrypted, estimatedSize); + int esimated = estimatedSize; + if (esimated != 0) { + Long finalSize = uploadSizes.get(location); + if (finalSize != null) { + esimated = 0; + uploadSizes.remove(location); + } + } + FileUploadOperation operation = new FileUploadOperation(location, encrypted, esimated); if (encrypted) { uploadOperationPathsEnc.put(location, operation); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java index 88cb53573..ee8f2da23 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java @@ -14,7 +14,6 @@ import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.content.res.Configuration; import android.database.Cursor; import android.net.Uri; import android.os.Build; @@ -51,7 +50,6 @@ import java.security.spec.RSAPublicKeySpec; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; -import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; @@ -74,23 +72,6 @@ public class Utilities { public static volatile DispatchQueue searchQueue = new DispatchQueue("searchQueue"); public static volatile DispatchQueue photoBookQueue = new DispatchQueue("photoBookQueue"); - public static int[] arrColors = {0xffee4928, 0xff41a903, 0xffe09602, 0xff0f94ed, 0xff8f3bf7, 0xfffc4380, 0xff00a1c4, 0xffeb7002}; - public static int[] arrUsersAvatars = { - R.drawable.user_red, - R.drawable.user_green, - R.drawable.user_yellow, - R.drawable.user_blue, - R.drawable.user_violet, - R.drawable.user_pink, - R.drawable.user_aqua, - R.drawable.user_orange}; - - public static int[] arrGroupsAvatars = { - R.drawable.group_green, - R.drawable.group_red, - R.drawable.group_blue, - R.drawable.group_yellow}; - final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); public static ProgressDialog progressDialog; @@ -132,6 +113,7 @@ public class Utilities { public native static long doPQNative(long _what); public native static void loadBitmap(String path, int[] bitmap, int scale, int format, int width, int height); public native static void blurBitmap(Object bitmap); + public native static int convertVideoFrame(ByteBuffer src, ByteBuffer dest, int destFormat, int width, int height, int padding); private native static void aesIgeEncryption(ByteBuffer buffer, byte[] key, byte[] iv, boolean encrypt, int offset, int length); public static void aesIgeEncryption(ByteBuffer buffer, byte[] key, byte[] iv, boolean encrypt, boolean changeIv, int offset, int length) { @@ -509,54 +491,6 @@ public class Utilities { return true; } - public static int getColorIndex(int id) { - int[] arr; - if (id >= 0) { - arr = arrUsersAvatars; - } else { - arr = arrGroupsAvatars; - } - try { - String str; - if (id >= 0) { - str = String.format(Locale.US, "%d%d", id, UserConfig.getClientUserId()); - } else { - str = String.format(Locale.US, "%d", id); - } - if (str.length() > 15) { - str = str.substring(0, 15); - } - java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); - byte[] digest = md.digest(str.getBytes()); - int b = digest[Math.abs(id % 16)]; - if (b < 0) { - b += 256; - } - return Math.abs(b) % arr.length; - } catch (Exception e) { - FileLog.e("tmessages", e); - } - return id % arr.length; - } - - public static int getColorForId(int id) { - if (id / 1000 == 333) { - return 0xff0f94ed; - } - return arrColors[getColorIndex(id)]; - } - - public static int getUserAvatarForId(int id) { - if (id / 1000 == 333 || id / 1000 == 777) { - return R.drawable.telegram_avatar; - } - return arrUsersAvatars[getColorIndex(id)]; - } - - public static int getGroupAvatarForId(int id) { - return arrGroupsAvatars[getColorIndex(-Math.abs(id))]; - } - public static String MD5(String md5) { if (md5 == null) { return null; @@ -757,16 +691,6 @@ public class Utilities { return null; } - public static String formatName(String firstName, String lastName) { - String result = firstName; - if (result == null || result.length() == 0) { - result = lastName; - } else if (result.length() != 0 && lastName != null && lastName.length() != 0) { - result += " " + lastName; - } - return result.trim(); - } - public static String formatFileSize(long size) { if (size < 1024) { return String.format("%d B", size); @@ -816,8 +740,4 @@ public class Utilities { UpdateManager.register(context, BuildVars.HOCKEY_APP_HASH); } } - - public static boolean isTablet(Context context) { - return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; - } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java index bedb1568f..f231ecec0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java @@ -23,7 +23,6 @@ import org.telegram.android.MediaController; import org.telegram.messenger.TLRPC; import org.telegram.android.MessagesController; import org.telegram.messenger.R; -import org.telegram.messenger.Utilities; import org.telegram.android.MessageObject; import org.telegram.android.ImageReceiver; import org.telegram.ui.Views.ProgressView; @@ -355,9 +354,9 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega if (audioUser.photo != null) { currentPhoto = audioUser.photo.photo_small; } - avatarImage.setImage(currentPhoto, "50_50", getResources().getDrawable(Utilities.getUserAvatarForId(uid))); + avatarImage.setImage(currentPhoto, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid))); } else { - avatarImage.setImage((TLRPC.FileLocation)null, "50_50", getResources().getDrawable(Utilities.getUserAvatarForId(uid))); + avatarImage.setImage((TLRPC.FileLocation)null, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid))); } if (messageObject.isOut()) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java index f7e73fc5b..700a43bc6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java @@ -23,11 +23,11 @@ import android.view.SoundEffectConstants; import android.view.ViewConfiguration; import org.telegram.android.AndroidUtilities; +import org.telegram.android.ContactsController; import org.telegram.android.LocaleController; import org.telegram.messenger.TLRPC; import org.telegram.android.MessagesController; import org.telegram.messenger.R; -import org.telegram.messenger.Utilities; import org.telegram.android.MessageObject; import org.telegram.android.ImageReceiver; @@ -233,7 +233,7 @@ public class ChatBaseCell extends BaseCell { String newNameString = null; if (drawName && isChat && newUser != null && !currentMessageObject.isOut()) { - newNameString = Utilities.formatName(newUser.first_name, newUser.last_name); + newNameString = ContactsController.formatName(newUser.first_name, newUser.last_name); } if (currentNameString == null && newNameString != null || currentNameString != null && newNameString == null || currentNameString != null && newNameString != null && !currentNameString.equals(newNameString)) { @@ -243,7 +243,7 @@ public class ChatBaseCell extends BaseCell { newUser = MessagesController.getInstance().getUser(currentMessageObject.messageOwner.fwd_from_id); newNameString = null; if (newUser != null && drawForwardedName && currentMessageObject.messageOwner instanceof TLRPC.TL_messageForwarded) { - newNameString = Utilities.formatName(newUser.first_name, newUser.last_name); + newNameString = ContactsController.formatName(newUser.first_name, newUser.last_name); } return currentForwardNameString == null && newNameString != null || currentForwardNameString != null && newNameString == null || currentForwardNameString != null && newNameString != null && !currentForwardNameString.equals(newNameString); } @@ -265,7 +265,7 @@ public class ChatBaseCell extends BaseCell { } else { currentPhoto = null; } - avatarImage.setImage(currentPhoto, "50_50", getResources().getDrawable(Utilities.getUserAvatarForId(currentUser.id))); + avatarImage.setImage(currentPhoto, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(currentUser.id))); } else { avatarImage.setImage((TLRPC.FileLocation)null, "50_50", null); } @@ -287,7 +287,7 @@ public class ChatBaseCell extends BaseCell { namesOffset = 0; if (drawName && isChat && currentUser != null && !currentMessageObject.isOut()) { - currentNameString = Utilities.formatName(currentUser.first_name, currentUser.last_name); + currentNameString = ContactsController.formatName(currentUser.first_name, currentUser.last_name); nameWidth = getMaxNameWidth(); CharSequence nameStringFinal = TextUtils.ellipsize(currentNameString.replace("\n", " "), namePaint, nameWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END); @@ -308,7 +308,7 @@ public class ChatBaseCell extends BaseCell { if (drawForwardedName && messageObject.messageOwner instanceof TLRPC.TL_messageForwarded) { currentForwardUser = MessagesController.getInstance().getUser(messageObject.messageOwner.fwd_from_id); if (currentForwardUser != null) { - currentForwardNameString = Utilities.formatName(currentForwardUser.first_name, currentForwardUser.last_name); + currentForwardNameString = ContactsController.formatName(currentForwardUser.first_name, currentForwardUser.last_name); forwardedNameWidth = getMaxNameWidth(); @@ -520,7 +520,7 @@ public class ChatBaseCell extends BaseCell { if (drawName && nameLayout != null) { canvas.save(); canvas.translate(currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(19) - nameOffsetX, AndroidUtilities.dp(10)); - namePaint.setColor(Utilities.getColorForId(currentUser.id)); + namePaint.setColor(AndroidUtilities.getColorForId(currentUser.id)); nameLayout.draw(canvas); canvas.restore(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java index 4679d766c..23afcd462 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java @@ -11,6 +11,7 @@ package org.telegram.ui.Cells; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.text.Layout; @@ -19,6 +20,7 @@ import android.text.TextPaint; import android.text.TextUtils; import android.view.MotionEvent; import android.view.SoundEffectConstants; +import android.view.animation.DecelerateInterpolator; import org.telegram.android.AndroidUtilities; import org.telegram.android.ImageLoader; @@ -32,7 +34,6 @@ import org.telegram.android.PhotoObject; import org.telegram.ui.PhotoViewer; import org.telegram.ui.Views.GifDrawable; import org.telegram.android.ImageReceiver; -import org.telegram.ui.Views.RoundProgressView; import java.io.File; import java.util.Locale; @@ -54,6 +55,9 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD private static MessageObject lastDownloadedGifMessage = null; private static TextPaint namePaint; private static Paint docBackPaint; + private static Paint progressPaint; + private static Paint progressBackgroundPaint; + private static DecelerateInterpolator decelerateInterpolator; private GifDrawable gifDrawable = null; @@ -63,7 +67,6 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD private String currentUrl; private String currentPhotoFilter; private ImageReceiver photoImage; - private RoundProgressView progressView; private boolean progressVisible = false; private boolean photoNotSet = false; private boolean cancelLoading = false; @@ -87,6 +90,15 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD public ChatMediaCellDelegate mediaDelegate = null; + private float currentProgress = 0; + private RectF progressRect = new RectF(); + private long lastUpdateTime = 0; + private boolean animationStarted = false; + private float radOffset = 0; + private float animatedProgressValue = 0; + private long currentProgressTime = 0; + private float animationProgressStart = 0; + public ChatMediaCell(Context context) { super(context); @@ -113,12 +125,21 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD namePaint.setTextSize(AndroidUtilities.dp(16)); docBackPaint = new Paint(); + + progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + progressPaint.setStyle(Paint.Style.STROKE); + progressPaint.setStrokeWidth(AndroidUtilities.dp(2)); + + decelerateInterpolator = new DecelerateInterpolator(); + + progressBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + progressBackgroundPaint.setStyle(Paint.Style.STROKE); + progressBackgroundPaint.setStrokeWidth(AndroidUtilities.dp(2)); } TAG = MediaController.getInstance().generateObserverTag(); photoImage = new ImageReceiver(this); - progressView = new RoundProgressView(); } public void clearGifImage() { @@ -260,6 +281,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.video); } progressVisible = true; + startAnimation(); buttonState = 1; invalidate(); } else if (buttonState == 1) { @@ -280,6 +302,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.video); } progressVisible = false; + stopAnimation(); buttonState = 0; invalidate(); } @@ -342,7 +365,17 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD if (name == null || name.length() == 0) { name = LocaleController.getString("AttachDocument", R.string.AttachDocument); } - int maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(122 + 86 + 24); + int maxWidth; + if (AndroidUtilities.isTablet()) { + int min = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y); + int leftWidth = min / 100 * 35; + if (leftWidth < AndroidUtilities.dp(320)) { + leftWidth = AndroidUtilities.dp(320); + } + maxWidth = min - leftWidth - AndroidUtilities.dp(122 + 86 + 24); + } else { + maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(122 + 86 + 24); + } if (currentNameString == null || !currentNameString.equals(name)) { currentNameString = name; nameWidth = Math.min(maxWidth, (int) Math.ceil(namePaint.measureText(currentNameString))); @@ -427,7 +460,16 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD currentUrl = String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&zoom=13&size=100x100&maptype=roadmap&scale=%d&markers=color:red|size:big|%f,%f&sensor=false", lat, lon, Math.min(2, (int)Math.ceil(AndroidUtilities.density)), lat, lon); photoImage.setImage(currentUrl, null, messageObject.isOut() ? placeholderOutDrawable : placeholderInDrawable); } else { - photoWidth = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f); + if (AndroidUtilities.isTablet()) { + int min = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y); + int leftWidth = min / 100 * 35; + if (leftWidth < AndroidUtilities.dp(320)) { + leftWidth = AndroidUtilities.dp(320); + } + photoWidth = (int)((min - leftWidth) * 0.7f); + } else { + photoWidth = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f); + } photoHeight = photoWidth + AndroidUtilities.dp(100); if (photoWidth > 800) { @@ -549,13 +591,10 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD if (currentMessageObject.messageOwner.attachPath != null) { MediaController.getInstance().addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, this); progressVisible = true; + startAnimation(); buttonState = 1; Float progress = FileLoader.getInstance().getFileProgress(currentMessageObject.messageOwner.attachPath); - if (progress != null) { - progressView.setProgress(progress); - } else { - progressView.setProgress(0); - } + setProgress(progress != null ? progress : 0, false); invalidate(); } } else { @@ -571,25 +610,25 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD if (cancelLoading || currentMessageObject.type != 1 || !MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO)) { buttonState = 0; progressVisible = false; + stopAnimation(); } else { buttonState = 1; progressVisible = true; + startAnimation(); } - progressView.setProgress(0); + setProgress(0, false); } else { buttonState = 1; progressVisible = true; + startAnimation(); Float progress = FileLoader.getInstance().getFileProgress(fileName); - if (progress != null) { - progressView.setProgress(progress); - } else { - progressView.setProgress(0); - } + setProgress(progress != null ? progress : 0, false); } invalidate(); } else { MediaController.getInstance().removeLoadingFileObserver(this); progressVisible = false; + stopAnimation(); if (currentMessageObject.type == 8 && (gifDrawable == null || gifDrawable != null && !gifDrawable.isRunning())) { buttonState = 2; } else if (currentMessageObject.type == 3) { @@ -602,6 +641,54 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } } + private void updateAnimation() { + long newTime = System.currentTimeMillis(); + long dt = newTime - lastUpdateTime; + lastUpdateTime = newTime; + + radOffset += 360 * dt / 3000.0f; + float progressDiff = currentProgress - animationProgressStart; + if (progressDiff > 0) { + currentProgressTime += dt; + if (currentProgressTime >= 300) { + animatedProgressValue = currentProgress; + animationProgressStart = currentProgress; + currentProgressTime = 0; + } else { + animatedProgressValue = animationProgressStart + progressDiff * decelerateInterpolator.getInterpolation(currentProgressTime / 300.0f); + } + } + + invalidateProgress(); + } + + private void startAnimation() { + lastUpdateTime = System.currentTimeMillis(); + animationStarted = true; + invalidateProgress(); + } + + private void setProgress(float value, boolean animated) { + if (!animated) { + animatedProgressValue = value; + animationProgressStart = value; + } else { + animationProgressStart = animatedProgressValue; + } + currentProgress = value; + currentProgressTime = 0; + } + + private void invalidateProgress() { + int offset = AndroidUtilities.dp(1); + invalidate((int)progressRect.left - offset, (int)progressRect.top - offset, (int)progressRect.right + offset * 2, (int)progressRect.bottom + offset * 2); + } + + private void stopAnimation() { + radOffset = 0; + animationStarted = false; + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), photoHeight + AndroidUtilities.dp(14)); @@ -629,7 +716,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD int size = AndroidUtilities.dp(44); buttonX = (int)(x + (photoWidth - size) / 2.0f); buttonY = (int)(AndroidUtilities.dp(7) + (photoHeight - size) / 2.0f); - progressView.rect.set(buttonX + AndroidUtilities.dp(1), buttonY + AndroidUtilities.dp(1), buttonX + AndroidUtilities.dp(43), buttonY + AndroidUtilities.dp(43)); + progressRect.set(buttonX + AndroidUtilities.dp(1), buttonY + AndroidUtilities.dp(1), buttonX + AndroidUtilities.dp(43), buttonY + AndroidUtilities.dp(43)); } @Override @@ -646,6 +733,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD drawTime = photoImage.getVisible(); } + + boolean needProgressBackground = false; if (currentMessageObject.type == 9) { if (currentMessageObject.isOut()) { infoPaint.setColor(0xff75b166); @@ -664,15 +753,21 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD drawable.draw(canvas); } if (currentMessageObject.isOut()) { - progressView.setColor(0xff81bd72); + progressPaint.setColor(0xff81bd72); + progressBackgroundPaint.setColor(0xffbae4a2); + } else { - progressView.setColor(0xffadbdcc); + progressPaint.setColor(0xffadbdcc); + progressBackgroundPaint.setColor(0xffd5dee7); } + needProgressBackground = true; } else { - progressView.setColor(0xffffffff); + progressPaint.setColor(0xffffffff); + needProgressBackground = false; } } else { - progressView.setColor(0xffffffff); + progressPaint.setColor(0xffffffff); + needProgressBackground = false; } if (buttonState >= 0 && buttonState < 4) { @@ -687,7 +782,10 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } if (progressVisible) { - progressView.draw(canvas); + if (needProgressBackground) { + canvas.drawArc(progressRect, 0, 360, false, progressBackgroundPaint); + } + canvas.drawArc(progressRect, -90 + radOffset, Math.max(4, 360 * animatedProgressValue), false, progressPaint); } if (nameLayout != null) { @@ -717,6 +815,10 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD infoLayout.draw(canvas); canvas.restore(); } + + if (animationStarted) { + updateAnimation(); + } } @Override @@ -738,17 +840,17 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD @Override public void onProgressDownload(String fileName, float progress) { progressVisible = true; - progressView.setProgress(progress); + setProgress(progress, true); if (buttonState != 1) { updateButtonState(); } - invalidate(); + invalidateProgress(); } @Override public void onProgressUpload(String fileName, float progress, boolean isEncrypted) { - progressView.setProgress(progress); - invalidate(); + setProgress(progress, true); + invalidateProgress(); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java index 8d03bfb04..f91dcb4e0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -131,12 +131,28 @@ public class ChatMessageCell extends ChatBaseCell { } pressedLink = null; int maxWidth; - if (isChat && !messageObject.isOut()) { - maxWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(122); - drawName = true; + + if (AndroidUtilities.isTablet()) { + int min = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y); + int leftWidth = min / 100 * 35; + if (leftWidth < AndroidUtilities.dp(320)) { + leftWidth = AndroidUtilities.dp(320); + } + if (isChat && !messageObject.isOut()) { + maxWidth = min - leftWidth - AndroidUtilities.dp(122); + drawName = true; + } else { + maxWidth = min - leftWidth - AndroidUtilities.dp(80); + drawName = false; + } } else { - maxWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(80); - drawName = false; + if (isChat && !messageObject.isOut()) { + maxWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(122); + drawName = true; + } else { + maxWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(80); + drawName = false; + } } backgroundWidth = maxWidth; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatOrUserCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatOrUserCell.java index 202138373..5b496167c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatOrUserCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatOrUserCell.java @@ -19,13 +19,13 @@ import android.text.TextUtils; import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; +import org.telegram.android.ContactsController; import org.telegram.android.LocaleController; import org.telegram.messenger.TLRPC; import org.telegram.messenger.ConnectionsManager; import org.telegram.android.MessagesController; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; -import org.telegram.messenger.Utilities; import org.telegram.android.ImageReceiver; public class ChatOrUserCell extends BaseCell { @@ -157,12 +157,16 @@ public class ChatOrUserCell extends BaseCell { if (user.photo != null) { photo = user.photo.photo_small; } - placeHolderId = Utilities.getUserAvatarForId(user.id); + placeHolderId = AndroidUtilities.getUserAvatarForId(user.id); } else if (chat != null) { if (chat.photo != null) { photo = chat.photo.photo_small; } - placeHolderId = Utilities.getGroupAvatarForId(chat.id); + if (chat.id > 0) { + placeHolderId = AndroidUtilities.getGroupAvatarForId(chat.id); + } else { + placeHolderId = AndroidUtilities.getBroadcastAvatarForId(chat.id); + } } if (mask != 0) { @@ -339,7 +343,7 @@ public class ChatOrUserCell extends BaseCell { if (chat != null) { nameString2 = chat.title; } else if (user != null) { - nameString2 = Utilities.formatName(user.first_name, user.last_name); + nameString2 = ContactsController.formatName(user.first_name, user.last_name); } nameString = nameString2.replace("\n", " "); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java index 640177455..d4ae34ae2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -27,7 +27,6 @@ import org.telegram.android.Emoji; import org.telegram.android.MessagesController; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; -import org.telegram.messenger.Utilities; import org.telegram.android.MessageObject; import org.telegram.android.ImageReceiver; @@ -155,6 +154,10 @@ public class DialogCell extends BaseCell { update(0); } + public TLRPC.TL_dialog getDialog() { + return currentDialog; + } + @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); @@ -249,12 +252,16 @@ public class DialogCell extends BaseCell { if (user.photo != null) { photo = user.photo.photo_small; } - placeHolderId = Utilities.getUserAvatarForId(user.id); + placeHolderId = AndroidUtilities.getUserAvatarForId(user.id); } else if (chat != null) { if (chat.photo != null) { photo = chat.photo.photo_small; } - placeHolderId = Utilities.getGroupAvatarForId(chat.id); + if (chat.id > 0) { + placeHolderId = AndroidUtilities.getGroupAvatarForId(chat.id); + } else { + placeHolderId = AndroidUtilities.getBroadcastAvatarForId(chat.id); + } } avatarImage.setImage(photo, "50_50", placeHolderId == 0 ? null : getResources().getDrawable(placeHolderId)); @@ -564,17 +571,17 @@ public class DialogCell extends BaseCell { } else if (user != null) { if (user.id / 1000 != 777 && user.id / 1000 != 333 && ContactsController.getInstance().contactsDict.get(user.id) == null) { if (ContactsController.getInstance().contactsDict.size() == 0 && (!ContactsController.getInstance().contactsLoaded || ContactsController.getInstance().isLoadingContacts())) { - nameString = Utilities.formatName(user.first_name, user.last_name); + nameString = ContactsController.formatName(user.first_name, user.last_name); } else { if (user.phone != null && user.phone.length() != 0) { nameString = PhoneFormat.getInstance().format("+" + user.phone); } else { currentNamePaint = nameUnknownPaint; - nameString = Utilities.formatName(user.first_name, user.last_name); + nameString = ContactsController.formatName(user.first_name, user.last_name); } } } else { - nameString = Utilities.formatName(user.first_name, user.last_name); + nameString = ContactsController.formatName(user.first_name, user.last_name); } if (encryptedChat != null) { currentNamePaint = nameEncryptedPaint; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index c27ab232c..41bee33df 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -20,11 +20,11 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Rect; -import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.media.MediaPlayer; import android.media.ThumbnailUtils; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.provider.MediaStore; import android.text.Html; @@ -83,6 +83,7 @@ import org.telegram.ui.Views.LayoutListView; import org.telegram.ui.Views.MessageActionLayout; import org.telegram.ui.Views.SizeNotifierRelativeLayout; import org.telegram.ui.Views.TimerButton; +import org.telegram.ui.Views.TypingDotsDrawable; import java.io.File; import java.util.ArrayList; @@ -112,6 +113,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private BackupImageView avatarImageView; private TextView bottomOverlayChatText; private View bottomOverlayChat; + private TypingDotsDrawable typingDotsDrawable; private TextView bottomOverlayText; @@ -146,6 +148,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private boolean loading = false; private boolean cacheEndReaced = false; private boolean firstLoading = true; + private int loadsCount = 0; private int minDate = 0; private boolean first = true; @@ -348,6 +351,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not userBlocked = MessagesController.getInstance().blockedUsers.contains(currentUser.id); } + if (AndroidUtilities.isTablet()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.openedChatChanged, dialog_id); + } + + typingDotsDrawable = new TypingDotsDrawable(); + typingDotsDrawable.setIsChat(currentChat != null); + return true; } @@ -376,6 +386,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidReset); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.screenshotTook); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.blockedUsersDidLoaded); + if (AndroidUtilities.isTablet()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.openedChatChanged, (long)0); + } if (currentEncryptedChat != null) { MediaController.getInstance().stopMediaObserver(); } @@ -387,6 +400,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not public View createView(LayoutInflater inflater, ViewGroup container) { if (fragmentView == null) { actionBarLayer.setDisplayHomeAsUpEnabled(true, R.drawable.ic_ab_back); + if (AndroidUtilities.isTablet()) { + actionBarLayer.setExtraLeftMargin(4); + } actionBarLayer.setBackOverlay(R.layout.updating_state_layout); actionBarLayer.setActionBarMenuOnItemClick(new ActionBarLayer.ActionBarMenuOnItemClick() { @Override @@ -554,7 +570,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not menuItem = item; ActionBarMenu actionMode = actionBarLayer.createActionMode(); - actionMode.addItem(-2, R.drawable.ic_ab_done_gray); + actionMode.addItem(-2, R.drawable.ic_ab_done_gray, R.drawable.bar_selector_mode); FrameLayout layout = new FrameLayout(actionMode.getContext()); layout.setBackgroundColor(0xffe5e5e5); @@ -573,7 +589,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not selectedMessagesCountTextView.setSingleLine(true); selectedMessagesCountTextView.setLines(1); selectedMessagesCountTextView.setEllipsize(TextUtils.TruncateAt.END); - selectedMessagesCountTextView.setPadding(AndroidUtilities.dp(6), 0, 0, 0); + selectedMessagesCountTextView.setPadding(AndroidUtilities.dp(11), 0, 0, 0); selectedMessagesCountTextView.setGravity(Gravity.CENTER_VERTICAL); selectedMessagesCountTextView.setOnTouchListener(new View.OnTouchListener() { @Override @@ -589,12 +605,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not selectedMessagesCountTextView.setLayoutParams(layoutParams); if (currentEncryptedChat == null) { - actionMode.addItem(copy, R.drawable.ic_ab_fwd_copy); - actionMode.addItem(forward, R.drawable.ic_ab_fwd_forward); - actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete); + actionMode.addItem(copy, R.drawable.ic_ab_fwd_copy, R.drawable.bar_selector_mode); + actionMode.addItem(forward, R.drawable.ic_ab_fwd_forward, R.drawable.bar_selector_mode); + actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete, R.drawable.bar_selector_mode); } else { - actionMode.addItem(copy, R.drawable.ic_ab_fwd_copy); - actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete); + actionMode.addItem(copy, R.drawable.ic_ab_fwd_copy, R.drawable.bar_selector_mode); + actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete, R.drawable.bar_selector_mode); } actionMode.getItem(copy).setVisibility(selectedMessagesCanCopyIds.size() != 0 ? View.VISIBLE : View.GONE); @@ -1023,12 +1039,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (currentUser.photo != null) { photo = currentUser.photo.photo_small; } - placeHolderId = Utilities.getUserAvatarForId(currentUser.id); + placeHolderId = AndroidUtilities.getUserAvatarForId(currentUser.id); } else if (currentChat != null) { if (currentChat.photo != null) { photo = currentChat.photo.photo_small; } - placeHolderId = Utilities.getGroupAvatarForId(currentChat.id); + if (isBraodcast) { + placeHolderId = AndroidUtilities.getBroadcastAvatarForId(currentChat.id); + } else { + placeHolderId = AndroidUtilities.getGroupAvatarForId(currentChat.id); + } } avatarImageView.setImage(photo, "50_50", placeHolderId); } @@ -1215,10 +1235,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (currentUser.phone != null && currentUser.phone.length() != 0) { actionBarLayer.setTitle(PhoneFormat.getInstance().format("+" + currentUser.phone)); } else { - actionBarLayer.setTitle(Utilities.formatName(currentUser.first_name, currentUser.last_name)); + actionBarLayer.setTitle(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); } } else { - actionBarLayer.setTitle(Utilities.formatName(currentUser.first_name, currentUser.last_name)); + actionBarLayer.setTitle(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); } } @@ -1268,7 +1288,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (currentUser.photo != null) { newPhoto = currentUser.photo.photo_small; } - placeHolderId = Utilities.getUserAvatarForId(currentUser.id); + placeHolderId = AndroidUtilities.getUserAvatarForId(currentUser.id); } else if (currentChat != null) { TLRPC.Chat chat = MessagesController.getInstance().getChat(currentChat.id); if (chat == null) { @@ -1278,7 +1298,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (currentChat.photo != null) { newPhoto = currentChat.photo.photo_small; } - placeHolderId = Utilities.getGroupAvatarForId(currentChat.id); + if (isBraodcast) { + placeHolderId = AndroidUtilities.getBroadcastAvatarForId(currentChat.id); + } else { + placeHolderId = AndroidUtilities.getGroupAvatarForId(currentChat.id); + } } if (avatarImageView != null) { avatarImageView.setImage(newPhoto, "50_50", placeHolderId); @@ -1331,15 +1355,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } currentPicturePath = null; } - /*if(android.os.Build.VERSION.SDK_INT >= 18) { + if(android.os.Build.VERSION.SDK_INT >= 16) { Bundle args = new Bundle(); args.putString("videoPath", videoPath); VideoEditorActivity fragment = new VideoEditorActivity(args); fragment.setDelegate(this); presentFragment(fragment); - } else {*/ + } else { processSendingVideo(videoPath, null, 0, 0, 0, 0); - //} + } } else if (requestCode == 21) { if (data == null || data.getData() == null) { showAttachmentError(); @@ -1703,6 +1727,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (id == NotificationCenter.messagesDidLoaded) { long did = (Long)args[0]; if (did == dialog_id) { + loadsCount++; int count = (Integer)args[1]; boolean isCache = (Boolean)args[3]; int fnid = (Integer)args[4]; @@ -1721,6 +1746,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not int newRowsCount = 0; unread_end_reached = last_unread_id == 0; + if (loadsCount == 1 && messArr.size() > 20) { + loadsCount++; + } + if (firstLoading) { if (!unread_end_reached) { messages.clear(); @@ -2488,19 +2517,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (start) { try { - if (currentChat != null) { - actionBarLayer.setSubTitleIcon(R.drawable.typing_dots_chat, AndroidUtilities.dp(4)); - } else { - actionBarLayer.setSubTitleIcon(R.drawable.typing_dots, AndroidUtilities.dp(4)); - } - AnimationDrawable mAnim = (AnimationDrawable)actionBarLayer.getSubTitleIcon(); - mAnim.setAlpha(200); - mAnim.start(); + actionBarLayer.setSubTitleIcon(0, typingDotsDrawable, AndroidUtilities.dp(4)); + typingDotsDrawable.start(); } catch (Exception e) { FileLog.e("tmessages", e); } } else { - actionBarLayer.setSubTitleIcon(0, 0); + actionBarLayer.setSubTitleIcon(0, null, 0); + typingDotsDrawable.stop(); } } @@ -2567,7 +2591,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return true; } int height = AndroidUtilities.dp(48); - if (!Utilities.isTablet(getParentActivity()) && getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (!AndroidUtilities.isTablet() && getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { height = AndroidUtilities.dp(40); selectedMessagesCountTextView.setTextSize(16); } else { @@ -2782,7 +2806,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return; } if (option == 0) { - if (SendMessagesHelper.getInstance().retrySendMessage(selectedObject)) { + if (SendMessagesHelper.getInstance().retrySendMessage(selectedObject, false)) { chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); } } else if (option == 1) { @@ -3196,6 +3220,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else { progressBar.setBackgroundResource(R.drawable.system_loader1); } + progressBar.setVisibility(loadsCount > 1 ? View.VISIBLE : View.INVISIBLE); } return view; } @@ -3440,33 +3465,42 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (fromUser.photo != null) { photo = fromUser.photo.photo_small; } - int placeHolderId = Utilities.getUserAvatarForId(fromUser.id); + int placeHolderId = AndroidUtilities.getUserAvatarForId(fromUser.id); avatarImageView.setImage(photo, "50_50", placeHolderId); } if (type != 12 && type != 13 && nameTextView != null && fromUser != null && type != 8 && type != 9) { - nameTextView.setText(Utilities.formatName(fromUser.first_name, fromUser.last_name)); - nameTextView.setTextColor(Utilities.getColorForId(message.messageOwner.from_id)); + nameTextView.setText(ContactsController.formatName(fromUser.first_name, fromUser.last_name)); + nameTextView.setTextColor(AndroidUtilities.getColorForId(message.messageOwner.from_id)); } if (type == 11 || type == 10) { - int width = AndroidUtilities.displaySize.x - AndroidUtilities.dp(30); + int width = 0; + if (AndroidUtilities.isTablet()) { + int leftWidth = AndroidUtilities.displaySize.x / 100 * 35; + if (leftWidth < AndroidUtilities.dp(320)) { + leftWidth = AndroidUtilities.dp(320); + } + width = AndroidUtilities.displaySize.x - leftWidth - AndroidUtilities.dp(30); + } else { + width = AndroidUtilities.displaySize.x - AndroidUtilities.dp(30); + } messageTextView.setText(message.messageText); messageTextView.setMaxWidth(width); if (type == 11) { if (message.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { - photoImage.setImage(message.messageOwner.action.newUserPhoto.photo_small, "50_50", Utilities.getUserAvatarForId(currentUser.id)); + photoImage.setImage(message.messageOwner.action.newUserPhoto.photo_small, "50_50", AndroidUtilities.getUserAvatarForId(currentUser.id)); } else { PhotoObject photo = PhotoObject.getClosestImageWithSize(message.photoThumbs, AndroidUtilities.dp(64), AndroidUtilities.dp(64)); if (photo != null) { if (photo.image != null) { photoImage.setImageBitmap(photo.image); } else { - photoImage.setImage(photo.photoOwner.location, "50_50", Utilities.getGroupAvatarForId(currentChat.id)); + photoImage.setImage(photo.photoOwner.location, "50_50", AndroidUtilities.getGroupAvatarForId(currentChat.id)); } } else { - photoImage.setImageResource(Utilities.getGroupAvatarForId(currentChat.id)); + photoImage.setImageResource(AndroidUtilities.getGroupAvatarForId(currentChat.id)); } } photoImage.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(message), false); @@ -3474,8 +3508,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else if (type == 12 || type == 13) { TLRPC.User contactUser = MessagesController.getInstance().getUser(message.messageOwner.media.user_id); if (contactUser != null) { - nameTextView.setText(Utilities.formatName(message.messageOwner.media.first_name, message.messageOwner.media.last_name)); - nameTextView.setTextColor(Utilities.getColorForId(contactUser.id)); + nameTextView.setText(ContactsController.formatName(message.messageOwner.media.first_name, message.messageOwner.media.last_name)); + nameTextView.setTextColor(AndroidUtilities.getColorForId(contactUser.id)); String phone = message.messageOwner.media.phone_number; if (phone != null && phone.length() != 0) { if (!phone.startsWith("+")) { @@ -3489,7 +3523,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (contactUser.photo != null) { photo = contactUser.photo.photo_small; } - int placeHolderId = Utilities.getUserAvatarForId(contactUser.id); + int placeHolderId = AndroidUtilities.getUserAvatarForId(contactUser.id); contactAvatar.setImage(photo, "50_50", placeHolderId); if (contactUser.id != UserConfig.getClientUserId() && ContactsController.getInstance().contactsDict.get(contactUser.id) == null) { addContactView.setVisibility(View.VISIBLE); @@ -3497,8 +3531,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not addContactView.setVisibility(View.GONE); } } else { - nameTextView.setText(Utilities.formatName(message.messageOwner.media.first_name, message.messageOwner.media.last_name)); - nameTextView.setTextColor(Utilities.getColorForId(message.messageOwner.media.user_id)); + nameTextView.setText(ContactsController.formatName(message.messageOwner.media.first_name, message.messageOwner.media.last_name)); + nameTextView.setTextColor(AndroidUtilities.getColorForId(message.messageOwner.media.user_id)); String phone = message.messageOwner.media.phone_number; if (phone != null && phone.length() != 0) { if (message.messageOwner.media.user_id != 0 && !phone.startsWith("+")) { @@ -3508,7 +3542,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else { phoneTextView.setText("Unknown"); } - contactAvatar.setImageResource(Utilities.getUserAvatarForId(message.messageOwner.media.user_id)); + contactAvatar.setImageResource(AndroidUtilities.getUserAvatarForId(message.messageOwner.media.user_id)); addContactView.setVisibility(View.GONE); } } else if (type == 6) { @@ -3632,8 +3666,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not FileLog.e("tmessages", e); } } else if (i == 0) { - int sdk = android.os.Build.VERSION.SDK_INT; - if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText(message.messageOwner.media.phone_number); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java index f9a93d1c8..2b4834da5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java @@ -641,7 +641,7 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen photo = chat.photo.photo_small; photoBig = chat.photo.photo_big; } - avatarImage.setImage(photo, "50_50", Utilities.getGroupAvatarForId(chat.id)); + avatarImage.setImage(photo, "50_50", chat_id > 0 ? AndroidUtilities.getGroupAvatarForId(chat.id) : AndroidUtilities.getBroadcastAvatarForId(chat.id)); avatarImage.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); return view; } else if (type == 1) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java index c3b275ec8..b136ba519 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java @@ -29,7 +29,6 @@ import org.telegram.messenger.TLRPC; import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; -import org.telegram.messenger.Utilities; import org.telegram.ui.Views.BackupImageView; import org.telegram.ui.Views.ActionBar.BaseFragment; @@ -165,7 +164,7 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent if (user.photo != null) { photo = user.photo.photo_small; } - avatarImage.setImage(photo, "50_50", Utilities.getUserAvatarForId(user.id)); + avatarImage.setImage(photo, "50_50", AndroidUtilities.getUserAvatarForId(user.id)); } public void didReceivedNotification(int id, Object... args) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java index 7a54a4109..e2d872e39 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java @@ -349,7 +349,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setMessage(LocaleController.formatStringSimple(selectAlertString, Utilities.formatName(user.first_name, user.last_name))); + builder.setMessage(LocaleController.formatStringSimple(selectAlertString, ContactsController.formatName(user.first_name, user.last_name))); final EditText editText = new EditText(getParentActivity()); if (android.os.Build.VERSION.SDK_INT < 11) { editText.setBackgroundResource(android.R.drawable.editbox_background_normal); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java index f699c8365..9aefe5125 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java @@ -332,7 +332,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen LayoutInflater lf = (LayoutInflater)ApplicationLoader.applicationContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); View textView = lf.inflate(R.layout.group_create_bubble, null); TextView text = (TextView)textView.findViewById(R.id.bubble_text_view); - String name = Utilities.formatName(user.first_name, user.last_name); + String name = ContactsController.formatName(user.first_name, user.last_name); if (name.length() == 0 && user.phone != null && user.phone.length() != 0) { name = PhoneFormat.getInstance().format("+" + user.phone); } @@ -539,7 +539,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen if (searchWas && searching) { holder.nameTextView.setText(searchResultNames.get(position)); } else { - String name = Utilities.formatName(user.first_name, user.last_name); + String name = ContactsController.formatName(user.first_name, user.last_name); if (name.length() == 0) { if (user.phone != null && user.phone.length() != 0) { name = PhoneFormat.getInstance().format("+" + user.phone); @@ -554,7 +554,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen if (user.photo != null) { photo = user.photo.photo_small; } - int placeHolderId = Utilities.getUserAvatarForId(user.id); + int placeHolderId = AndroidUtilities.getUserAvatarForId(user.id); holder.avatarImage.setImage(photo, "50_50", placeHolderId); holder.messageTextView.setText(LocaleController.formatUserStatus(user)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java index d8141fda8..ebcf31338 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java @@ -10,6 +10,7 @@ package org.telegram.ui; import android.app.Activity; import android.content.Intent; +import android.content.pm.ActivityInfo; import android.database.DataSetObserver; import android.os.Bundle; import android.os.Parcelable; @@ -24,6 +25,7 @@ import android.view.animation.AnimationUtils; import android.widget.ImageView; import android.widget.TextView; +import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.messenger.R; import org.telegram.messenger.Utilities; @@ -46,7 +48,12 @@ public class IntroActivity extends Activity { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); - setContentView(R.layout.intro_layout); + if (AndroidUtilities.isTablet()) { + setContentView(R.layout.intro_layout_tablet); + } else { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setContentView(R.layout.intro_layout); + } if (LocaleController.isRTL) { icons = new int[] { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java index 26bbde3aa..bee83e3f3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java @@ -125,7 +125,7 @@ public class LanguageSelectActivity extends BaseFragment { } if (localeInfo != null) { LocaleController.getInstance().applyLanguage(localeInfo, true); - getParentActivity().rebuildAllFragmentViews(); + parentLayout.rebuildAllFragmentViews(false); } finishFragment(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index 021a148ef..abfc24331 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -8,15 +8,25 @@ package org.telegram.ui; +import android.app.Activity; import android.content.ContentResolver; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Parcelable; import android.provider.ContactsContract; +import android.view.ActionMode; +import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.Window; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -31,7 +41,7 @@ import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; -import org.telegram.ui.Views.ActionBar.ActionBarActivity; +import org.telegram.ui.Views.ActionBar.ActionBarLayout; import org.telegram.ui.Views.ActionBar.BaseFragment; import java.io.BufferedReader; @@ -40,7 +50,7 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Map; -public class LaunchActivity extends ActionBarActivity implements NotificationCenter.NotificationCenterDelegate, MessagesActivity.MessagesActivityDelegate { +public class LaunchActivity extends Activity implements ActionBarLayout.ActionBarLayoutDelegate, NotificationCenter.NotificationCenterDelegate, MessagesActivity.MessagesActivityDelegate { private boolean finished = false; private String videoPath = null; private String sendingText = null; @@ -49,6 +59,16 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen private ArrayList documentsOriginalPathsArray = null; private ArrayList contactsToSend = null; private int currentConnectionState; + private static ArrayList mainFragmentsStack = new ArrayList(); + private static ArrayList layerFragmentsStack = new ArrayList(); + private static ArrayList rightFragmentsStack = new ArrayList(); + + private ActionBarLayout actionBarLayout = null; + private ActionBarLayout layersActionBarLayout = null; + private ActionBarLayout rightActionBarLayout = null; + private FrameLayout shadowTablet = null; + private LinearLayout buttonLayoutTablet = null; + private FrameLayout shadowTabletSide = null; @Override protected void onCreate(Bundle savedInstanceState) { @@ -57,7 +77,7 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen if (!UserConfig.isClientActivated()) { Intent intent = getIntent(); if (intent != null && intent.getAction() != null && (Intent.ACTION_SEND.equals(intent.getAction()) || intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE))) { - super.onCreateFinish(savedInstanceState); + super.onCreate(savedInstanceState); finish(); return; } @@ -67,15 +87,123 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen if (state.isEmpty()) { Intent intent2 = new Intent(this, IntroActivity.class); startActivity(intent2); - super.onCreateFinish(savedInstanceState); + super.onCreate(savedInstanceState); finish(); return; } } } + requestWindowFeature(Window.FEATURE_NO_TITLE); + setTheme(R.style.Theme_TMessages); + getWindow().setBackgroundDrawableResource(R.drawable.transparent); + super.onCreate(savedInstanceState); + actionBarLayout = new ActionBarLayout(this); + if (AndroidUtilities.isTablet()) { + setContentView(R.layout.launch_layout_tablet); + shadowTablet = (FrameLayout)findViewById(R.id.shadow_tablet); + buttonLayoutTablet = (LinearLayout)findViewById(R.id.launch_button_layout); + shadowTabletSide = (FrameLayout)findViewById(R.id.shadow_tablet_side); + + shadowTablet.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + RelativeLayout launchLayout = (RelativeLayout)findViewById(R.id.launch_layout); + + layersActionBarLayout = new ActionBarLayout(this); + layersActionBarLayout.setBackgroundView(shadowTablet); + layersActionBarLayout.setUseAlphaAnimations(true); + layersActionBarLayout.setBackgroundResource(R.drawable.boxshadow); + launchLayout.addView(layersActionBarLayout); + RelativeLayout.LayoutParams relativeLayoutParams = (RelativeLayout.LayoutParams)layersActionBarLayout.getLayoutParams(); + relativeLayoutParams.width = AndroidUtilities.dp(498); + relativeLayoutParams.height = AndroidUtilities.dp(528); + relativeLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); + layersActionBarLayout.setLayoutParams(relativeLayoutParams); + layersActionBarLayout.init(layerFragmentsStack); + layersActionBarLayout.setDelegate(this); + layersActionBarLayout.setVisibility(View.GONE); + + launchLayout.addView(actionBarLayout, 2); + relativeLayoutParams = (RelativeLayout.LayoutParams)actionBarLayout.getLayoutParams(); + relativeLayoutParams.width = AndroidUtilities.dp(320); + relativeLayoutParams.height = RelativeLayout.LayoutParams.MATCH_PARENT; + actionBarLayout.setLayoutParams(relativeLayoutParams); + + rightActionBarLayout = new ActionBarLayout(this); + launchLayout.addView(rightActionBarLayout, 3); + relativeLayoutParams = (RelativeLayout.LayoutParams)rightActionBarLayout.getLayoutParams(); + relativeLayoutParams.width = AndroidUtilities.dp(320); + relativeLayoutParams.height = RelativeLayout.LayoutParams.MATCH_PARENT; + rightActionBarLayout.setLayoutParams(relativeLayoutParams); + rightActionBarLayout.init(rightFragmentsStack); + rightActionBarLayout.setDelegate(this); + rightActionBarLayout.setVisibility(rightFragmentsStack.isEmpty() ? View.GONE : View.VISIBLE); + buttonLayoutTablet.setVisibility(rightFragmentsStack.isEmpty() ? View.VISIBLE : View.GONE); + + TextView button = (TextView)findViewById(R.id.new_group_button); + button.setText(LocaleController.getString("NewGroup", R.string.NewGroup)); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + presentFragment(new GroupCreateActivity()); + } + }); + + button = (TextView)findViewById(R.id.new_secret_button); + button.setText(LocaleController.getString("NewSecretChat", R.string.NewSecretChat)); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Bundle args = new Bundle(); + args.putBoolean("onlyUsers", true); + args.putBoolean("destroyAfterSelect", true); + args.putBoolean("usersAsSections", true); + args.putBoolean("createSecretChat", true); + presentFragment(new ContactsActivity(args)); + } + }); + + button = (TextView)findViewById(R.id.new_broadcast_button); + button.setText(LocaleController.getString("NewBroadcastList", R.string.NewBroadcastList)); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Bundle args = new Bundle(); + args.putBoolean("broadcast", true); + presentFragment(new GroupCreateActivity(args)); + } + }); + + button = (TextView)findViewById(R.id.contacts_button); + button.setText(LocaleController.getString("Contacts", R.string.Contacts)); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + presentFragment(new ContactsActivity(null)); + } + }); + + button = (TextView)findViewById(R.id.settings_button); + button.setText(LocaleController.getString("Settings", R.string.Settings)); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + presentFragment(new SettingsActivity()); + } + }); + } else { + setContentView(actionBarLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + } + actionBarLayout.init(mainFragmentsStack); + actionBarLayout.setDelegate(this); + int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { AndroidUtilities.statusBarHeight = getResources().getDimensionPixelSize(resourceId); @@ -88,11 +216,11 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen NotificationCenter.getInstance().addObserver(this, NotificationCenter.closeOtherAppActivities); NotificationCenter.getInstance().addObserver(this, NotificationCenter.didUpdatedConnectionState); - if (fragmentsStack.isEmpty()) { + if (actionBarLayout.fragmentsStack.isEmpty()) { if (!UserConfig.isClientActivated()) { - addFragmentToStack(new LoginActivity()); + actionBarLayout.addFragmentToStack(new LoginActivity()); } else { - addFragmentToStack(new MessagesActivity(null)); + actionBarLayout.addFragmentToStack(new MessagesActivity(null)); } try { @@ -103,31 +231,31 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen if (fragmentName.equals("chat")) { if (args != null) { ChatActivity chat = new ChatActivity(args); - if (addFragmentToStack(chat)) { + if (actionBarLayout.addFragmentToStack(chat)) { chat.restoreSelfArgs(savedInstanceState); } } } else if (fragmentName.equals("settings")) { SettingsActivity settings = new SettingsActivity(); - addFragmentToStack(settings); + actionBarLayout.addFragmentToStack(settings); settings.restoreSelfArgs(savedInstanceState); } else if (fragmentName.equals("group")) { if (args != null) { GroupCreateFinalActivity group = new GroupCreateFinalActivity(args); - if (addFragmentToStack(group)) { + if (actionBarLayout.addFragmentToStack(group)) { group.restoreSelfArgs(savedInstanceState); } } } else if (fragmentName.equals("chat_profile")) { if (args != null) { ChatProfileActivity profile = new ChatProfileActivity(args); - if (addFragmentToStack(profile)) { + if (actionBarLayout.addFragmentToStack(profile)) { profile.restoreSelfArgs(savedInstanceState); } } } else if (fragmentName.equals("wallpapers")) { SettingsWallpapersActivity settings = new SettingsWallpapersActivity(); - addFragmentToStack(settings); + actionBarLayout.addFragmentToStack(settings); settings.restoreSelfArgs(savedInstanceState); } } @@ -138,6 +266,7 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen } handleIntent(getIntent(), false, savedInstanceState != null); + needLayout(); } private void handleIntent(Intent intent, boolean isNew, boolean restore) { @@ -382,7 +511,7 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen Bundle args = new Bundle(); args.putInt("user_id", push_user_id); ChatActivity fragment = new ChatActivity(args); - if (presentFragment(fragment, false, true)) { + if (actionBarLayout.presentFragment(fragment, false, true)) { pushOpened = true; } } @@ -390,19 +519,19 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen Bundle args = new Bundle(); args.putInt("chat_id", push_chat_id); ChatActivity fragment = new ChatActivity(args); - if (presentFragment(fragment, false, true)) { + if (actionBarLayout.presentFragment(fragment, false, true)) { pushOpened = true; } } else if (push_enc_id != 0) { Bundle args = new Bundle(); args.putInt("enc_id", push_enc_id); ChatActivity fragment = new ChatActivity(args); - if (presentFragment(fragment, false, true)) { + if (actionBarLayout.presentFragment(fragment, false, true)) { pushOpened = true; } } else if (showDialogsList) { - for (int a = 1; a < fragmentsStack.size(); a++) { - removeFragmentFromStack(fragmentsStack.get(a)); + for (int a = 1; a < actionBarLayout.fragmentsStack.size(); a++) { + actionBarLayout.removeFragmentFromStack(actionBarLayout.fragmentsStack.get(a)); a--; } pushOpened = false; @@ -415,25 +544,29 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen args.putString("selectAlertString", LocaleController.getString("SendMessagesTo", R.string.SendMessagesTo)); MessagesActivity fragment = new MessagesActivity(args); fragment.setDelegate(this); - presentFragment(fragment, false, true); + actionBarLayout.presentFragment(fragment, false, true); pushOpened = true; if (PhotoViewer.getInstance().isVisible()) { PhotoViewer.getInstance().closePhoto(true); } } if (open_settings != 0) { - presentFragment(new SettingsActivity(), false, true); + actionBarLayout.presentFragment(new SettingsActivity(), false, true); pushOpened = true; } if (!pushOpened && !isNew) { - if (fragmentsStack.isEmpty()) { + if (actionBarLayout.fragmentsStack.isEmpty()) { if (!UserConfig.isClientActivated()) { - addFragmentToStack(new LoginActivity()); + actionBarLayout.addFragmentToStack(new LoginActivity()); } else { - addFragmentToStack(new MessagesActivity(null)); + actionBarLayout.addFragmentToStack(new MessagesActivity(null)); } } - showLastFragment(); + actionBarLayout.showLastFragment(); + if (AndroidUtilities.isTablet()) { + layersActionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); + } } intent.setAction(null); @@ -468,7 +601,7 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen args.putInt("enc_id", high_id); } ChatActivity fragment = new ChatActivity(args); - presentFragment(fragment, true); + actionBarLayout.presentFragment(fragment, true); if (videoPath != null) { fragment.processSendingVideo(videoPath, null, 0, 0, 0, 0); } @@ -496,18 +629,98 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen } } + private void onFinish() { + if (finished) { + return; + } + finished = true; + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.appDidLogout); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeOtherAppActivities); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didUpdatedConnectionState); + } + + public void presentFragment(BaseFragment fragment) { + actionBarLayout.presentFragment(fragment); + } + + public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation) { + return actionBarLayout.presentFragment(fragment, removeLast, forceWithoutAnimation); + } + + public void needLayout() { + if (AndroidUtilities.isTablet()) { + int leftWidth = AndroidUtilities.displaySize.x / 100 * 35; + if (leftWidth < AndroidUtilities.dp(320)) { + leftWidth = AndroidUtilities.dp(320); + } + + RelativeLayout.LayoutParams relativeLayoutParams = (RelativeLayout.LayoutParams) actionBarLayout.getLayoutParams(); + relativeLayoutParams.width = leftWidth; + relativeLayoutParams.height = RelativeLayout.LayoutParams.MATCH_PARENT; + actionBarLayout.setLayoutParams(relativeLayoutParams); + + relativeLayoutParams = (RelativeLayout.LayoutParams) shadowTabletSide.getLayoutParams(); + relativeLayoutParams.leftMargin = leftWidth; + shadowTabletSide.setLayoutParams(relativeLayoutParams); + + relativeLayoutParams = (RelativeLayout.LayoutParams) rightActionBarLayout.getLayoutParams(); + relativeLayoutParams.width = AndroidUtilities.displaySize.x - leftWidth; + relativeLayoutParams.height = RelativeLayout.LayoutParams.MATCH_PARENT; + relativeLayoutParams.leftMargin = leftWidth; + rightActionBarLayout.setLayoutParams(relativeLayoutParams); + + relativeLayoutParams = (RelativeLayout.LayoutParams) buttonLayoutTablet.getLayoutParams(); + relativeLayoutParams.width = AndroidUtilities.displaySize.x - leftWidth; + relativeLayoutParams.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + relativeLayoutParams.leftMargin = leftWidth; + buttonLayoutTablet.setLayoutParams(relativeLayoutParams); + } + } + + public void fixLayout() { + if (AndroidUtilities.isTablet()) { + final ViewTreeObserver obs = actionBarLayout.getViewTreeObserver(); + obs.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + needLayout(); + if (Build.VERSION.SDK_INT < 16) { + obs.removeGlobalOnLayoutListener(this); + } else { + obs.removeOnGlobalLayoutListener(this); + } + } + }); + } + } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (fragmentsStack.size() != 0) { - BaseFragment fragment = fragmentsStack.get(fragmentsStack.size() - 1); + if (actionBarLayout.fragmentsStack.size() != 0) { + BaseFragment fragment = actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1); fragment.onActivityResultFragment(requestCode, resultCode, data); } + if (AndroidUtilities.isTablet()) { + if (rightActionBarLayout.fragmentsStack.size() != 0) { + BaseFragment fragment = rightActionBarLayout.fragmentsStack.get(rightActionBarLayout.fragmentsStack.size() - 1); + fragment.onActivityResultFragment(requestCode, resultCode, data); + } + if (layersActionBarLayout.fragmentsStack.size() != 0) { + BaseFragment fragment = layersActionBarLayout.fragmentsStack.get(layersActionBarLayout.fragmentsStack.size() - 1); + fragment.onActivityResultFragment(requestCode, resultCode, data); + } + } } @Override protected void onPause() { super.onPause(); + actionBarLayout.onPause(); + if (AndroidUtilities.isTablet()) { + rightActionBarLayout.onPause(); + layersActionBarLayout.onPause(); + } ApplicationLoader.mainInterfacePaused = true; ConnectionsManager.getInstance().setAppPaused(true, false); } @@ -522,38 +735,43 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen @Override protected void onResume() { super.onResume(); + actionBarLayout.onResume(); + if (AndroidUtilities.isTablet()) { + rightActionBarLayout.onResume(); + layersActionBarLayout.onResume(); + } Utilities.checkForCrashes(this); Utilities.checkForUpdates(this); ApplicationLoader.mainInterfacePaused = false; ConnectionsManager.getInstance().setAppPaused(false, false); - actionBar.setBackOverlayVisible(currentConnectionState != 0); - } - - @Override - protected void onFinish() { - if (finished) { - return; - } - finished = true; - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.appDidLogout); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeOtherAppActivities); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didUpdatedConnectionState); + actionBarLayout.getActionBar().setBackOverlayVisible(currentConnectionState != 0); } @Override public void onConfigurationChanged(android.content.res.Configuration newConfig) { - super.onConfigurationChanged(newConfig); AndroidUtilities.checkDisplaySize(); + super.onConfigurationChanged(newConfig); + fixLayout(); } @Override @SuppressWarnings("unchecked") public void didReceivedNotification(int id, Object... args) { if (id == NotificationCenter.appDidLogout) { - for (BaseFragment fragment : fragmentsStack) { + for (BaseFragment fragment : actionBarLayout.fragmentsStack) { fragment.onFragmentDestroy(); } - fragmentsStack.clear(); + actionBarLayout.fragmentsStack.clear(); + if (AndroidUtilities.isTablet()) { + for (BaseFragment fragment : layersActionBarLayout.fragmentsStack) { + fragment.onFragmentDestroy(); + } + layersActionBarLayout.fragmentsStack.clear(); + for (BaseFragment fragment : rightActionBarLayout.fragmentsStack) { + fragment.onFragmentDestroy(); + } + rightActionBarLayout.fragmentsStack.clear(); + } Intent intent2 = new Intent(this, IntroActivity.class); startActivity(intent2); onFinish(); @@ -567,35 +785,17 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen if (currentConnectionState != state) { FileLog.e("tmessages", "switch to state " + state); currentConnectionState = state; - actionBar.setBackOverlayVisible(currentConnectionState != 0); + actionBarLayout.getActionBar().setBackOverlayVisible(currentConnectionState != 0); } } } - @Override - public void onOverlayShow(View view, BaseFragment fragment) { - if (view == null || fragment == null || fragmentsStack.isEmpty()) { - return; - } - View backStatusButton = view.findViewById(R.id.back_button); - TextView statusText = (TextView)view.findViewById(R.id.status_text); - backStatusButton.setVisibility(fragmentsStack.get(0) == fragment ? View.GONE : View.VISIBLE); - view.setEnabled(fragmentsStack.get(0) != fragment); - if (currentConnectionState == 1) { - statusText.setText(LocaleController.getString("WaitingForNetwork", R.string.WaitingForNetwork)); - } else if (currentConnectionState == 2) { - statusText.setText(LocaleController.getString("Connecting", R.string.Connecting)); - } else if (currentConnectionState == 3) { - statusText.setText(LocaleController.getString("Updating", R.string.Updating)); - } - } - @Override protected void onSaveInstanceState(Bundle outState) { try { super.onSaveInstanceState(outState); - if (!fragmentsStack.isEmpty()) { - BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); + if (!actionBarLayout.fragmentsStack.isEmpty()) { + BaseFragment lastFragment = actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1); Bundle args = lastFragment.getArguments(); if (lastFragment instanceof ChatActivity && args != null) { outState.putBundle("args", args); @@ -623,7 +823,52 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen if (PhotoViewer.getInstance().isVisible()) { PhotoViewer.getInstance().closePhoto(true); } else { - super.onBackPressed(); + if (AndroidUtilities.isTablet()) { + if (layersActionBarLayout.getVisibility() == View.VISIBLE) { + layersActionBarLayout.onBackPressed(); + } else { + boolean cancel = false; + if (rightActionBarLayout.getVisibility() == View.VISIBLE && !rightActionBarLayout.fragmentsStack.isEmpty()) { + BaseFragment lastFragment = rightActionBarLayout.fragmentsStack.get(rightActionBarLayout.fragmentsStack.size() - 1); + cancel = !lastFragment.onBackPressed(); + } + if (!cancel) { + actionBarLayout.onBackPressed(); + } + } + } else { + actionBarLayout.onBackPressed(); + } + } + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + actionBarLayout.onLowMemory(); + if (AndroidUtilities.isTablet()) { + rightActionBarLayout.onLowMemory(); + layersActionBarLayout.onLowMemory(); + } + } + + @Override + public void onActionModeStarted(ActionMode mode) { + super.onActionModeStarted(mode); + actionBarLayout.onActionModeStarted(mode); + if (AndroidUtilities.isTablet()) { + rightActionBarLayout.onActionModeStarted(mode); + layersActionBarLayout.onActionModeStarted(mode); + } + } + + @Override + public void onActionModeFinished(ActionMode mode) { + super.onActionModeFinished(mode); + actionBarLayout.onActionModeFinished(mode); + if (AndroidUtilities.isTablet()) { + rightActionBarLayout.onActionModeFinished(mode); + layersActionBarLayout.onActionModeFinished(mode); } } @@ -633,11 +878,150 @@ public class LaunchActivity extends ActionBarActivity implements NotificationCen PhotoViewer.getInstance().closePhoto(true); return true; } - return super.onPreIme(); + return false; } @Override - public void onLowMemory() { - super.onLowMemory(); + public void onOverlayShow(View view, BaseFragment fragment) { + if (view == null || fragment == null || actionBarLayout.fragmentsStack.isEmpty()) { + return; + } + View backStatusButton = view.findViewById(R.id.back_button); + TextView statusText = (TextView)view.findViewById(R.id.status_text); + backStatusButton.setVisibility(actionBarLayout.fragmentsStack.get(0) == fragment ? View.GONE : View.VISIBLE); + view.setEnabled(actionBarLayout.fragmentsStack.get(0) != fragment); + if (currentConnectionState == 1) { + statusText.setText(LocaleController.getString("WaitingForNetwork", R.string.WaitingForNetwork)); + } else if (currentConnectionState == 2) { + statusText.setText(LocaleController.getString("Connecting", R.string.Connecting)); + } else if (currentConnectionState == 3) { + statusText.setText(LocaleController.getString("Updating", R.string.Updating)); + } + } + + @Override + public boolean needPresentFragment(BaseFragment fragment, boolean removeLast, boolean forceWithoutAnimation, ActionBarLayout layout) { + if (AndroidUtilities.isTablet()) { + if (fragment instanceof MessagesActivity) { + MessagesActivity messagesActivity = (MessagesActivity)fragment; + if (messagesActivity.getDelegate() == null && layout != actionBarLayout) { + actionBarLayout.removeAllFragments(); + actionBarLayout.presentFragment(fragment, removeLast, forceWithoutAnimation); + layersActionBarLayout.removeAllFragments(); + layersActionBarLayout.setVisibility(View.GONE); + if (rightFragmentsStack.isEmpty()) { + buttonLayoutTablet.setVisibility(View.VISIBLE); + } + return false; + } + } else if (fragment instanceof ChatActivity) { + if (layout != rightActionBarLayout) { + rightActionBarLayout.setVisibility(View.VISIBLE); + buttonLayoutTablet.setVisibility(View.GONE); + rightActionBarLayout.removeAllFragments(); + rightActionBarLayout.presentFragment(fragment, removeLast, true); + if (removeLast) { + layout.closeLastFragment(true); + } + return false; + } + } else if (layout != layersActionBarLayout) { + layersActionBarLayout.setVisibility(View.VISIBLE); + if (fragment instanceof LoginActivity) { + buttonLayoutTablet.setVisibility(View.GONE); + shadowTablet.setBackgroundColor(0x00000000); + } else { + shadowTablet.setBackgroundColor(0x7F000000); + } + layersActionBarLayout.presentFragment(fragment, removeLast, forceWithoutAnimation); + return false; + } + return true; + } else { + return true; + } + } + + @Override + public boolean needAddFragmentToStack(BaseFragment fragment, ActionBarLayout layout) { + if (AndroidUtilities.isTablet()) { + if (fragment instanceof MessagesActivity) { + MessagesActivity messagesActivity = (MessagesActivity)fragment; + if (messagesActivity.getDelegate() == null && layout != actionBarLayout) { + actionBarLayout.removeAllFragments(); + actionBarLayout.addFragmentToStack(fragment); + layersActionBarLayout.removeAllFragments(); + layersActionBarLayout.setVisibility(View.GONE); + if (rightFragmentsStack.isEmpty()) { + buttonLayoutTablet.setVisibility(View.VISIBLE); + } + return false; + } + } else if (fragment instanceof ChatActivity) { + if (layout != rightActionBarLayout) { + rightActionBarLayout.setVisibility(View.VISIBLE); + buttonLayoutTablet.setVisibility(View.GONE); + rightActionBarLayout.removeAllFragments(); + rightActionBarLayout.addFragmentToStack(fragment); + return false; + } + } else if (layout != layersActionBarLayout) { + layersActionBarLayout.setVisibility(View.VISIBLE); + if (fragment instanceof LoginActivity) { + buttonLayoutTablet.setVisibility(View.GONE); + shadowTablet.setBackgroundColor(0x00000000); + } else { + shadowTablet.setBackgroundColor(0x7F000000); + } + layersActionBarLayout.addFragmentToStack(fragment); + return false; + } + return true; + } else { + return true; + } + } + + @Override + public boolean needCloseLastFragment(ActionBarLayout layout) { + if (AndroidUtilities.isTablet()) { + if (layout == actionBarLayout && layout.fragmentsStack.size() <= 1) { + onFinish(); + finish(); + return false; + } else if (layout == rightActionBarLayout) { + buttonLayoutTablet.setVisibility(View.VISIBLE); + } + } else { + if (layout.fragmentsStack.size() <= 1) { + onFinish(); + finish(); + return false; + } + } + return true; + } + + @Override + public void onRebuildAllFragments(ActionBarLayout layout) { + if (AndroidUtilities.isTablet()) { + if (layout == layersActionBarLayout) { + rightActionBarLayout.rebuildAllFragmentViews(true); + rightActionBarLayout.showLastFragment(); + actionBarLayout.rebuildAllFragmentViews(true); + actionBarLayout.showLastFragment(); + + TextView button = (TextView)findViewById(R.id.new_group_button); + button.setText(LocaleController.getString("NewGroup", R.string.NewGroup)); + button = (TextView)findViewById(R.id.new_secret_button); + button.setText(LocaleController.getString("NewSecretChat", R.string.NewSecretChat)); + button = (TextView)findViewById(R.id.new_broadcast_button); + button.setText(LocaleController.getString("NewBroadcastList", R.string.NewBroadcastList)); + button = (TextView)findViewById(R.id.contacts_button); + button.setText(LocaleController.getString("Contacts", R.string.Contacts)); + button = (TextView)findViewById(R.id.settings_button); + button.setText(LocaleController.getString("Settings", R.string.Settings)); + } + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java index 44f33396b..e3e065e87 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java @@ -27,6 +27,8 @@ import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; +import org.telegram.android.AndroidUtilities; +import org.telegram.android.ContactsController; import org.telegram.messenger.FileLog; import org.telegram.android.LocaleController; import org.telegram.messenger.TLRPC; @@ -34,7 +36,6 @@ import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; -import org.telegram.messenger.Utilities; import org.telegram.ui.Views.ActionBar.ActionBarLayer; import org.telegram.ui.Views.ActionBar.ActionBarMenu; import org.telegram.ui.Views.ActionBar.ActionBarMenuItem; @@ -235,8 +236,8 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (user.photo != null) { photo = user.photo.photo_small; } - avatarImageView.setImage(photo, "50_50", Utilities.getUserAvatarForId(user.id)); - nameTextView.setText(Utilities.formatName(user.first_name, user.last_name)); + avatarImageView.setImage(photo, "50_50", AndroidUtilities.getUserAvatarForId(user.id)); + nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); } userLocation = new Location("network"); userLocation.setLatitude(messageObject.messageOwner.media.geo.lat); @@ -284,8 +285,8 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (user.photo != null) { photo = user.photo.photo_small; } - avatarImageView.setImage(photo, null, Utilities.getUserAvatarForId(user.id)); - nameTextView.setText(Utilities.formatName(user.first_name, user.last_name)); + avatarImageView.setImage(photo, null, AndroidUtilities.getUserAvatarForId(user.id)); + nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java index 100936d0f..da71c6f4c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java @@ -326,14 +326,20 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); int rotation = manager.getDefaultDisplay().getRotation(); - if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { - listView.setNumColumns(6); - itemWidth = getParentActivity().getResources().getDisplayMetrics().widthPixels / 6 - AndroidUtilities.dp(2) * 5; + if (AndroidUtilities.isTablet()) { + listView.setNumColumns(4); + itemWidth = AndroidUtilities.dp(490) / 4 - AndroidUtilities.dp(2) * 3; listView.setColumnWidth(itemWidth); } else { - listView.setNumColumns(4); - itemWidth = getParentActivity().getResources().getDisplayMetrics().widthPixels / 4 - AndroidUtilities.dp(2) * 3; - listView.setColumnWidth(itemWidth); + if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { + listView.setNumColumns(6); + itemWidth = AndroidUtilities.displaySize.x / 6 - AndroidUtilities.dp(2) * 5; + listView.setColumnWidth(itemWidth); + } else { + listView.setNumColumns(4); + itemWidth = AndroidUtilities.displaySize.x / 4 - AndroidUtilities.dp(2) * 3; + listView.setColumnWidth(itemWidth); + } } listView.setPadding(listView.getPaddingLeft(), AndroidUtilities.dp(4), listView.getPaddingRight(), listView.getPaddingBottom()); listAdapter.notifyDataSetChanged(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java index 85cb4a3dd..16de820dd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java @@ -68,6 +68,8 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter private MessagesActivityDelegate delegate; + private long openedDialogId = 0; + private final static int messages_list_menu_new_messages = 1; private final static int messages_list_menu_new_chat = 2; private final static int messages_list_menu_other = 6; @@ -94,6 +96,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter NotificationCenter.getInstance().addObserver(this, NotificationCenter.encryptedChatUpdated); NotificationCenter.getInstance().addObserver(this, NotificationCenter.contactsDidLoaded); NotificationCenter.getInstance().addObserver(this, NotificationCenter.appDidLogout); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.openedChatChanged); if (getArguments() != null) { onlySelect = arguments.getBoolean("onlySelect", false); serverOnly = arguments.getBoolean("serverOnly", false); @@ -116,6 +119,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter NotificationCenter.getInstance().removeObserver(this, NotificationCenter.encryptedChatUpdated); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.contactsDidLoaded); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.appDidLogout); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.openedChatChanged); delegate = null; } @@ -224,6 +228,10 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter messagesListView = (ListView)fragmentView.findViewById(R.id.messages_list_view); messagesListView.setAdapter(messagesListViewAdapter); + if (delegate == null && AndroidUtilities.isTablet()) { + messagesListView.setDivider(inflater.getContext().getResources().getDrawable(R.drawable.messages_list_divider2)); + messagesListView.setDividerHeight(1); + } progressView = fragmentView.findViewById(R.id.progressLayout); messagesListViewAdapter.notifyDataSetChanged(); @@ -305,7 +313,14 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } else { args.putInt("enc_id", high_id); } + if (AndroidUtilities.isTablet()) { + if (openedDialogId == dialog_id) { + return; + } + openedDialogId = dialog_id; + } presentFragment(new ChatActivity(args)); + updateVisibleRows(0); } } }); @@ -469,6 +484,11 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter updateVisibleRows(0); } else if (id == NotificationCenter.contactsDidLoaded) { updateVisibleRows(0); + } else if (id == NotificationCenter.openedChatChanged) { + if (!serverOnly && AndroidUtilities.isTablet()) { + openedDialogId = (Long)args[0]; + updateVisibleRows(0); + } } } @@ -480,7 +500,15 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter for (int a = 0; a < count; a++) { View child = messagesListView.getChildAt(a); if (child instanceof DialogCell) { - ((DialogCell) child).update(mask); + DialogCell cell = (DialogCell) child; + if (!serverOnly && AndroidUtilities.isTablet() && cell.getDialog() != null) { + if (cell.getDialog().id == openedDialogId) { + child.setBackgroundColor(0x0f000000); + } else { + child.setBackgroundColor(0); + } + } + cell.update(mask); } else if (child instanceof ChatOrUserCell) { ((ChatOrUserCell) child).update(mask); } @@ -491,6 +519,10 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter this.delegate = delegate; } + public MessagesActivityDelegate getDelegate() { + return delegate; + } + private void didSelectResult(final long dialog_id, boolean useAlert, final boolean param) { if (useAlert && selectAlertString != null) { if (getParentActivity() == null) { @@ -513,7 +545,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (user == null) { return; } - builder.setMessage(LocaleController.formatStringSimple(selectAlertString, Utilities.formatName(user.first_name, user.last_name))); + builder.setMessage(LocaleController.formatStringSimple(selectAlertString, ContactsController.formatName(user.first_name, user.last_name))); } else if (lower_part < 0) { TLRPC.Chat chat = MessagesController.getInstance().getChat(-lower_part); if (chat == null) { @@ -528,7 +560,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (user == null) { return; } - builder.setMessage(LocaleController.formatStringSimple(selectAlertString, Utilities.formatName(user.first_name, user.last_name))); + builder.setMessage(LocaleController.formatStringSimple(selectAlertString, ContactsController.formatName(user.first_name, user.last_name))); } CheckBox checkBox = null; /*if (delegate instanceof ChatActivity) { @@ -713,7 +745,15 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (serverOnly) { ((DialogCell)view).setDialog(MessagesController.getInstance().dialogsServerOnly.get(i)); } else { - ((DialogCell)view).setDialog(MessagesController.getInstance().dialogs.get(i)); + TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs.get(i); + if (AndroidUtilities.isTablet()) { + if (dialog.id == openedDialogId) { + view.setBackgroundColor(0x0f000000); + } else { + view.setBackgroundColor(0); + } + } + ((DialogCell)view).setDialog(dialog); } return view; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java index 2a6e8afc8..91c0b1beb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java @@ -12,17 +12,14 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; -import android.graphics.Point; import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Bundle; import android.util.AttributeSet; -import android.view.Display; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.view.WindowManager; import android.widget.Button; import android.widget.FrameLayout; import android.widget.TextView; @@ -302,14 +299,12 @@ public class PhotoCropActivity extends BaseFragment { return false; } } - Point displaySize = new Point(); - Display display = ((WindowManager)ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); - if(android.os.Build.VERSION.SDK_INT < 13) { - displaySize.set(display.getWidth(), display.getHeight()); + int size = 0; + if (AndroidUtilities.isTablet()) { + size = AndroidUtilities.dp(520); } else { - display.getSize(displaySize); + size = Math.max(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y); } - int size = Math.max(displaySize.x, displaySize.y); imageToCrop = ImageLoader.loadBitmap(photoPath, photoUri, size, size); if (imageToCrop == null) { return false; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java index 11a719e69..81b253b91 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java @@ -394,10 +394,14 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen int columnsCount = 2; if (selectedAlbum != null) { - if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { - columnsCount = 5; - } else { + if (AndroidUtilities.isTablet()) { columnsCount = 3; + } else { + if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { + columnsCount = 5; + } else { + columnsCount = 3; + } } } else { if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { @@ -405,7 +409,11 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen } } listView.setNumColumns(columnsCount); - itemWidth = (getParentActivity().getResources().getDisplayMetrics().widthPixels - ((columnsCount + 1) * AndroidUtilities.dp(4))) / columnsCount; + if (AndroidUtilities.isTablet()) { + itemWidth = (AndroidUtilities.dp(490) - ((columnsCount + 1) * AndroidUtilities.dp(4))) / columnsCount; + } else { + itemWidth = (AndroidUtilities.displaySize.x - ((columnsCount + 1) * AndroidUtilities.dp(4))) / columnsCount; + } listView.setColumnWidth(itemWidth); listAdapter.notifyDataSetChanged(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java index 210ca91c5..686abc463 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -47,6 +47,7 @@ import android.widget.Scroller; import android.widget.TextView; import org.telegram.android.AndroidUtilities; +import org.telegram.android.ContactsController; import org.telegram.android.MessagesStorage; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; @@ -62,7 +63,6 @@ import org.telegram.messenger.Utilities; import org.telegram.android.MessageObject; import org.telegram.android.PhotoObject; import org.telegram.ui.Views.ActionBar.ActionBar; -import org.telegram.ui.Views.ActionBar.ActionBarActivity; import org.telegram.ui.Views.ActionBar.ActionBarLayer; import org.telegram.ui.Views.ActionBar.ActionBarMenu; import org.telegram.ui.Views.ActionBar.ActionBarMenuItem; @@ -521,7 +521,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat closePhoto(false); Bundle args2 = new Bundle(); args2.putLong("dialog_id", currentDialogId); - ((ActionBarActivity)parentActivity).presentFragment(new MediaActivity(args2), false, true); + ((LaunchActivity)parentActivity).presentFragment(new MediaActivity(args2), false, true); } } else if (id == gallery_menu_send) { /*Intent intent = new Intent(this, MessagesActivity.class); @@ -1219,7 +1219,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat currentMessageObject = imagesArr.get(currentIndex); TLRPC.User user = MessagesController.getInstance().getUser(currentMessageObject.messageOwner.from_id); if (user != null) { - nameTextView.setText(Utilities.formatName(user.first_name, user.last_name)); + nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); } else { nameTextView.setText(""); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java index 2d4bef557..4486fc2cd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java @@ -13,7 +13,6 @@ import android.app.KeyguardManager; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; -import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.os.PowerManager; import android.util.AttributeSet; @@ -43,7 +42,6 @@ import org.telegram.messenger.FileLog; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; -import org.telegram.messenger.Utilities; import org.telegram.android.MessageObject; import org.telegram.android.PhotoObject; import org.telegram.ui.Views.ActionBar.ActionBar; @@ -53,6 +51,7 @@ import org.telegram.ui.Views.BackupImageView; import org.telegram.ui.Views.ChatActivityEnterView; import org.telegram.ui.Views.FrameLayoutFixed; import org.telegram.ui.Views.PopupAudioView; +import org.telegram.ui.Views.TypingDotsDrawable; import java.io.File; import java.util.ArrayList; @@ -71,6 +70,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC private ArrayList imageViews = new ArrayList(); private ArrayList audioViews = new ArrayList(); private VelocityTracker velocityTracker = null; + private TypingDotsDrawable typingDotsDrawable; private int classGuid; private TLRPC.User currentUser; @@ -151,6 +151,8 @@ public class PopupNotificationActivity extends Activity implements NotificationC NotificationCenter.getInstance().addObserver(this, NotificationCenter.contactsDidLoaded); NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded); + typingDotsDrawable = new TypingDotsDrawable(); + chatActivityEnterView = new ChatActivityEnterView(); chatActivityEnterView.setDelegate(new ChatActivityEnterView.ChatActivityEnterViewDelegate() { @Override @@ -624,7 +626,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC messageContainer.getViewTreeObserver().removeOnPreDrawListener(this); if (!checkTransitionAnimation() && !startedMoving) { ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)messageContainer.getLayoutParams(); - if (!Utilities.isTablet(PopupNotificationActivity.this) && PopupNotificationActivity.this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (!AndroidUtilities.isTablet() && PopupNotificationActivity.this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { layoutParams.topMargin = AndroidUtilities.dp(40); } else { layoutParams.topMargin = AndroidUtilities.dp(48); @@ -739,10 +741,10 @@ public class PopupNotificationActivity extends Activity implements NotificationC if (currentChat != null && currentUser != null) { actionBarLayer.setTitle(currentChat.title); - actionBarLayer.setSubtitle(Utilities.formatName(currentUser.first_name, currentUser.last_name)); + actionBarLayer.setSubtitle(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); actionBarLayer.setTitleIcon(0, 0); } else if (currentUser != null) { - actionBarLayer.setTitle(Utilities.formatName(currentUser.first_name, currentUser.last_name)); + actionBarLayer.setTitle(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); if ((int)dialog_id == 0) { actionBarLayer.setTitleIcon(R.drawable.ic_lock_white, AndroidUtilities.dp(4)); } else { @@ -767,10 +769,10 @@ public class PopupNotificationActivity extends Activity implements NotificationC if (currentUser.phone != null && currentUser.phone.length() != 0) { actionBarLayer.setTitle(PhoneFormat.getInstance().format("+" + currentUser.phone)); } else { - actionBarLayer.setTitle(Utilities.formatName(currentUser.first_name, currentUser.last_name)); + actionBarLayer.setTitle(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); } } else { - actionBarLayer.setTitle(Utilities.formatName(currentUser.first_name, currentUser.last_name)); + actionBarLayer.setTitle(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); } CharSequence printString = MessagesController.getInstance().printingStrings.get(currentMessageObject.getDialogId()); if (printString == null || printString.length() == 0) { @@ -800,7 +802,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC if (currentChat.photo != null) { newPhoto = currentChat.photo.photo_small; } - placeHolderId = Utilities.getGroupAvatarForId(currentChat.id); + placeHolderId = AndroidUtilities.getGroupAvatarForId(currentChat.id); } else if (currentUser != null) { TLRPC.User user = MessagesController.getInstance().getUser(currentUser.id); if (user == null) { @@ -810,7 +812,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC if (currentUser.photo != null) { newPhoto = currentUser.photo.photo_small; } - placeHolderId = Utilities.getUserAvatarForId(currentUser.id); + placeHolderId = AndroidUtilities.getUserAvatarForId(currentUser.id); } if (avatarImageView != null) { avatarImageView.setImage(newPhoto, "50_50", placeHolderId); @@ -823,15 +825,14 @@ public class PopupNotificationActivity extends Activity implements NotificationC } if (start) { try { - actionBarLayer.setSubTitleIcon(R.drawable.typing_dots, AndroidUtilities.dp(4)); - AnimationDrawable mAnim = (AnimationDrawable)actionBarLayer.getSubTitleIcon(); - mAnim.setAlpha(200); - mAnim.start(); + actionBarLayer.setSubTitleIcon(0, typingDotsDrawable, AndroidUtilities.dp(4)); + typingDotsDrawable.start(); } catch (Exception e) { FileLog.e("tmessages", e); } } else { - actionBarLayer.setSubTitleIcon(0, 0); + actionBarLayer.setSubTitleIcon(0, null, 0); + typingDotsDrawable.stop(); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java index 8266801a3..f0d96c0d6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java @@ -52,7 +52,6 @@ import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.RPCRequest; import org.telegram.messenger.UserConfig; -import org.telegram.messenger.Utilities; import org.telegram.android.MessageObject; import org.telegram.android.PhotoObject; import org.telegram.ui.Adapters.BaseFragmentAdapter; @@ -817,7 +816,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter user = UserConfig.getCurrentUser(); } if (user != null) { - textView.setText(Utilities.formatName(user.first_name, user.last_name)); + textView.setText(ContactsController.formatName(user.first_name, user.last_name)); BackupImageView avatarImage = (BackupImageView)view.findViewById(R.id.settings_avatar_image); avatarImage.processDetach = false; TLRPC.FileLocation photo = null; @@ -826,7 +825,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter photo = user.photo.photo_small; photoBig = user.photo.photo_big; } - avatarImage.setImage(photo, "50_50", Utilities.getUserAvatarForId(user.id)); + avatarImage.setImage(photo, "50_50", AndroidUtilities.getUserAvatarForId(user.id)); avatarImage.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); } return view; @@ -979,7 +978,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter View divider = view.findViewById(R.id.settings_row_divider); if (i == textSizeRow) { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - int size = preferences.getInt("fons_size", 16); + int size = preferences.getInt("fons_size", AndroidUtilities.isTablet() ? 18 : 16); detailTextView.setText(String.format("%d", size)); textView.setText(LocaleController.getString("TextSize", R.string.TextSize)); divider.setVisibility(View.VISIBLE); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/UserProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/UserProfileActivity.java index a89cf848a..718fb101f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/UserProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/UserProfileActivity.java @@ -34,7 +34,6 @@ import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; -import org.telegram.messenger.Utilities; import org.telegram.android.MessageObject; import org.telegram.ui.Adapters.BaseFragmentAdapter; import org.telegram.ui.Views.ActionBar.ActionBarLayer; @@ -542,7 +541,7 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen Typeface typeface = AndroidUtilities.getTypeface("fonts/rmedium.ttf"); textView.setTypeface(typeface); - textView.setText(Utilities.formatName(user.first_name, user.last_name)); + textView.setText(ContactsController.formatName(user.first_name, user.last_name)); onlineText.setText(LocaleController.formatUserStatus(user)); TLRPC.FileLocation photo = null; @@ -551,7 +550,7 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen photo = user.photo.photo_small; photoBig = user.photo.photo_big; } - avatarImage.setImage(photo, "50_50", Utilities.getUserAvatarForId(user.id)); + avatarImage.setImage(photo, "50_50", AndroidUtilities.getUserAvatarForId(user.id)); avatarImage.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); return view; } else if (type == 1) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java index b72986a39..264f1734d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java @@ -10,16 +10,19 @@ package org.telegram.ui; import android.annotation.TargetApi; import android.content.res.Configuration; +import android.graphics.SurfaceTexture; import android.media.MediaCodec; import android.media.MediaCodecInfo; +import android.media.MediaCodecList; import android.media.MediaExtractor; import android.media.MediaFormat; -import android.media.MediaMetadataRetriever; import android.media.MediaPlayer; +import android.os.Build; import android.os.Bundle; +import android.view.Gravity; import android.view.LayoutInflater; -import android.view.SurfaceHolder; -import android.view.SurfaceView; +import android.view.Surface; +import android.view.TextureView; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; @@ -28,14 +31,20 @@ import android.widget.ImageView; import android.widget.TextView; import com.coremedia.iso.IsoFile; +import com.coremedia.iso.boxes.Box; import com.coremedia.iso.boxes.Container; +import com.coremedia.iso.boxes.MediaBox; +import com.coremedia.iso.boxes.MediaHeaderBox; +import com.coremedia.iso.boxes.SampleSizeBox; import com.coremedia.iso.boxes.TrackBox; +import com.coremedia.iso.boxes.TrackHeaderBox; import com.coremedia.iso.boxes.h264.AvcConfigurationBox; import com.googlecode.mp4parser.authoring.Movie; import com.googlecode.mp4parser.authoring.Track; import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder; import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator; import com.googlecode.mp4parser.authoring.tracks.CroppedTrack; +import com.googlecode.mp4parser.util.Matrix; import com.googlecode.mp4parser.util.Path; import org.telegram.android.AndroidUtilities; @@ -58,22 +67,24 @@ import java.io.File; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; -import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; -@TargetApi(18) -public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.Callback { +@TargetApi(16) +public class VideoEditorActivity extends BaseFragment implements TextureView.SurfaceTextureListener { private final static int OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100; private final static int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; private final static int OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03; private final static int OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002; private final static int OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m = 0x7FA30C04; + private final static String MIME_TYPE = "video/avc"; + + private final static int PROCESSOR_TYPE_OTHER = 0; + private final static int PROCESSOR_TYPE_QCOM = 1; private MediaPlayer videoPlayer = null; - private SurfaceHolder surfaceHolder = null; private VideoTimelineView videoTimelineView = null; private View videoContainerView = null; private TextView originalSizeTextView = null; @@ -81,21 +92,33 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C private View textContainerView = null; private ImageView playButton = null; private VideoSeekBarView videoSeekBarView = null; + private TextureView textureView = null; + private View controlView = null; - private boolean initied = false; private String videoPath = null; - private int videoWidth; - private int videoHeight; - private int editedVideoWidth; - private int editedVideoHeight; - private int editedVideoDuration; private float lastProgress = 0; private boolean needSeek = false; private VideoEditorActivityDelegate delegate; - private long esimatedFileSize = 0; + + private boolean firstWrite = true; + //MediaMetadataRetriever TODO + + private int rotationValue = 0; + private int originalWidth = 0; + private int originalHeight = 0; + private int resultWidth = 0; + private int resultHeight = 0; + private int bitrate = 0; + private float videoDuration = 0; + private long startTime = 0; + private long endTime = 0; + private int audioFramesSize = 0; + private int videoFramesSize = 0; + private int estimatedSize = 0; + private long esimatedDuration = 0; public interface VideoEditorActivityDelegate { - public abstract void didStartVideoConverting(String videoPath, String originalPath, long esimatedSize, int duration, int width, int height); + public abstract void didStartVideoConverting(String videoPath, String originalPath, long estimatedSize, int duration, int width, int height); public abstract void didAppenedVideoData(String videoPath, long finalSize); } @@ -107,12 +130,14 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C @Override public void run() { if (videoPlayer.isPlaying()) { - float startTime = videoTimelineView.getLeftProgress() * videoPlayer.getDuration(); - float endTime = videoTimelineView.getRightProgress() * videoPlayer.getDuration(); + float startTime = videoTimelineView.getLeftProgress() * videoDuration; + float endTime = videoTimelineView.getRightProgress() * videoDuration; if (startTime == endTime) { startTime = endTime - 0.01f; } float progress = (videoPlayer.getCurrentPosition() - startTime) / (endTime - startTime); + float lrdiff = videoTimelineView.getRightProgress() - videoTimelineView.getLeftProgress(); + progress = videoTimelineView.getLeftProgress() + lrdiff * progress; if (progress > lastProgress) { videoSeekBarView.setProgress(progress); lastProgress = progress; @@ -144,7 +169,7 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C @Override public boolean onFragmentCreate() { - if (videoPath == null) { + if (videoPath == null || !processOpenVideo()) { return false; } videoPlayer = new MediaPlayer(); @@ -204,6 +229,11 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C editedSizeTextView = (TextView) fragmentView.findViewById(R.id.edited_size); videoContainerView = fragmentView.findViewById(R.id.video_container); textContainerView = fragmentView.findViewById(R.id.info_container); + controlView = fragmentView.findViewById(R.id.control_layout); + TextView titleTextView = (TextView) fragmentView.findViewById(R.id.original_title); + titleTextView.setText(LocaleController.getString("OriginalVideo", R.string.OriginalVideo)); + titleTextView = (TextView) fragmentView.findViewById(R.id.edited_title); + titleTextView.setText(LocaleController.getString("EditedVideo", R.string.EditedVideo)); videoTimelineView = (VideoTimelineView) fragmentView.findViewById(R.id.video_timeline_view); videoTimelineView.setVideoPath(videoPath); @@ -216,12 +246,12 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C playButton.setImageResource(R.drawable.video_play); } videoPlayer.setOnSeekCompleteListener(null); - videoPlayer.seekTo((int) (videoPlayer.getDuration() * progress)); + videoPlayer.seekTo((int) (videoDuration * progress)); } catch (Exception e) { FileLog.e("tmessages", e); } needSeek = true; - videoSeekBarView.setProgress(0); + videoSeekBarView.setProgress(videoTimelineView.getLeftProgress()); updateVideoEditedInfo(); } @@ -233,12 +263,12 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C playButton.setImageResource(R.drawable.video_play); } videoPlayer.setOnSeekCompleteListener(null); - videoPlayer.seekTo((int) (videoPlayer.getDuration() * progress)); + videoPlayer.seekTo((int) (videoDuration * progress)); } catch (Exception e) { FileLog.e("tmessages", e); } needSeek = true; - videoSeekBarView.setProgress(0); + videoSeekBarView.setProgress(videoTimelineView.getLeftProgress()); updateVideoEditedInfo(); } }); @@ -250,7 +280,7 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C if (videoPlayer.isPlaying()) { try { float prog = videoTimelineView.getLeftProgress() + (videoTimelineView.getRightProgress() - videoTimelineView.getLeft()) * progress; - videoPlayer.seekTo((int) (videoPlayer.getDuration() * prog)); + videoPlayer.seekTo((int) (videoDuration * prog)); lastProgress = progress; } catch (Exception e) { FileLog.e("tmessages", e); @@ -266,18 +296,12 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C playButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (surfaceHolder.isCreating()) { - return; - } play(); } }); - SurfaceView surfaceView = (SurfaceView) fragmentView.findViewById(R.id.video_view); - surfaceHolder = surfaceView.getHolder(); - surfaceHolder.addCallback(this); - surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); - surfaceHolder.setFixedSize(270, 480); + textureView = (TextureView) fragmentView.findViewById(R.id.video_view); + textureView.setSurfaceTextureListener(this); updateVideoOriginalInfo(); updateVideoEditedInfo(); @@ -303,102 +327,114 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C } @Override - public void surfaceCreated(SurfaceHolder holder) { - videoPlayer.setDisplay(holder); + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { try { + Surface s = new Surface(surface); + videoPlayer.setSurface(s); videoPlayer.setDataSource(videoPath); videoPlayer.prepare(); - videoWidth = videoPlayer.getVideoWidth(); - videoHeight = videoPlayer.getVideoHeight(); - fixVideoSize(); - videoPlayer.seekTo((int) (videoTimelineView.getLeftProgress() * videoPlayer.getDuration())); - initied = true; + videoPlayer.seekTo((int) (videoTimelineView.getLeftProgress() * videoDuration)); } catch (Exception e) { FileLog.e("tmessages", e); } - updateVideoOriginalInfo(); - updateVideoEditedInfo(); } @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override - public void surfaceDestroyed(SurfaceHolder holder) { + public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { videoPlayer.setDisplay(null); + return true; + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + } private void onPlayComplete() { playButton.setImageResource(R.drawable.video_play); - videoSeekBarView.setProgress(0); + videoSeekBarView.setProgress(videoTimelineView.getLeftProgress()); try { - videoPlayer.seekTo((int) (videoTimelineView.getLeftProgress() * videoPlayer.getDuration())); + videoPlayer.seekTo((int) (videoTimelineView.getLeftProgress() * videoDuration)); } catch (Exception e) { FileLog.e("tmessages", e); } } private void updateVideoOriginalInfo() { - if (!initied || originalSizeTextView == null) { + if (originalSizeTextView == null) { return; } File file = new File(videoPath); - String videoDimension = String.format("%dx%d", videoPlayer.getVideoWidth(), videoPlayer.getVideoHeight()); - int minutes = videoPlayer.getDuration() / 1000 / 60; - int seconds = (int) Math.ceil(videoPlayer.getDuration() / 1000) - minutes * 60; + int width = rotationValue == 90 || rotationValue == 270 ? originalHeight : originalWidth; + int height = rotationValue == 90 || rotationValue == 270 ? originalWidth : originalHeight; + String videoDimension = String.format("%dx%d", width, height); + int minutes = (int)(videoDuration / 1000 / 60); + int seconds = (int) Math.ceil(videoDuration / 1000) - minutes * 60; String videoTimeSize = String.format("%d:%02d, %s", minutes, seconds, Utilities.formatFileSize(file.length())); - originalSizeTextView.setText(String.format("%s: %s, %s", LocaleController.getString("OriginalVideo", R.string.OriginalVideo), videoDimension, videoTimeSize)); + originalSizeTextView.setText(String.format("%s, %s", videoDimension, videoTimeSize)); } private void updateVideoEditedInfo() { - if (!initied || editedSizeTextView == null) { + if (editedSizeTextView == null) { return; } - File file = new File(videoPath); - long size = file.length(); - editedVideoWidth = videoPlayer.getVideoWidth(); - editedVideoHeight = videoPlayer.getVideoHeight(); - if (editedVideoWidth > 640 || editedVideoHeight > 640) { - float scale = editedVideoWidth > editedVideoHeight ? 640.0f / editedVideoWidth : 640.0f / editedVideoHeight; - editedVideoWidth *= scale; - editedVideoHeight *= scale; - size *= (scale * scale) * 1.02f; - } - String videoDimension = String.format("%dx%d", editedVideoWidth, editedVideoHeight); - editedVideoDuration = videoPlayer.getDuration(); - int minutes = editedVideoDuration / 1000 / 60; - int seconds = (int) Math.ceil(editedVideoDuration / 1000) - minutes * 60; - String videoTimeSize = String.format("%d:%02d, ~%s", minutes, seconds, Utilities.formatFileSize(size)); - esimatedFileSize = size; - editedSizeTextView.setText(String.format("%s: %s, %s", LocaleController.getString("EditedVideo", R.string.EditedVideo), videoDimension, videoTimeSize)); + int width = rotationValue == 90 || rotationValue == 270 ? resultHeight : resultWidth; + int height = rotationValue == 90 || rotationValue == 270 ? resultWidth : resultHeight; + String videoDimension = String.format("%dx%d", resultWidth, resultHeight); + + esimatedDuration = (long)Math.max(1000, (videoTimelineView.getRightProgress() - videoTimelineView.getLeftProgress()) * videoDuration); + estimatedSize = calculateEstimatedSize((float)esimatedDuration / videoDuration); + startTime = (long)(videoTimelineView.getLeftProgress() * videoDuration) * 1000; + endTime = (long)(videoTimelineView.getRightProgress() * videoDuration) * 1000; + + int minutes = (int)(esimatedDuration / 1000 / 60); + int seconds = (int) Math.ceil(esimatedDuration / 1000) - minutes * 60; + String videoTimeSize = String.format("%d:%02d, ~%s", minutes, seconds, Utilities.formatFileSize(estimatedSize)); + editedSizeTextView.setText(String.format("%s, %s", videoDimension, videoTimeSize)); } private void fixVideoSize() { - if (videoWidth == 0 || videoHeight == 0 || fragmentView == null || getParentActivity() == null) { + if (fragmentView == null || getParentActivity() == null) { return; } int viewHeight = 0; - if (!Utilities.isTablet(getParentActivity()) && getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { - viewHeight = AndroidUtilities.displaySize.y - AndroidUtilities.statusBarHeight - AndroidUtilities.dp(40); + if (AndroidUtilities.isTablet()) { + viewHeight = AndroidUtilities.dp(472); } else { - viewHeight = AndroidUtilities.displaySize.y - AndroidUtilities.statusBarHeight - AndroidUtilities.dp(48); + if (!AndroidUtilities.isTablet() && getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + viewHeight = AndroidUtilities.displaySize.y - AndroidUtilities.statusBarHeight - AndroidUtilities.dp(40); + } else { + viewHeight = AndroidUtilities.displaySize.y - AndroidUtilities.statusBarHeight - AndroidUtilities.dp(48); + } } int width = 0; int height = 0; - if (getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { - width = AndroidUtilities.displaySize.x - AndroidUtilities.displaySize.x / 2 - AndroidUtilities.dp(24); - height = viewHeight - AndroidUtilities.dp(32); + if (AndroidUtilities.isTablet()) { + width = AndroidUtilities.dp(490); + height = viewHeight - AndroidUtilities.dp(276); } else { - width = AndroidUtilities.displaySize.x; - height = viewHeight - AndroidUtilities.dp(176); + if (getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + width = AndroidUtilities.displaySize.x / 3 - AndroidUtilities.dp(24); + height = viewHeight - AndroidUtilities.dp(32); + } else { + width = AndroidUtilities.displaySize.x; + height = viewHeight - AndroidUtilities.dp(276); + } } - float wr = (float) width / (float) videoWidth; - float hr = (float) height / (float) videoHeight; - float ar = (float) videoWidth / (float) videoHeight; + int aWidth = width; + int aHeight = height; + int vwidth = rotationValue == 90 || rotationValue == 270 ? originalHeight : originalWidth; + int vheight = rotationValue == 90 || rotationValue == 270 ? originalWidth : originalHeight; + float wr = (float) width / (float) vwidth; + float hr = (float) height / (float) vheight; + float ar = (float) vwidth / (float) vheight; if (wr > hr) { width = (int) (height * ar); @@ -406,7 +442,12 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C height = (int) (width / ar); } - surfaceHolder.setFixedSize(width, height); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)textureView.getLayoutParams(); + layoutParams.width = width; + layoutParams.height = height; + layoutParams.leftMargin = 0; + layoutParams.topMargin = 0; + textureView.setLayoutParams(layoutParams); } private void fixLayout() { @@ -417,35 +458,49 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C @Override public boolean onPreDraw() { originalSizeTextView.getViewTreeObserver().removeOnPreDrawListener(this); - if (getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (!AndroidUtilities.isTablet() && getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) videoContainerView.getLayoutParams(); layoutParams.topMargin = AndroidUtilities.dp(16); layoutParams.bottomMargin = AndroidUtilities.dp(16); - layoutParams.width = AndroidUtilities.displaySize.x / 2 - AndroidUtilities.dp(24); + layoutParams.width = AndroidUtilities.displaySize.x / 3 - AndroidUtilities.dp(24); layoutParams.leftMargin = AndroidUtilities.dp(16); videoContainerView.setLayoutParams(layoutParams); - layoutParams = (FrameLayout.LayoutParams) textContainerView.getLayoutParams(); - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.width = AndroidUtilities.displaySize.x / 2 - AndroidUtilities.dp(24); - layoutParams.leftMargin = AndroidUtilities.displaySize.x / 2 + AndroidUtilities.dp(8); - layoutParams.rightMargin = AndroidUtilities.dp(16); + layoutParams = (FrameLayout.LayoutParams) controlView.getLayoutParams(); layoutParams.topMargin = AndroidUtilities.dp(16); + layoutParams.bottomMargin = 0; + layoutParams.width = AndroidUtilities.displaySize.x / 3 * 2 - AndroidUtilities.dp(32); + layoutParams.leftMargin = AndroidUtilities.displaySize.x / 3 + AndroidUtilities.dp(16); + layoutParams.gravity = Gravity.TOP; + controlView.setLayoutParams(layoutParams); + + layoutParams = (FrameLayout.LayoutParams) textContainerView.getLayoutParams(); + layoutParams.width = AndroidUtilities.displaySize.x / 3 * 2 - AndroidUtilities.dp(32); + layoutParams.leftMargin = AndroidUtilities.displaySize.x / 3 + AndroidUtilities.dp(16); + layoutParams.rightMargin = AndroidUtilities.dp(16); + layoutParams.bottomMargin = AndroidUtilities.dp(16); textContainerView.setLayoutParams(layoutParams); } else { FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) videoContainerView.getLayoutParams(); layoutParams.topMargin = AndroidUtilities.dp(16); - layoutParams.bottomMargin = AndroidUtilities.dp(160); + layoutParams.bottomMargin = AndroidUtilities.dp(260); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.leftMargin = 0; videoContainerView.setLayoutParams(layoutParams); - layoutParams = (FrameLayout.LayoutParams) textContainerView.getLayoutParams(); - layoutParams.height = AndroidUtilities.dp(143); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.leftMargin = 0; - layoutParams.rightMargin = 0; + layoutParams = (FrameLayout.LayoutParams) controlView.getLayoutParams(); layoutParams.topMargin = 0; + layoutParams.leftMargin = 0; + layoutParams.bottomMargin = AndroidUtilities.dp(150); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.BOTTOM; + controlView.setLayoutParams(layoutParams); + + layoutParams = (FrameLayout.LayoutParams) textContainerView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.leftMargin = AndroidUtilities.dp(16); + layoutParams.rightMargin = AndroidUtilities.dp(16); + layoutParams.bottomMargin = AndroidUtilities.dp(16); textContainerView.setLayoutParams(layoutParams); } fixVideoSize(); @@ -465,18 +520,20 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C lastProgress = 0; if (needSeek) { float prog = videoTimelineView.getLeftProgress() + (videoTimelineView.getRightProgress() - videoTimelineView.getLeft()) * videoSeekBarView.getProgress(); - videoPlayer.seekTo((int) (videoPlayer.getDuration() * prog)); + videoPlayer.seekTo((int) (videoDuration * prog)); needSeek = false; } videoPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() { @Override public void onSeekComplete(MediaPlayer mp) { - float startTime = videoTimelineView.getLeftProgress() * videoPlayer.getDuration(); - float endTime = videoTimelineView.getRightProgress() * videoPlayer.getDuration(); + float startTime = videoTimelineView.getLeftProgress() * videoDuration; + float endTime = videoTimelineView.getRightProgress() * videoDuration; if (startTime == endTime) { startTime = endTime - 0.01f; } lastProgress = (videoPlayer.getCurrentPosition() - startTime) / (endTime - startTime); + float lrdiff = videoTimelineView.getRightProgress() - videoTimelineView.getLeftProgress(); + lastProgress = videoTimelineView.getLeftProgress() + lrdiff * lastProgress; videoSeekBarView.setProgress(lastProgress); } }); @@ -538,12 +595,14 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C } } - private void didWriteData(final String videoPath, final boolean first, final long finalSize) { + private void didWriteData(final String videoPath, final long finalSize) { AndroidUtilities.RunOnUIThread(new Runnable() { @Override public void run() { - if (first) { - delegate.didStartVideoConverting(videoPath, VideoEditorActivity.this.videoPath, esimatedFileSize, editedVideoDuration, editedVideoWidth, editedVideoHeight); + if (firstWrite) { + delegate.didStartVideoConverting(videoPath, VideoEditorActivity.this.videoPath, estimatedSize, (int)esimatedDuration, resultWidth, resultHeight); + firstWrite = false; + finishFragment(); } else { delegate.didAppenedVideoData(videoPath, finalSize); } @@ -551,327 +610,511 @@ public class VideoEditorActivity extends BaseFragment implements SurfaceHolder.C }); } - private boolean startConvert2() { - MediaCodec decoder = null; - MediaCodec encoder = null; - MediaExtractor extractor = null; - InputSurface inputSurface = null; - OutputSurface outputSurface = null; - MP4Builder mediaMuxer = null; - File cacheFile = null; - long time = System.currentTimeMillis(); - boolean finished = true; - boolean firstWrite = true; - - class AudioBufferTemp { - ByteBuffer buffer; - int flags; - int size; - long presentationTimeUs; - } - - try { - File inputFile = new File(videoPath); - if (!inputFile.canRead()) { - return false; + private static MediaCodecInfo selectCodec(String mimeType) { + int numCodecs = MediaCodecList.getCodecCount(); + for (int i = 0; i < numCodecs; i++) { + MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i); + if (!codecInfo.isEncoder()) { + continue; } - - boolean outputDone = false; - boolean inputDone = false; - boolean decoderDone = false; - boolean muxerStarted = false; - int videoTrackIndex = -5; - int audioTrackIndex = -5; - int audioIndex = -5; - int videoIndex = -5; - int audioBufferSize = 0; - ByteBuffer audioBuffer = null; - ArrayList audioBuffers = new ArrayList(); - - MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever(); - mediaMetadataRetriever.setDataSource(inputFile.toString()); - String rotation = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION); - int rotationValue = 0; - if (rotation != null) { - try { - rotationValue = Integer.parseInt(rotation); - } catch (Exception e) { - //don't promt + String[] types = codecInfo.getSupportedTypes(); + for (String type : types) { + if (type.equalsIgnoreCase(mimeType)) { + return codecInfo; } } + } + return null; + } - extractor = new MediaExtractor(); - extractor.setDataSource(inputFile.toString()); - - String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4"; - UserConfig.lastLocalId--; - cacheFile = new File(AndroidUtilities.getCacheDir(), fileName); - UserConfig.saveConfig(false); - - Mp4Movie movie = new Mp4Movie(); - movie.setCacheFile(cacheFile); - movie.setRotation(rotationValue); - movie.setSize(640, 360); - mediaMuxer = new MP4Builder().createMovie(movie); - - videoIndex = selectTrack(extractor, false); - if (videoIndex < 0) { + private static boolean isRecognizedFormat(int colorFormat) { + switch (colorFormat) { + case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar: + case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar: + case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar: + case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar: + case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar: + return true; + default: return false; + } + } + + private static int selectColorFormat(MediaCodecInfo codecInfo, String mimeType) { + MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType); + for (int i = 0; i < capabilities.colorFormats.length; i++) { + int colorFormat = capabilities.colorFormats[i]; + if (isRecognizedFormat(colorFormat)) { + return colorFormat; } - extractor.selectTrack(videoIndex); - MediaFormat inputFormat = extractor.getTrackFormat(videoIndex); - String mime = inputFormat.getString(MediaFormat.KEY_MIME); + } + return 0; + } - audioIndex = selectTrack(extractor, true); - if (audioIndex >= 0) { - extractor.selectTrack(audioIndex); - MediaFormat audioFormat = extractor.getTrackFormat(audioIndex); - audioTrackIndex = mediaMuxer.addTrack(audioFormat, false); - audioBufferSize = audioFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE); - } + private long readAndWriteTrack(MediaExtractor extractor, MP4Builder mediaMuxer, MediaCodec.BufferInfo info, long start, long end, File file, boolean isAudio) throws Exception { + int trackIndex = selectTrack(extractor, isAudio); + if (trackIndex >= 0) { + extractor.selectTrack(trackIndex); + MediaFormat trackFormat = extractor.getTrackFormat(trackIndex); + int muxerTrackIndex = mediaMuxer.addTrack(trackFormat, isAudio); + int maxBufferSize = trackFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE); + boolean inputDone = false; + extractor.seekTo(start, MediaExtractor.SEEK_TO_PREVIOUS_SYNC); + ByteBuffer buffer = ByteBuffer.allocateDirect(maxBufferSize); + long startTime = -1; - MediaFormat outputFormat = MediaFormat.createVideoFormat(mime, 640, 360); - outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); - outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, 1000000); - outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 25); - outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); - - encoder = MediaCodec.createEncoderByType(mime); - encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); - inputSurface = new InputSurface(encoder.createInputSurface()); - inputSurface.makeCurrent(); - encoder.start(); - - decoder = MediaCodec.createDecoderByType(mime); - outputSurface = new OutputSurface(); - decoder.configure(inputFormat, outputSurface.getSurface(), null, 0); - decoder.start(); - - final int TIMEOUT_USEC = 10000; - ByteBuffer[] decoderInputBuffers = decoder.getInputBuffers(); - ByteBuffer[] encoderOutputBuffers = encoder.getOutputBuffers(); - MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); - - while (!outputDone) { - if (!inputDone) { - boolean eof = false; - int index = extractor.getSampleTrackIndex(); - if (index == videoIndex) { - int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC); - if (inputBufIndex >= 0) { - ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex]; - int chunkSize = extractor.readSampleData(inputBuf, 0); - if (chunkSize < 0) { - decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM); - inputDone = true; - } else { - decoder.queueInputBuffer(inputBufIndex, 0, chunkSize, extractor.getSampleTime(), 0); - extractor.advance(); - } + while (!inputDone) { + boolean eof = false; + int index = extractor.getSampleTrackIndex(); + if (index == trackIndex) { + info.size = extractor.readSampleData(buffer, 0); + if (info.size < 0) { + info.size = 0; + eof = true; + } else { + info.presentationTimeUs = extractor.getSampleTime(); + if (startTime == -1) { + startTime = info.presentationTimeUs; } - } else if (index == audioIndex) { - if (audioBuffer == null) { - audioBuffer = ByteBuffer.allocate(audioBufferSize); - } - info.size = extractor.readSampleData(audioBuffer, 0); - if (info.size < 0) { - info.size = 0; - eof = true; - } else { - if (muxerStarted) { - info.offset = 0; - info.presentationTimeUs = extractor.getSampleTime(); - info.flags = extractor.getSampleFlags(); - mediaMuxer.writeSampleData(audioTrackIndex, audioBuffer, info); - } else { - AudioBufferTemp audioBufferTemp = new AudioBufferTemp(); - audioBufferTemp.buffer = audioBuffer; - audioBufferTemp.presentationTimeUs = extractor.getSampleTime(); - audioBufferTemp.flags = extractor.getSampleFlags(); - audioBufferTemp.size = info.size; - audioBuffers.add(audioBufferTemp); - audioBuffer = null; + if (info.presentationTimeUs < end) { + info.offset = 0; + info.flags = extractor.getSampleFlags(); + if (mediaMuxer.writeSampleData(muxerTrackIndex, buffer, info)) { + didWriteData(file.toString(), 0); } extractor.advance(); - } - } else if (index == -1) { - eof = true; - } - if (eof) { - int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC); - if (inputBufIndex >= 0) { - decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM); - inputDone = true; - } - } - } - - boolean decoderOutputAvailable = !decoderDone; - boolean encoderOutputAvailable = true; - while (decoderOutputAvailable || encoderOutputAvailable) { - int encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC); - if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { - encoderOutputAvailable = false; - } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { - encoderOutputBuffers = encoder.getOutputBuffers(); - } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { - MediaFormat newFormat = encoder.getOutputFormat(); - if (muxerStarted) { - throw new RuntimeException("format changed twice"); - } - videoTrackIndex = mediaMuxer.addTrack(newFormat, true); - - muxerStarted = true; - if (!audioBuffers.isEmpty()) { - for (AudioBufferTemp audioBufferTemp : audioBuffers) { - info.size = audioBufferTemp.size; - info.offset = 0; - info.presentationTimeUs = audioBufferTemp.presentationTimeUs; - info.flags = audioBufferTemp.flags; - mediaMuxer.writeSampleData(audioTrackIndex, audioBufferTemp.buffer, info); - } - audioBuffers.clear(); - } - } else if (encoderStatus < 0) { - FileLog.e("tmessages", "unexpected result from encoder.dequeueOutputBuffer: " + encoderStatus); - return false; - } else { - ByteBuffer encodedData = encoderOutputBuffers[encoderStatus]; - if (encodedData == null) { - FileLog.e("tmessages", "encoderOutputBuffer " + encoderStatus + " was null"); - return false; - } - if (info.size != 0) { - if (!muxerStarted) { - throw new RuntimeException("muxer hasn't started"); - } - if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) { - encodedData.limit(info.size); - encodedData.position(info.offset); - encodedData.putInt(Integer.reverseBytes(info.size - 4)); - mediaMuxer.writeSampleData(videoTrackIndex, encodedData, info); - didWriteData(cacheFile.toString(), firstWrite, 0); - if (firstWrite) { - firstWrite = false; - } - } - } - outputDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0; - encoder.releaseOutputBuffer(encoderStatus, false); - } - if (encoderStatus != MediaCodec.INFO_TRY_AGAIN_LATER) { - continue; - } - - if (!decoderDone) { - int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC); - if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { - decoderOutputAvailable = false; - } else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { - - } else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { - MediaFormat newFormat = decoder.getOutputFormat(); - } else if (decoderStatus < 0) { - FileLog.e("tmessages", "unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus); - return false; } else { - boolean doRender = (info.size != 0); - decoder.releaseOutputBuffer(decoderStatus, doRender); - if (doRender) { - outputSurface.awaitNewImage(); - outputSurface.drawImage(); - inputSurface.setPresentationTime(info.presentationTimeUs * 1000); - inputSurface.swapBuffers(); - } - if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { - FileLog.e("tmessages", "signaling input EOS"); - //if (WORK_AROUND_BUGS) { - // Bail early, possibly dropping a frame. - // return; - //} else { - encoder.signalEndOfInputStream(); - //} - } + eof = true; } } + } else if (index == -1) { + eof = true; } + if (eof) { + inputDone = true; + } + } - /*if (!outputDone) { without surface - int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC); - if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { - FileLog.e("tmessages", "no output from decoder available"); - } else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { - FileLog.e("tmessages", "decoder output buffers changed"); - decoderOutputBuffers = decoder.getOutputBuffers(); - } else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { - decoderOutputFormat = decoder.getOutputFormat(); - FileLog.e("tmessages", "decoder output format changed: " + decoderOutputFormat); - } else if (decoderStatus < 0) { - FileLog.e("tmessages", "unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus); - return false; - } else { - ByteBuffer outputFrame = decoderOutputBuffers[decoderStatus]; - outputFrame.position(info.offset); - outputFrame.limit(info.offset + info.size); - if (info.size == 0) { - FileLog.e("tmessages", "got empty frame"); - } else { - FileLog.e("tmessages", "decoded, checking frame format = " + decoderOutputFormat + " size = " + outputFrame.limit()); - } - if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { - FileLog.e("tmessages", "output EOS"); - outputDone = true; - } - decoder.releaseOutputBuffer(decoderStatus, false); - } - }*/ - } - } catch (Exception e) { - FileLog.e("tmessages", e); - finished = false; - } finally { - if (outputSurface != null) { - outputSurface.release(); - outputSurface = null; - } - if (inputSurface != null) { - inputSurface.release(); - inputSurface = null; - } - if (decoder != null) { - decoder.stop(); - decoder.release(); - decoder = null; - } - if (encoder != null) { - encoder.stop(); - encoder.release(); - encoder = null; - } - if (extractor != null) { - extractor.release(); - extractor = null; - } - if (mediaMuxer != null) { + extractor.unselectTrack(trackIndex); + return startTime; + } + return -1; + } + + private boolean processOpenVideo() { + try { + IsoFile isoFile = new IsoFile(videoPath); + List boxes = Path.getPaths(isoFile, "/moov/trak/"); + TrackHeaderBox trackHeaderBox = null; + for (Box box : boxes) { + TrackBox trackBox = (TrackBox)box; + int sampleSizes = 0; + int trackBitrate = 0; try { - mediaMuxer.finishMovie(false); + MediaBox mediaBox = trackBox.getMediaBox(); + MediaHeaderBox mediaHeaderBox = mediaBox.getMediaHeaderBox(); + SampleSizeBox sampleSizeBox = mediaBox.getMediaInformationBox().getSampleTableBox().getSampleSizeBox(); + for (long size : sampleSizeBox.getSampleSizes()) { + sampleSizes += size; + } + videoDuration = mediaHeaderBox.getDuration() / mediaHeaderBox.getTimescale(); + trackBitrate = (int)(sampleSizes * 8 / videoDuration); } catch (Exception e) { FileLog.e("tmessages", e); } - mediaMuxer = null; + TrackHeaderBox headerBox = trackBox.getTrackHeaderBox(); + if (headerBox.getWidth() != 0 && headerBox.getHeight() != 0) { + trackHeaderBox = headerBox; + bitrate = trackBitrate / 100000 * 100000; + if (bitrate > 900000) { + bitrate = 900000; + } + } else { + audioFramesSize += sampleSizes; + } } - FileLog.e("tmessages", "time = " + (System.currentTimeMillis() - time)); - } - if (finished) { - didWriteData(cacheFile.toString(), firstWrite, cacheFile.length()); - } - AndroidUtilities.RunOnUIThread(new Runnable() { - @Override - public void run() { - finishFragment(); + if (trackHeaderBox == null) { + return false; } - }); - return finished; + + Matrix matrix = trackHeaderBox.getMatrix(); + if (matrix.equals(Matrix.ROTATE_90)) { + rotationValue = 90; + } else if (matrix.equals(Matrix.ROTATE_180)) { + rotationValue = 180; + } else if (matrix.equals(Matrix.ROTATE_270)) { + rotationValue = 270; + } + resultWidth = originalWidth = (int)trackHeaderBox.getWidth(); + resultHeight = originalHeight = (int)trackHeaderBox.getHeight(); + + if (resultWidth > 640 || resultHeight > 640) { + float scale = resultWidth > resultHeight ? 640.0f / resultWidth : 640.0f / resultHeight; + resultWidth *= scale; + resultHeight *= scale; + if (bitrate != 0) { + bitrate *= scale; + videoFramesSize = (int)(bitrate / 8 * videoDuration); + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + return false; + } + + videoDuration *= 1000; + + updateVideoOriginalInfo(); + updateVideoEditedInfo(); + + return true; + } + + private int calculateEstimatedSize(float timeDelta) { + int size = (int)((audioFramesSize + videoFramesSize) * timeDelta); + size += size / (32 * 1024) * 16; + return size; + } + + private boolean startConvert2() { + File inputFile = new File(videoPath); + if (!inputFile.canRead()) { + return false; + } + + firstWrite = true; + File cacheFile = null; + boolean error = false; + long videoStartTime = startTime; + + long time = System.currentTimeMillis(); + + if (resultWidth != 0 && resultHeight != 0) { + MP4Builder mediaMuxer = null; + MediaExtractor extractor = null; + + MediaCodec decoder = null; + MediaCodec encoder = null; + InputSurface inputSurface = null; + OutputSurface outputSurface = null; + + try { + String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4"; + UserConfig.lastLocalId--; + cacheFile = new File(AndroidUtilities.getCacheDir(), fileName); + UserConfig.saveConfig(false); + + MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); + Mp4Movie movie = new Mp4Movie(); + movie.setCacheFile(cacheFile); + movie.setRotation(rotationValue); + movie.setSize(resultWidth, resultHeight); + mediaMuxer = new MP4Builder().createMovie(movie); + extractor = new MediaExtractor(); + extractor.setDataSource(inputFile.toString()); + + if (resultWidth != originalWidth || resultHeight != originalHeight) { + int videoIndex = -5; + videoIndex = selectTrack(extractor, false); + if (videoIndex >= 0) { + boolean outputDone = false; + boolean inputDone = false; + boolean decoderDone = false; + int videoTrackIndex = -5; + long videoTime = -1; + + int colorFormat = 0; + int processorType = PROCESSOR_TYPE_OTHER; + if (Build.VERSION.SDK_INT < 18) { + MediaCodecInfo codecInfo = selectCodec(MIME_TYPE); + colorFormat = selectColorFormat(codecInfo, MIME_TYPE); + if (codecInfo.getName().contains("OMX.qcom.")) { + processorType = PROCESSOR_TYPE_QCOM; + } + FileLog.e("tmessages", "codec = " + codecInfo.getName()); + } else { + colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface; + } + FileLog.e("tmessages", "colorFormat = " + colorFormat); + + int resultHeightAligned = resultHeight; + int padding = 0; + int bufferSize = resultWidth * resultHeight * 3 / 2; + if (processorType == PROCESSOR_TYPE_OTHER) { + if (resultHeight % 16 != 0) { + resultHeightAligned += (16 - (resultHeight % 16)); + padding = resultWidth * (resultHeightAligned - resultHeight); + bufferSize += padding * 5 / 4; + } + } else if (processorType == PROCESSOR_TYPE_QCOM) { + int uvoffset = (resultWidth * resultHeight + 2047) & ~2047; + padding = uvoffset - (resultWidth * resultHeight); + bufferSize += padding; + } + + extractor.selectTrack(videoIndex); + extractor.seekTo(startTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC); + MediaFormat inputFormat = extractor.getTrackFormat(videoIndex); + + MediaFormat outputFormat = MediaFormat.createVideoFormat(MIME_TYPE, resultWidth, resultHeight); + outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat); + outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate != 0 ? bitrate : 921600); + outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 25); + outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10); + if (Build.VERSION.SDK_INT < 18) { + outputFormat.setInteger("stride", resultWidth); + outputFormat.setInteger("slice-height", resultHeightAligned); + } + + encoder = MediaCodec.createEncoderByType(MIME_TYPE); + encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); + if (Build.VERSION.SDK_INT >= 18) { + inputSurface = new InputSurface(encoder.createInputSurface()); + inputSurface.makeCurrent(); + } + encoder.start(); + + decoder = MediaCodec.createDecoderByType(inputFormat.getString(MediaFormat.KEY_MIME)); + if (Build.VERSION.SDK_INT >= 18) { + outputSurface = new OutputSurface(); + } else { + outputSurface = new OutputSurface(resultWidth, resultHeight); + } + decoder.configure(inputFormat, outputSurface.getSurface(), null, 0); + decoder.start(); + + final int TIMEOUT_USEC = 2500; + ByteBuffer[] decoderInputBuffers = decoder.getInputBuffers(); + ByteBuffer[] encoderOutputBuffers = encoder.getOutputBuffers(); + ByteBuffer[] encoderInputBuffers = null; + if (Build.VERSION.SDK_INT < 18) { + encoderInputBuffers = encoder.getInputBuffers(); + } + + while (!outputDone) { + if (!inputDone) { + boolean eof = false; + int index = extractor.getSampleTrackIndex(); + if (index == videoIndex) { + int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC); + if (inputBufIndex >= 0) { + ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex]; + int chunkSize = extractor.readSampleData(inputBuf, 0); + if (chunkSize < 0) { + decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM); + inputDone = true; + } else { + decoder.queueInputBuffer(inputBufIndex, 0, chunkSize, extractor.getSampleTime(), 0); + extractor.advance(); + } + } + } else if (index == -1) { + eof = true; + } + if (eof) { + int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC); + if (inputBufIndex >= 0) { + decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM); + inputDone = true; + } + } + } + + boolean decoderOutputAvailable = !decoderDone; + boolean encoderOutputAvailable = true; + while (decoderOutputAvailable || encoderOutputAvailable) { + int encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC); + if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { + encoderOutputAvailable = false; + } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { + encoderOutputBuffers = encoder.getOutputBuffers(); + } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { + MediaFormat newFormat = encoder.getOutputFormat(); + if (videoTrackIndex == -5) { + videoTrackIndex = mediaMuxer.addTrack(newFormat, false); + } + } else if (encoderStatus < 0) { + throw new RuntimeException("unexpected result from encoder.dequeueOutputBuffer: " + encoderStatus); + } else { + ByteBuffer encodedData = encoderOutputBuffers[encoderStatus]; + if (encodedData == null) { + throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null"); + } + if (info.size > 1) { + if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) { + encodedData.limit(info.offset + info.size); + encodedData.position(info.offset); + encodedData.putInt(Integer.reverseBytes(info.size - 4)); + if (mediaMuxer.writeSampleData(videoTrackIndex, encodedData, info)) { + didWriteData(cacheFile.toString(), 0); + } + } else if (videoTrackIndex == -5) { + byte[] csd = new byte[info.size]; + encodedData.limit(info.offset + info.size); + encodedData.position(info.offset); + encodedData.get(csd); + ByteBuffer sps = null; + ByteBuffer pps = null; + for (int a = info.size - 1; a >= 0; a--) { + if (a > 3) { + if (csd[a] == 1 && csd[a - 1] == 0 && csd[a - 2] == 0 && csd[a - 3] == 0) { + sps = ByteBuffer.allocate(a - 3); + pps = ByteBuffer.allocate(info.size - (a - 3)); + sps.put(csd, 0, a - 3).position(0); + pps.put(csd, a - 3, info.size - (a - 3)).position(0); + break; + } + } else { + break; + } + } + + MediaFormat newFormat = MediaFormat.createVideoFormat(MIME_TYPE, resultWidth, resultHeight); + if (sps != null && pps != null) { + newFormat.setByteBuffer("csd-0", sps); + newFormat.setByteBuffer("csd-1", pps); + } + videoTrackIndex = mediaMuxer.addTrack(newFormat, false); + } + } + outputDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0; + encoder.releaseOutputBuffer(encoderStatus, false); + } + if (encoderStatus != MediaCodec.INFO_TRY_AGAIN_LATER) { + continue; + } + + if (!decoderDone) { + int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC); + if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { + decoderOutputAvailable = false; + } else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { + + } else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { + MediaFormat newFormat = decoder.getOutputFormat(); + } else if (decoderStatus < 0) { + throw new RuntimeException("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus); + } else { + boolean doRender = false; + if (Build.VERSION.SDK_INT >= 18) { + doRender = info.size != 0; + } else { + doRender = info.size != 0 || info.presentationTimeUs != 0; + } + if (info.presentationTimeUs >= endTime) { + inputDone = true; + decoderDone = true; + doRender = false; + info.flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM; + } + if (videoTime == -1) { + if (info.presentationTimeUs < startTime) { + doRender = false; + FileLog.e("tmessages", "drop frame startTime = " + startTime + " present time = " + info.presentationTimeUs); + } else { + videoTime = info.presentationTimeUs; + } + } + decoder.releaseOutputBuffer(decoderStatus, doRender); + if (doRender) { + boolean errorWait = false; + try { + outputSurface.awaitNewImage(); + } catch (Exception e) { + errorWait = true; + FileLog.e("tmessages", e); + } + if (!errorWait) { + if (Build.VERSION.SDK_INT >= 18) { + outputSurface.drawImage(false); + inputSurface.setPresentationTime(info.presentationTimeUs * 1000); + inputSurface.swapBuffers(); + } else { + int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC); + if (inputBufIndex >= 0) { + outputSurface.drawImage(true); + ByteBuffer rgbBuf = outputSurface.getFrame(); + ByteBuffer yuvBuf = encoderInputBuffers[inputBufIndex]; + yuvBuf.clear(); + Utilities.convertVideoFrame(rgbBuf, yuvBuf, colorFormat, resultWidth, resultHeight, padding); + encoder.queueInputBuffer(inputBufIndex, 0, bufferSize, info.presentationTimeUs, 0); + } else { + FileLog.e("tmessages", "input buffer not available"); + } + } + } + } + if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { + decoderOutputAvailable = false; + FileLog.e("tmessages", "decoder stream end"); + if (Build.VERSION.SDK_INT >= 18) { + encoder.signalEndOfInputStream(); + } else { + int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC); + if (inputBufIndex >= 0) { + encoder.queueInputBuffer(inputBufIndex, 0, 1, info.presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM); + } + } + } + } + } + } + } + extractor.unselectTrack(videoIndex); + if (videoTime != -1) { + videoStartTime = videoTime; + } + } + } else { + long videoTime = readAndWriteTrack(extractor, mediaMuxer, info, startTime, endTime, cacheFile, false); + if (videoTime != -1) { + videoStartTime = videoTime; + } + } + readAndWriteTrack(extractor, mediaMuxer, info, videoStartTime, endTime, cacheFile, true); + } catch (Exception e) { + error = true; + FileLog.e("tmessages", e); + } finally { + if (extractor != null) { + extractor.release(); + extractor = null; + } + if (outputSurface != null) { + outputSurface.release(); + outputSurface = null; + } + if (inputSurface != null) { + inputSurface.release(); + inputSurface = null; + } + if (decoder != null) { + decoder.stop(); + decoder.release(); + decoder = null; + } + if (encoder != null) { + encoder.stop(); + encoder.release(); + encoder = null; + } + if (mediaMuxer != null) { + try { + mediaMuxer.finishMovie(false); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + mediaMuxer = null; + } + FileLog.e("tmessages", "time = " + (System.currentTimeMillis() - time)); + } + } else { + return false; + } + if (!error && cacheFile != null) { + didWriteData(cacheFile.toString(), cacheFile.length()); + } + return true; } private void startConvert() throws Exception { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBar.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBar.java index faf729a6a..d616b9dde 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBar.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBar.java @@ -21,7 +21,6 @@ import android.widget.FrameLayout; import org.telegram.android.AndroidUtilities; import org.telegram.messenger.R; -import org.telegram.messenger.Utilities; import java.util.ArrayList; @@ -171,7 +170,7 @@ public class ActionBar extends FrameLayout { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - if (!Utilities.isTablet(getContext()) && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(40), MeasureSpec.EXACTLY)); } else { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(48), MeasureSpec.EXACTLY)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayer.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayer.java index 701624e00..cdeebd1a2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayer.java @@ -23,7 +23,6 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.messenger.R; -import org.telegram.messenger.Utilities; public class ActionBarLayer extends FrameLayout { @@ -55,6 +54,7 @@ public class ActionBarLayer extends FrameLayout { private boolean isBackOverlayVisible; protected BaseFragment parentFragment; public ActionBarMenuOnItemClick actionBarMenuOnItemClick; + private int leftMargin = 0; public ActionBarLayer(Context context, ActionBar actionBar) { super(context); @@ -94,13 +94,17 @@ public class ActionBarLayer extends FrameLayout { super(context, attrs, defStyleAttr); } + public void setExtraLeftMargin(int margin) { + leftMargin = margin; + } + private void positionBackImage(int height) { if (backButtonImageView != null) { LayoutParams layoutParams = (LayoutParams)backButtonImageView.getLayoutParams(); layoutParams.width = LayoutParams.WRAP_CONTENT; layoutParams.height = LayoutParams.WRAP_CONTENT; layoutParams.gravity = Gravity.TOP | Gravity.LEFT; - layoutParams.setMargins(AndroidUtilities.dp(3), (height - backButtonImageView.getDrawable().getIntrinsicHeight()) / 2, 0, 0); + layoutParams.setMargins(AndroidUtilities.dp(3 + leftMargin), (height - backButtonImageView.getDrawable().getIntrinsicHeight()) / 2, 0, 0); backButtonImageView.setLayoutParams(layoutParams); } } @@ -108,7 +112,7 @@ public class ActionBarLayer extends FrameLayout { private void positionLogoImage(int height) { if (logoImageView != null) { LayoutParams layoutParams = (LayoutParams) logoImageView.getLayoutParams(); - if (!Utilities.isTablet(getContext()) && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { layoutParams.width = (int)(logoImageView.getDrawable().getIntrinsicWidth() / 1.3f); layoutParams.height = (int)(logoImageView.getDrawable().getIntrinsicHeight() / 1.3f); layoutParams.setMargins(AndroidUtilities.dp(12), (height - layoutParams.height) / 2, 0, 0); @@ -124,7 +128,7 @@ public class ActionBarLayer extends FrameLayout { private void positionTitle(int width, int height) { int offset = AndroidUtilities.dp(2); - if (!Utilities.isTablet(getContext()) && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { offset = AndroidUtilities.dp(1); } int maxTextWidth = 0; @@ -132,7 +136,7 @@ public class ActionBarLayer extends FrameLayout { LayoutParams layoutParams = null; if (titleTextView != null && titleTextView.getVisibility() == VISIBLE) { - if (!Utilities.isTablet(getContext()) && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { titleTextView.setTextSize(16); } else { titleTextView.setTextSize(18); @@ -147,7 +151,7 @@ public class ActionBarLayer extends FrameLayout { maxTextWidth = titleTextView.getMeasuredWidth(); } if (subTitleTextView != null && subTitleTextView.getVisibility() == VISIBLE) { - if (!Utilities.isTablet(getContext()) && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { subTitleTextView.setTextSize(12); } else { subTitleTextView.setTextSize(14); @@ -164,12 +168,12 @@ public class ActionBarLayer extends FrameLayout { int x = 0; if (logoImageView == null || logoImageView.getVisibility() == GONE) { - x = AndroidUtilities.dp(16); + x = AndroidUtilities.dp(16 + leftMargin); } else { - if (!Utilities.isTablet(getContext()) && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { - x = AndroidUtilities.dp(22) + (int)(logoImageView.getDrawable().getIntrinsicWidth() / 1.3f); + if (!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + x = AndroidUtilities.dp(22 + leftMargin) + (int)(logoImageView.getDrawable().getIntrinsicWidth() / 1.3f); } else { - x = AndroidUtilities.dp(22) + logoImageView.getDrawable().getIntrinsicWidth(); + x = AndroidUtilities.dp(22 + leftMargin) + logoImageView.getDrawable().getIntrinsicWidth(); } } @@ -258,8 +262,8 @@ public class ActionBarLayer extends FrameLayout { } } - public void setSubTitleIcon(int resourceId, int padding) { - if (resourceId != 0 && subTitleTextView == null) { + public void setSubTitleIcon(int resourceId, Drawable drawable, int padding) { + if ((resourceId != 0 || drawable != null) && subTitleTextView == null) { subTitleTextView = new TextView(getContext()); backButtonFrameLayout.addView(subTitleTextView); subTitleTextView.setGravity(Gravity.LEFT); @@ -271,7 +275,11 @@ public class ActionBarLayer extends FrameLayout { positionTitle(getMeasuredWidth(), getMeasuredHeight()); } if (subTitleTextView != null) { - subTitleTextView.setCompoundDrawablesWithIntrinsicBounds(resourceId, 0, 0, 0); + if (drawable != null) { + subTitleTextView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null); + } else { + subTitleTextView.setCompoundDrawablesWithIntrinsicBounds(resourceId, 0, 0, 0); + } subTitleTextView.setCompoundDrawablePadding(padding); } } @@ -479,7 +487,7 @@ public class ActionBarLayer extends FrameLayout { } isBackOverlayVisible = visible; if (visible) { - ((ActionBarActivity)getContext()).onOverlayShow(actionOverlay, parentFragment); + parentFragment.parentLayout.onOverlayShow(actionOverlay, parentFragment); } positionBackOverlay(getMeasuredWidth(), getMeasuredHeight()); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayout.java similarity index 66% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarActivity.java rename to TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayout.java index 2cde70995..54e6dfcdb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayout.java @@ -16,7 +16,6 @@ import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.os.Build; -import android.os.Bundle; import android.os.Handler; import android.view.ActionMode; import android.view.Gravity; @@ -26,7 +25,6 @@ import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; -import android.view.Window; import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; @@ -35,11 +33,10 @@ import android.widget.FrameLayout; import org.telegram.android.AndroidUtilities; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; -import org.telegram.messenger.Utilities; import java.util.ArrayList; -public class ActionBarActivity extends Activity { +public class ActionBarLayout extends FrameLayout { private class FrameLayoutAnimationListener extends FrameLayout { public FrameLayoutAnimationListener(Context context) { @@ -49,18 +46,30 @@ public class ActionBarActivity extends Activity { @Override protected void onAnimationEnd() { super.onAnimationEnd(); - ActionBarActivity.this.onAnimationEnd(); + ActionBarLayout.this.onAnimationEndCheck(); } } + public static interface ActionBarLayoutDelegate { + public abstract boolean onPreIme(); + public abstract void onOverlayShow(View view, BaseFragment fragment); + public abstract boolean needPresentFragment(BaseFragment fragment, boolean removeLast, boolean forceWithoutAnimation, ActionBarLayout layout); + public abstract boolean needAddFragmentToStack(BaseFragment fragment, ActionBarLayout layout); + public abstract boolean needCloseLastFragment(ActionBarLayout layout); + public abstract void onRebuildAllFragments(ActionBarLayout layout); + } + protected ActionBar actionBar; private FrameLayoutAnimationListener containerView; private FrameLayoutAnimationListener containerViewBack; - protected FrameLayout contentView; private View shadowView; private Animation openAnimation; private Animation closeAnimation; + private Animation alphaOpenAnimation; + private Animation alphaOpenAnimation2; + private Animation alphaCloseAnimation; + private Animation alphaCloseAnimation2; private boolean maybeStartTracking = false; protected boolean startedTracking = false; @@ -75,69 +84,35 @@ public class ActionBarActivity extends Activity { private int startedTrackingPointerId; private Runnable onCloseAnimationEndRunnable = null; private Runnable onOpenAnimationEndRunnable = null; + private boolean useAlphaAnimations = false; + private View backgroundView; - private class FrameLayoutTouch extends FrameLayout { - public FrameLayoutTouch(Context context) { - super(context); - } + private ActionBarLayoutDelegate delegate = null; + protected Activity parentActivity = null; - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - return !(!animationInProgress && !checkTransitionAnimation()) || ((ActionBarActivity) getContext()).onTouchEvent(ev); - } - - @Override - public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { - ((ActionBarActivity)getContext()).onTouchEvent(null); - super.requestDisallowInterceptTouchEvent(disallowIntercept); - } - - @Override - public boolean dispatchKeyEventPreIme(KeyEvent event) { - if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { - return ((ActionBarActivity)getContext()).onPreIme() || super.dispatchKeyEventPreIme(event); - } - return super.dispatchKeyEventPreIme(event); - } - - @Override - public boolean onKeyPreIme(int keyCode, KeyEvent event) { - return super.onKeyPreIme(keyCode, event); - } - } - - public static ArrayList fragmentsStack = new ArrayList(); - - protected void onCreateFinish(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - requestWindowFeature(Window.FEATURE_NO_TITLE); + public ArrayList fragmentsStack = null; + public ActionBarLayout(Context context) { + super(context); + parentActivity = (Activity)context; try { - openAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_in); - closeAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_out); + openAnimation = AnimationUtils.loadAnimation(context, R.anim.scale_in); + closeAnimation = AnimationUtils.loadAnimation(context, R.anim.scale_out); } catch (Exception e) { FileLog.e("tmessages", e); } + } - setTheme(R.style.Theme_TMessages); - getWindow().setBackgroundDrawableResource(R.drawable.transparent); + public void init(ArrayList stack) { + fragmentsStack = stack; + containerViewBack = new FrameLayoutAnimationListener(parentActivity); + addView(containerViewBack); - contentView = new FrameLayoutTouch(this); - setContentView(contentView, new ViewGroup.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); + containerView = new FrameLayoutAnimationListener(parentActivity); + addView(containerView); - containerViewBack = new FrameLayoutAnimationListener(this); - contentView.addView(containerViewBack); - - containerView = new FrameLayoutAnimationListener(this); - contentView.addView(containerView); - - shadowView = new FrameLayout(this); - contentView.addView(shadowView); + shadowView = new FrameLayout(parentActivity); + addView(shadowView); shadowView.setBackgroundResource(R.drawable.shadow); ViewGroup.LayoutParams layoutParams = shadowView.getLayoutParams(); layoutParams.width = AndroidUtilities.dp(2); @@ -145,14 +120,14 @@ public class ActionBarActivity extends Activity { shadowView.setLayoutParams(layoutParams); shadowView.setVisibility(View.INVISIBLE); - actionBar = new ActionBar(this); - contentView.addView(actionBar); + actionBar = new ActionBar(parentActivity); + addView(actionBar); layoutParams = actionBar.getLayoutParams(); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; actionBar.setLayoutParams(layoutParams); for (BaseFragment fragment : fragmentsStack) { - fragment.setParentActivity(this); + fragment.setParentLayout(this); } needLayout(); @@ -168,9 +143,7 @@ public class ActionBarActivity extends Activity { } } - @Override - protected void onResume() { - super.onResume(); + public void onResume() { fixLayout(); if (transitionAnimationInProgress) { if (onCloseAnimationEndRunnable != null) { @@ -189,15 +162,42 @@ public class ActionBarActivity extends Activity { } } - @Override - protected void onPause() { - super.onPause(); + public void onPause() { if (!fragmentsStack.isEmpty()) { BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); lastFragment.onPause(); } } + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return !(!animationInProgress && !checkTransitionAnimation()) || onTouchEvent(ev); + } + + @Override + public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { + onTouchEvent(null); + super.requestDisallowInterceptTouchEvent(disallowIntercept); + } + + @Override + public boolean dispatchKeyEventPreIme(KeyEvent event) { + if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { + return delegate != null && delegate.onPreIme() || super.dispatchKeyEventPreIme(event); + } + return super.dispatchKeyEventPreIme(event); + } + + @Override + protected void onAnimationEnd() { + super.onAnimationEnd(); + onAnimationEndCheck(); + } + + public void setDelegate(ActionBarLayoutDelegate delegate) { + this.delegate = delegate; + } + private void onSlideAnimationEnd(boolean backAnimation) { containerView.setX(0); containerViewBack.setX(0); @@ -208,7 +208,7 @@ public class ActionBarActivity extends Activity { BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); lastFragment.onPause(); lastFragment.onFragmentDestroy(); - lastFragment.setParentActivity(null); + lastFragment.setParentLayout(null); fragmentsStack.remove(fragmentsStack.size() - 1); FrameLayoutAnimationListener temp = containerView; @@ -230,7 +230,7 @@ public class ActionBarActivity extends Activity { } } containerViewBack.setVisibility(View.GONE); - AndroidUtilities.unlockOrientation(this); + AndroidUtilities.unlockOrientation(parentActivity); startedTracking = false; animationInProgress = false; } @@ -246,7 +246,7 @@ public class ActionBarActivity extends Activity { BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 2); actionBar.prepareForMoving(lastFragment.actionBarLayer); - View fragmentView = lastFragment.createView(getLayoutInflater(), null); + View fragmentView = lastFragment.createView(parentActivity.getLayoutInflater(), null); ViewGroup parentView = (ViewGroup)fragmentView.getParent(); if (parentView != null) { parentView.removeView(fragmentView); @@ -261,7 +261,7 @@ public class ActionBarActivity extends Activity { } lastFragment.onResume(); - AndroidUtilities.lockOrientation(this); + AndroidUtilities.lockOrientation(parentActivity); } public boolean onTouchEvent(MotionEvent ev) { @@ -289,8 +289,8 @@ public class ActionBarActivity extends Activity { prepareForMoving(ev); } else if (startedTracking) { if (!beginTrackingSent) { - if (getCurrentFocus() != null) { - AndroidUtilities.hideKeyboard(getCurrentFocus()); + if (parentActivity.getCurrentFocus() != null) { + AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus()); } BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1); currentFragment.onBeginSlide(); @@ -377,7 +377,10 @@ public class ActionBarActivity extends Activity { return false; } - @Override + public ActionBar getActionBar() { + return actionBar; + } + public void onBackPressed() { if (startedTracking || checkTransitionAnimation() || fragmentsStack.isEmpty()) { return; @@ -388,58 +391,54 @@ public class ActionBarActivity extends Activity { } BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); if (lastFragment.onBackPressed()) { - if (fragmentsStack.size() == 1) { - fragmentsStack.get(0).onFragmentDestroy(); - fragmentsStack.clear(); - onFinish(); - finish(); - } else if (!fragmentsStack.isEmpty()) { + if (!fragmentsStack.isEmpty()) { closeLastFragment(true); } } } - @Override public void onLowMemory() { - super.onLowMemory(); for (BaseFragment fragment : fragmentsStack) { fragment.onLowMemory(); } } + private void onAnimationEndCheck() { + onCloseAnimationEnd(false); + onOpenAnimationEnd(false); + } + public boolean checkTransitionAnimation() { if (transitionAnimationInProgress && transitionAnimationStartTime < System.currentTimeMillis() - 400) { transitionAnimationInProgress = false; - onAnimationEnd(); + onAnimationEndCheck(); } return transitionAnimationInProgress; } private void fixLayout() { - if (contentView != null) { - ViewTreeObserver obs = contentView.getViewTreeObserver(); - obs.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - needLayout(); + ViewTreeObserver obs = getViewTreeObserver(); + obs.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + needLayout(); - if (Build.VERSION.SDK_INT < 16) { - contentView.getViewTreeObserver().removeGlobalOnLayoutListener(this); - } else { - contentView.getViewTreeObserver().removeOnGlobalLayoutListener(this); - } + if (Build.VERSION.SDK_INT < 16) { + getViewTreeObserver().removeGlobalOnLayoutListener(this); + } else { + getViewTreeObserver().removeOnGlobalLayoutListener(this); } - }); - } + } + }); } public void needLayout() { - WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE); + WindowManager manager = (WindowManager)parentActivity.getSystemService(Context.WINDOW_SERVICE); int rotation = manager.getDefaultDisplay().getRotation(); int height = 0; if (actionBar.getVisibility() == View.VISIBLE) { - if (!Utilities.isTablet(this) && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { height = AndroidUtilities.dp(40); } else { height = AndroidUtilities.dp(48); @@ -475,7 +474,7 @@ public class ActionBarActivity extends Activity { fragment.onPause(); if (removeLast) { fragment.onFragmentDestroy(); - fragment.setParentActivity(null); + fragment.setParentLayout(null); fragmentsStack.remove(fragment); } else { if (fragment.fragmentView != null) { @@ -497,18 +496,21 @@ public class ActionBarActivity extends Activity { } public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation) { - if (checkTransitionAnimation() || !fragment.onFragmentCreate()) { + if (checkTransitionAnimation() || delegate != null && !delegate.needPresentFragment(fragment, removeLast, forceWithoutAnimation, this) || !fragment.onFragmentCreate()) { return false; } - if (getCurrentFocus() != null) { - AndroidUtilities.hideKeyboard(getCurrentFocus()); + if (parentActivity.getCurrentFocus() != null) { + AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus()); + } + boolean needAnimation = openAnimation != null && !forceWithoutAnimation && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true); + if (useAlphaAnimations && fragmentsStack.size() == 0 && alphaOpenAnimation == null) { + needAnimation = false; } - boolean needAnimation = openAnimation != null && !forceWithoutAnimation && getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true); final BaseFragment currentFragment = !fragmentsStack.isEmpty() ? fragmentsStack.get(fragmentsStack.size() - 1) : null; - fragment.setParentActivity(this); - View fragmentView = fragment.createView(getLayoutInflater(), null); + fragment.setParentLayout(this); + View fragmentView = fragment.createView(parentActivity.getLayoutInflater(), null); containerViewBack.addView(fragmentView); ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams(); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; @@ -534,17 +536,26 @@ public class ActionBarActivity extends Activity { } if (needAnimation) { - transitionAnimationStartTime = System.currentTimeMillis(); - transitionAnimationInProgress = true; - onOpenAnimationEndRunnable = new Runnable() { - @Override - public void run() { - presentFragmentInternalRemoveOld(removeLast, currentFragment); - fragment.onOpenAnimationEnd(); + if (useAlphaAnimations && fragmentsStack.size() == 1) { + presentFragmentInternalRemoveOld(removeLast, currentFragment); + startAnimation(alphaOpenAnimation); + if (backgroundView != null) { + backgroundView.setVisibility(VISIBLE); + backgroundView.startAnimation(alphaOpenAnimation2); } - }; - openAnimation.reset(); - containerView.startAnimation(openAnimation); + } else { + transitionAnimationStartTime = System.currentTimeMillis(); + transitionAnimationInProgress = true; + onOpenAnimationEndRunnable = new Runnable() { + @Override + public void run() { + presentFragmentInternalRemoveOld(removeLast, currentFragment); + fragment.onOpenAnimationEnd(); + } + }; + openAnimation.reset(); + containerView.startAnimation(openAnimation); + } } else { fragment.onOpenAnimationEnd(); } @@ -552,10 +563,10 @@ public class ActionBarActivity extends Activity { } public boolean addFragmentToStack(BaseFragment fragment) { - if (!fragment.onFragmentCreate()) { + if (delegate != null && !delegate.needAddFragmentToStack(fragment, this) || !fragment.onFragmentCreate()) { return false; } - fragment.setParentActivity(this); + fragment.setParentLayout(this); fragmentsStack.add(fragment); return true; } @@ -563,7 +574,7 @@ public class ActionBarActivity extends Activity { private void closeLastFragmentInternalRemoveOld(BaseFragment fragment) { fragment.onPause(); fragment.onFragmentDestroy(); - fragment.setParentActivity(null); + fragment.setParentLayout(null); fragmentsStack.remove(fragment); containerViewBack.setVisibility(View.GONE); ViewGroup parent = (ViewGroup)containerView.getParent(); @@ -572,49 +583,84 @@ public class ActionBarActivity extends Activity { } public void closeLastFragment(boolean animated) { - if (fragmentsStack.size() <= 1 || checkTransitionAnimation()) { + if (delegate != null && !delegate.needCloseLastFragment(this) || checkTransitionAnimation()) { return; } - if (getCurrentFocus() != null) { - AndroidUtilities.hideKeyboard(getCurrentFocus()); + if (parentActivity.getCurrentFocus() != null) { + AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus()); + } + boolean needAnimation = animated && closeAnimation != null && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true); + if (useAlphaAnimations && fragmentsStack.size() == 1 && alphaCloseAnimation == null) { + needAnimation = false; } - boolean needAnimation = animated && closeAnimation != null && getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true); final BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1); - BaseFragment previousFragment = fragmentsStack.get(fragmentsStack.size() - 2); - - FrameLayoutAnimationListener temp = containerView; - containerView = containerViewBack; - containerViewBack = temp; - containerView.setVisibility(View.VISIBLE); - - previousFragment.setParentActivity(this); - View fragmentView = previousFragment.createView(getLayoutInflater(), null); - containerView.addView(fragmentView); - ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - fragmentView.setLayoutParams(layoutParams); - previousFragment.onResume(); - actionBar.setCurrentActionBarLayer(previousFragment.actionBarLayer); - if (fragmentView.getBackground() == null) { - fragmentView.setBackgroundColor(0xffffffff); + BaseFragment previousFragment = null; + if (fragmentsStack.size() > 1) { + previousFragment = fragmentsStack.get(fragmentsStack.size() - 2); } - if (!needAnimation) { - closeLastFragmentInternalRemoveOld(currentFragment); - } + if (previousFragment != null) { + FrameLayoutAnimationListener temp = containerView; + containerView = containerViewBack; + containerViewBack = temp; + containerView.setVisibility(View.VISIBLE); - if (needAnimation) { - transitionAnimationStartTime = System.currentTimeMillis(); - transitionAnimationInProgress = true; - closeAnimation.reset(); - onCloseAnimationEndRunnable = new Runnable() { - @Override - public void run() { - closeLastFragmentInternalRemoveOld(currentFragment); + previousFragment.setParentLayout(this); + View fragmentView = previousFragment.createView(parentActivity.getLayoutInflater(), null); + containerView.addView(fragmentView); + ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + fragmentView.setLayoutParams(layoutParams); + previousFragment.onResume(); + actionBar.setCurrentActionBarLayer(previousFragment.actionBarLayer); + if (fragmentView.getBackground() == null) { + fragmentView.setBackgroundColor(0xffffffff); + } + + if (!needAnimation) { + closeLastFragmentInternalRemoveOld(currentFragment); + } + + if (needAnimation) { + transitionAnimationStartTime = System.currentTimeMillis(); + transitionAnimationInProgress = true; + closeAnimation.reset(); + onCloseAnimationEndRunnable = new Runnable() { + @Override + public void run() { + closeLastFragmentInternalRemoveOld(currentFragment); + } + }; + containerViewBack.startAnimation(closeAnimation); + } + } else { + if (needAnimation && useAlphaAnimations) { + transitionAnimationStartTime = System.currentTimeMillis(); + transitionAnimationInProgress = true; + alphaCloseAnimation.reset(); + alphaCloseAnimation2.reset(); + startAnimation(alphaCloseAnimation); + if (backgroundView != null) { + backgroundView.startAnimation(alphaCloseAnimation2); } - }; - containerViewBack.startAnimation(closeAnimation); + onCloseAnimationEndRunnable = new Runnable() { + @Override + public void run() { + removeFragmentFromStack(currentFragment); + setVisibility(GONE); + if (backgroundView != null) { + backgroundView.setVisibility(GONE); + } + } + }; + } else { + removeFragmentFromStack(currentFragment); + setVisibility(GONE); + if (backgroundView != null) { + backgroundView.setVisibility(GONE); + } + } } } @@ -623,8 +669,8 @@ public class ActionBarActivity extends Activity { return; } BaseFragment previousFragment = fragmentsStack.get(fragmentsStack.size() - 1); - previousFragment.setParentActivity(this); - View fragmentView = previousFragment.createView(getLayoutInflater(), null); + previousFragment.setParentLayout(this); + View fragmentView = previousFragment.createView(parentActivity.getLayoutInflater(), null); containerView.addView(fragmentView); ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams(); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; @@ -640,19 +686,25 @@ public class ActionBarActivity extends Activity { public void removeFragmentFromStack(BaseFragment fragment) { fragment.onPause(); fragment.onFragmentDestroy(); - fragment.setParentActivity(null); + fragment.setParentLayout(null); fragmentsStack.remove(fragment); } - public void rebuildAllFragmentViews() { - for (int a = 0; a < fragmentsStack.size() - 1; a++) { - fragmentsStack.get(a).setParentActivity(null); - fragmentsStack.get(a).setParentActivity(this); + public void removeAllFragments() { + for (int a = 0; a < fragmentsStack.size(); a++) { + removeFragmentFromStack(fragmentsStack.get(a)); + a--; } } - protected void onFinish() { - + public void rebuildAllFragmentViews(boolean last) { + for (int a = 0; a < fragmentsStack.size() - (last ? 0 : 1); a++) { + fragmentsStack.get(a).setParentLayout(null); + fragmentsStack.get(a).setParentLayout(this); + } + if (delegate != null) { + delegate.onRebuildAllFragments(this); + } } public void showActionBar() { @@ -672,28 +724,22 @@ public class ActionBarActivity extends Activity { return super.onKeyUp(keyCode, event); } - public void onOverlayShow(View view, BaseFragment fragment) { - + protected void onOverlayShow(View view, BaseFragment fragment) { + if (delegate != null) { + delegate.onOverlayShow(view, fragment); + } } - @Override public void onActionModeStarted(ActionMode mode) { - super.onActionModeStarted(mode); hideActionBar(); inActionMode = true; } - @Override public void onActionModeFinished(ActionMode mode) { - super.onActionModeFinished(mode); showActionBar(); inActionMode = false; } - public boolean onPreIme() { - return false; - } - private void onCloseAnimationEnd(boolean post) { if (transitionAnimationInProgress && onCloseAnimationEndRunnable != null) { transitionAnimationInProgress = false; @@ -730,12 +776,6 @@ public class ActionBarActivity extends Activity { } } - private void onAnimationEnd() { - onCloseAnimationEnd(false); - onOpenAnimationEnd(false); - } - - @Override public void startActivityForResult(final Intent intent, final int requestCode) { if (transitionAnimationInProgress) { if (onCloseAnimationEndRunnable != null) { @@ -747,12 +787,26 @@ public class ActionBarActivity extends Activity { } containerView.invalidate(); if (intent != null) { - super.startActivityForResult(intent, requestCode); + parentActivity.startActivityForResult(intent, requestCode); } } else { if (intent != null) { - super.startActivityForResult(intent, requestCode); + parentActivity.startActivityForResult(intent, requestCode); } } } + + public void setUseAlphaAnimations(boolean value) { + useAlphaAnimations = value; + if (useAlphaAnimations) { + alphaOpenAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.icon_anim_fade_in); + alphaOpenAnimation2 = AnimationUtils.loadAnimation(getContext(), R.anim.icon_anim_fade_in); + alphaCloseAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.icon_anim_fade_out); + alphaCloseAnimation2 = AnimationUtils.loadAnimation(getContext(), R.anim.icon_anim_fade_out); + } + } + + public void setBackgroundView(View view) { + backgroundView = view; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarMenu.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarMenu.java index b22b439e4..ae1288bdb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarMenu.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarMenu.java @@ -61,7 +61,11 @@ public class ActionBarMenu extends LinearLayout { } public ActionBarMenuItem addItem(int id, int icon) { - ActionBarMenuItem menuItem = new ActionBarMenuItem(getContext(), this, parentActionBar, parentActionBarLayer.itemsBackgroundResourceId); + return addItem(id, icon, parentActionBarLayer.itemsBackgroundResourceId); + } + + public ActionBarMenuItem addItem(int id, int icon, int backgroundResource) { + ActionBarMenuItem menuItem = new ActionBarMenuItem(getContext(), this, parentActionBar, backgroundResource); menuItem.setTag(id); menuItem.setScaleType(ImageView.ScaleType.CENTER); menuItem.setImageResource(icon); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarMenuItem.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarMenuItem.java index e3c1117df..579b11161 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarMenuItem.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarMenuItem.java @@ -14,8 +14,12 @@ import android.os.Build; import android.text.Editable; import android.text.TextWatcher; import android.util.AttributeSet; +import android.view.ActionMode; +import android.view.ContextMenu; import android.view.Gravity; import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; @@ -28,7 +32,6 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.messenger.R; -import org.telegram.messenger.Utilities; import java.lang.reflect.Field; @@ -257,6 +260,30 @@ public class ActionBarMenuItem extends ImageView { searchField.setBackgroundResource(R.drawable.search_light_states); searchField.setPadding(AndroidUtilities.dp(6), 0, AndroidUtilities.dp(6), 0); searchField.setInputType(EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + if (android.os.Build.VERSION.SDK_INT < 11) { + searchField.setOnCreateContextMenuListener(new OnCreateContextMenuListener() { + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + menu.clear(); + } + }); + } else { + searchField.setCustomSelectionActionModeCallback(new ActionMode.Callback() { + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } + + public void onDestroyActionMode(ActionMode mode) { + } + + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + return false; + } + + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return false; + } + }); + } searchField.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/BaseFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/BaseFragment.java index c3e0e2069..05e609b4d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/BaseFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/BaseFragment.java @@ -8,6 +8,7 @@ package org.telegram.ui.Views.ActionBar; +import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; @@ -23,7 +24,7 @@ import org.telegram.messenger.R; public class BaseFragment { private boolean isFinished = false; protected View fragmentView; - private ActionBarActivity parentActivity; + protected ActionBarLayout parentLayout; protected ActionBarLayer actionBarLayer; protected int classGuid = 0; protected Bundle arguments; @@ -47,9 +48,9 @@ public class BaseFragment { return arguments; } - public void setParentActivity(ActionBarActivity activity) { - if (parentActivity != activity) { - parentActivity = activity; + public void setParentLayout(ActionBarLayout layout) { + if (parentLayout != layout) { + parentLayout = layout; if (fragmentView != null) { ViewGroup parent = (ViewGroup) fragmentView.getParent(); if (parent != null) { @@ -57,11 +58,11 @@ public class BaseFragment { } fragmentView = null; } - if (parentActivity != null) { + if (parentLayout != null) { if (actionBarLayer != null) { actionBarLayer.onDestroy(); } - actionBarLayer = parentActivity.getInternalActionBar().createLayer(); + actionBarLayer = parentLayout.getInternalActionBar().createLayer(); actionBarLayer.parentFragment = this; actionBarLayer.setBackgroundResource(R.color.header); actionBarLayer.setItemsBackground(R.drawable.bar_selector); @@ -74,17 +75,17 @@ public class BaseFragment { } public void finishFragment(boolean animated) { - if (isFinished || parentActivity == null) { + if (isFinished || parentLayout == null) { return; } - parentActivity.closeLastFragment(animated); + parentLayout.closeLastFragment(animated); } public void removeSelfFromStack() { - if (isFinished || parentActivity == null) { + if (isFinished || parentLayout == null) { return; } - parentActivity.removeFragmentFromStack(this); + parentLayout.removeFragmentFromStack(this); } public boolean onFragmentCreate() { @@ -139,39 +140,39 @@ public class BaseFragment { } public void presentFragment(BaseFragment fragment) { - if (parentActivity == null) { + if (parentLayout == null) { return; } - parentActivity.presentFragment(fragment); + parentLayout.presentFragment(fragment); } public void presentFragment(BaseFragment fragment, boolean removeLast) { - if (parentActivity == null) { + if (parentLayout == null) { return; } - parentActivity.presentFragment(fragment, removeLast); + parentLayout.presentFragment(fragment, removeLast); } public void presentFragment(BaseFragment fragment, boolean removeLast, boolean forceWithoutAnimation) { - if (parentActivity == null) { + if (parentLayout == null) { return; } - parentActivity.presentFragment(fragment, removeLast, forceWithoutAnimation); + parentLayout.presentFragment(fragment, removeLast, forceWithoutAnimation); } - public ActionBarActivity getParentActivity() { - return parentActivity; + public Activity getParentActivity() { + return parentLayout.parentActivity; } public void showActionBar() { - if (parentActivity != null) { - parentActivity.showActionBar(); + if (parentLayout != null) { + parentLayout.showActionBar(); } } public void hideActionBar() { - if (parentActivity != null) { - parentActivity.hideActionBar(); + if (parentLayout != null) { + parentLayout.hideActionBar(); } } @@ -198,7 +199,7 @@ public class BaseFragment { } protected void showAlertDialog(AlertDialog.Builder builder) { - if (parentActivity == null || parentActivity.checkTransitionAnimation() || parentActivity.animationInProgress || parentActivity.startedTracking) { + if (parentLayout == null || parentLayout.checkTransitionAnimation() || parentLayout.animationInProgress || parentLayout.startedTracking) { return; } try { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java index 69d7542ba..87ae3235b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java @@ -451,7 +451,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } emojiPopup.setHeight(View.MeasureSpec.makeMeasureSpec(currentHeight, View.MeasureSpec.EXACTLY)); if (sizeNotifierRelativeLayout != null) { - emojiPopup.setWidth(View.MeasureSpec.makeMeasureSpec(sizeNotifierRelativeLayout.getWidth(), View.MeasureSpec.EXACTLY)); + emojiPopup.setWidth(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x, View.MeasureSpec.EXACTLY)); } emojiPopup.showAtLocation(parentActivity.getWindow().getDecorView(), 83, 0, 0); @@ -585,7 +585,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen if (emojiPopup != null && emojiPopup.isShowing()) { WindowManager wm = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); final WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams)emojiPopup.getContentView().getLayoutParams(); - layoutParams.width = sizeNotifierRelativeLayout.getWidth(); + layoutParams.width = AndroidUtilities.displaySize.x; if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { layoutParams.height = keyboardHeightLand; } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/EmojiView.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/EmojiView.java index b8cb4817e..b4c6c7785 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/EmojiView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/EmojiView.java @@ -104,7 +104,11 @@ public class EmojiView extends LinearLayout { setOrientation(LinearLayout.VERTICAL); for (int i = 0; i < Emoji.data.length; i++) { GridView gridView = new GridView(getContext()); - gridView.setColumnWidth(AndroidUtilities.dpf(45.0f)); + if (AndroidUtilities.isTablet()) { + gridView.setColumnWidth(AndroidUtilities.dp(60)); + } else { + gridView.setColumnWidth(AndroidUtilities.dp(45)); + } gridView.setNumColumns(-1); views.add(gridView); @@ -122,7 +126,7 @@ public class EmojiView extends LinearLayout { tabs.setIndicatorColor(0xff33b5e5); tabs.setIndicatorHeight(AndroidUtilities.dpf(2.0f)); tabs.setUnderlineHeight(AndroidUtilities.dpf(2.0f)); - tabs.setUnderlineColor(1711276032); + tabs.setUnderlineColor(0x66000000); tabs.setTabBackground(0); LinearLayout localLinearLayout = new LinearLayout(getContext()); localLinearLayout.setOrientation(LinearLayout.HORIZONTAL); @@ -138,7 +142,7 @@ public class EmojiView extends LinearLayout { } } }); - localLinearLayout.addView(localImageView, new LinearLayout.LayoutParams(AndroidUtilities.dpf(61.0f), LayoutParams.MATCH_PARENT)); + localLinearLayout.addView(localImageView, new LinearLayout.LayoutParams(AndroidUtilities.dp(61), LayoutParams.MATCH_PARENT)); recentsWrap = new FrameLayout(getContext()); recentsWrap.addView(views.get(0)); TextView localTextView = new TextView(getContext()); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/RoundProgressView.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/RoundProgressView.java deleted file mode 100644 index 551b49441..000000000 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/RoundProgressView.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This is the source code of Telegram for Android v. 1.7.x. - * It is licensed under GNU GPL v. 2 or later. - * You should have received a copy of the license in this archive (see LICENSE). - * - * Copyright Nikolai Kudashov, 2013-2014. - */ - -package org.telegram.ui.Views; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.RectF; - -import org.telegram.android.AndroidUtilities; - -public class RoundProgressView { - private Paint paint; - - public float currentProgress = 0; - public RectF rect = new RectF(); - - public RoundProgressView() { - paint = new Paint(); - paint.setColor(0xffffffff); - paint.setStyle(Paint.Style.STROKE); - paint.setStrokeWidth(AndroidUtilities.dp(2)); - paint.setAntiAlias(true); - } - - public void setColor(int color) { - paint.setColor(color); - } - - public void setProgress(float progress) { - currentProgress = progress; - if (currentProgress < 0) { - currentProgress = 0; - } else if (currentProgress > 1) { - currentProgress = 1; - } - } - - public void draw(Canvas canvas) { - canvas.drawArc(rect, -90, 360 * currentProgress, false, paint); - } -} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/SizeNotifierRelativeLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/SizeNotifierRelativeLayout.java index f8eb84abd..ffe96479a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/SizeNotifierRelativeLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/SizeNotifierRelativeLayout.java @@ -65,13 +65,13 @@ public class SizeNotifierRelativeLayout extends RelativeLayout { @Override protected void onDraw(Canvas canvas) { if (backgroundDrawable != null) { - float scaleX = (float)AndroidUtilities.displaySize.x / (float)backgroundDrawable.getIntrinsicWidth(); - float scaleY = (float)AndroidUtilities.displaySize.y / (float)backgroundDrawable.getIntrinsicHeight(); + float scaleX = (float)getMeasuredWidth() / (float)backgroundDrawable.getIntrinsicWidth(); + float scaleY = (float)getMeasuredHeight() / (float)backgroundDrawable.getIntrinsicHeight(); float scale = scaleX < scaleY ? scaleY : scaleX; int width = (int)Math.ceil(backgroundDrawable.getIntrinsicWidth() * scale); int height = (int)Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale); - int x = (AndroidUtilities.displaySize.x - width) / 2; - int y = (AndroidUtilities.displaySize.y - height) / 2; + int x = (getMeasuredWidth() - width) / 2; + int y = (getMeasuredHeight() - height) / 2; backgroundDrawable.setBounds(x, y, x + width, y + height); backgroundDrawable.draw(canvas); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/TypingDotsDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/TypingDotsDrawable.java new file mode 100644 index 000000000..b0069496e --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/TypingDotsDrawable.java @@ -0,0 +1,125 @@ +/* + * This is the source code of Telegram for Android v. 1.7.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.ui.Views; + +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.view.animation.DecelerateInterpolator; + +import org.telegram.android.AndroidUtilities; + +public class TypingDotsDrawable extends Drawable { + private boolean isChat = false; + private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + private float[] scales = new float[3]; + private float[] startTimes = new float[] {0, 150, 300}; + private float[] elapsedTimes = new float[] {0, 0, 0}; + private long lastUpdateTime = 0; + private boolean started = false; + private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator(); + + public TypingDotsDrawable() { + super(); + paint.setColor(0xffd7e8f7); + } + + public void setIsChat(boolean value) { + isChat = value; + } + + private void update() { + long newTime = System.currentTimeMillis(); + long dt = newTime - lastUpdateTime; + lastUpdateTime = newTime; + + for (int a = 0; a < 3; a++) { + elapsedTimes[a] += dt; + float timeSinceStart = elapsedTimes[a] - startTimes[a]; + if (timeSinceStart > 0) { + if (timeSinceStart <= 320) { + float diff = decelerateInterpolator.getInterpolation(timeSinceStart / 320.0f); + scales[a] = 1.33f + diff; + } else if (timeSinceStart <= 640) { + float diff = decelerateInterpolator.getInterpolation((timeSinceStart - 320.0f) / 320.0f); + scales[a] = 1.33f + (1 - diff); + } else if (timeSinceStart >= 800) { + elapsedTimes[a] = 0; + startTimes[a] = 0; + scales[a] = 1.33f; + } else { + scales[a] = 1.33f; + } + } else { + scales[a] = 1.33f; + } + } + + invalidateSelf(); + } + + public void start() { + lastUpdateTime = System.currentTimeMillis(); + started = true; + invalidateSelf(); + } + + public void stop() { + for (int a = 0; a < 3; a++) { + elapsedTimes[a] = 0; + scales[a] = 1.33f; + } + startTimes[0] = 0; + startTimes[1] = 150; + startTimes[2] = 300; + started = false; + } + + @Override + public void draw(Canvas canvas) { + int y = 0; + if (isChat) { + y = AndroidUtilities.dp(6); + } else { + y = AndroidUtilities.dp(7); + } + canvas.drawCircle(AndroidUtilities.dp(3), y, scales[0] * AndroidUtilities.density, paint); + canvas.drawCircle(AndroidUtilities.dp(9), y, scales[1] * AndroidUtilities.density, paint); + canvas.drawCircle(AndroidUtilities.dp(15), y, scales[2] * AndroidUtilities.density, paint); + if (started) { + update(); + } + } + + @Override + public void setAlpha(int alpha) { + + } + + @Override + public void setColorFilter(ColorFilter cf) { + + } + + @Override + public int getOpacity() { + return 0; + } + + @Override + public int getIntrinsicWidth() { + return AndroidUtilities.dp(18); + } + + @Override + public int getIntrinsicHeight() { + return AndroidUtilities.dp(10); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoSeekBarView.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoSeekBarView.java index 4bdab183d..f414b650c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoSeekBarView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoSeekBarView.java @@ -22,7 +22,6 @@ import org.telegram.messenger.R; public class VideoSeekBarView extends View { private static Drawable thumbDrawable1; - private static Drawable thumbDrawablePressed1; private static Paint innerPaint1 = new Paint(); private static int thumbWidth; private static int thumbHeight; @@ -37,8 +36,7 @@ public class VideoSeekBarView extends View { private void init(Context context) { if (thumbDrawable1 == null) { - thumbDrawable1 = context.getResources().getDrawable(R.drawable.playback); - thumbDrawablePressed1 = context.getResources().getDrawable(R.drawable.playback_active); + thumbDrawable1 = context.getResources().getDrawable(R.drawable.videolapse); innerPaint1.setColor(0x99999999); thumbWidth = thumbDrawable1.getIntrinsicWidth(); thumbHeight = thumbDrawable1.getIntrinsicHeight(); @@ -118,16 +116,10 @@ public class VideoSeekBarView extends View { @Override protected void onDraw(Canvas canvas) { - Drawable thumb = null; - if (!pressed) { - thumb = thumbDrawable1; - } else { - thumb = thumbDrawablePressed1; - } int y = (getMeasuredHeight() - thumbHeight) / 2; int thumbX = (int)((getMeasuredWidth() - thumbWidth) * progress); canvas.drawRect(thumbWidth / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), getMeasuredWidth() - thumbWidth / 2, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), innerPaint1); - thumb.setBounds(thumbX, y, thumbX + thumbWidth, y + thumbHeight); - thumb.draw(canvas); + thumbDrawable1.setBounds(thumbX, y, thumbX + thumbWidth, y + thumbHeight); + thumbDrawable1.draw(canvas); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoTimelineView.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoTimelineView.java index f8fe8e21f..926c08db4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoTimelineView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoTimelineView.java @@ -14,6 +14,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.media.MediaMetadataRetriever; import android.os.AsyncTask; import android.util.AttributeSet; @@ -22,6 +23,7 @@ import android.view.View; import org.telegram.android.AndroidUtilities; import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; import java.util.ArrayList; @@ -44,32 +46,34 @@ public class VideoTimelineView extends View { private int frameWidth = 0; private int frameHeight = 0; private int framesToLoad = 0; + private Drawable pickDrawable = null; public abstract interface VideoTimelineViewDelegate { public void onLeftProgressChanged(float progress); public void onRifhtProgressChanged(float progress); } - private void init() { + private void init(Context context) { paint = new Paint(); paint.setColor(0xff66d1ee); paint2 = new Paint(); - paint2.setColor(0x2266d1ee); + paint2.setColor(0x7f000000); + pickDrawable = getResources().getDrawable(R.drawable.videotrimmer); } public VideoTimelineView(Context context) { super(context); - init(); + init(context); } public VideoTimelineView(Context context, AttributeSet attrs) { super(context, attrs); - init(); + init(context); } public VideoTimelineView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - init(); + init(context); } public float getLeftProgress() { @@ -88,9 +92,9 @@ public class VideoTimelineView extends View { float x = event.getX(); float y = event.getY(); - int width = getMeasuredWidth() - AndroidUtilities.dp(12); - int startX = (int)(width * progressLeft) + AndroidUtilities.dp(3); - int endX = (int)(width * progressRight) + AndroidUtilities.dp(9); + int width = getMeasuredWidth() - AndroidUtilities.dp(32); + int startX = (int)(width * progressLeft) + AndroidUtilities.dp(16); + int endX = (int)(width * progressRight) + AndroidUtilities.dp(16); if (event.getAction() == MotionEvent.ACTION_DOWN) { int additionWidth = AndroidUtilities.dp(12); @@ -118,12 +122,12 @@ public class VideoTimelineView extends View { } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (pressedLeft) { startX = (int)(x - pressDx); - if (startX < AndroidUtilities.dp(3)) { - startX = AndroidUtilities.dp(3); - } else if (startX > endX - AndroidUtilities.dp(6)) { - startX = endX - AndroidUtilities.dp(6); + if (startX < AndroidUtilities.dp(16)) { + startX = AndroidUtilities.dp(16); + } else if (startX > endX) { + startX = endX; } - progressLeft = (float)(startX - AndroidUtilities.dp(3)) / (float)width; + progressLeft = (float)(startX - AndroidUtilities.dp(16)) / (float)width; if (delegate != null) { delegate.onLeftProgressChanged(progressLeft); } @@ -131,12 +135,12 @@ public class VideoTimelineView extends View { return true; } else if (pressedRight) { endX = (int)(x - pressDx); - if (endX < startX + AndroidUtilities.dp(6)) { - endX = startX + AndroidUtilities.dp(6); - } else if (endX > width + AndroidUtilities.dp(9)) { - endX = width + AndroidUtilities.dp(9); + if (endX < startX) { + endX = startX; + } else if (endX > width + AndroidUtilities.dp(16)) { + endX = width + AndroidUtilities.dp(16); } - progressRight = (float)(endX - AndroidUtilities.dp(9)) / (float)width; + progressRight = (float)(endX - AndroidUtilities.dp(16)) / (float)width; if (delegate != null) { delegate.onRifhtProgressChanged(progressRight); } @@ -163,9 +167,9 @@ public class VideoTimelineView extends View { return; } if (frameNum == 0) { - frameHeight = getMeasuredHeight() - AndroidUtilities.dp(4); - framesToLoad = getMeasuredWidth() / frameHeight; - frameWidth = (int)Math.ceil((float)getMeasuredWidth() / (float)framesToLoad); + frameHeight = AndroidUtilities.dp(40); + framesToLoad = (getMeasuredWidth() - AndroidUtilities.dp(16)) / frameHeight; + frameWidth = (int)Math.ceil((float)(getMeasuredWidth() - AndroidUtilities.dp(16)) / (float)framesToLoad); frameTimeOffset = videoLength / framesToLoad; } currentTask = new AsyncTask() { @@ -262,24 +266,39 @@ public class VideoTimelineView extends View { @Override protected void onDraw(Canvas canvas) { + int width = getMeasuredWidth() - AndroidUtilities.dp(36); + int startX = (int)(width * progressLeft) + AndroidUtilities.dp(16); + int endX = (int)(width * progressRight) + AndroidUtilities.dp(16); + + canvas.save(); + canvas.clipRect(AndroidUtilities.dp(16), 0, width + AndroidUtilities.dp(20), AndroidUtilities.dp(44)); if (frames.isEmpty() && currentTask == null) { reloadFrames(0); } else { int offset = 0; for (Bitmap bitmap : frames) { if (bitmap != null) { - canvas.drawBitmap(bitmap, offset * frameWidth, AndroidUtilities.dp(2), null); + canvas.drawBitmap(bitmap, AndroidUtilities.dp(16) + offset * frameWidth, AndroidUtilities.dp(2), null); } offset++; } } - int width = getMeasuredWidth() - AndroidUtilities.dp(12); - int startX = (int)(width * progressLeft); - int endX = (int)(width * progressRight); - canvas.drawRect(startX, 0, startX + AndroidUtilities.dp(6), getMeasuredHeight(), paint); - canvas.drawRect(endX + AndroidUtilities.dp(6), 0, endX + AndroidUtilities.dp(12), getMeasuredHeight(), paint); - canvas.drawRect(startX + AndroidUtilities.dp(6), AndroidUtilities.dp(4), endX + AndroidUtilities.dp(6), getMeasuredHeight() - AndroidUtilities.dp(4), paint2); - canvas.drawRect(startX + AndroidUtilities.dp(6), AndroidUtilities.dp(2), endX + AndroidUtilities.dp(6), AndroidUtilities.dp(4), paint); - canvas.drawRect(startX + AndroidUtilities.dp(6), getMeasuredHeight() - AndroidUtilities.dp(4), endX + AndroidUtilities.dp(6), getMeasuredHeight() - AndroidUtilities.dp(2), paint); + + canvas.drawRect(AndroidUtilities.dp(16), AndroidUtilities.dp(2), startX, AndroidUtilities.dp(42), paint2); + canvas.drawRect(endX + AndroidUtilities.dp(4), AndroidUtilities.dp(2), AndroidUtilities.dp(16) + width + AndroidUtilities.dp(4), AndroidUtilities.dp(42), paint2); + + canvas.drawRect(startX, 0, startX + AndroidUtilities.dp(2), AndroidUtilities.dp(44), paint); + canvas.drawRect(endX + AndroidUtilities.dp(2), 0, endX + AndroidUtilities.dp(4), AndroidUtilities.dp(44), paint); + canvas.drawRect(startX + AndroidUtilities.dp(2), 0, endX + AndroidUtilities.dp(4), AndroidUtilities.dp(2), paint); + canvas.drawRect(startX + AndroidUtilities.dp(2), AndroidUtilities.dp(42), endX + AndroidUtilities.dp(4), AndroidUtilities.dp(44), paint); + canvas.restore(); + + int drawableWidth = pickDrawable.getIntrinsicWidth(); + int drawableHeight = pickDrawable.getIntrinsicHeight(); + pickDrawable.setBounds(startX - drawableWidth / 2, getMeasuredHeight() - drawableHeight, startX + drawableWidth / 2, getMeasuredHeight()); + pickDrawable.draw(canvas); + + pickDrawable.setBounds(endX - drawableWidth / 2 + AndroidUtilities.dp(4), getMeasuredHeight() - drawableHeight, endX + drawableWidth / 2 + AndroidUtilities.dp(4), getMeasuredHeight()); + pickDrawable.draw(canvas); } } diff --git a/TMessagesProj/src/main/res/drawable-hdpi/boxshadow.9.png b/TMessagesProj/src/main/res/drawable-hdpi/boxshadow.9.png new file mode 100644 index 000000000..a4559eb2c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/boxshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/broadcast_aqua.png b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_aqua.png new file mode 100755 index 000000000..69e9ee758 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_aqua.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/broadcast_blue.png b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_blue.png new file mode 100755 index 000000000..8a41f2a39 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_blue.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/broadcast_green.png b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_green.png new file mode 100755 index 000000000..24c5329b1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_green.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/broadcast_orange.png b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_orange.png new file mode 100755 index 000000000..a942fc9ce Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_orange.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/broadcast_pink.png b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_pink.png new file mode 100755 index 000000000..c0a8a3d51 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_pink.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/broadcast_red.png b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_red.png new file mode 100755 index 000000000..b782c3ab5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_red.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/broadcast_violet.png b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_violet.png new file mode 100755 index 000000000..905048e45 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_violet.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/broadcast_yellow.png b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_yellow.png new file mode 100755 index 000000000..c427ad488 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/broadcast_yellow.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/btnshadow.9.png b/TMessagesProj/src/main/res/drawable-hdpi/btnshadow.9.png new file mode 100644 index 000000000..a75bd31af Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/btnshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/cats.jpg b/TMessagesProj/src/main/res/drawable-hdpi/cats.jpg new file mode 100644 index 000000000..5cee44af5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/cats.jpg differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/gift_aqua.png b/TMessagesProj/src/main/res/drawable-hdpi/gift_aqua.png deleted file mode 100755 index a3086e427..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/gift_aqua.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/gift_blue.png b/TMessagesProj/src/main/res/drawable-hdpi/gift_blue.png deleted file mode 100755 index ff2b89af2..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/gift_blue.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/gift_green.png b/TMessagesProj/src/main/res/drawable-hdpi/gift_green.png deleted file mode 100755 index 715f27bae..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/gift_green.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/gift_orange.png b/TMessagesProj/src/main/res/drawable-hdpi/gift_orange.png deleted file mode 100755 index f313c8ac6..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/gift_orange.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/gift_pink.png b/TMessagesProj/src/main/res/drawable-hdpi/gift_pink.png deleted file mode 100755 index ad5408605..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/gift_pink.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/gift_red.png b/TMessagesProj/src/main/res/drawable-hdpi/gift_red.png deleted file mode 100755 index ce4977569..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/gift_red.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/gift_violet.png b/TMessagesProj/src/main/res/drawable-hdpi/gift_violet.png deleted file mode 100755 index 7c8dac79d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/gift_violet.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/gift_yellow.png b/TMessagesProj/src/main/res/drawable-hdpi/gift_yellow.png deleted file mode 100755 index d59d949f3..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/gift_yellow.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/intro1.png b/TMessagesProj/src/main/res/drawable-hdpi/intro1.png index b788d850e..8eb54b3ca 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/intro1.png and b/TMessagesProj/src/main/res/drawable-hdpi/intro1.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/playback.png b/TMessagesProj/src/main/res/drawable-hdpi/playback.png deleted file mode 100644 index 1ca26fcac..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/playback.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/playback_active.png b/TMessagesProj/src/main/res/drawable-hdpi/playback_active.png deleted file mode 100644 index 11760303e..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/playback_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame0.png b/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame0.png deleted file mode 100755 index 1b8817dcb..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame0.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame1.png b/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame1.png deleted file mode 100755 index b30359a20..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame1.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame2.png b/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame2.png deleted file mode 100755 index a64fbf2bc..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame2.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame3.png b/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame3.png deleted file mode 100755 index 0be0c8d66..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_chat_frame3.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame0.png b/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame0.png deleted file mode 100755 index 921ad23fb..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame0.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame1.png b/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame1.png deleted file mode 100755 index 9e9d63eb0..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame1.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame2.png b/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame2.png deleted file mode 100755 index 2ff89fddd..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame2.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame3.png b/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame3.png deleted file mode 100755 index 30a602143..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/typing_dot_frame3.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/videolapse.png b/TMessagesProj/src/main/res/drawable-hdpi/videolapse.png new file mode 100755 index 000000000..9165609b2 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/videolapse.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/videotrimmer.png b/TMessagesProj/src/main/res/drawable-hdpi/videotrimmer.png new file mode 100755 index 000000000..c28033118 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/videotrimmer.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/boxshadow.9.png b/TMessagesProj/src/main/res/drawable-ldpi/boxshadow.9.png new file mode 100644 index 000000000..e0c55dc12 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/boxshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/broadcast_aqua.png b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_aqua.png new file mode 100755 index 000000000..842ff62e8 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_aqua.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/broadcast_blue.png b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_blue.png new file mode 100755 index 000000000..e0a722174 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_blue.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/broadcast_green.png b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_green.png new file mode 100755 index 000000000..099d3caac Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_green.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/broadcast_orange.png b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_orange.png new file mode 100755 index 000000000..84d22c9a9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_orange.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/broadcast_pink.png b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_pink.png new file mode 100755 index 000000000..a6ef2ff5f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_pink.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/broadcast_red.png b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_red.png new file mode 100755 index 000000000..44969ccea Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_red.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/broadcast_violet.png b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_violet.png new file mode 100755 index 000000000..5b1e01588 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_violet.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/broadcast_yellow.png b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_yellow.png new file mode 100755 index 000000000..e81e8c8fd Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/broadcast_yellow.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/btnshadow.9.png b/TMessagesProj/src/main/res/drawable-ldpi/btnshadow.9.png new file mode 100644 index 000000000..862afedd3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/btnshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/gift_aqua.png b/TMessagesProj/src/main/res/drawable-ldpi/gift_aqua.png deleted file mode 100755 index 18fe949ea..000000000 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/gift_aqua.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/gift_blue.png b/TMessagesProj/src/main/res/drawable-ldpi/gift_blue.png deleted file mode 100755 index 4b6d2af16..000000000 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/gift_blue.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/gift_green.png b/TMessagesProj/src/main/res/drawable-ldpi/gift_green.png deleted file mode 100755 index 71beea6af..000000000 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/gift_green.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/gift_orange.png b/TMessagesProj/src/main/res/drawable-ldpi/gift_orange.png deleted file mode 100755 index 9b0e4c659..000000000 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/gift_orange.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/gift_pink.png b/TMessagesProj/src/main/res/drawable-ldpi/gift_pink.png deleted file mode 100755 index be6817f44..000000000 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/gift_pink.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/gift_red.png b/TMessagesProj/src/main/res/drawable-ldpi/gift_red.png deleted file mode 100755 index 8e7d56270..000000000 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/gift_red.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/gift_violet.png b/TMessagesProj/src/main/res/drawable-ldpi/gift_violet.png deleted file mode 100755 index 167f2815f..000000000 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/gift_violet.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/gift_yellow.png b/TMessagesProj/src/main/res/drawable-ldpi/gift_yellow.png deleted file mode 100755 index 159c56585..000000000 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/gift_yellow.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/intro1.png b/TMessagesProj/src/main/res/drawable-ldpi/intro1.png index d4b0675eb..d065bb3c6 100755 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/intro1.png and b/TMessagesProj/src/main/res/drawable-ldpi/intro1.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/playback.png b/TMessagesProj/src/main/res/drawable-ldpi/playback.png deleted file mode 100644 index d82736e01..000000000 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/playback.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/playback_active.png b/TMessagesProj/src/main/res/drawable-ldpi/playback_active.png deleted file mode 100644 index 66d42bc17..000000000 Binary files a/TMessagesProj/src/main/res/drawable-ldpi/playback_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/videolapse.png b/TMessagesProj/src/main/res/drawable-ldpi/videolapse.png new file mode 100755 index 000000000..8a8a2744b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/videolapse.png differ diff --git a/TMessagesProj/src/main/res/drawable-ldpi/videotrimmer.png b/TMessagesProj/src/main/res/drawable-ldpi/videotrimmer.png new file mode 100755 index 000000000..1a6e341f0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-ldpi/videotrimmer.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/boxshadow.9.png b/TMessagesProj/src/main/res/drawable-mdpi/boxshadow.9.png new file mode 100644 index 000000000..e0ed0f591 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/boxshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/broadcast_aqua.png b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_aqua.png new file mode 100755 index 000000000..ee955dee9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_aqua.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/broadcast_blue.png b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_blue.png new file mode 100755 index 000000000..cfe7cea90 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_blue.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/broadcast_green.png b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_green.png new file mode 100755 index 000000000..322153280 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_green.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/broadcast_orange.png b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_orange.png new file mode 100755 index 000000000..2f3b81594 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_orange.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/broadcast_pink.png b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_pink.png new file mode 100755 index 000000000..cace0d662 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_pink.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/broadcast_red.png b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_red.png new file mode 100755 index 000000000..d63200980 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_red.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/broadcast_violet.png b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_violet.png new file mode 100755 index 000000000..fb7135aa0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_violet.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/broadcast_yellow.png b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_yellow.png new file mode 100755 index 000000000..9ed3aa714 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/broadcast_yellow.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/btnshadow.9.png b/TMessagesProj/src/main/res/drawable-mdpi/btnshadow.9.png new file mode 100644 index 000000000..9bda10680 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/btnshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/cats.jpg b/TMessagesProj/src/main/res/drawable-mdpi/cats.jpg new file mode 100644 index 000000000..714170084 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/cats.jpg differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/gift_aqua.png b/TMessagesProj/src/main/res/drawable-mdpi/gift_aqua.png deleted file mode 100755 index fcaad6b56..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/gift_aqua.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/gift_blue.png b/TMessagesProj/src/main/res/drawable-mdpi/gift_blue.png deleted file mode 100755 index 120263daf..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/gift_blue.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/gift_green.png b/TMessagesProj/src/main/res/drawable-mdpi/gift_green.png deleted file mode 100755 index e3023d090..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/gift_green.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/gift_orange.png b/TMessagesProj/src/main/res/drawable-mdpi/gift_orange.png deleted file mode 100755 index 380c9cb48..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/gift_orange.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/gift_pink.png b/TMessagesProj/src/main/res/drawable-mdpi/gift_pink.png deleted file mode 100755 index f1c22d744..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/gift_pink.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/gift_red.png b/TMessagesProj/src/main/res/drawable-mdpi/gift_red.png deleted file mode 100755 index 55a622325..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/gift_red.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/gift_violet.png b/TMessagesProj/src/main/res/drawable-mdpi/gift_violet.png deleted file mode 100755 index 2a2ee8d8c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/gift_violet.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/gift_yellow.png b/TMessagesProj/src/main/res/drawable-mdpi/gift_yellow.png deleted file mode 100755 index 19bfa3870..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/gift_yellow.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/intro1.png b/TMessagesProj/src/main/res/drawable-mdpi/intro1.png index 37c9583ef..9a068122e 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/intro1.png and b/TMessagesProj/src/main/res/drawable-mdpi/intro1.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/playback.png b/TMessagesProj/src/main/res/drawable-mdpi/playback.png deleted file mode 100644 index 729c999e9..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/playback.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/playback_active.png b/TMessagesProj/src/main/res/drawable-mdpi/playback_active.png deleted file mode 100644 index 65c7c4750..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/playback_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame0.png b/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame0.png deleted file mode 100755 index 4c12121a2..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame0.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame1.png b/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame1.png deleted file mode 100755 index faf6900df..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame1.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame2.png b/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame2.png deleted file mode 100755 index 4f8c5c5da..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame2.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame3.png b/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame3.png deleted file mode 100755 index 0969a95a1..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_chat_frame3.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame0.png b/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame0.png deleted file mode 100755 index 98235ffb5..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame0.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame1.png b/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame1.png deleted file mode 100755 index 0f4acc0b4..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame1.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame2.png b/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame2.png deleted file mode 100755 index 8086e2a3f..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame2.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame3.png b/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame3.png deleted file mode 100755 index 6806fbcf2..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/typing_dot_frame3.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/videolapse.png b/TMessagesProj/src/main/res/drawable-mdpi/videolapse.png new file mode 100755 index 000000000..08336314a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/videolapse.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/videotrimmer.png b/TMessagesProj/src/main/res/drawable-mdpi/videotrimmer.png new file mode 100755 index 000000000..f68380eb2 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/videotrimmer.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/boxshadow.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/boxshadow.9.png new file mode 100644 index 000000000..ac112f7c5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/boxshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_aqua.png b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_aqua.png new file mode 100755 index 000000000..70dfa6f69 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_aqua.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_blue.png b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_blue.png new file mode 100755 index 000000000..4a30d7b6e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_blue.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_green.png b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_green.png new file mode 100755 index 000000000..8cabb2c33 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_green.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_orange.png b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_orange.png new file mode 100755 index 000000000..da46755d0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_orange.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_pink.png b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_pink.png new file mode 100755 index 000000000..fbc921282 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_pink.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_red.png b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_red.png new file mode 100755 index 000000000..1cc2c2d8d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_red.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_violet.png b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_violet.png new file mode 100755 index 000000000..9f2ed8bfb Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_violet.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_yellow.png b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_yellow.png new file mode 100755 index 000000000..2609fca15 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/broadcast_yellow.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/btnshadow.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/btnshadow.9.png new file mode 100644 index 000000000..e3d0d98f3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/btnshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/cats.jpg b/TMessagesProj/src/main/res/drawable-xhdpi/cats.jpg new file mode 100644 index 000000000..396bbcf4e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/cats.jpg differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/gift_aqua.png b/TMessagesProj/src/main/res/drawable-xhdpi/gift_aqua.png deleted file mode 100755 index dc837db7a..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/gift_aqua.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/gift_blue.png b/TMessagesProj/src/main/res/drawable-xhdpi/gift_blue.png deleted file mode 100755 index 4885cba79..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/gift_blue.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/gift_green.png b/TMessagesProj/src/main/res/drawable-xhdpi/gift_green.png deleted file mode 100755 index 436a52720..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/gift_green.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/gift_orange.png b/TMessagesProj/src/main/res/drawable-xhdpi/gift_orange.png deleted file mode 100755 index 7ab9b1146..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/gift_orange.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/gift_pink.png b/TMessagesProj/src/main/res/drawable-xhdpi/gift_pink.png deleted file mode 100755 index fe89dcd6a..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/gift_pink.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/gift_red.png b/TMessagesProj/src/main/res/drawable-xhdpi/gift_red.png deleted file mode 100755 index b4d3ad36e..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/gift_red.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/gift_violet.png b/TMessagesProj/src/main/res/drawable-xhdpi/gift_violet.png deleted file mode 100755 index e18de6ae5..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/gift_violet.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/gift_yellow.png b/TMessagesProj/src/main/res/drawable-xhdpi/gift_yellow.png deleted file mode 100755 index 9eb372807..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/gift_yellow.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/intro1.png b/TMessagesProj/src/main/res/drawable-xhdpi/intro1.png index 24b4c74fc..639e7d834 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/intro1.png and b/TMessagesProj/src/main/res/drawable-xhdpi/intro1.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/playback.png b/TMessagesProj/src/main/res/drawable-xhdpi/playback.png deleted file mode 100644 index 8393b7406..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/playback.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/playback_active.png b/TMessagesProj/src/main/res/drawable-xhdpi/playback_active.png deleted file mode 100644 index 48c99fb9d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/playback_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame0.png b/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame0.png deleted file mode 100755 index d4c5524e7..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame0.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame1.png b/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame1.png deleted file mode 100755 index 8ec3841da..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame1.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame2.png b/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame2.png deleted file mode 100755 index cc0151bac..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame2.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame3.png b/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame3.png deleted file mode 100755 index 0d8b81613..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_chat_frame3.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame0.png b/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame0.png deleted file mode 100755 index 8aa8e1798..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame0.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame1.png b/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame1.png deleted file mode 100755 index 8d2d0360a..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame1.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame2.png b/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame2.png deleted file mode 100755 index 5a456eb5b..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame2.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame3.png b/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame3.png deleted file mode 100755 index 7fdce1db7..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/typing_dot_frame3.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/videolapse.png b/TMessagesProj/src/main/res/drawable-xhdpi/videolapse.png new file mode 100755 index 000000000..6347d2bae Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/videolapse.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/videotrimmer.png b/TMessagesProj/src/main/res/drawable-xhdpi/videotrimmer.png new file mode 100755 index 000000000..5c8753f2e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/videotrimmer.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/boxshadow.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/boxshadow.9.png new file mode 100644 index 000000000..25232d9c3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/boxshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_aqua.png b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_aqua.png new file mode 100755 index 000000000..6d3d49d99 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_aqua.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_blue.png b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_blue.png new file mode 100755 index 000000000..a0b79c115 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_blue.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_green.png b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_green.png new file mode 100755 index 000000000..21cd9614f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_green.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_orange.png b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_orange.png new file mode 100755 index 000000000..1ed205ff8 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_orange.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_pink.png b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_pink.png new file mode 100755 index 000000000..0b65cfd00 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_pink.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_red.png b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_red.png new file mode 100755 index 000000000..37404ef89 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_red.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_violet.png b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_violet.png new file mode 100755 index 000000000..a6a22b4a0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_violet.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_yellow.png b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_yellow.png new file mode 100755 index 000000000..df5340e4b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/broadcast_yellow.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/btnshadow.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/btnshadow.9.png new file mode 100644 index 000000000..f74d3632c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/btnshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/cats.jpg b/TMessagesProj/src/main/res/drawable-xxhdpi/cats.jpg new file mode 100644 index 000000000..834e6ddf6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/cats.jpg differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_aqua.png b/TMessagesProj/src/main/res/drawable-xxhdpi/gift_aqua.png deleted file mode 100755 index cb5db7ce8..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_aqua.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_blue.png b/TMessagesProj/src/main/res/drawable-xxhdpi/gift_blue.png deleted file mode 100755 index 63645824b..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_blue.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_green.png b/TMessagesProj/src/main/res/drawable-xxhdpi/gift_green.png deleted file mode 100755 index e8b72c4c5..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_green.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_orange.png b/TMessagesProj/src/main/res/drawable-xxhdpi/gift_orange.png deleted file mode 100755 index 5e508a296..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_orange.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_pink.png b/TMessagesProj/src/main/res/drawable-xxhdpi/gift_pink.png deleted file mode 100755 index d6eadc83a..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_pink.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_red.png b/TMessagesProj/src/main/res/drawable-xxhdpi/gift_red.png deleted file mode 100755 index 77c96c8dc..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_red.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_violet.png b/TMessagesProj/src/main/res/drawable-xxhdpi/gift_violet.png deleted file mode 100755 index 94f5eb1a3..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_violet.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_yellow.png b/TMessagesProj/src/main/res/drawable-xxhdpi/gift_yellow.png deleted file mode 100755 index a20610574..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/gift_yellow.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/intro1.png b/TMessagesProj/src/main/res/drawable-xxhdpi/intro1.png index 6383edf74..ca6c90bbd 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/intro1.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/intro1.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/playback.png b/TMessagesProj/src/main/res/drawable-xxhdpi/playback.png deleted file mode 100644 index 517920f78..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/playback.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/playback_active.png b/TMessagesProj/src/main/res/drawable-xxhdpi/playback_active.png deleted file mode 100644 index 4ed866438..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/playback_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame0.png b/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame0.png deleted file mode 100755 index c2a610a13..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame0.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame1.png b/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame1.png deleted file mode 100755 index efe53d373..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame1.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame2.png b/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame2.png deleted file mode 100755 index 2c4fb310e..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame2.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame3.png b/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame3.png deleted file mode 100755 index a4bb53683..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_chat_frame3.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame0.png b/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame0.png deleted file mode 100755 index 48a42a553..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame0.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame1.png b/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame1.png deleted file mode 100755 index bc8179a3e..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame1.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame2.png b/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame2.png deleted file mode 100755 index 226a7ae84..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame2.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame3.png b/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame3.png deleted file mode 100755 index db9b4597e..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/typing_dot_frame3.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/videolapse.png b/TMessagesProj/src/main/res/drawable-xxhdpi/videolapse.png new file mode 100755 index 000000000..059016c44 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/videolapse.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/videotrimmer.png b/TMessagesProj/src/main/res/drawable-xxhdpi/videotrimmer.png new file mode 100755 index 000000000..f880b9d38 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/videotrimmer.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxxhdpi/ic_launcher.png b/TMessagesProj/src/main/res/drawable-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..3d97d66d1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxxhdpi/ic_launcher.png differ diff --git a/TMessagesProj/src/main/res/drawable/bar_selector.xml b/TMessagesProj/src/main/res/drawable/bar_selector.xml index 236178c0e..961d245f2 100644 --- a/TMessagesProj/src/main/res/drawable/bar_selector.xml +++ b/TMessagesProj/src/main/res/drawable/bar_selector.xml @@ -2,17 +2,17 @@ xmlns:android="http://schemas.android.com/apk/res/android"> - + - + - + diff --git a/TMessagesProj/src/main/res/drawable/bar_selector_mode.xml b/TMessagesProj/src/main/res/drawable/bar_selector_mode.xml new file mode 100644 index 000000000..f3319e321 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable/bar_selector_mode.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable/launch_button_states.xml b/TMessagesProj/src/main/res/drawable/launch_button_states.xml new file mode 100644 index 000000000..b9581e53c --- /dev/null +++ b/TMessagesProj/src/main/res/drawable/launch_button_states.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable/loading_header_animation.xml b/TMessagesProj/src/main/res/drawable/loading_header_animation.xml deleted file mode 100644 index 801fe84a0..000000000 --- a/TMessagesProj/src/main/res/drawable/loading_header_animation.xml +++ /dev/null @@ -1,6 +0,0 @@ - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable/messages_list_divider2.xml b/TMessagesProj/src/main/res/drawable/messages_list_divider2.xml new file mode 100644 index 000000000..42b348a2c --- /dev/null +++ b/TMessagesProj/src/main/res/drawable/messages_list_divider2.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable/typing_dots.xml b/TMessagesProj/src/main/res/drawable/typing_dots.xml deleted file mode 100644 index fb3154cb3..000000000 --- a/TMessagesProj/src/main/res/drawable/typing_dots.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable/typing_dots_chat.xml b/TMessagesProj/src/main/res/drawable/typing_dots_chat.xml deleted file mode 100644 index 702e218b7..000000000 --- a/TMessagesProj/src/main/res/drawable/typing_dots_chat.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/intro_layout_tablet.xml b/TMessagesProj/src/main/res/layout/intro_layout_tablet.xml new file mode 100644 index 000000000..d5aa085c6 --- /dev/null +++ b/TMessagesProj/src/main/res/layout/intro_layout_tablet.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/launch_layout_tablet.xml b/TMessagesProj/src/main/res/layout/launch_layout_tablet.xml new file mode 100644 index 000000000..47c514403 --- /dev/null +++ b/TMessagesProj/src/main/res/layout/launch_layout_tablet.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/updating_state_layout.xml b/TMessagesProj/src/main/res/layout/updating_state_layout.xml index b00a8df1c..9157620e5 100644 --- a/TMessagesProj/src/main/res/layout/updating_state_layout.xml +++ b/TMessagesProj/src/main/res/layout/updating_state_layout.xml @@ -6,17 +6,6 @@ android:id="@+id/back_button_background" android:layout_gravity="top"> - - - + + + + + android:layout_marginLeft="8dp" + android:layout_marginRight="8dp"/> + + - + android:background="#ff2d2d2d" + android:layout_marginLeft="16dp" + android:layout_marginRight="16dp" + android:layout_marginBottom="16dp" + android:id="@+id/info_container" + android:orientation="vertical"> - + + + - +