1
0
mirror of https://github.com/MGislv/NekoX.git synced 2024-06-30 10:14:04 +00:00

Merge official v8.5.0

This commit is contained in:
luvletter2333 2022-02-03 23:02:55 +08:00
commit d54dd02b59
139 changed files with 5270 additions and 2454 deletions

View File

@ -12,6 +12,7 @@ ${CMAKE_HOME_DIRECTORY}/ffmpeg/build/${ANDROID_ABI}/lib/libavcodec.a,
${CMAKE_HOME_DIRECTORY}/ffmpeg/build/${ANDROID_ABI}/lib/libavresample.a,
${CMAKE_HOME_DIRECTORY}/ffmpeg/build/${ANDROID_ABI}/lib/libavutil.a,
${CMAKE_HOME_DIRECTORY}/ffmpeg/build/${ANDROID_ABI}/lib/libswresample.a,
${CMAKE_HOME_DIRECTORY}/ffmpeg/${ANDROID_ABI}/libvpx.a,
${CMAKE_HOME_DIRECTORY}/boringssl/build/${ANDROID_ABI}/ssl/libssl.a,
${CMAKE_HOME_DIRECTORY}/boringssl/build/${ANDROID_ABI}/crypto/libcrypto.a")
@ -58,6 +59,10 @@ set_target_properties(crypto PROPERTIES IMPORTED_LOCATION ${CMAKE_HOME_DIRECTORY
add_library(ssl STATIC IMPORTED)
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION ${CMAKE_HOME_DIRECTORY}/boringssl/build/${ANDROID_ABI}/ssl/libssl.a)
add_library(libvpx STATIC IMPORTED)
set_target_properties(libvpx PROPERTIES IMPORTED_LOCATION ${CMAKE_HOME_DIRECTORY}/ffmpeg/${ANDROID_ABI}/libvpx.a)
#tgnet
add_library(mozjpeg STATIC
mozjpeg/cjpeg.c mozjpeg/cdjpeg.c mozjpeg/rdgif.c mozjpeg/rdppm.c mozjpeg/rdjpeg.c mozjpeg/rdswitch.c mozjpeg/rdbmp.c
@ -461,7 +466,7 @@ target_compile_definitions(sqlite PUBLIC
#voip
include(${CMAKE_HOME_DIRECTORY}/voip/CMakeLists.txt)
set(NATIVE_LIB "tmessages.40")
set(NATIVE_LIB "tmessages.41")
#tmessages
add_library(${NATIVE_LIB} SHARED
@ -747,6 +752,7 @@ target_link_libraries(${NATIVE_LIB}
avcodec
avresample
swresample
libvpx
avutil
ssl
crypto
@ -759,11 +765,6 @@ target_link_libraries(${NATIVE_LIB}
OpenSLES
cpufeatures)
if (${ANDROID_ABI} STREQUAL "x86" OR ${ANDROID_ABI} STREQUAL "x86_64")
target_link_libraries(${NATIVE_LIB}
libvpx_yasm -Wl,--no-whole-archive)
endif ()
#if (${ANDROID_ABI} STREQUAL "x86" OR ${ANDROID_ABI} STREQUAL "x86_64")
# target_link_libraries(${NATIVE_LIB}
# -Wl,--whole-archive vpxasm -Wl,--no-whole-archive

View File

@ -1,186 +0,0 @@
#!/bin/bash
function build_one {
echo "Cleaning..."
rm config.h
make clean
echo "Configuring..."
./configure \
--cc=$CC \
--nm=$NM \
--enable-stripping \
--arch=$ARCH \
--target-os=linux \
--enable-cross-compile \
--x86asmexe=$NDK/prebuilt/$BUILD_PLATFORM/bin/yasm \
--prefix=$PREFIX \
--enable-pic \
--disable-shared \
--enable-static \
--enable-asm \
--enable-inline-asm \
--cross-prefix=$CROSS_PREFIX \
--sysroot=$PLATFORM \
--extra-cflags="-Wl,-Bsymbolic -Os -DCONFIG_LINUX_PERF=0 -DANDROID $OPTIMIZE_CFLAGS -fPIE -pie --static -fPIC" \
--extra-ldflags="-Wl,-Bsymbolic -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -fPIC" \
--extra-libs="-lgcc" \
\
--enable-version3 \
--enable-gpl \
\
--disable-linux-perf \
\
--disable-doc \
--disable-htmlpages \
--disable-avx \
\
--disable-everything \
--disable-network \
--disable-zlib \
--disable-avfilter \
--disable-avdevice \
--disable-postproc \
--disable-debug \
--disable-programs \
--disable-network \
--disable-ffplay \
--disable-ffprobe \
--disable-postproc \
--disable-avdevice \
\
--enable-runtime-cpudetect \
--enable-pthreads \
--enable-avresample \
--enable-swscale \
--enable-protocol=file \
--enable-decoder=h264 \
--enable-decoder=mpeg4 \
--enable-decoder=mjpeg \
--enable-decoder=gif \
--enable-decoder=alac \
--enable-demuxer=mov \
--enable-demuxer=gif \
--enable-demuxer=ogg \
--enable-hwaccels \
--enable-runtime-cpudetect \
$ADDITIONAL_CONFIGURE_FLAG
#echo "continue?"
#read
make -j$COMPILATION_PROC_COUNT
make install
}
function setCurrentPlatform {
PLATFORM="$(uname -s)"
case "${PLATFORM}" in
Darwin*)
BUILD_PLATFORM=darwin-x86_64
COMPILATION_PROC_COUNT=`sysctl -n hw.physicalcpu`
;;
Linux*)
BUILD_PLATFORM=linux-x86_64
COMPILATION_PROC_COUNT=$(nproc)
;;
*)
echo -e "\033[33mWarning! Unknown platform ${PLATFORM}! falling back to linux-x86_64\033[0m"
BUILD_PLATFORM=linux-x86_64
COMPILATION_PROC_COUNT=1
;;
esac
echo "build platform: ${BUILD_PLATFORM}"
echo "parallel jobs: ${COMPILATION_PROC_COUNT}"
}
function checkPreRequisites {
if ! [ -d "ffmpeg" ] || ! [ "$(ls -A ffmpeg)" ]; then
echo -e "\033[31mFailed! Submodule 'ffmpeg' not found!\033[0m"
echo -e "\033[31mTry to run: 'git submodule init && git submodule update'\033[0m"
exit
fi
if [ -z "$NDK" -a "$NDK" == "" ]; then
echo -e "\033[31mFailed! NDK is empty. Run 'export NDK=[PATH_TO_NDK]'\033[0m"
exit
fi
}
setCurrentPlatform
checkPreRequisites
# TODO: fix env variable for NDK
# NDK=/opt/android-sdk/ndk-bundle
cd ffmpeg
#x86_64
PREBUILT=$NDK/toolchains/x86_64-4.9/prebuilt/$BUILD_PLATFORM
PLATFORM=$NDK/platforms/android-21/arch-x86_64
LD=$PREBUILT/bin/x86_64-linux-android-ld
AR=$PREBUILT/bin/x86_64-linux-android-ar
NM=$PREBUILT/bin/x86_64-linux-android-nm
GCCLIB=$PREBUILT/lib/gcc/x86_64-linux-android/4.9.x/libgcc.a
CC=$PREBUILT/bin/x86_64-linux-android-gcc
CROSS_PREFIX=$PREBUILT/bin/x86_64-linux-android-
ARCH=x86_64
CPU=x86_64
PREFIX=./build/$CPU
ADDITIONAL_CONFIGURE_FLAG="--disable-mmx --disable-inline-asm"
#build_one
#arm64-v8a
PREBUILT=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/$BUILD_PLATFORM
PLATFORM=$NDK/platforms/android-21/arch-arm64
LD=$PREBUILT/bin/aarch64-linux-android-ld
AR=$PREBUILT/bin/aarch64-linux-android-ar
NM=$PREBUILT/bin/aarch64-linux-android-nm
GCCLIB=$PREBUILT/lib/gcc/aarch64-linux-android/4.9.x/libgcc.a
CC=$PREBUILT/bin/aarch64-linux-android-gcc
CROSS_PREFIX=$PREBUILT/bin/aarch64-linux-android-
ARCH=arm64
CPU=arm64-v8a
OPTIMIZE_CFLAGS=
PREFIX=./build/$CPU
ADDITIONAL_CONFIGURE_FLAG="--enable-neon --enable-optimizations"
build_one
#arm v7n
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/$BUILD_PLATFORM
PLATFORM=$NDK/platforms/android-16/arch-arm
LD=$PREBUILT/bin/arm-linux-androideabi-ld
AR=$PREBUILT/bin/arm-linux-androideabi-ar
NM=$PREBUILT/bin/arm-linux-androideabi-nm
GCCLIB=$PREBUILT/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
CC=$PREBUILT/bin/arm-linux-androideabi-gcc
CROSS_PREFIX=$PREBUILT/bin/arm-linux-androideabi-
ARCH=arm
CPU=armv7-a
OPTIMIZE_CFLAGS="-marm -march=$CPU"
PREFIX=./build/$CPU
ADDITIONAL_CONFIGURE_FLAG=--enable-neon
build_one
#x86 platform
PREBUILT=$NDK/toolchains/x86-4.9/prebuilt/$BUILD_PLATFORM
PLATFORM=$NDK/platforms/android-16/arch-x86
LD=$PREBUILT/bin/i686-linux-android-ld
AR=$PREBUILT/bin/i686-linux-android-ar
NM=$PREBUILT/bin/i686-linux-android-nm
GCCLIB=$PREBUILT/lib/gcc/i686-linux-android/4.9.x/libgcc.a
CC=$PREBUILT/bin/i686-linux-android-gcc
CROSS_PREFIX=$PREBUILT/bin/i686-linux-android-
ARCH=x86
CPU=i686
OPTIMIZE_CFLAGS="-march=$CPU"
PREFIX=./build/$CPU
ADDITIONAL_CONFIGURE_FLAG="--disable-mmx --disable-yasm"
build_one

View File

@ -19,18 +19,20 @@ extern "C" {
#include <libavformat/isom.h>
#include <libavcodec/bytestream.h>
#include <libavcodec/get_bits.h>
#include <libavcodec/golomb.h>
#include <libavcodec/golomb.h>
#include <libavutil/eval.h>
#include <libavutil/intmath.h>
#include <libswscale/swscale.h>
}
#define RGB8888_A(p) ((p & (0xff<<24)) >> 24 )
static const std::string av_make_error_str(int errnum) {
char errbuf[AV_ERROR_MAX_STRING_SIZE];
av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
return (std::string) errbuf;
}
#undef av_err2str
#define av_err2str(errnum) av_make_error_str(errnum).c_str()
#define FFMPEG_AVSEEK_SIZE 0x10000
@ -89,7 +91,7 @@ void ff_h2645_packet_uninit(H2645Packet *pkt) {
}
typedef struct VideoInfo {
~VideoInfo() {
if (video_dec_ctx) {
avcodec_close(video_dec_ctx);
@ -194,6 +196,18 @@ void custom_log(void *ptr, int level, const char* fmt, va_list vl){
LOGE(line);
}
static enum AVPixelFormat get_format(AVCodecContext *ctx,
const enum AVPixelFormat *pix_fmts)
{
const enum AVPixelFormat *p;
for (p = pix_fmts; *p != -1; p++) {
LOGE("available format %d", p);
}
return pix_fmts[0];
}
int open_codec_context(int *stream_idx, AVCodecContext **dec_ctx, AVFormatContext *fmt_ctx, enum AVMediaType type) {
int ret, stream_index;
AVStream *st;
@ -683,7 +697,7 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, int &width, int &height)
}
return mb_width != width || mb_height != height;
}
int decode_packet(VideoInfo *info, int *got_frame) {
int ret = 0;
int decoded = info->pkt.size;
@ -709,7 +723,7 @@ int decode_packet(VideoInfo *info, int *got_frame) {
}
}
}
return decoded;
}
@ -922,7 +936,7 @@ extern "C" JNIEXPORT void JNICALL Java_org_telegram_ui_Components_AnimatedFileDr
extern "C" JNIEXPORT jlong JNICALL Java_org_telegram_ui_Components_AnimatedFileDrawable_createDecoder(JNIEnv *env, jclass clazz, jstring src, jintArray data, jint account, jlong streamFileSize, jobject stream, jboolean preview) {
VideoInfo *info = new VideoInfo();
char const *srcString = env->GetStringUTFChars(src, 0);
size_t len = strlen(srcString);
info->src = new char[len + 1];
@ -969,13 +983,13 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_telegram_ui_Components_AnimatedFileD
return 0;
}
}
if ((ret = avformat_find_stream_info(info->fmt_ctx, NULL)) < 0) {
LOGE("can't find stream information %s, %s", info->src, av_err2str(ret));
delete info;
return 0;
}
if (open_codec_context(&info->video_stream_idx, &info->video_dec_ctx, info->fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
info->video_stream = info->fmt_ctx->streams[info->video_stream_idx];
}
@ -985,14 +999,14 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_telegram_ui_Components_AnimatedFileD
delete info;
return 0;
}
info->frame = av_frame_alloc();
if (info->frame == nullptr) {
LOGE("can't allocate frame %s", info->src);
delete info;
return 0;
}
av_init_packet(&info->pkt);
info->pkt.data = NULL;
info->pkt.size = 0;
@ -1016,9 +1030,9 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_telegram_ui_Components_AnimatedFileD
//(int32_t) (1000 * info->video_stream->duration * av_q2d(info->video_stream->time_base));
env->ReleaseIntArrayElements(data, dataArr, 0);
}
//LOGD("successfully opened file %s", info->src);
return (jlong) (intptr_t) info;
}
@ -1167,7 +1181,9 @@ static inline void writeFrameToBitmap(JNIEnv *env, VideoInfo *info, jintArray da
}
}
if (info->sws_ctx == nullptr || ((intptr_t) pixels) % 16 != 0) {
if (info->frame->format == AV_PIX_FMT_YUV444P) {
if (info->frame->format == AV_PIX_FMT_YUVA420P) {
libyuv::I420AlphaToARGBMatrix(info->frame->data[0], info->frame->linesize[0], info->frame->data[2], info->frame->linesize[2], info->frame->data[1], info->frame->linesize[1], info->frame->data[3], info->frame->linesize[3], (uint8_t *) pixels, bitmapWidth * 4, &libyuv::kYvuI601Constants, bitmapWidth, bitmapHeight, 50);
} else if (info->frame->format == AV_PIX_FMT_YUV444P) {
libyuv::H444ToARGB(info->frame->data[0], info->frame->linesize[0], info->frame->data[2], info->frame->linesize[2], info->frame->data[1], info->frame->linesize[1], (uint8_t *) pixels, bitmapWidth * 4, bitmapWidth, bitmapHeight);
} else if (info->frame->format == AV_PIX_FMT_YUV420P || info->frame->format == AV_PIX_FMT_YUVJ420P) {
if (info->frame->colorspace == AVColorSpace::AVCOL_SPC_BT709) {
@ -1182,7 +1198,19 @@ static inline void writeFrameToBitmap(JNIEnv *env, VideoInfo *info, jintArray da
uint8_t __attribute__ ((aligned (16))) *dst_data[1];
dst_data[0] = (uint8_t *) pixels;
info->dst_linesize[0] = stride;
sws_scale(info->sws_ctx, info->frame->data, info->frame->linesize, 0, info->frame->height, dst_data, info->dst_linesize);
sws_scale(info->sws_ctx, info->frame->data, info->frame->linesize, 0,
info->frame->height, dst_data, info->dst_linesize);
if (info->frame->format == AV_PIX_FMT_YUVA420P) {
auto pixelArr = ((uint32_t *) pixels);
for (int i = 0; i < bitmapWidth; i++) {
for (int j = 0; j < bitmapHeight; j++) {
int a = RGB8888_A(pixelArr[j * bitmapWidth + i]);
if (a < 125) {
pixelArr[j * bitmapWidth + i] = 0;
}
}
}
}
}
}
AndroidBitmap_unlockPixels(env, bitmap);
@ -1338,7 +1366,7 @@ extern "C" JNIEXPORT jint JNICALL Java_org_telegram_ui_Components_AnimatedFileDr
}
if (got_frame) {
//LOGD("decoded frame with w = %d, h = %d, format = %d", info->frame->width, info->frame->height, info->frame->format);
if (info->frame->format == AV_PIX_FMT_YUV420P || info->frame->format == AV_PIX_FMT_BGRA || info->frame->format == AV_PIX_FMT_YUVJ420P || info->frame->format == AV_PIX_FMT_YUV444P) {
if (info->frame->format == AV_PIX_FMT_YUV420P || info->frame->format == AV_PIX_FMT_BGRA || info->frame->format == AV_PIX_FMT_YUVJ420P || info->frame->format == AV_PIX_FMT_YUV444P || info->frame->format == AV_PIX_FMT_YUVA420P) {
writeFrameToBitmap(env, info, data, bitmap, stride);
}
info->has_decoded_frames = true;

View File

@ -1,10 +1,5 @@
cmake_minimum_required(VERSION 3.6.0)
#libvpx_yasm
if (${ANDROID_ABI} STREQUAL "x86" OR ${ANDROID_ABI} STREQUAL "x86_64")
add_library(libvpx_yasm STATIC IMPORTED)
set_target_properties(libvpx_yasm PROPERTIES IMPORTED_LOCATION ${CMAKE_HOME_DIRECTORY}/third_party/libvpx/source/libvpx/vpx_dsp/x86/libvpx_${ANDROID_ABI}_yasm.a)
endif()
#tgvoip
add_library(tgvoip STATIC
@ -253,193 +248,6 @@ add_library(tgcalls_tp STATIC
third_party/rnnoise/src/rnn_vad_weights.cc
third_party/pffft/src/fftpack.c
third_party/pffft/src/pffft.c
third_party/libvpx/source/libvpx/args.c
third_party/libvpx/source/libvpx/ivfdec.c
third_party/libvpx/source/libvpx/ivfenc.c
third_party/libvpx/source/libvpx/md5_utils.c
third_party/libvpx/source/libvpx/rate_hist.c
third_party/libvpx/source/libvpx/tools_common.c
third_party/libvpx/source/libvpx/video_reader.c
third_party/libvpx/source/libvpx/video_writer.c
third_party/libvpx/source/libvpx/vp8/common/alloccommon.c
third_party/libvpx/source/libvpx/vp8/common/blockd.c
third_party/libvpx/source/libvpx/vp8/common/context.c
third_party/libvpx/source/libvpx/vp8/common/debugmodes.c
third_party/libvpx/source/libvpx/vp8/common/dequantize.c
third_party/libvpx/source/libvpx/vp8/common/entropy.c
third_party/libvpx/source/libvpx/vp8/common/entropymode.c
third_party/libvpx/source/libvpx/vp8/common/entropymv.c
third_party/libvpx/source/libvpx/vp8/common/extend.c
third_party/libvpx/source/libvpx/vp8/common/filter.c
third_party/libvpx/source/libvpx/vp8/common/findnearmv.c
third_party/libvpx/source/libvpx/vp8/common/generic/systemdependent.c
third_party/libvpx/source/libvpx/vp8/common/idct_blk.c
third_party/libvpx/source/libvpx/vp8/common/idctllm.c
third_party/libvpx/source/libvpx/vp8/common/loopfilter_filters.c
third_party/libvpx/source/libvpx/vp8/common/mbpitch.c
third_party/libvpx/source/libvpx/vp8/common/mfqe.c
third_party/libvpx/source/libvpx/vp8/common/modecont.c
third_party/libvpx/source/libvpx/vp8/common/postproc.c
third_party/libvpx/source/libvpx/vp8/common/quant_common.c
third_party/libvpx/source/libvpx/vp8/common/reconinter.c
third_party/libvpx/source/libvpx/vp8/common/reconintra.c
third_party/libvpx/source/libvpx/vp8/common/reconintra4x4.c
third_party/libvpx/source/libvpx/vp8/common/rtcd.c
third_party/libvpx/source/libvpx/vp8/common/setupintrarecon.c
third_party/libvpx/source/libvpx/vp8/common/swapyv12buffer.c
third_party/libvpx/source/libvpx/vp8/common/treecoder.c
third_party/libvpx/source/libvpx/vp8/common/vp8_loopfilter.c
third_party/libvpx/source/libvpx/vp8/common/vp8_skin_detection.c
third_party/libvpx/source/libvpx/vp8/decoder/dboolhuff.c
third_party/libvpx/source/libvpx/vp8/decoder/decodeframe.c
third_party/libvpx/source/libvpx/vp8/decoder/decodemv.c
third_party/libvpx/source/libvpx/vp8/decoder/detokenize.c
third_party/libvpx/source/libvpx/vp8/decoder/onyxd_if.c
third_party/libvpx/source/libvpx/vp8/decoder/threading.c
third_party/libvpx/source/libvpx/vp8/encoder/bitstream.c
third_party/libvpx/source/libvpx/vp8/encoder/boolhuff.c
third_party/libvpx/source/libvpx/vp8/encoder/copy_c.c
third_party/libvpx/source/libvpx/vp8/encoder/dct.c
third_party/libvpx/source/libvpx/vp8/encoder/denoising.c
third_party/libvpx/source/libvpx/vp8/encoder/encodeframe.c
third_party/libvpx/source/libvpx/vp8/encoder/encodeintra.c
third_party/libvpx/source/libvpx/vp8/encoder/encodemb.c
third_party/libvpx/source/libvpx/vp8/encoder/encodemv.c
third_party/libvpx/source/libvpx/vp8/encoder/ethreading.c
third_party/libvpx/source/libvpx/vp8/encoder/firstpass.c
third_party/libvpx/source/libvpx/vp8/encoder/lookahead.c
third_party/libvpx/source/libvpx/vp8/encoder/mcomp.c
third_party/libvpx/source/libvpx/vp8/encoder/modecosts.c
third_party/libvpx/source/libvpx/vp8/encoder/mr_dissim.c
third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c
third_party/libvpx/source/libvpx/vp8/encoder/pickinter.c
third_party/libvpx/source/libvpx/vp8/encoder/picklpf.c
third_party/libvpx/source/libvpx/vp8/encoder/ratectrl.c
third_party/libvpx/source/libvpx/vp8/encoder/rdopt.c
third_party/libvpx/source/libvpx/vp8/encoder/segmentation.c
third_party/libvpx/source/libvpx/vp8/encoder/temporal_filter.c
third_party/libvpx/source/libvpx/vp8/encoder/tokenize.c
third_party/libvpx/source/libvpx/vp8/encoder/treewriter.c
third_party/libvpx/source/libvpx/vp8/encoder/vp8_quantize.c
third_party/libvpx/source/libvpx/vp8/vp8_cx_iface.c
third_party/libvpx/source/libvpx/vp8/vp8_dx_iface.c
third_party/libvpx/source/libvpx/vp9/common/vp9_alloccommon.c
third_party/libvpx/source/libvpx/vp9/common/vp9_blockd.c
third_party/libvpx/source/libvpx/vp9/common/vp9_common_data.c
third_party/libvpx/source/libvpx/vp9/common/vp9_debugmodes.c
third_party/libvpx/source/libvpx/vp9/common/vp9_entropy.c
third_party/libvpx/source/libvpx/vp9/common/vp9_entropymode.c
third_party/libvpx/source/libvpx/vp9/common/vp9_entropymv.c
third_party/libvpx/source/libvpx/vp9/common/vp9_filter.c
third_party/libvpx/source/libvpx/vp9/common/vp9_frame_buffers.c
third_party/libvpx/source/libvpx/vp9/common/vp9_idct.c
third_party/libvpx/source/libvpx/vp9/common/vp9_loopfilter.c
third_party/libvpx/source/libvpx/vp9/common/vp9_mfqe.c
third_party/libvpx/source/libvpx/vp9/common/vp9_mvref_common.c
third_party/libvpx/source/libvpx/vp9/common/vp9_postproc.c
third_party/libvpx/source/libvpx/vp9/common/vp9_pred_common.c
third_party/libvpx/source/libvpx/vp9/common/vp9_quant_common.c
third_party/libvpx/source/libvpx/vp9/common/vp9_reconinter.c
third_party/libvpx/source/libvpx/vp9/common/vp9_reconintra.c
third_party/libvpx/source/libvpx/vp9/common/vp9_rtcd.c
third_party/libvpx/source/libvpx/vp9/common/vp9_scale.c
third_party/libvpx/source/libvpx/vp9/common/vp9_scan.c
third_party/libvpx/source/libvpx/vp9/common/vp9_seg_common.c
third_party/libvpx/source/libvpx/vp9/common/vp9_thread_common.c
third_party/libvpx/source/libvpx/vp9/common/vp9_tile_common.c
third_party/libvpx/source/libvpx/vp9/decoder/vp9_decodeframe.c
third_party/libvpx/source/libvpx/vp9/decoder/vp9_decodemv.c
third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c
third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.c
third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c
third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_360.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_complexity.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_variance.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_bitstream.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_blockiness.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_context_tree.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_cost.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_dct.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_denoiser.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodemb.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodemv.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_ethread.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_extend.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_frame_scale.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_lookahead.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_mbgraph.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_mcomp.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_multi_thread.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_noise_estimate.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_non_greedy_mv.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_picklpf.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_pickmode.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_quantize.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_rd.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_resize.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_segmentation.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_skin_detection.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_speed_features.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_subexp.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_temporal_filter.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_tokenize.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_treewriter.c
third_party/libvpx/source/libvpx/vp9/encoder/vp9_ext_ratectrl.c
third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.cc
third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c
third_party/libvpx/source/libvpx/vp9/vp9_dx_iface.c
third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c
third_party/libvpx/source/libvpx/vpx/src/vpx_codec.c
third_party/libvpx/source/libvpx/vpx/src/vpx_decoder.c
third_party/libvpx/source/libvpx/vpx/src/vpx_encoder.c
third_party/libvpx/source/libvpx/vpx/src/vpx_image.c
third_party/libvpx/source/libvpx/vpx_dsp/add_noise.c
third_party/libvpx/source/libvpx/vpx_dsp/avg.c
third_party/libvpx/source/libvpx/vpx_dsp/bitreader.c
third_party/libvpx/source/libvpx/vpx_dsp/bitreader_buffer.c
third_party/libvpx/source/libvpx/vpx_dsp/bitwriter.c
third_party/libvpx/source/libvpx/vpx_dsp/bitwriter_buffer.c
third_party/libvpx/source/libvpx/vpx_dsp/deblock.c
third_party/libvpx/source/libvpx/vpx_dsp/fastssim.c
third_party/libvpx/source/libvpx/vpx_dsp/fwd_txfm.c
third_party/libvpx/source/libvpx/vpx_dsp/intrapred.c
third_party/libvpx/source/libvpx/vpx_dsp/inv_txfm.c
third_party/libvpx/source/libvpx/vpx_dsp/loopfilter.c
third_party/libvpx/source/libvpx/vpx_dsp/prob.c
third_party/libvpx/source/libvpx/vpx_dsp/psnr.c
third_party/libvpx/source/libvpx/vpx_dsp/psnrhvs.c
third_party/libvpx/source/libvpx/vpx_dsp/quantize.c
third_party/libvpx/source/libvpx/vpx_dsp/sad.c
third_party/libvpx/source/libvpx/vpx_dsp/skin_detection.c
third_party/libvpx/source/libvpx/vpx_dsp/ssim.c
third_party/libvpx/source/libvpx/vpx_dsp/subtract.c
third_party/libvpx/source/libvpx/vpx_dsp/sum_squares.c
third_party/libvpx/source/libvpx/vpx_dsp/variance.c
third_party/libvpx/source/libvpx/vpx_dsp/vpx_convolve.c
third_party/libvpx/source/libvpx/vpx_dsp/vpx_dsp_rtcd.c
third_party/libvpx/source/libvpx/vpx_mem/vpx_mem.c
third_party/libvpx/source/libvpx/vpx_ports/arm_cpudetect.c
third_party/libvpx/source/libvpx/vpx_scale/generic/gen_scalers.c
third_party/libvpx/source/libvpx/vpx_scale/generic/vpx_scale.c
third_party/libvpx/source/libvpx/vpx_scale/generic/yv12config.c
third_party/libvpx/source/libvpx/vpx_scale/generic/yv12extend.c
third_party/libvpx/source/libvpx/vpx_scale/vpx_scale_rtcd.c
third_party/libvpx/source/libvpx/vpx_util/vpx_debug_util.c
third_party/libvpx/source/libvpx/vpx_util/vpx_thread.c
third_party/libvpx/source/libvpx/vpx_util/vpx_write_yuv_frame.c
third_party/libvpx/source/libvpx/vpxstats.c
third_party/libvpx/source/libvpx/warnings.c
third_party/libvpx/source/libvpx/y4menc.c
third_party/libvpx/source/libvpx/y4minput.c
third_party/libsrtp/crypto/cipher/aes_gcm_ossl.c
third_party/libsrtp/crypto/cipher/aes_icm_ossl.c
third_party/libsrtp/crypto/cipher/cipher.c
@ -617,283 +425,8 @@ target_include_directories(tgcalls_tp PUBLIC
third_party/libsrtp/include
third_party/libsrtp/config
third_party/libsrtp/crypto/include
third_party/libvpx/source/libvpx
third_party/libvpx/source/config
third_party)
if (${ANDROID_ABI} STREQUAL "armeabi-v7a")
target_sources(tgcalls_tp PRIVATE
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct4x4_1_add_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct4x4_add_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/intrapred_neon_asm.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/loopfilter_4_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/loopfilter_8_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/loopfilter_16_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/save_reg_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve_avg_neon_asm.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve_copy_neon_asm.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_avg_horiz_filter_type1_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_avg_horiz_filter_type2_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_avg_vert_filter_type1_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_avg_vert_filter_type2_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_horiz_filter_type1_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_horiz_filter_type2_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_vert_filter_type1_neon.asm.S
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_vert_filter_type2_neon.asm.S)
target_compile_definitions(tgcalls_tp PUBLIC
WEBRTC_ARCH_ARM WEBRTC_ARCH_ARM_V7 WEBRTC_HAS_NEON)
target_include_directories(tgcalls_tp PUBLIC
third_party/libvpx/source/config/linux/arm-neon-cpu-detect)
elseif(${ANDROID_ABI} STREQUAL "arm64-v8a")
target_compile_definitions(tgcalls_tp PUBLIC
WEBRTC_ARCH_ARM64 WEBRTC_HAS_NEON)
target_include_directories(tgcalls_tp PUBLIC
third_party/libvpx/source/config/linux/arm64-highbd)
elseif(${ANDROID_ABI} STREQUAL "x86")
target_sources(tgcalls_tp PRIVATE
third_party/libvpx/source/libvpx/vpx_ports/emms_mmx.c)
target_compile_definitions(tgcalls_tp PUBLIC
HAVE_SSE2)
target_include_directories(tgcalls_tp PUBLIC
third_party/libvpx/source/config/linux/ia32)
elseif(${ANDROID_ABI} STREQUAL "x86_64")
target_compile_definitions(tgcalls_tp PUBLIC
HAVE_SSE2)
target_include_directories(tgcalls_tp PUBLIC
third_party/libvpx/source/config/linux/x64)
endif()
if (${ANDROID_ABI} STREQUAL "armeabi-v7a" OR ${ANDROID_ABI} STREQUAL "arm64-v8a")
target_sources(tgcalls_tp PRIVATE
third_party/libvpx/source/libvpx/vp8/common/arm/loopfilter_arm.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/bilinearpredict_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/copymem_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/dc_only_idct_add_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/dequant_idct_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/dequantizeb_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/idct_blk_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/iwalsh_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/mbloopfilter_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/shortidct4x4llm_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/sixtappredict_neon.c
third_party/libvpx/source/libvpx/vp8/common/arm/neon/vp8_loopfilter_neon.c
third_party/libvpx/source/libvpx/vp8/encoder/arm/neon/denoising_neon.c
third_party/libvpx/source/libvpx/vp8/encoder/arm/neon/fastquantizeb_neon.c
third_party/libvpx/source/libvpx/vp8/encoder/arm/neon/shortfdct_neon.c
third_party/libvpx/source/libvpx/vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.c
third_party/libvpx/source/libvpx/vp9/common/arm/neon/vp9_highbd_iht16x16_add_neon.c
third_party/libvpx/source/libvpx/vp9/common/arm/neon/vp9_highbd_iht4x4_add_neon.c
third_party/libvpx/source/libvpx/vp9/common/arm/neon/vp9_highbd_iht8x8_add_neon.c
third_party/libvpx/source/libvpx/vp9/common/arm/neon/vp9_iht16x16_add_neon.c
third_party/libvpx/source/libvpx/vp9/common/arm/neon/vp9_iht4x4_add_neon.c
third_party/libvpx/source/libvpx/vp9/common/arm/neon/vp9_iht8x8_add_neon.c
third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_denoiser_neon.c
third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_error_neon.c
third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_frame_scale_neon.c
third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_quantize_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/avg_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/avg_pred_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/deblock_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/fdct16x16_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/fdct32x32_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/fdct_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/fdct_partial_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/fwd_txfm_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/hadamard_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_idct16x16_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_idct32x32_1024_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_idct32x32_135_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_idct32x32_34_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_idct32x32_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_idct4x4_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_idct8x8_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_intrapred_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_loopfilter_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_vpx_convolve8_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_vpx_convolve_avg_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_vpx_convolve_copy_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/highbd_vpx_convolve_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct16x16_1_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct16x16_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct32x32_135_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct32x32_1_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct32x32_34_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct32x32_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct4x4_1_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct4x4_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct8x8_1_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/idct8x8_add_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/intrapred_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/loopfilter_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/quantize_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/sad4d_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/sad_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/subpel_variance_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/subtract_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/sum_squares_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/variance_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_neon_asm.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve_avg_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve_copy_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve_neon.c
third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_scaled_convolve8_neon.c)
else()
target_sources(tgcalls_tp PRIVATE
third_party/libvpx/source/libvpx/vp8/encoder/x86/denoising_sse2.c
third_party/libvpx/source/libvpx/vp8/encoder/x86/vp8_enc_stubs_sse2.c
third_party/libvpx/source/libvpx/vp8/encoder/x86/vp8_quantize_sse2.c
third_party/libvpx/source/libvpx/vp8/common/x86/bilinear_filter_sse2.c
third_party/libvpx/source/libvpx/vp8/common/x86/idct_blk_mmx.c
third_party/libvpx/source/libvpx/vp8/common/x86/idct_blk_sse2.c
third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_x86.c
third_party/libvpx/source/libvpx/vp8/common/x86/vp8_asm_stubs.c
third_party/libvpx/source/libvpx/vp9/common/x86/vp9_idct_intrin_sse2.c
third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_dct_intrin_sse2.c
third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_denoiser_sse2.c
third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_highbd_block_error_intrin_sse2.c
third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_quantize_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/avg_intrin_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/avg_pred_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_txfm_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct16x16_add_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct32x32_add_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct4x4_add_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct8x8_add_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_intrapred_intrin_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_loopfilter_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_quantize_intrin_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_variance_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/loopfilter_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/post_proc_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/quantize_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/sum_squares_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/variance_sse2.c
third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_4t_intrin_sse2.c)
endif()
#vpxasm
#if (${ANDROID_ABI} STREQUAL "x86" OR ${ANDROID_ABI} STREQUAL "x86_64")
# if(${ANDROID_ABI} STREQUAL "x86")
# add_library(vpxasm STATIC
# third_party/libvpx/source/libvpx/vpx_ports/emms_mmx.c
# third_party/libvpx/source/libvpx/vp8/common/x86/dequantize_mmx.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_mmx.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/iwalsh_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/mfqe_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/recon_mmx.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/recon_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_mmx.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_ssse3.asm
# third_party/libvpx/source/libvpx/vp8/encoder/x86/block_error_sse2.asm
# third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse2.asm
# third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse3.asm
# third_party/libvpx/source/libvpx/vp8/encoder/x86/dct_sse2.asm
# third_party/libvpx/source/libvpx/vp8/encoder/x86/fwalsh_sse2.asm
# third_party/libvpx/source/libvpx/vp9/common/x86/vp9_mfqe_sse2.asm
# third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_dct_sse2.asm
# third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_error_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/add_noise_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/deblock_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_intrapred_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_sad4d_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_sad_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_subpel_variance_impl_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_variance_impl_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/intrapred_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/intrapred_ssse3.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_wht_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/sad4d_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse3.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse4.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_ssse3.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/subpel_variance_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/subtract_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_convolve_copy_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_8t_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm)
# target_compile_definitions(vpxasm PUBLIC
# HAVE_SSE2)
# target_include_directories(vpxasm PUBLIC
# third_party/libvpx/source/config/linux/ia32)
# set(CMAKE_ASM_NASM_COMPILER_ARG1 "${CMAKE_ASM_NASM_COMPILER_ARG1} -felf32 -m x86 -DABI_IS_32BIT=1 -D__ANDROID__")
# elseif(${ANDROID_ABI} STREQUAL "x86_64")
# add_library(vpxasm STATIC
# third_party/libvpx/source/libvpx/vp8/common/x86/dequantize_mmx.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_mmx.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/iwalsh_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_block_sse2_x86_64.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/mfqe_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/recon_mmx.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/recon_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_mmx.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_sse2.asm
# third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_ssse3.asm
# third_party/libvpx/source/libvpx/vp8/encoder/x86/block_error_sse2.asm
# third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse2.asm
# third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse3.asm
# third_party/libvpx/source/libvpx/vp8/encoder/x86/dct_sse2.asm
# third_party/libvpx/source/libvpx/vp8/encoder/x86/fwalsh_sse2.asm
# third_party/libvpx/source/libvpx/vp9/common/x86/vp9_mfqe_sse2.asm
# third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_dct_sse2.asm
# third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_error_sse2.asm
# third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_quantize_ssse3_x86_64.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/add_noise_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/avg_ssse3_x86_64.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/deblock_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_txfm_ssse3_x86_64.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_intrapred_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_sad4d_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_sad_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_subpel_variance_impl_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_variance_impl_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/intrapred_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/intrapred_ssse3.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_wht_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/sad4d_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse3.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse4.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_ssse3.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/ssim_opt_x86_64.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/subpel_variance_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/subtract_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_convolve_copy_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_8t_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm
# third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm
# third_party/libvpx/source/libvpx/vpx_ports/emms_mmx.asm
# third_party/libvpx/source/libvpx/vpx_ports/float_control_word.asm)
# target_compile_definitions(vpxasm PUBLIC
# HAVE_SSE2)
# target_include_directories(vpxasm PUBLIC
# third_party/libvpx/source/config/linux/x64)
# set(CMAKE_ASM_NASM_COMPILER_ARG1 "${CMAKE_ASM_NASM_COMPILER_ARG1} -DPIC -felf64 -m amd64 -DABI_IS_32BIT=0 -D__ANDROID__")
# endif()
# target_compile_definitions(vpxasm PUBLIC
# __ANDROID__)
# target_include_directories(vpxasm PUBLIC
# third_party/libvpx/source/libvpx
# third_party/libvpx/source/config)
#endif()
#tgcalls+webrtc
add_library(tgcalls STATIC
voip/tgcalls/CodecSelectHelper.cpp
@ -2149,8 +1682,6 @@ target_include_directories(tgcalls PUBLIC
third_party/libsrtp/include
third_party/libsrtp/config
third_party/libsrtp/crypto/include
third_party/libvpx/source/libvpx
third_party/libvpx/source/config
third_party/usrsctplib
third_party
voip/libtgvoip
@ -2162,28 +1693,20 @@ if (${ANDROID_ABI} STREQUAL "armeabi-v7a")
voip/webrtc/common_audio/signal_processing/filter_ar_fast_q12_armv7.S)
target_compile_definitions(tgcalls PUBLIC
WEBRTC_ARCH_ARM WEBRTC_ARCH_ARM_V7 WEBRTC_HAS_NEON)
target_include_directories(tgcalls PUBLIC
third_party/libvpx/source/config/linux/arm-neon-cpu-detect)
elseif(${ANDROID_ABI} STREQUAL "arm64-v8a")
target_sources(tgcalls PRIVATE
voip/webrtc/common_audio/signal_processing/complex_bit_reverse.c
voip/webrtc/common_audio/signal_processing/filter_ar_fast_q12.c)
target_compile_definitions(tgcalls PUBLIC
WEBRTC_ARCH_ARM64 WEBRTC_HAS_NEON)
target_include_directories(tgcalls PUBLIC
third_party/libvpx/source/config/linux/arm64-highbd)
elseif(${ANDROID_ABI} STREQUAL "x86")
target_sources(tgcalls PRIVATE
)
target_compile_definitions(tgcalls PUBLIC
HAVE_SSE2)
target_include_directories(tgcalls PUBLIC
third_party/libvpx/source/config/linux/ia32)
elseif(${ANDROID_ABI} STREQUAL "x86_64")
target_compile_definitions(tgcalls PUBLIC
HAVE_SSE2)
target_include_directories(tgcalls PUBLIC
third_party/libvpx/source/config/linux/x64)
endif()
if (${ANDROID_ABI} STREQUAL "armeabi-v7a" OR ${ANDROID_ABI} STREQUAL "arm64-v8a")
@ -2332,8 +1855,6 @@ target_include_directories(voipandroid PUBLIC
third_party/libsrtp/include
third_party/libsrtp/config
third_party/libsrtp/crypto/include
third_party/libvpx/source/libvpx
third_party/libvpx/source/config
third_party/usrsctplib
third_party
voip/libtgvoip)
@ -2341,21 +1862,13 @@ target_include_directories(voipandroid PUBLIC
if (${ANDROID_ABI} STREQUAL "armeabi-v7a")
target_compile_definitions(voipandroid PUBLIC
WEBRTC_ARCH_ARM WEBRTC_ARCH_ARM_V7 WEBRTC_HAS_NEON)
target_include_directories(voipandroid PUBLIC
third_party/libvpx/source/config/linux/arm-neon-cpu-detect)
elseif(${ANDROID_ABI} STREQUAL "arm64-v8a")
target_compile_definitions(voipandroid PUBLIC
WEBRTC_ARCH_ARM64 WEBRTC_HAS_NEON)
target_include_directories(voipandroid PUBLIC
third_party/libvpx/source/config/linux/arm64-highbd)
elseif(${ANDROID_ABI} STREQUAL "x86")
target_compile_definitions(voipandroid PUBLIC
HAVE_SSE2)
target_include_directories(voipandroid PUBLIC
third_party/libvpx/source/config/linux/ia32)
elseif(${ANDROID_ABI} STREQUAL "x86_64")
target_compile_definitions(voipandroid PUBLIC
HAVE_SSE2)
target_include_directories(voipandroid PUBLIC
third_party/libvpx/source/config/linux/x64)
endif()

View File

@ -370,6 +370,7 @@ void initWebRTC(JNIEnv *env) {
FinalStateInitMethod = env->GetMethodID(FinalStateClass, "<init>", "([BLjava/lang/String;Lorg/telegram/messenger/voip/Instance$TrafficStats;Z)V");
}
extern "C"
JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeGroupNativeInstance(JNIEnv *env, jclass clazz, jobject instanceObj, jstring logFilePath, jboolean highQuality, jlong videoCapturer, jboolean screencast, jboolean noiseSupression, jshort customBitrate) {
initWebRTC(env);
@ -474,6 +475,7 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeGrou
return reinterpret_cast<jlong>(holder);
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setJoinResponsePayload(JNIEnv *env, jobject obj, jstring payload) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance == nullptr) {
@ -483,6 +485,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setJoinRe
instance->groupNativeInstance->setJoinResponsePayload(tgvoip::jni::JavaStringToStdString(env, payload));
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_prepareForStream(JNIEnv *env, jobject obj) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance == nullptr) {
@ -497,6 +500,7 @@ void onEmitJoinPayload(const std::shared_ptr<PlatformContext>& platformContext,
env->CallVoidMethod(globalRef, env->GetMethodID(NativeInstanceClass, "onEmitJoinPayload", "(Ljava/lang/String;I)V"), env->NewStringUTF(payload.json.c_str()), (jint) payload.audioSsrc);
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_resetGroupInstance(JNIEnv *env, jobject obj, jboolean set, jboolean disconnect) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance == nullptr) {
@ -523,6 +527,7 @@ void broadcastRequestedSinks(InstanceHolder *instance) {
instance->groupNativeInstance->setRequestedVideoChannels(std::move(descriptions));
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setNoiseSuppressionEnabled(JNIEnv *env, jobject obj, jboolean enabled) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance == nullptr) {
@ -532,6 +537,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setNoiseS
}
extern "C"
JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_addIncomingVideoOutput(JNIEnv *env, jobject obj, jint quality, jstring endpointId, jobjectArray ssrcGroups, jobject remoteSink) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance == nullptr) {
@ -563,6 +569,7 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_addIncom
return reinterpret_cast<intptr_t>(ptr.get());
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_removeIncomingVideoOutput(JNIEnv *env, jobject obj, jlong nativeRemoteSink) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance == nullptr) {
@ -581,6 +588,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_removeInc
broadcastRequestedSinks(instance);
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setVideoEndpointQuality(JNIEnv *env, jobject obj, jstring endpointId, jint quality) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance == nullptr) {
@ -595,6 +603,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setVideoE
broadcastRequestedSinks(instance);
}
extern "C"
JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNativeInstance(JNIEnv *env, jclass clazz, jstring version, jobject instanceObj, jobject config, jstring persistentStateFilePath, jobjectArray endpoints, jobject proxyClass, jint networkType, jobject encryptionKey, jobject remoteSink, jlong videoCapturer, jfloat aspectRatio) {
initWebRTC(env);
@ -731,20 +740,23 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNati
holder->nativeInstance->setRequestedVideoAspect(aspectRatio);
return reinterpret_cast<jlong>(holder);
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setGlobalServerConfig(JNIEnv *env, jobject obj, jstring serverConfigJson) {
SetLegacyGlobalServerConfig(tgvoip::jni::JavaStringToStdString(env, serverConfigJson));
}
extern "C"
JNIEXPORT jstring JNICALL Java_org_telegram_messenger_voip_NativeInstance_getVersion(JNIEnv *env, jobject obj) {
return env->NewStringUTF(tgvoip::VoIPController::GetVersion());
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setBufferSize(JNIEnv *env, jobject obj, jint size) {
tgvoip::audio::AudioOutputOpenSLES::nativeBufferSize = (unsigned int) size;
tgvoip::audio::AudioInputOpenSLES::nativeBufferSize = (unsigned int) size;
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setNetworkType(JNIEnv *env, jobject obj, jint networkType) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance == nullptr) {
@ -753,6 +765,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setNetwor
instance->nativeInstance->setNetworkType(parseNetworkType(networkType));
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setMuteMicrophone(JNIEnv *env, jobject obj, jboolean muteMicrophone) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance != nullptr) {
@ -762,6 +775,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setMuteMi
}
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setVolume(JNIEnv *env, jobject obj, jint ssrc, jdouble volume) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance != nullptr) {
@ -769,6 +783,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setVolume
}
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setAudioOutputGainControlEnabled(JNIEnv *env, jobject obj, jboolean enabled) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance == nullptr) {
@ -777,6 +792,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setAudioO
instance->nativeInstance->setAudioOutputGainControlEnabled(enabled);
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setEchoCancellationStrength(JNIEnv *env, jobject obj, jint strength) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance == nullptr) {
@ -785,6 +801,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setEchoCa
instance->nativeInstance->setEchoCancellationStrength(strength);
}
extern "C"
JNIEXPORT jstring JNICALL Java_org_telegram_messenger_voip_NativeInstance_getLastError(JNIEnv *env, jobject obj) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance == nullptr) {
@ -793,6 +810,7 @@ JNIEXPORT jstring JNICALL Java_org_telegram_messenger_voip_NativeInstance_getLas
return env->NewStringUTF(instance->nativeInstance->getLastError().c_str());
}
extern "C"
JNIEXPORT jstring JNICALL Java_org_telegram_messenger_voip_NativeInstance_getDebugInfo(JNIEnv *env, jobject obj) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance == nullptr) {
@ -801,6 +819,7 @@ JNIEXPORT jstring JNICALL Java_org_telegram_messenger_voip_NativeInstance_getDeb
return env->NewStringUTF(instance->nativeInstance->getDebugInfo().c_str());
}
extern "C"
JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_getPreferredRelayId(JNIEnv *env, jobject obj) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance == nullptr) {
@ -809,6 +828,7 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_getPrefe
return instance->nativeInstance->getPreferredRelayId();
}
extern "C"
JNIEXPORT jobject JNICALL Java_org_telegram_messenger_voip_NativeInstance_getTrafficStats(JNIEnv *env, jobject obj) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance == nullptr) {
@ -817,6 +837,7 @@ JNIEXPORT jobject JNICALL Java_org_telegram_messenger_voip_NativeInstance_getTra
return asJavaTrafficStats(env, instance->nativeInstance->getTrafficStats());
}
extern "C"
JNIEXPORT jbyteArray JNICALL Java_org_telegram_messenger_voip_NativeInstance_getPersistentState(JNIEnv *env, jobject obj) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance == nullptr) {
@ -825,6 +846,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_telegram_messenger_voip_NativeInstance_get
return copyVectorToJavaByteArray(env, instance->nativeInstance->getPersistentState().value);
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_stopNative(JNIEnv *env, jobject obj) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance == nullptr) {
@ -840,6 +862,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_stopNativ
});
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_stopGroupNative(JNIEnv *env, jobject obj) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance == nullptr) {
@ -850,6 +873,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_stopGroup
delete instance;
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_onStreamPartAvailable(JNIEnv *env, jobject obj, jlong ts, jobject byteBuffer, jint size, jlong responseTs, jint videoChannel, jint quality) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance == nullptr) {
@ -885,6 +909,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_onStreamP
}
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_onMediaDescriptionAvailable(JNIEnv *env, jobject obj, jlong taskPtr, jintArray ssrcs) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->groupNativeInstance == nullptr) {
@ -901,6 +926,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_onMediaDe
}
}
extern "C"
JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_createVideoCapturer(JNIEnv *env, jclass clazz, jobject localSink, jint type) {
initWebRTC(env);
std::unique_ptr<VideoCaptureInterface> capture;
@ -914,6 +940,7 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_createVi
return reinterpret_cast<intptr_t>(capture.release());
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_activateVideoCapturer(JNIEnv *env, jobject obj, jlong videoCapturer) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance) {
@ -925,6 +952,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_activateV
capturer->setState(VideoState::Active);
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_clearVideoCapturer(JNIEnv *env, jobject obj) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance) {
@ -934,21 +962,25 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_clearVide
}
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_destroyVideoCapturer(JNIEnv *env, jclass clazz, jlong videoCapturer) {
auto capturer = reinterpret_cast<VideoCaptureInterface *>(videoCapturer);
delete capturer;
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_switchCameraCapturer(JNIEnv *env, jclass clazz, jlong videoCapturer, jboolean front) {
auto capturer = reinterpret_cast<VideoCaptureInterface *>(videoCapturer);
capturer->switchToDevice(front ? "front" : "back", false);
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setVideoStateCapturer(JNIEnv *env, jclass clazz, jlong videoCapturer, jint videoState) {
auto capturer = reinterpret_cast<VideoCaptureInterface *>(videoCapturer);
capturer->setState(static_cast<VideoState>(videoState));
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_switchCamera(JNIEnv *env, jobject obj, jboolean front) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->_videoCapture == nullptr) {
@ -957,6 +989,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_switchCam
instance->_videoCapture->switchToDevice(front ? "front" : "back", false);
}
extern "C"
JNIEXPORT jboolean JNICALL Java_org_telegram_messenger_voip_NativeInstance_hasVideoCapturer(JNIEnv *env, jobject obj) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->_videoCapture == nullptr) {
@ -965,6 +998,7 @@ JNIEXPORT jboolean JNICALL Java_org_telegram_messenger_voip_NativeInstance_hasVi
return JNI_TRUE;
}
extern "C"
JNIEXPORT void Java_org_telegram_messenger_voip_NativeInstance_setVideoState(JNIEnv *env, jobject obj, jint state) {
InstanceHolder *instance = getInstanceHolder(env, obj);
std::shared_ptr<tgcalls::VideoCaptureInterface> capturer = instance->useScreencast ? instance->_screenVideoCapture : instance->_videoCapture;
@ -974,6 +1008,7 @@ JNIEXPORT void Java_org_telegram_messenger_voip_NativeInstance_setVideoState(JNI
capturer->setState(static_cast<VideoState>(state));
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setupOutgoingVideo(JNIEnv *env, jobject obj, jobject localSink, jint type) {
InstanceHolder *instance = getInstanceHolder(env, obj);
std::shared_ptr<tgcalls::VideoCaptureInterface> capturer;
@ -999,6 +1034,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setupOutg
}
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setupOutgoingVideoCreated(JNIEnv *env, jobject obj, jlong videoCapturer) {
if (videoCapturer == 0) {
return;
@ -1016,6 +1052,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setupOutg
}
}
extern "C"
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_onSignalingDataReceive(JNIEnv *env, jobject obj, jbyteArray value) {
InstanceHolder *instance = getInstanceHolder(env, obj);
if (instance->nativeInstance == nullptr) {

View File

@ -15,10 +15,10 @@
#include <memory>
#include "vpx/vp8cx.h"
#include "vpx/vpx_codec.h"
#include "vpx/vpx_encoder.h"
#include "vpx/vpx_image.h"
#include <libvpx/vp8cx.h>
#include <libvpx/vpx_codec.h>
#include <libvpx/vpx_encoder.h>
#include <libvpx/vpx_image.h>
namespace webrtc {

View File

@ -31,9 +31,9 @@
#include "system_wrappers/include/field_trial.h"
#include "system_wrappers/include/metrics.h"
#include "third_party/libyuv/include/libyuv/convert.h"
#include "vpx/vp8.h"
#include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h"
#include <libvpx/vp8.h>
#include <libvpx/vp8dx.h>
#include <libvpx/vpx_decoder.h>
namespace webrtc {
namespace {

View File

@ -19,8 +19,8 @@
#include "common_video/include/video_frame_buffer_pool.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h"
#include <libvpx/vp8dx.h>
#include <libvpx/vpx_decoder.h>
namespace webrtc {

View File

@ -40,7 +40,7 @@
#include "rtc_base/trace_event.h"
#include "system_wrappers/include/field_trial.h"
#include "third_party/libyuv/include/libyuv/scale.h"
#include "vpx/vp8cx.h"
#include <libvpx/vp8cx.h>
namespace webrtc {
namespace {

View File

@ -28,8 +28,8 @@
#include "rtc_base/experiments/cpu_speed_experiment.h"
#include "rtc_base/experiments/encoder_info_settings.h"
#include "rtc_base/experiments/rate_control_settings.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include <libvpx/vp8cx.h>
#include <libvpx/vpx_encoder.h>
namespace webrtc {

View File

@ -24,8 +24,8 @@
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "third_party/libyuv/include/libyuv/convert.h"
#include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h"
#include <libvpx/vp8dx.h>
#include <libvpx/vpx_decoder.h>
namespace webrtc {
namespace {

View File

@ -19,7 +19,7 @@
#include "common_video/include/video_frame_buffer_pool.h"
#include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h"
#include "vpx/vp8cx.h"
#include <libvpx/vp8cx.h>
namespace webrtc {

View File

@ -40,8 +40,8 @@
#include "rtc_base/time_utils.h"
#include "rtc_base/trace_event.h"
#include "third_party/libyuv/include/libyuv/convert.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include <libvpx/vp8cx.h>
#include <libvpx/vpx_encoder.h>
namespace webrtc {

View File

@ -29,7 +29,7 @@
#include "modules/video_coding/svc/scalable_video_controller.h"
#include "modules/video_coding/utility/framerate_controller.h"
#include "rtc_base/experiments/encoder_info_settings.h"
#include "vpx/vp8cx.h"
#include <libvpx/vp8cx.h>
namespace webrtc {

View File

@ -18,9 +18,9 @@
#include "modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h"
#include "modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h"
#include "rtc_base/checks.h"
#include "vpx/vp8cx.h"
#include "vpx/vp8dx.h"
#include "vpx/vpx_codec.h"
#include <libvpx/vp8cx.h>
#include <libvpx/vp8dx.h>
#include <libvpx/vpx_codec.h>
namespace webrtc {

View File

@ -15,9 +15,9 @@
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "vpx/vpx_codec.h"
#include "vpx/vpx_decoder.h"
#include "vpx/vpx_frame_buffer.h"
#include <libvpx/vpx_codec.h>
#include <libvpx/vpx_decoder.h>
#include <libvpx/vpx_frame_buffer.h>
namespace webrtc {

View File

@ -53,7 +53,7 @@ statisticChartLine_lightblue=-12814100
chat_inContactNameText=-8796932
chats_menuPhoneCats=-8613724
chat_outPreviewLine=-6631937
chat_messagePanelHint=-9798256
chat_messagePanelHint=1690950634
windowBackgroundGray=-15393241
chat_inViaBotNameText=-8796932
chat_outVoiceSeekbar=-429551165
@ -111,7 +111,7 @@ groupcreate_spanBackground=-13878194
dialogButton=-10177041
contextProgressInner1=-11509903
chat_inLoaderPhotoIconSelected=-1
actionBarDefaultSubtitle=-7628894
actionBarDefaultSubtitle=-1933849638
chat_inContactPhoneText=-8812393
chat_inlineResultIcon=-8796932
chat_outBubbleGradientSelectedOverlay=352321535
@ -264,9 +264,9 @@ statisticChartInactivePickerChart=-936297140
chats_unreadCounterMuted=-12692893
chat_outVoiceSeekbarFill=-7944965
chat_outReplyLine=-6631937
chat_messagePanelIcons=-9733492
chat_messagePanelIcons=1690029025
chat_inReplyMediaMessageText=-8812393
inappPlayerTitle=-8220258
inappPlayerTitle=-2067736855
chat_emojiPanelIconSelected=-10177041
progressCircle=-10177027
chat_inContactBackground=-10445358
@ -298,6 +298,7 @@ inappPlayerBackground=-14602949
avatar_nameInMessagePink=-624741
windowBackgroundWhiteGrayText=-8549479
statisticChartSignature=-1214008894
actionBarDefaultSubmenuItemIcon=-7627862
avatar_actionBarSelectorViolet=-12758164
chat_attachPollBackground=-2183099
avatar_nameInMessageBlue=-8796932
@ -341,7 +342,7 @@ chat_inFileInfoSelectedText=-7490861
chat_wallpaper=-15393241
chat_outMenuSelected=-541138950
chat_outLoaderPhotoSelected=-13208924
chat_muteIcon=-11640982
chat_muteIcon=1019012607
chat_selectedBackground=710909411
chat_inAudioDurationText=-8746857
chat_secretTimeText=-3679765
@ -393,7 +394,7 @@ chat_replyPanelMessage=-7628894
chat_inViewsSelected=-7490861
windowBackgroundWhiteLinkSelection=862238205
player_background=-14734794
inappPlayerClose=-9336677
inappPlayerClose=1522324204
chat_outMediaIcon=-1
chats_message_threeLines=-8549479
player_actionBarSubtitle=-8549479
@ -429,6 +430,7 @@ windowBackgroundWhiteGrayText4=-931296359
chat_inTimeText=-645885536
dialogRadioBackground=-11245959
statisticChartRipple=748994002
chat_BlurAlpha=-771751936
chat_outReplyMessageText=-1
chat_recordedVoiceDot=-1221292
chat_messagePanelBackground=-14602949

View File

@ -53,7 +53,7 @@ chat_inContactNameText=-8796932
chats_menuPhoneCats=-8224126
chat_outPreviewLine=-6631937
dialogScrollGlow=-657931
chat_messagePanelHint=-9408399
chat_messagePanelHint=1675682017
windowBackgroundGray=-16119286
chat_inViaBotNameText=-8796932
chat_outVoiceSeekbar=-10245406
@ -66,7 +66,7 @@ chat_inFileProgress=-1
dialogIcon=-7566196
chat_emojiPanelEmptyText=-8553090
chat_emojiPanelBackspace=-9539985
chat_replyPanelClose=-9013383
chat_replyPanelClose=1690748875
chat_inContactPhoneSelectedText=-7490861
dialogSearchText=-1
actionBarTabUnactiveText=-7434609
@ -115,7 +115,7 @@ groupcreate_spanBackground=-13816531
dialogButton=-10177041
contextProgressInner1=-11184811
chat_inLoaderPhotoIconSelected=-1
actionBarDefaultSubtitle=-7895161
actionBarDefaultSubtitle=1693643506
chat_inContactPhoneText=-8486783
chat_inlineResultIcon=-8796932
chat_outBubbleGradientSelectedOverlay=352321535
@ -174,7 +174,7 @@ chats_nameMessageArchived=-8553091
avatar_nameInMessageOrange=-13984
chats_pinnedIcon=-10197916
chat_attachActiveTab=-9781249
chat_replyPanelLine=-1509949440
chat_replyPanelLine=1006632960
avatar_subtitleInProfileOrange=-7628894
chat_outSentCheckSelected=-5841921
dialogSearchHint=-8421505
@ -279,7 +279,7 @@ statisticChartInactivePickerChart=-667862461
chats_unreadCounterMuted=-12237499
chat_outVoiceSeekbarFill=-1
chat_outReplyLine=-8466689
chat_messagePanelIcons=-8947847
chat_messagePanelIcons=1692327650
chat_inReplyMediaMessageText=-8421247
inappPlayerTitle=-8618626
chat_emojiPanelIconSelected=-10177041
@ -359,7 +359,7 @@ chat_wallpaper=-16316665
chat_outMenuSelected=-541138950
fastScrollActive=-13133079
chat_outLoaderPhotoSelected=-13208924
chat_muteIcon=-10724260
chat_muteIcon=1688577445
chat_selectedBackground=710909411
chat_inAudioDurationText=-9013641
chat_recordedVoiceBackground=-11690258
@ -451,6 +451,7 @@ windowBackgroundWhiteGrayText4=-10987432
chat_inTimeText=-8552575
dialogRadioBackground=-10855846
statisticChartRipple=748994002
chat_BlurAlpha=-771751936
chat_outBubbleGradient=-12874567
chat_outReplyMessageText=-1
chat_recordedVoiceDot=-1221292

View File

@ -80,6 +80,7 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
* helps {@link LinearLayoutManager} make those decisions.
*/
OrientationHelper mOrientationHelper;
public boolean mIgnoreTopPadding = false;
/**
* We need to track this so that we can ignore current position when it changes.
@ -1883,7 +1884,7 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
ensureLayoutState();
View invalidMatch = null;
View outOfBoundsMatch = null;
final int boundsStart = mOrientationHelper.getStartAfterPadding();
final int boundsStart = mIgnoreTopPadding ? 0 : mOrientationHelper.getStartAfterPadding();
final int boundsEnd = mOrientationHelper.getEndAfterPadding();
final int diff = end > start ? 1 : -1;
for (int i = start; i != end; i += diff) {

View File

@ -17,6 +17,7 @@ import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
@ -64,7 +65,6 @@ import android.text.util.Linkify;
import android.util.DisplayMetrics;
import android.util.StateSet;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
@ -144,6 +144,7 @@ import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
@ -399,8 +400,8 @@ public class AndroidUtilities {
if (context instanceof Activity) {
return (Activity) context;
}
if (context instanceof ContextThemeWrapper) {
return findActivity(((ContextThemeWrapper) context).getBaseContext());
if (context instanceof ContextWrapper) {
return findActivity(((ContextWrapper) context).getBaseContext());
}
return null;
}
@ -4213,6 +4214,41 @@ public class AndroidUtilities {
}
}
private static final HashMap<Window, ArrayList<Long>> flagSecureReasons = new HashMap<>();
// Sets FLAG_SECURE to true, until it gets unregistered (when returned callback is run)
// Useful for having multiple reasons to have this flag on.
public static Runnable registerFlagSecure(Window window) {
final long reasonId = (long) (Math.random() * 999999999);
final ArrayList<Long> reasonIds;
if (flagSecureReasons.containsKey(window)) {
reasonIds = flagSecureReasons.get(window);
} else {
reasonIds = new ArrayList<>();
flagSecureReasons.put(window, reasonIds);
}
reasonIds.add(reasonId);
updateFlagSecure(window);
return () -> {
reasonIds.remove(reasonId);
updateFlagSecure(window);
};
}
private static void updateFlagSecure(Window window) {
if (Build.VERSION.SDK_INT >= 23) {
if (window == null) {
return;
}
final boolean value = flagSecureReasons.containsKey(window) && flagSecureReasons.get(window).size() > 0;
try {
if (value) {
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
} catch (Exception ignore) {}
}
}
public static void openSharing(BaseFragment fragment, String url) {
if (fragment == null || fragment.getParentActivity() == null) {
return;

View File

@ -90,7 +90,7 @@ public class ImageLoader {
private LruCache<BitmapDrawable> smallImagesMemCache;
private LruCache<BitmapDrawable> memCache;
private LruCache<BitmapDrawable> wallpaperMemCache;
private LruCache<RLottieDrawable> lottieMemCache;
private LruCache<BitmapDrawable> lottieMemCache;
private HashMap<String, CacheImage> imageLoadingByUrl = new HashMap<>();
private HashMap<String, CacheImage> imageLoadingByKeys = new HashMap<>();
private SparseArray<CacheImage> imageLoadingByTag = new SparseArray<>();
@ -957,7 +957,7 @@ public class ImageLoader {
h = (int) (h_filter * AndroidUtilities.density);
}
}
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, "d".equals(cacheImage.filter), 0, null, null, null, seekTo, cacheImage.currentAccount, false , w, h);
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, "d".equals(cacheImage.filter), 0, cacheImage.imageLocation.document, null, null, seekTo, cacheImage.currentAccount, false , w, h);
}
Thread.interrupted();
onPostExecute(fileDrawable);
@ -1462,7 +1462,20 @@ public class ImageLoader {
decrementKey = cacheImage.key;
}
} else if (drawable instanceof AnimatedFileDrawable) {
toSet = drawable;
AnimatedFileDrawable animatedFileDrawable = (AnimatedFileDrawable) drawable;
if (animatedFileDrawable.isWebmSticker) {
toSet = getFromLottieCahce(cacheImage.key);
if (toSet == null) {
lottieMemCache.put(cacheImage.key, animatedFileDrawable);
toSet = animatedFileDrawable;
} else {
animatedFileDrawable.recycle();
}
incrementUseCount(cacheImage.key);
decrementKey = cacheImage.key;
} else {
toSet = drawable;
}
} else if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
toSet = getFromMemCache(cacheImage.key);
@ -1514,6 +1527,9 @@ public class ImageLoader {
if (drawable == null) {
drawable = wallpaperMemCache.get(key);
}
if (drawable == null) {
drawable = getFromLottieCahce(key);
}
return drawable;
}
@ -1791,17 +1807,22 @@ public class ImageLoader {
}
};
lottieMemCache = new LruCache<RLottieDrawable>(512 * 512 * 2 * 4 * 5) {
lottieMemCache = new LruCache<BitmapDrawable>(512 * 512 * 2 * 4 * 5) {
@Override
protected int sizeOf(String key, RLottieDrawable value) {
protected int sizeOf(String key, BitmapDrawable value) {
return value.getIntrinsicWidth() * value.getIntrinsicHeight() * 4 * 2;
}
@Override
protected void entryRemoved(boolean evicted, String key, final RLottieDrawable oldValue, RLottieDrawable newValue) {
protected void entryRemoved(boolean evicted, String key, final BitmapDrawable oldValue, BitmapDrawable newValue) {
final Integer count = bitmapUseCounts.get(key);
if (count == null || count == 0) {
oldValue.recycle();
if (oldValue instanceof AnimatedFileDrawable) {
((AnimatedFileDrawable) oldValue).recycle();
}
if (oldValue instanceof RLottieDrawable) {
((RLottieDrawable) oldValue).recycle();
}
}
}
};
@ -2160,7 +2181,7 @@ public class ImageLoader {
public boolean isInMemCache(String key, boolean animated) {
if (animated) {
return lottieMemCache.get(key) != null;
return getFromLottieCahce(key) != null;
} else {
return getFromMemCache(key) != null;
}
@ -2475,13 +2496,13 @@ public class ImageLoader {
boolean isEncrypted = imageLocation.isEncrypted();
CacheImage img = new CacheImage();
if (!currentKeyQuality) {
if (imageLocation.imageType == FileLoader.IMAGE_TYPE_ANIMATION || MessageObject.isGifDocument(imageLocation.webFile) || MessageObject.isGifDocument(imageLocation.document) || MessageObject.isRoundVideoDocument(imageLocation.document)) {
if (imageLocation.imageType == FileLoader.IMAGE_TYPE_ANIMATION || MessageObject.isGifDocument(imageLocation.webFile) || MessageObject.isGifDocument(imageLocation.document) || MessageObject.isRoundVideoDocument(imageLocation.document) || MessageObject.isVideoSticker(imageLocation.document)) {
img.imageType = FileLoader.IMAGE_TYPE_ANIMATION;
} else if (imageLocation.path != null) {
String location = imageLocation.path;
if (!location.startsWith("vthumb") && !location.startsWith("thumb")) {
String trueExt = getHttpUrlExtension(location, "jpg");
if (trueExt.equals("mp4") || trueExt.equals("gif")) {
if (trueExt.equals("webm") || trueExt.equals("mp4") || trueExt.equals("gif")) {
img.imageType = FileLoader.IMAGE_TYPE_ANIMATION;
} else if ("tgs".equals(ext)) {
img.imageType = FileLoader.IMAGE_TYPE_LOTTIE;
@ -2689,8 +2710,8 @@ public class ImageLoader {
if (mediaKey != null) {
ImageLocation mediaLocation = imageReceiver.getMediaLocation();
Drawable drawable;
if (mediaLocation != null && (MessageObject.isAnimatedStickerDocument(mediaLocation.document, true) || mediaLocation.imageType == FileLoader.IMAGE_TYPE_LOTTIE)) {
drawable = lottieMemCache.get(mediaKey);
if (useLottieMemChache(mediaLocation)) {
drawable = getFromLottieCahce(mediaKey);
} else {
drawable = memCache.get(mediaKey);
if (drawable != null) {
@ -2722,8 +2743,8 @@ public class ImageLoader {
if (!imageSet && imageKey != null) {
ImageLocation imageLocation = imageReceiver.getImageLocation();
Drawable drawable;
if (imageLocation != null && (MessageObject.isAnimatedStickerDocument(imageLocation.document, true) || imageLocation.imageType == FileLoader.IMAGE_TYPE_LOTTIE)) {
drawable = lottieMemCache.get(imageKey);
if (useLottieMemChache(imageLocation)) {
drawable = getFromLottieCahce(imageKey);
} else {
drawable = memCache.get(imageKey);
if (drawable != null) {
@ -2756,8 +2777,8 @@ public class ImageLoader {
if (thumbKey != null) {
ImageLocation thumbLocation = imageReceiver.getThumbLocation();
Drawable drawable;
if (thumbLocation != null && (MessageObject.isAnimatedStickerDocument(thumbLocation.document, true) || thumbLocation.imageType == FileLoader.IMAGE_TYPE_LOTTIE)) {
drawable = lottieMemCache.get(thumbKey);
if (useLottieMemChache(thumbLocation)) {
drawable = getFromLottieCahce(thumbKey);
} else {
drawable = memCache.get(thumbKey);
if (drawable != null) {
@ -2970,6 +2991,21 @@ public class ImageLoader {
}
}
private BitmapDrawable getFromLottieCahce(String imageKey) {
BitmapDrawable drawable = lottieMemCache.get(imageKey);
if (drawable instanceof AnimatedFileDrawable) {
if (((AnimatedFileDrawable) drawable).isRecycled()) {
lottieMemCache.remove(imageKey);
drawable = null;
}
}
return drawable;
}
private boolean useLottieMemChache(ImageLocation imageLocation) {
return imageLocation != null && (MessageObject.isAnimatedStickerDocument(imageLocation.document, true) || imageLocation.imageType == FileLoader.IMAGE_TYPE_LOTTIE || MessageObject.isVideoSticker(imageLocation.document));
}
private void httpFileLoadError(final String location) {
imageLoadQueue.postRunnable(() -> {
CacheImage img = imageLoadingByUrl.get(location);

View File

@ -419,6 +419,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentCacheType = 0;
staticThumbDrawable = thumb;
currentAlpha = 1.0f;
previousAlpha = 1f;
currentSize = 0;
if (staticThumbDrawable instanceof SvgHelper.SvgDrawable) {
@ -584,6 +585,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (staticThumbDrawable instanceof SvgHelper.SvgDrawable) {
((SvgHelper.SvgDrawable) staticThumbDrawable).setParent(this);
}
updateDrawableRadius(staticThumbDrawable);
if (delegate != null) {
delegate.didSetImage(this, currentImageDrawable != null || currentThumbDrawable != null || staticThumbDrawable != null || currentMediaDrawable != null, currentImageDrawable == null && currentMediaDrawable == null, false);
@ -709,7 +711,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (bitmap instanceof AnimatedFileDrawable) {
AnimatedFileDrawable fileDrawable = (AnimatedFileDrawable) bitmap;
fileDrawable.setParentView(parentView);
fileDrawable.setUseSharedQueue(useSharedAnimationQueue);
fileDrawable.setUseSharedQueue(useSharedAnimationQueue || fileDrawable.isWebmSticker);
if (allowStartAnimation && currentOpenedLayerFlags == 0) {
fileDrawable.start();
}
@ -722,6 +724,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
fileDrawable.setAllowDecodeSingleFrame(true);
}
thumbShader = null;
staticThumbDrawable = bitmap;
updateDrawableRadius(bitmap);
currentMediaLocation = null;
@ -816,14 +819,18 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
private void updateDrawableRadius(Drawable drawable) {
if (drawable == null) {
return;
}
if ((hasRoundRadius() || gradientShader != null) && drawable instanceof BitmapDrawable) {
if (drawable instanceof RLottieDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if (bitmapDrawable instanceof RLottieDrawable) {
} else if (drawable instanceof AnimatedFileDrawable) {
} else if (bitmapDrawable instanceof AnimatedFileDrawable) {
AnimatedFileDrawable animatedFileDrawable = (AnimatedFileDrawable) drawable;
animatedFileDrawable.setRoundRadius(roundRadius);
} else {
setDrawableShader(drawable, new BitmapShader(((BitmapDrawable) drawable).getBitmap(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
} else if (bitmapDrawable.getBitmap() != null) {
setDrawableShader(drawable, new BitmapShader(bitmapDrawable.getBitmap(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
}
} else {
setDrawableShader(drawable, null);
@ -899,7 +906,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
AnimatedFileDrawable animatedFileDrawable = getAnimation();
if (animatedFileDrawable != null && allowStartAnimation && currentOpenedLayerFlags == 0) {
animatedFileDrawable.stop();
animatedFileDrawable.start();
if (parentView != null) {
parentView.invalidate();
}
}
if (NotificationCenter.getGlobalInstance().isAnimationInProgress()) {
didReceivedNotification(NotificationCenter.stopAllHeavyOperations, currentAccount, 512);
@ -989,6 +999,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
bitmapW = bitmapDrawable.getIntrinsicWidth();
bitmapH = bitmapDrawable.getIntrinsicHeight();
}
if (parentView != null) {
parentView.invalidate();
}
} else {
Bitmap bitmap = bitmapDrawable.getBitmap();
if (bitmap != null && bitmap.isRecycled()) {
@ -1416,6 +1429,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
shaderToUse = thumbShader;
orientation = thumbOrientation;
}
if (drawable != null) {
if (crossfadeAlpha != 0) {
if (previousAlpha != 1f && (drawable == currentImageDrawable || drawable == currentMediaDrawable) && staticThumbDrawable != null) {
@ -1477,6 +1491,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
} else {
checkAlphaAnimation(animationNotReady);
}
if (drawable == null && animationNotReady && parentView != null) {
parentView.invalidate();
}
} catch (Exception e) {
FileLog.e(e);
}
@ -2073,7 +2091,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (!(drawable instanceof AnimatedFileDrawable)) {
ImageLoader.getInstance().incrementUseCount(currentImageKey);
} else {
((AnimatedFileDrawable) drawable).setStartEndTime(startTime, endTime);
AnimatedFileDrawable animatedFileDrawable = (AnimatedFileDrawable) drawable;
animatedFileDrawable.setStartEndTime(startTime, endTime);
if (animatedFileDrawable.isWebmSticker) {
ImageLoader.getInstance().incrementUseCount(currentImageKey);
}
}
currentImageDrawable = drawable;
if (drawable instanceof ExtendedBitmapDrawable) {
@ -2089,13 +2111,18 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
allowCorssfade = staticThumbDrawable instanceof LoadingStickerDrawable || staticThumbDrawable instanceof SvgHelper.SvgDrawable || staticThumbDrawable instanceof Emoji.EmojiDrawable;
}
if (allowCorssfade && (currentThumbDrawable != null || staticThumbDrawable != null || forceCrossfade)) {
previousAlpha = currentAlpha;
if (currentThumbDrawable != null && staticThumbDrawable != null) {
previousAlpha = currentAlpha;
} else {
previousAlpha = 1f;
}
currentAlpha = 0.0f;
lastUpdateAlphaTime = System.currentTimeMillis();
crossfadeWithThumb = crossfadeImage != null || currentThumbDrawable != null || staticThumbDrawable != null;
}
} else {
currentAlpha = 1.0f;
previousAlpha = 1f;
}
} else if (type == TYPE_MEDIA) {
if (!key.equals(currentMediaKey)) {
@ -2104,7 +2131,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (!(drawable instanceof AnimatedFileDrawable)) {
ImageLoader.getInstance().incrementUseCount(currentMediaKey);
} else {
((AnimatedFileDrawable) drawable).setStartEndTime(startTime, endTime);
AnimatedFileDrawable animatedFileDrawable = (AnimatedFileDrawable) drawable;
animatedFileDrawable.setStartEndTime(startTime, endTime);
if (animatedFileDrawable.isWebmSticker) {
ImageLoader.getInstance().incrementUseCount(currentImageKey);
}
}
currentMediaDrawable = drawable;
updateDrawableRadius(drawable);
@ -2113,13 +2144,18 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
boolean allowCorssfade = true;
if (!memCache && !forcePreview || forceCrossfade) {
if (currentThumbDrawable == null && staticThumbDrawable == null || currentAlpha == 1.0f || forceCrossfade) {
previousAlpha = currentAlpha;
if (currentThumbDrawable != null && staticThumbDrawable != null) {
previousAlpha = currentAlpha;
} else {
previousAlpha = 1f;
}
currentAlpha = 0.0f;
lastUpdateAlphaTime = System.currentTimeMillis();
crossfadeWithThumb = crossfadeImage != null || currentThumbDrawable != null || staticThumbDrawable != null;
}
} else {
currentAlpha = 1.0f;
previousAlpha = 1f;
}
}
} else if (type == TYPE_THUMB) {
@ -2149,13 +2185,16 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (!memCache && crossfadeAlpha != 2) {
if (currentParentObject instanceof MessageObject && ((MessageObject) currentParentObject).isRoundVideo() && ((MessageObject) currentParentObject).isSending()) {
currentAlpha = 1.0f;
previousAlpha = 1f;
} else {
currentAlpha = 0.0f;
previousAlpha = 1f;
lastUpdateAlphaTime = System.currentTimeMillis();
crossfadeWithThumb = staticThumbDrawable != null;
}
} else {
currentAlpha = 1.0f;
previousAlpha = 1f;
}
}
if (delegate != null) {
@ -2163,13 +2202,15 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
if (drawable instanceof AnimatedFileDrawable) {
AnimatedFileDrawable fileDrawable = (AnimatedFileDrawable) drawable;
fileDrawable.setParentView(parentView);
fileDrawable.setUseSharedQueue(useSharedAnimationQueue);
if (allowStartAnimation && currentOpenedLayerFlags == 0) {
fileDrawable.start();
}
fileDrawable.setAllowDecodeSingleFrame(allowDecodeSingleFrame);
animationReadySent = false;
if (parentView != null) {
parentView.invalidate();
}
} else if (drawable instanceof RLottieDrawable) {
RLottieDrawable fileDrawable = (RLottieDrawable) drawable;
fileDrawable.addParentView(parentView);
@ -2236,7 +2277,18 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
} else if (image instanceof AnimatedFileDrawable) {
AnimatedFileDrawable fileDrawable = (AnimatedFileDrawable) image;
fileDrawable.recycle();
if (fileDrawable.isWebmSticker) {
boolean canDelete = ImageLoader.getInstance().decrementUseCount(key);
if (!ImageLoader.getInstance().isInMemCache(key, true)) {
if (canDelete) {
fileDrawable.recycle();
}
} else if (canDelete) {
fileDrawable.stop();
}
} else {
fileDrawable.recycle();
}
} else if (image instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) image).getBitmap();
boolean canDelete = ImageLoader.getInstance().decrementUseCount(key);
@ -2321,6 +2373,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
AnimatedFileDrawable animatedFileDrawable = getAnimation();
if (allowStartAnimation && animatedFileDrawable != null) {
animatedFileDrawable.start();
if (parentView != null) {
parentView.invalidate();
}
}
}
}

View File

@ -1674,6 +1674,31 @@ public class LocaleController {
return "LOC_ERR";
}
public static String formatDateTime(long date) {
try {
date *= 1000;
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (dateDay == day && year == dateYear) {
return LocaleController.formatString("TodayAtFormattedWithToday", R.string.TodayAtFormattedWithToday, getInstance().formatterDay.format(new Date(date)));
} else if (dateDay + 1 == day && year == dateYear) {
return LocaleController.formatString("YesterdayAtFormatted", R.string.YesterdayAtFormatted, getInstance().formatterDay.format(new Date(date)));
} else if (Math.abs(System.currentTimeMillis() - date) < 31536000000L) {
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().chatDate.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
} else {
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().chatFullDate.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
}
} catch (Exception e) {
FileLog.e(e);
}
return "LOC_ERR";
}
public static String formatLocationUpdateDate(long date) {
try {
date *= 1000;

View File

@ -2771,7 +2771,7 @@ public class MediaDataController extends BaseController {
}
if (isVoice) {
return MEDIA_AUDIO;
} else if (isVideo && !isAnimated) {
} else if (isVideo && !isAnimated && !isSticker) {
return MEDIA_PHOTOVIDEO;
} else if (isSticker) {
return -1;

View File

@ -76,6 +76,7 @@ public class MessageObject {
public static final int TYPE_PHOTO = 1;
public static final int TYPE_VIDEO = 3;
public static final int TYPE_GEO = 4; // TL_messageMediaGeo, TL_messageMediaVenue, TL_messageMediaGeoLive
public static final int TYPE_ROUND_VIDEO = 5;
public static final int TYPE_STICKER = 13;
public static final int TYPE_ANIMATED_STICKER = 15;
@ -223,6 +224,25 @@ public class MessageObject {
};
public Drawable customAvatarDrawable;
public static boolean hasUnreadReactions(TLRPC.Message message) {
if (message == null) {
return false;
}
return hasUnreadReactions(message.reactions);
}
public static boolean hasUnreadReactions(TLRPC.TL_messageReactions reactions) {
if (reactions == null) {
return false;
}
for (int i = 0; i < reactions.recent_reactions.size(); i++) {
if (reactions.recent_reactions.get(i).unread) {
return true;
}
}
return false;
}
public int getEmojiOnlyCount() {
return emojiOnlyCount;
}
@ -230,11 +250,34 @@ public class MessageObject {
public boolean shouldDrawReactionsInLayout() {
return getDialogId() < 0;
}
public boolean isSenderChannel() {
return messageOwner.from_id instanceof TLRPC.TL_peerChannel;
}
public TLRPC.TL_messagePeerReaction getRandomUnreadReaction() {
if (messageOwner.reactions == null || messageOwner.reactions.recent_reactions == null || messageOwner.reactions.recent_reactions.isEmpty()) {
return null;
}
return messageOwner.reactions.recent_reactions.get(0);
}
public void markReactionsAsRead() {
if (messageOwner.reactions == null || messageOwner.reactions.recent_reactions == null) {
return;
}
boolean changed = false;
for (int i = 0; i < messageOwner.reactions.recent_reactions.size(); i++) {
if (messageOwner.reactions.recent_reactions.get(i).unread) {
messageOwner.reactions.recent_reactions.get(i).unread = false;
changed = true;
}
}
if (changed) {
MessagesStorage.getInstance(currentAccount).markMessageReactionsAsRead(messageOwner.dialog_id, messageOwner.id, true);
}
}
public static class SendAnimationData {
public float x;
public float y;
@ -3172,7 +3215,7 @@ public class MessageObject {
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
type = TYPE_PHOTO;
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaGeo || messageOwner.media instanceof TLRPC.TL_messageMediaVenue || messageOwner.media instanceof TLRPC.TL_messageMediaGeoLive) {
type = 4;
type = TYPE_GEO;
} else if (isRoundVideo()) {
type = TYPE_ROUND_VIDEO;
} else if (isVideo()) {
@ -3296,6 +3339,9 @@ public class MessageObject {
return canPreviewDocument(getDocument());
}
public static boolean isAnimatedStickerDocument(TLRPC.Document document) {
return document != null && document.mime_type.equals("video/webm");
}
public static boolean isGifDocument(WebFile document) {
return document != null && (document.mime_type.equals("image/gif") || isNewGifDocument(document));
}
@ -4280,6 +4326,8 @@ public class MessageObject {
return false;
} else if (eventId != 0) {
return false;
} else if (messageOwner.noforwards) {
return false;
} else if (messageOwner.fwd_from != null && !isOutOwner() && messageOwner.fwd_from.saved_from_peer != null && getDialogId() == UserConfig.getInstance(currentAccount).getClientUserId()) {
return true;
} else if (type == TYPE_STICKER || type == TYPE_ANIMATED_STICKER) {
@ -4661,6 +4709,9 @@ public class MessageObject {
if (customAvatarDrawable != null) {
return true;
}
if (isSponsored() && isFromChat()) {
return true;
}
return !isSponsored() && (isFromUser() || isFromGroup() || eventId != 0 || messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null);
}
@ -4989,12 +5040,20 @@ public class MessageObject {
return FileLoader.getDocumentFileName(getDocument());
}
public static boolean isVideoSticker(TLRPC.Document document) {
return document != null && "video/webm".equals(document.mime_type);
}
public boolean isVideoSticker() {
return getDocument() != null && "video/webm".equals(getDocument().mime_type);
}
public static boolean isStickerDocument(TLRPC.Document document) {
if (document != null) {
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
return "image/webp".equals(document.mime_type);
return "image/webp".equals(document.mime_type) || "video/webm".equals(document.mime_type);
}
}
}
@ -5215,6 +5274,9 @@ public class MessageObject {
}
public static boolean isVideoMessage(TLRPC.Message message) {
if (message.media != null && isVideoSticker(message.media.document)) {
return false;
}
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
return isVideoDocument(message.media.webpage.document);
}
@ -5445,7 +5507,7 @@ public class MessageObject {
if (type != 1000) {
return type == TYPE_STICKER;
}
return isStickerDocument(getDocument());
return isStickerDocument(getDocument()) || isVideoSticker(getDocument());
}
public boolean isAnimatedSticker() {
@ -5808,7 +5870,7 @@ public class MessageObject {
}
public boolean canForwardMessage() {
return NekoXConfig.disableFlagSecure || !(messageOwner instanceof TLRPC.TL_message_secret) && !needDrawBluredPreview() && !isLiveLocation() && type != 16 && !isSponsored();
return NekoXConfig.disableFlagSecure || !(messageOwner instanceof TLRPC.TL_message_secret) && !needDrawBluredPreview() && !isLiveLocation() && type != 16 && !isSponsored() && !messageOwner.noforwards;
}
public boolean canEditMedia() {
@ -6320,9 +6382,9 @@ public class MessageObject {
messageOwner.reactions.results.remove(choosenReaction);
}
if (messageOwner.reactions.can_see_list) {
for (int i = 0; i < messageOwner.reactions.recent_reactons.size(); i++) {
if (messageOwner.reactions.recent_reactons.get(i).user_id == UserConfig.getInstance(currentAccount).getClientUserId()) {
messageOwner.reactions.recent_reactons.remove(i);
for (int i = 0; i < messageOwner.reactions.recent_reactions.size(); i++) {
if (MessageObject.getPeerId(messageOwner.reactions.recent_reactions.get(i).peer_id) == UserConfig.getInstance(currentAccount).getClientUserId()) {
messageOwner.reactions.recent_reactions.remove(i);
i--;
}
}
@ -6338,9 +6400,9 @@ public class MessageObject {
messageOwner.reactions.results.remove(choosenReaction);
}
if (messageOwner.reactions.can_see_list) {
for (int i = 0; i < messageOwner.reactions.recent_reactons.size(); i++) {
if (messageOwner.reactions.recent_reactons.get(i).user_id == UserConfig.getInstance(currentAccount).getClientUserId()) {
messageOwner.reactions.recent_reactons.remove(i);
for (int i = 0; i < messageOwner.reactions.recent_reactions.size(); i++) {
if (MessageObject.getPeerId(messageOwner.reactions.recent_reactions.get(i).peer_id) == UserConfig.getInstance(currentAccount).getClientUserId()) {
messageOwner.reactions.recent_reactions.remove(i);
i--;
}
}
@ -6356,9 +6418,10 @@ public class MessageObject {
newReaction.count++;
if (messageOwner.reactions.can_see_list) {
TLRPC.TL_messageUserReaction action = new TLRPC.TL_messageUserReaction();
messageOwner.reactions.recent_reactons.add(0, action);
action.user_id = UserConfig.getInstance(currentAccount).getClientUserId();
TLRPC.TL_messagePeerReaction action = new TLRPC.TL_messagePeerReaction();
messageOwner.reactions.recent_reactions.add(0, action);
action.peer_id = new TLRPC.TL_peerUser();
action.peer_id.user_id = UserConfig.getInstance(currentAccount).getClientUserId();
action.reaction = reaction;
}
reactionsChanged = true;

View File

@ -27,8 +27,11 @@ import android.util.SparseIntArray;
import androidx.collection.LongSparseArray;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.util.Consumer;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLiteException;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.messenger.support.LongSparseIntArray;
import org.telegram.messenger.support.LongSparseLongArray;
import org.telegram.messenger.voip.VoIPService;
@ -103,7 +106,13 @@ public class MessagesController extends BaseController implements NotificationCe
public int unreadUnmutedDialogs;
public ConcurrentHashMap<Long, Integer> dialogs_read_inbox_max = new ConcurrentHashMap<>(100, 1.0f, 2);
public ConcurrentHashMap<Long, Integer> dialogs_read_outbox_max = new ConcurrentHashMap<>(100, 1.0f, 2);
public LongSparseArray<TLRPC.Dialog> dialogs_dict = new LongSparseArray<>();
public LongSparseArray<TLRPC.Dialog> dialogs_dict = new LongSparseArray<TLRPC.Dialog>() {
@Override
public void put(long key, TLRPC.Dialog value) {
super.put(key, value);
}
};
public LongSparseArray<MessageObject> dialogMessage = new LongSparseArray<>();
// NekoX: ignoreBlocked, Messages cache for Dialog Cell
public LongSparseArray<MessageObject> dialogMessageFromUnblocked = new LongSparseArray<>();
@ -347,6 +356,46 @@ public class MessagesController extends BaseController implements NotificationCe
public volatile boolean ignoreSetOnline;
public void getNextReactionMention(long dialogId, int count, Consumer<Integer> callback) {
final MessagesStorage messagesStorage = getMessagesStorage();
messagesStorage.getStorageQueue().postRunnable(() -> {
boolean needRequest = true;
try {
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT message_id FROM reaction_mentions WHERE state = 1 AND dialog_id = %d LIMIT 1", dialogId));
int messageId = 0;
if (cursor.next()) {
messageId = cursor.intValue(0);
needRequest = false;
}
cursor.dispose();
if (messageId != 0) {
getMessagesStorage().markMessageReactionsAsRead(dialogId, messageId, false);
int finalMessageId = messageId;
AndroidUtilities.runOnUIThread(() -> callback.accept(finalMessageId));
}
} catch (SQLiteException e) {
e.printStackTrace();
}
if (needRequest) {
TLRPC.TL_messages_getUnreadReactions req = new TLRPC.TL_messages_getUnreadReactions();
req.peer = getMessagesController().getInputPeer(dialogId);
req.limit = 1;
req.add_offset = count - 1;
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
int messageId = 0;
if (error != null && !res.messages.isEmpty()) {
messageId = res.messages.get(0).id;
}
int finalMessageId = messageId;
AndroidUtilities.runOnUIThread(() -> callback.accept(finalMessageId));
}));
}
});
}
private class SponsoredMessagesInfo {
private ArrayList<MessageObject> messages;
private long loadTime;
@ -2858,11 +2907,14 @@ public class MessagesController extends BaseController implements NotificationCe
}
public boolean isChatNoForwards(TLRPC.Chat chat) {
if (chat == null) return false;
if (chat == null) {
return false;
}
if (chat.migrated_to != null) {
TLRPC.Chat migratedTo = getChat(chat.migrated_to.channel_id);
if (migratedTo != null)
if (migratedTo != null) {
return migratedTo.noforwards;
}
}
return chat.noforwards;
}
@ -6822,6 +6874,7 @@ public class MessagesController extends BaseController implements NotificationCe
message.dialog_id = dialogId;
long checkFileTime = SystemClock.elapsedRealtime();
MessageObject messageObject = new MessageObject(currentAccount, message, usersDict, chatsDict, true, true);
messageObject.createStrippedThumb();
fileProcessTime += (SystemClock.elapsedRealtime() - checkFileTime);
messageObject.scheduled = mode == 1;
objects.add(messageObject);
@ -8512,6 +8565,7 @@ public class MessagesController extends BaseController implements NotificationCe
newDialog.unread_count = dialog.unread_count;
newDialog.unread_mark = dialog.unread_mark;
newDialog.unread_mentions_count = dialog.unread_mentions_count;
newDialog.unread_reactions_count = dialog.unread_reactions_count;
newDialog.read_inbox_max_id = dialog.read_inbox_max_id;
newDialog.read_outbox_max_id = dialog.read_outbox_max_id;
newDialog.pinned = dialog.pinned;
@ -8677,6 +8731,10 @@ public class MessagesController extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.updateMentionsCount, currentDialog.id, currentDialog.unread_mentions_count);
}
}
if (currentDialog.unread_reactions_count != value.unread_reactions_count) {
currentDialog.unread_reactions_count = value.unread_reactions_count;
getNotificationCenter().postNotificationName(NotificationCenter.dialogsUnreadReactionsCounterChanged, currentDialog.id, currentDialog.unread_reactions_count, null);
}
MessageObject oldMsg = dialogMessage.get(key);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("processDialogsUpdate oldMsg " + oldMsg + " old top_message = " + currentDialog.top_message + " new top_message = " + value.top_message);
@ -8781,6 +8839,11 @@ public class MessagesController extends BaseController implements NotificationCe
getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.Updates updates = (TLRPC.Updates) response;
for (int i = 0; i < updates.updates.size(); i++) {
if (updates.updates.get(i) instanceof TLRPC.TL_updateMessageReactions) {
((TLRPC.TL_updateMessageReactions) updates.updates.get(i)).updateUnreadState = false;
}
}
processUpdates(updates, false);
}
});
@ -12461,13 +12524,6 @@ public class MessagesController extends BaseController implements NotificationCe
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.onEmojiInteractionsReceived, update.user_id, update.action));
continue;
}
// if (update.action instanceof TLRPC.TL_sendMessageEmojiInteraction) {
// if (emojiInteractions == null) {
// emojiInteractions = new ArrayList<>();
// }
// emojiInteractions.add(update.action);
// }
} else {
TLRPC.TL_updateChatUserTyping update = (TLRPC.TL_updateChatUserTyping) baseUpdate;
chatId = update.chat_id;
@ -12485,13 +12541,6 @@ public class MessagesController extends BaseController implements NotificationCe
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.onEmojiInteractionsReceived, -update.chat_id, update.action));
continue;
}
// if (update.action instanceof TLRPC.TL_sendMessageEmojiInteraction) {
// if (emojiInteractions == null) {
// emojiInteractions = new ArrayList<>();
// }
// emojiInteractions.add(update.action);
// }
}
long uid = -chatId;
if (uid == 0) {
@ -13151,6 +13200,11 @@ public class MessagesController extends BaseController implements NotificationCe
TLRPC.TL_updateMessageReactions update = (TLRPC.TL_updateMessageReactions) baseUpdate;
long dialogId = MessageObject.getPeerId(update.peer);
getMessagesStorage().updateMessageReactions(dialogId, update.msg_id, update.reactions);
if (update.updateUnreadState) {
SparseBooleanArray sparseBooleanArray = new SparseBooleanArray();
sparseBooleanArray.put(update.msg_id, MessageObject.hasUnreadReactions(update.reactions));
checkUnreadReactions(dialogId, sparseBooleanArray);
}
if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>();
}
@ -13803,14 +13857,7 @@ public class MessagesController extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.newPeopleNearbyAvailable, baseUpdate);
} else if (baseUpdate instanceof TLRPC.TL_updateMessageReactions) {
TLRPC.TL_updateMessageReactions update = (TLRPC.TL_updateMessageReactions) baseUpdate;
long dialogId;
if (update.peer.chat_id != 0) {
dialogId = -update.peer.chat_id;
} else if (update.peer.channel_id != 0) {
dialogId = -update.peer.channel_id;
} else {
dialogId = update.peer.user_id;
}
long dialogId = MessageObject.getPeerId(update.peer);
getNotificationCenter().postNotificationName(NotificationCenter.didUpdateReactions, dialogId, update.msg_id, update.reactions);
} else if (baseUpdate instanceof TLRPC.TL_updateTheme) {
TLRPC.TL_updateTheme update = (TLRPC.TL_updateTheme) baseUpdate;
@ -13981,7 +14028,20 @@ public class MessagesController extends BaseController implements NotificationCe
if (editingMessagesFinal != null) {
for (int b = 0, size = editingMessagesFinal.size(); b < size; b++) {
long dialogId = editingMessagesFinal.keyAt(b);
SparseBooleanArray unreadReactions = null;
ArrayList<MessageObject> arrayList = editingMessagesFinal.valueAt(b);
for (int a = 0, size2 = arrayList.size(); a < size2; a++) {
MessageObject messageObject = arrayList.get(a);
if (dialogId > 0) {
if (unreadReactions == null) {
unreadReactions = new SparseBooleanArray();
}
unreadReactions.put(messageObject.getId(), MessageObject.hasUnreadReactions(messageObject.messageOwner));
}
}
if (dialogId > 0) {
checkUnreadReactions(dialogId, unreadReactions);
}
MessageObject oldObject = dialogMessage.get(dialogId);
if (oldObject != null) {
for (int a = 0, size2 = arrayList.size(); a < size2; a++) {
@ -14223,6 +14283,99 @@ public class MessagesController extends BaseController implements NotificationCe
return true;
}
private void checkUnreadReactions(long dialogId, SparseBooleanArray unreadReactions) {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
boolean needReload = false;
boolean changed = false;
ArrayList<Integer> newUnreadMessages = new ArrayList<>();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < unreadReactions.size(); i++) {
int messageId = unreadReactions.keyAt(i);
if (stringBuilder.length() > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(messageId);
}
SparseBooleanArray reactionsMentionsMessageIds = new SparseBooleanArray();
try {
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT message_id, state FROM reaction_mentions WHERE message_id IN (%s) AND dialog_id = %d", stringBuilder.toString(), dialogId));
while (cursor.next()) {
int messageId = cursor.intValue(0);
boolean hasUnreadReactions = cursor.intValue(1) == 1;
reactionsMentionsMessageIds.put(messageId, hasUnreadReactions);
}
cursor.dispose();
} catch (SQLiteException e) {
e.printStackTrace();
}
int newUnreadCount = 0;
for (int i = 0; i < unreadReactions.size(); i++) {
int messageId = unreadReactions.keyAt(i);
boolean hasUnreadReaction = unreadReactions.valueAt(i);
if (reactionsMentionsMessageIds.indexOfKey(messageId) >= 0) {
if (reactionsMentionsMessageIds.get(messageId) != hasUnreadReaction) {
newUnreadCount += hasUnreadReaction ? 1 : -1;
changed = true;
}
} else {
needReload = true;
}
if (hasUnreadReaction) {
newUnreadMessages.add(messageId);
}
SQLitePreparedStatement state = null;
try {
state = getMessagesStorage().getDatabase().executeFast("REPLACE INTO reaction_mentions VALUES(?, ?, ?)");
state.requery();
state.bindInteger(1, messageId);
state.bindInteger(2, hasUnreadReaction ? 1 : 0);
state.bindLong(3, dialogId);
state.step();
state.dispose();
} catch (SQLiteException e) {
e.printStackTrace();
}
}
if (needReload) {
TLRPC.TL_messages_getUnreadReactions req = new TLRPC.TL_messages_getUnreadReactions();
req.limit = 1;
req.peer = getInputPeer(dialogId);
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) {
TLRPC.messages_Messages messages = (TLRPC.messages_Messages) response;
int count = Math.max(messages.count, messages.messages.size());
AndroidUtilities.runOnUIThread(() -> {
TLRPC.Dialog dialog = dialogs_dict.get(dialogId);
if (dialog == null) {
return;
}
dialog.unread_reactions_count = count;
getMessagesStorage().updateUnreadReactionsCount(dialogId, count);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsUnreadReactionsCounterChanged, dialogId, count, newUnreadMessages);
});
}
});
} else if (changed) {
int finalNewUnreadCount = newUnreadCount;
AndroidUtilities.runOnUIThread(() -> {
TLRPC.Dialog dialog = dialogs_dict.get(dialogId);
if (dialog == null) {
return;
}
dialog.unread_reactions_count += finalNewUnreadCount;
if (dialog.unread_reactions_count < 0) {
dialog.unread_reactions_count = 0;
}
getMessagesStorage().updateUnreadReactionsCount(dialogId, dialog.unread_reactions_count);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsUnreadReactionsCounterChanged, dialogId, dialog.unread_reactions_count, newUnreadMessages);
});
}
});
}
public boolean isDialogMuted(long dialogId) {
return isDialogMuted(dialogId, null);
}
@ -14249,6 +14402,19 @@ public class MessagesController extends BaseController implements NotificationCe
return false;
}
public void markReactionsAsRead(long dialogId) {
TLRPC.Dialog dialog = dialogs_dict.get(dialogId);
if (dialog != null) {
dialog.unread_reactions_count = 0;
}
getMessagesStorage().updateUnreadReactionsCount(dialogId, 0);
TLRPC.TL_messages_readReactions req = new TLRPC.TL_messages_readReactions();
req.peer = getInputPeer(dialogId);
getConnectionsManager().sendRequest(req, (response, error) -> {
});
}
public ArrayList<MessageObject> getSponsoredMessages(long dialogId) {
SponsoredMessagesInfo info = sponsoredMessages.get(dialogId);
if (info != null && (info.loading || Math.abs(SystemClock.elapsedRealtime() - info.loadTime) <= 5 * 60 * 1000)) {

View File

@ -74,6 +74,83 @@ public class MessagesStorage extends BaseController {
return messageIds;
}
public void updateUnreadReactionsCount(long dialogId, int count) {
storageQueue.postRunnable(() -> {
try {
SQLitePreparedStatement state = database.executeFast("UPDATE dialogs SET unread_reactions = ? WHERE did = ?");
state.bindInteger(1, count);
state.bindLong(2, dialogId);
state.step();
state.dispose();
if (count == 0) {
state = database.executeFast("UPDATE reaction_mentions SET state = 0 WHERE dialog_id ?");
state.bindLong(1, dialogId);
state.step();
state.dispose();
}
} catch (SQLiteException e) {
e.printStackTrace();
}
});
}
public void markMessageReactionsAsRead(long dialogId, int messageId, boolean usequeue) {
if (usequeue) {
getStorageQueue().postRunnable(() -> {
markMessageReactionsAsReadInternal(dialogId, messageId);
});
} else {
markMessageReactionsAsReadInternal(dialogId, messageId);
}
}
public void markMessageReactionsAsReadInternal(long dialogId, int messageId) {
try {
SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("UPDATE reaction_mentions SET state = 0 WHERE message_id = ? AND dialog_id = ?");
state.bindInteger(1, messageId);
state.bindLong(2, dialogId);
state.step();
state.dispose();
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM messages_v2 WHERE uid = %d AND mid = %d", dialogId, messageId));
TLRPC.Message message = null;
if (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.readAttachPath(data, getUserConfig().clientUserId);
data.reuse();
if (message.reactions != null && message.reactions.recent_reactions != null) {
for (int i = 0; i < message.reactions.recent_reactions.size(); i++) {
message.reactions.recent_reactions.get(i).unread = false;
}
}
}
}
cursor.dispose();
if (message != null) {
state = getMessagesStorage().getDatabase().executeFast(String.format(Locale.US, "UPDATE messages_v2 SET data = ? WHERE uid = %d AND mid = %d", dialogId, messageId));
try {
NativeByteBuffer data = new NativeByteBuffer(message.getObjectSize());
message.serializeToStream(data);
state.bindByteBuffer(1, data);
state.step();
state.dispose();
data.reuse();
} catch (Exception e) {
e.printStackTrace();
}
}
getMessagesStorage().getDatabase().executeFast("UPDATE reaction_mentions SET state = 0 WHERE uid = %d AND ");
} catch (SQLiteException e) {
e.printStackTrace();
}
}
public interface IntCallback {
void run(int param);
}
@ -122,7 +199,7 @@ public class MessagesStorage extends BaseController {
private CountDownLatch openSync = new CountDownLatch(1);
private static SparseArray<MessagesStorage> Instance = new SparseArray();
private final static int LAST_DB_VERSION = 87;
private final static int LAST_DB_VERSION = 89;
private boolean databaseMigrationInProgress;
public static MessagesStorage getInstance(int num) {
@ -340,7 +417,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE user_phones_v7(key TEXT, phone TEXT, sphone TEXT, deleted INTEGER, PRIMARY KEY (key, phone))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS sphone_deleted_idx_user_phones ON user_phones_v7(sphone, deleted);").stepThis().dispose();
database.executeFast("CREATE TABLE dialogs(did INTEGER PRIMARY KEY, date INTEGER, unread_count INTEGER, last_mid INTEGER, inbox_max INTEGER, outbox_max INTEGER, last_mid_i INTEGER, unread_count_i INTEGER, pts INTEGER, date_i INTEGER, pinned INTEGER, flags INTEGER, folder_id INTEGER, data BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE dialogs(did INTEGER PRIMARY KEY, date INTEGER, unread_count INTEGER, last_mid INTEGER, inbox_max INTEGER, outbox_max INTEGER, last_mid_i INTEGER, unread_count_i INTEGER, pts INTEGER, date_i INTEGER, pinned INTEGER, flags INTEGER, folder_id INTEGER, data BLOB, unread_reactions INTEGER)").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_dialogs ON dialogs(date);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS last_mid_idx_dialogs ON dialogs(last_mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS unread_count_idx_dialogs ON dialogs(unread_count);").stepThis().dispose();
@ -428,6 +505,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE INDEX IF NOT EXISTS polls_id_v2 ON polls_v2(id);").stepThis().dispose();
database.executeFast("CREATE TABLE reactions(data BLOB, hash INTEGER, date INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE reaction_mentions(message_id INTEGER PRIMARY KEY, state INTEGER, dialog_id INTEGER);").stepThis().dispose();
//version
database.executeFast("PRAGMA user_version = " + LAST_DB_VERSION).stepThis().dispose();
} else {
@ -1566,6 +1644,20 @@ public class MessagesStorage extends BaseController {
version = 87;
}
if (version == 87) {
database.executeFast("ALTER TABLE dialogs ADD COLUMN unread_reactions INTEGER default 0").stepThis().dispose();
database.executeFast("CREATE TABLE reaction_mentions(message_id INTEGER PRIMARY KEY, state INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 88").stepThis().dispose();
version = 88;
}
if (version == 88) {
database.executeFast("DROP TABLE IF EXISTS reaction_mentions;").stepThis().dispose();
database.executeFast("CREATE TABLE reaction_mentions(message_id INTEGER PRIMARY KEY, state INTEGER, dialog_id INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 89").stepThis().dispose();
version = 89;
}
FileLog.d("MessagesStorage db migration finished");
AndroidUtilities.runOnUIThread(() -> {
databaseMigrationInProgress = false;
@ -2161,7 +2253,7 @@ public class MessagesStorage extends BaseController {
TLRPC.messages_Dialogs dialogs = new TLRPC.TL_messages_dialogs();
LongSparseArray<TLRPC.Message> replyMessageOwners = new LongSparseArray<>();
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, s.flags, m.date, d.pts, d.inbox_max, d.outbox_max, m.replydata, d.pinned, d.unread_count_i, d.flags, d.folder_id, d.data FROM dialogs as d LEFT JOIN messages_v2 as m ON d.last_mid = m.mid AND d.did = m.uid LEFT JOIN dialog_settings as s ON d.did = s.did WHERE d.did IN (%s) ORDER BY d.pinned DESC, d.date DESC", ids));
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, s.flags, m.date, d.pts, d.inbox_max, d.outbox_max, m.replydata, d.pinned, d.unread_count_i, d.flags, d.folder_id, d.data, d.unread_reactions FROM dialogs as d LEFT JOIN messages_v2 as m ON d.last_mid = m.mid AND d.did = m.uid LEFT JOIN dialog_settings as s ON d.did = s.did WHERE d.did IN (%s) ORDER BY d.pinned DESC, d.date DESC", ids));
while (cursor.next()) {
long dialogId = cursor.longValue(0);
TLRPC.Dialog dialog = new TLRPC.TL_dialog();
@ -2188,6 +2280,7 @@ public class MessagesStorage extends BaseController {
}
}
dialog.folder_id = cursor.intValue(17);
dialog.unread_reactions_count = cursor.intValue(19);
dialogs.dialogs.add(dialog);
NativeByteBuffer data = cursor.byteBufferValue(4);
@ -8039,7 +8132,7 @@ public class MessagesStorage extends BaseController {
data4.reuse();
data5.reuse();
if (dialog != null) {
state = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
state = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
state.bindLong(1, dialog.id);
state.bindInteger(2, dialog.last_message_date);
state.bindInteger(3, dialog.unread_count);
@ -8054,6 +8147,7 @@ public class MessagesStorage extends BaseController {
state.bindInteger(12, dialog.flags);
state.bindInteger(13, dialog.folder_id);
state.bindNull(14);
state.bindInteger(15, dialog.unread_reactions_count);
state.step();
state.dispose();
}
@ -9363,7 +9457,7 @@ public class MessagesStorage extends BaseController {
state_download.dispose();
state_webpage.dispose();
SQLitePreparedStatement state_dialogs_replace = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state_dialogs_replace = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state_dialogs_update = database.executeFast("UPDATE dialogs SET date = ?, unread_count = ?, last_mid = ?, unread_count_i = ? WHERE did = ?");
ArrayList<Long> dids = new ArrayList<>();
@ -9442,6 +9536,7 @@ public class MessagesStorage extends BaseController {
state_dialogs_replace.bindInteger(12, 0);
state_dialogs_replace.bindInteger(13, 0);
state_dialogs_replace.bindNull(14);
state_dialogs_replace.bindInteger(15, 0);
state_dialogs_replace.step();
unknownDialogsIds.put(key, true);
}
@ -9592,7 +9687,7 @@ public class MessagesStorage extends BaseController {
updates.updates.add(update);
Utilities.stageQueue.postRunnable(() -> getMessagesController().processUpdates(updates, false));
try {
database.executeFast(String.format(Locale.US, "DELETE FROM randoms WHERE random_id = %d AND mid = %d AND uid = %d", randomId, _oldId, dialogId)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "DELETE FROM randoms_v2 WHERE random_id = %d AND mid = %d AND uid = %d", randomId, _oldId, dialogId)).stepThis().dispose();
} catch (Exception e) {
FileLog.e(e);
}
@ -10285,7 +10380,7 @@ public class MessagesStorage extends BaseController {
ArrayList<Long> usersToLoad = new ArrayList<>();
ArrayList<Long> chatsToLoad = new ArrayList<>();
ArrayList<Integer> encryptedToLoad = new ArrayList<>();
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, m.date, d.pts, d.inbox_max, d.outbox_max, d.pinned, d.unread_count_i, d.flags, d.folder_id, d.data FROM dialogs as d LEFT JOIN messages_v2 as m ON d.last_mid = m.mid AND d.did = m.uid WHERE d.did IN(%s)", ids));
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, m.date, d.pts, d.inbox_max, d.outbox_max, d.pinned, d.unread_count_i, d.flags, d.folder_id, d.data, d.unread_reactions FROM dialogs as d LEFT JOIN messages_v2 as m ON d.last_mid = m.mid AND d.did = m.uid WHERE d.did IN(%s)", ids));
while (cursor.next()) {
long dialogId = cursor.longValue(0);
TLRPC.Dialog dialog;
@ -10319,6 +10414,7 @@ public class MessagesStorage extends BaseController {
int dialog_flags = cursor.intValue(14);
dialog.unread_mark = (dialog_flags & 1) != 0;
dialog.folder_id = cursor.intValue(15);
dialog.unread_reactions_count = cursor.intValue(17);
dialogs.dialogs.add(dialog);
@ -10999,7 +11095,7 @@ public class MessagesStorage extends BaseController {
state3.bindInteger(6, message.date);
state3.bindLong(7, dialogId);
} else {
state3 = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
state3 = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
state3.bindLong(1, dialogId);
state3.bindInteger(2, message.date);
state3.bindInteger(3, 0);
@ -11014,6 +11110,7 @@ public class MessagesStorage extends BaseController {
state3.bindInteger(12, flags);
state3.bindInteger(13, -1);
state3.bindNull(14);
state3.bindInteger(15, 0);
unknownDialogsIds.put(dialogId, true);
}
state3.step();
@ -11350,7 +11447,7 @@ public class MessagesStorage extends BaseController {
cnt = 100;
}
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, s.flags, m.date, d.pts, d.inbox_max, d.outbox_max, m.replydata, d.pinned, d.unread_count_i, d.flags, d.folder_id, d.data FROM dialogs as d LEFT JOIN messages_v2 as m ON d.last_mid = m.mid AND d.did = m.uid LEFT JOIN dialog_settings as s ON d.did = s.did WHERE d.folder_id = %d ORDER BY d.pinned DESC, d.date DESC LIMIT %d,%d", fid, off, cnt));
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, s.flags, m.date, d.pts, d.inbox_max, d.outbox_max, m.replydata, d.pinned, d.unread_count_i, d.flags, d.folder_id, d.data, d.unread_reactions FROM dialogs as d LEFT JOIN messages_v2 as m ON d.last_mid = m.mid AND d.did = m.uid LEFT JOIN dialog_settings as s ON d.did = s.did WHERE d.folder_id = %d ORDER BY d.pinned DESC, d.date DESC LIMIT %d,%d", fid, off, cnt));
while (cursor.next()) {
long dialogId = cursor.longValue(0);
TLRPC.Dialog dialog;
@ -11396,6 +11493,7 @@ public class MessagesStorage extends BaseController {
}
}
dialog.folder_id = cursor.intValue(17);
dialog.unread_reactions_count = cursor.intValue(19);
dialogs.dialogs.add(dialog);
if (draftsDialogIds != null) {
@ -11563,7 +11661,7 @@ public class MessagesStorage extends BaseController {
if (!dialogs.dialogs.isEmpty()) {
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, 0)");
SQLitePreparedStatement state_dialogs = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state_dialogs = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state_media = database.executeFast("REPLACE INTO media_v4 VALUES(?, ?, ?, ?, ?)");
SQLitePreparedStatement state_settings = database.executeFast("REPLACE INTO dialog_settings VALUES(?, ?)");
SQLitePreparedStatement state_holes = database.executeFast("REPLACE INTO messages_holes VALUES(?, ?, ?)");
@ -11729,6 +11827,7 @@ public class MessagesStorage extends BaseController {
data = null;
state_dialogs.bindNull(14);
}
state_dialogs.bindInteger(15, dialog.unread_reactions_count);
state_dialogs.step();
if (data != null) {
data.reuse();

View File

@ -18,7 +18,7 @@ import tw.nekomimi.nekogram.utils.FileUtil;
public class NativeLoader {
private final static int LIB_VERSION = 40;
private final static int LIB_VERSION = 41;
private final static String LIB_NAME = "tmessages." + LIB_VERSION;
private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so";
private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so";

View File

@ -208,6 +208,7 @@ public class NotificationCenter {
public static final int needSetDayNightTheme = totalEvents++;
public static final int goingToPreviewTheme = totalEvents++;
public static final int locationPermissionGranted = totalEvents++;
public static final int locationPermissionDenied = totalEvents++;
public static final int reloadInterface = totalEvents++;
public static final int suggestedLangpack = totalEvents++;
public static final int didSetNewWallpapper = totalEvents++;
@ -232,6 +233,7 @@ public class NotificationCenter {
public static final int emojiPreviewThemesChanged = totalEvents++;
public static final int reactionsDidLoad = totalEvents++;
public static final int chatAvailableReactionsUpdated = totalEvents++;
public static final int dialogsUnreadReactionsCounterChanged = totalEvents++;
// custom
@ -413,7 +415,7 @@ public class NotificationCenter {
delayedRunnablesTmp.addAll(delayedRunnables);
delayedRunnables.clear();
for (int a = 0; a < delayedRunnablesTmp.size(); a++) {
delayedRunnablesTmp.get(a).run();
AndroidUtilities.runOnUIThread(delayedRunnablesTmp.get(a));
}
delayedRunnablesTmp.clear();
}

View File

@ -2656,7 +2656,7 @@ public boolean retriedToSend;
return voteSendTime.get(pollId, 0L);
}
public void sendReaction(MessageObject messageObject, CharSequence reaction, ChatActivity parentFragment, Runnable callback) {
public void sendReaction(MessageObject messageObject, CharSequence reaction, boolean big, ChatActivity parentFragment, Runnable callback) {
if (messageObject == null || parentFragment == null) {
return;
}
@ -2672,6 +2672,10 @@ public boolean retriedToSend;
req.reaction = reaction.toString();
req.flags |= 1;
}
if (big) {
req.flags |= 2;
req.big = true;
}
getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) {
getMessagesController().processUpdates((TLRPC.Updates) response, false);
@ -3353,7 +3357,7 @@ public boolean retriedToSend;
newMsg.media.document = document;
if (params != null && params.containsKey("query_id")) {
type = 9;
} else if (MessageObject.isVideoDocument(document) || MessageObject.isRoundVideoDocument(document) || videoEditedInfo != null) {
} else if (!MessageObject.isVideoSticker(document) && (MessageObject.isVideoDocument(document) || MessageObject.isRoundVideoDocument(document) || videoEditedInfo != null)) {
type = 3;
} else if (MessageObject.isVoiceDocument(document)) {
type = 8;

View File

@ -140,7 +140,7 @@ public class SharedConfig {
public static boolean saveStreamMedia = true;
public static boolean smoothKeyboard = true;
public static boolean pauseMusicOnRecord = true;
public static boolean chatBlur = false;
public static boolean chatBlur = true;
public static boolean noiseSupression;
public static boolean noStatusBar;
public static boolean sortContactsByName;
@ -1212,7 +1212,7 @@ public class SharedConfig {
saveStreamMedia = preferences.getBoolean("saveStreamMedia", true);
smoothKeyboard = preferences.getBoolean("smoothKeyboard2", true);
pauseMusicOnRecord = preferences.getBoolean("pauseMusicOnRecord", false);
chatBlur = preferences.getBoolean("chatBlur", false);
chatBlur = preferences.getBoolean("chatBlur", true);
streamAllVideo = preferences.getBoolean("streamAllVideo", BuildVars.DEBUG_VERSION);
streamMkv = preferences.getBoolean("streamMkv", false);
suggestStickers = preferences.getInt("suggestStickers", 0);
@ -1819,7 +1819,7 @@ public class SharedConfig {
editor.commit();
}
public static void toggleDebugChatBlur() {
public static void toggleChatBlur() {
chatBlur = !chatBlur;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();

View File

@ -176,7 +176,7 @@ public class Browser {
if (equals) {
return url.equals("telegra.ph") || url.equals("te.legra.ph") || url.equals("graph.org");
}
return url.contains("telegra.ph") || url.contains("te.legra.ph") || url.contains("graph.org");
return url.matches("^(https?://)?(te\\.?legra\\.ph|graph\\.org).*"); // telegra.ph, te.legra.ph, graph.org
}
public static void openUrl(final Context context, Uri uri, final boolean allowCustom, boolean tryTelegraph) {

View File

@ -69,7 +69,7 @@ public class TLRPC {
public static final int MESSAGE_FLAG_HAS_BOT_ID = 0x00000800;
public static final int MESSAGE_FLAG_EDITED = 0x00008000;
public static final int LAYER = 137;
public static final int LAYER = 138;
public static class TL_stats_megagroupStats extends TLObject {
public static int constructor = 0xef7ff916;
@ -2241,28 +2241,66 @@ public class TLRPC {
}
}
public static class TL_messageUserReaction extends TLObject {
public static abstract class MessagePeerReaction extends TLObject {
public int flags;
public boolean big;
public boolean unread;
public Peer peer_id;
public String reaction;
public static TL_messagePeerReaction TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
TL_messagePeerReaction result = null;
switch (constructor) {
case 0x51b67eff:
result = new TL_messagePeerReaction();
break;
case 0x932844fa:
result = new TL_messagePeerReaction_layer137();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in MessagePeerReaction", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
return result;
}
}
public static class TL_messagePeerReaction extends MessagePeerReaction {
public static int constructor = 0x51b67eff;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
big = (flags & 1) != 0;
unread = (flags & 2) != 0;
peer_id = Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
reaction = stream.readString(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = big ? (flags | 1) : (flags &~ 1);
flags = unread ? (flags | 2) : (flags &~ 2);
stream.writeInt32(flags);
peer_id.serializeToStream(stream);
stream.writeString(reaction);
}
}
public static class TL_messagePeerReaction_layer137 extends TL_messagePeerReaction {
public static int constructor = 0x932844fa;
public long user_id;
public String reaction;
public static TL_messageUserReaction TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_messageUserReaction.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_messageUserReaction", constructor));
} else {
return null;
}
}
TL_messageUserReaction result = new TL_messageUserReaction();
result.readParams(stream, exception);
return result;
}
public void readParams(AbstractSerializedData stream, boolean exception) {
user_id = stream.readInt64(exception);
reaction = stream.readString(exception);
peer_id = new TL_peerUser();
peer_id.user_id = user_id;
}
public void serializeToStream(AbstractSerializedData stream) {
@ -22767,14 +22805,103 @@ public class TLRPC {
}
}
public static class TL_messageReactions extends TLObject {
public static int constructor = 0x87b6e36;
public static abstract class MessageReactions extends TLObject {
public int flags;
public boolean min;
public boolean can_see_list;
public ArrayList<TL_reactionCount> results = new ArrayList<>();
public ArrayList<TL_messageUserReaction> recent_reactons = new ArrayList<>();
public ArrayList<TL_messagePeerReaction> recent_reactions = new ArrayList<>();
public static TL_messageReactions TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
TL_messageReactions result = null;
switch (constructor) {
case 0x87b6e36:
result = new TL_messageReactionsOld();
break;
case 0x4f2b9479:
result = new TL_messageReactions();
break;
case 0xb87a24d1:
result = new TL_messageReactions_layer137();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in MessageReactions", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
return result;
}
}
public static class TL_messageReactions extends MessageReactions {
public static int constructor = 0x4f2b9479;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
min = (flags & 1) != 0;
can_see_list = (flags & 4) != 0;
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_reactionCount object = TL_reactionCount.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
results.add(object);
}
if ((flags & 2) != 0) {
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_messagePeerReaction object = MessagePeerReaction.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
recent_reactions.add(object);
}
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = min ? (flags | 1) : (flags &~ 1);
flags = can_see_list ? (flags | 4) : (flags &~ 4);
stream.writeInt32(flags);
stream.writeInt32(0x1cb5c415);
int count = results.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
results.get(a).serializeToStream(stream);
}
if ((flags & 2) != 0) {
stream.writeInt32(0x1cb5c415);
count = recent_reactions.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
recent_reactions.get(a).serializeToStream(stream);
}
}
}
}
public static class TL_messageReactionsOld extends TL_messageReactions {
public static int constructor = 0x87b6e36;
public static TL_messageReactions TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_messageReactions.constructor != constructor) {
@ -22818,11 +22945,11 @@ public class TLRPC {
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_messageUserReaction object = TL_messageUserReaction.TLdeserialize(stream, stream.readInt32(exception), exception);
TL_messagePeerReaction object = TL_messagePeerReaction.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
recent_reactons.add(object);
recent_reactions.add(object);
}
}
}
@ -22840,15 +22967,51 @@ public class TLRPC {
}
if ((flags & 2) != 0) {
stream.writeInt32(0x1cb5c415);
count = recent_reactons.size();
count = recent_reactions.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
recent_reactons.get(a).serializeToStream(stream);
recent_reactions.get(a).serializeToStream(stream);
}
}
}
}
public static class TL_messageReactions_layer137 extends TL_messageReactions {
public static int constructor = 0xb87a24d1;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
min = (flags & 1) != 0;
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_reactionCount object = TL_reactionCount.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
results.add(object);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = min ? (flags | 1) : (flags &~ 1);
stream.writeInt32(flags);
stream.writeInt32(0x1cb5c415);
int count = results.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
results.get(a).serializeToStream(stream);
}
}
}
public static abstract class Video extends TLObject {
public long id;
public long access_hash;
@ -28671,6 +28834,7 @@ public class TLRPC {
public Peer peer;
public int msg_id;
public TL_messageReactions reactions;
public boolean updateUnreadState = true; //custom
public void readParams(AbstractSerializedData stream, boolean exception) {
peer = Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
@ -39325,6 +39489,7 @@ public class TLRPC {
public ArrayList<PhotoSize> thumbs = new ArrayList<>();
public int thumb_dc_id;
public int thumb_version;
public boolean gifs;
public static StickerSet TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
StickerSet result = null;
@ -39384,13 +39549,13 @@ public class TLRPC {
public static class TL_stickerSet extends StickerSet {
public static int constructor = 0xd7df217a;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
archived = (flags & 2) != 0;
official = (flags & 4) != 0;
masks = (flags & 8) != 0;
animated = (flags & 32) != 0;
gifs = (flags & 64) != 0;
if ((flags & 1) != 0) {
installed_date = stream.readInt32(exception);
}
@ -39431,6 +39596,7 @@ public class TLRPC {
flags = official ? (flags | 4) : (flags &~ 4);
flags = masks ? (flags | 8) : (flags &~ 8);
flags = animated ? (flags | 32) : (flags &~ 32);
flags = gifs ? (flags | 64) : (flags &~ 64);
stream.writeInt32(flags);
if ((flags & 1) != 0) {
stream.writeInt32(installed_date);
@ -43079,11 +43245,12 @@ public class TLRPC {
}
public static class TL_messages_messageReactionsList extends TLObject {
public static int constructor = 0xa366923c;
public static int constructor = 0x31bd492d;
public int flags;
public int count;
public ArrayList<TL_messageUserReaction> reactions = new ArrayList<>();
public ArrayList<TL_messagePeerReaction> reactions = new ArrayList<>();
public ArrayList<Chat> chats = new ArrayList<>();
public ArrayList<User> users = new ArrayList<>();
public String next_offset;
@ -43112,7 +43279,7 @@ public class TLRPC {
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_messageUserReaction object = TL_messageUserReaction.TLdeserialize(stream, stream.readInt32(exception), exception);
TL_messagePeerReaction object = MessagePeerReaction.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
@ -43126,6 +43293,21 @@ public class TLRPC {
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
Chat object = Chat.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
chats.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
User object = User.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
@ -43149,6 +43331,12 @@ public class TLRPC {
reactions.get(a).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = chats.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
chats.get(a).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = users.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
@ -49569,6 +49757,7 @@ public class TLRPC {
public static int constructor = 0x25690ce4;
public int flags;
public boolean big;
public InputPeer peer;
public int msg_id;
public String reaction;
@ -49579,6 +49768,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = big ? (flags | 2) : (flags &~ 2);
stream.writeInt32(flags);
peer.serializeToStream(stream);
stream.writeInt32(msg_id);
@ -49621,6 +49811,46 @@ public class TLRPC {
}
}
public static class TL_messages_getUnreadReactions extends TLObject {
public static int constructor = 0xe85bae1a;
public InputPeer peer;
public int offset_id;
public int add_offset;
public int limit;
public int max_id;
public int min_id;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return messages_Messages.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
peer.serializeToStream(stream);
stream.writeInt32(offset_id);
stream.writeInt32(add_offset);
stream.writeInt32(limit);
stream.writeInt32(max_id);
stream.writeInt32(min_id);
}
}
public static class TL_messages_readReactions extends TLObject {
public static int constructor = 0x82e251d7;
public InputPeer peer;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TL_messages_affectedHistory.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
peer.serializeToStream(stream);
}
}
public static class TL_messages_getMessagesReactions extends TLObject {
public static int constructor = 0x8bba90e6;
@ -54168,7 +54398,7 @@ public class TLRPC {
grouped_id = stream.readInt64(exception);
}
if ((flags & 1048576) != 0) {
reactions = TL_messageReactions.TLdeserialize(stream, stream.readInt32(exception), exception);
reactions = MessageReactions.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 4194304) != 0) {
int magic = stream.readInt32(exception);
@ -55186,7 +55416,7 @@ public class TLRPC {
grouped_id = stream.readInt64(exception);
}
if ((flags & 1048576) != 0) {
reactions = TL_messageReactions.TLdeserialize(stream, stream.readInt32(exception), exception);
reactions = MessageReactions.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 4194304) != 0) {
int magic = stream.readInt32(exception);
@ -55349,7 +55579,7 @@ public class TLRPC {
grouped_id = stream.readInt64(exception);
}
if ((flags & 1048576) != 0) {
reactions = TL_messageReactions.TLdeserialize(stream, stream.readInt32(exception), exception);
reactions = MessageReactions.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 4194304) != 0) {
stream.readString(exception);
@ -56390,6 +56620,7 @@ public class TLRPC {
public int read_outbox_max_id;
public int unread_count;
public int unread_mentions_count;
public int unread_reactions_count;
public PeerNotifySettings notify_settings;
public int pts;
public DraftMessage draft;
@ -56401,7 +56632,7 @@ public class TLRPC {
public static Dialog TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
Dialog result = null;
switch (constructor) {
case 0x2c171f72:
case 0xa8edd0f5:
result = new TL_dialog();
break;
case 0x71bd134c:
@ -56419,8 +56650,7 @@ public class TLRPC {
}
public static class TL_dialog extends Dialog {
public static int constructor = 0x2c171f72;
public static int constructor = 0xa8edd0f5;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
@ -56432,6 +56662,7 @@ public class TLRPC {
read_outbox_max_id = stream.readInt32(exception);
unread_count = stream.readInt32(exception);
unread_mentions_count = stream.readInt32(exception);
unread_reactions_count = stream.readInt32(exception);
notify_settings = PeerNotifySettings.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 1) != 0) {
pts = stream.readInt32(exception);
@ -56455,6 +56686,7 @@ public class TLRPC {
stream.writeInt32(read_outbox_max_id);
stream.writeInt32(unread_count);
stream.writeInt32(unread_mentions_count);
stream.writeInt32(unread_reactions_count);
notify_settings.serializeToStream(stream);
if ((flags & 1) != 0) {
stream.writeInt32(pts);

View File

@ -503,7 +503,36 @@ public class ActionBar extends FrameLayout {
actionMode = new ActionBarMenu(getContext(), this) {
@Override
public void setBackgroundColor(int color) {
super.setBackgroundColor(actionModeColor = color);
actionModeColor = color;
if (!blurredBackground) {
super.setBackgroundColor(actionModeColor);
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (blurredBackground) {
rectTmp.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
blurScrimPaint.setColor(actionModeColor);
contentView.drawBlur(canvas, 0, rectTmp, blurScrimPaint, true);
}
super.dispatchDraw(canvas);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (contentView != null) {
contentView.blurBehindViews.add(this);
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (contentView != null) {
contentView.blurBehindViews.remove(this);
}
}
};
actionMode.isActionMode = true;
@ -519,17 +548,17 @@ public class ActionBar extends FrameLayout {
actionMode.setLayoutParams(layoutParams);
actionMode.setVisibility(INVISIBLE);
if (occupyStatusBar && needTop && actionModeTop == null) {
actionModeTop = new View(getContext());
actionModeTop.setBackgroundColor(getThemedColor(Theme.key_actionBarActionModeDefaultTop));
addView(actionModeTop);
layoutParams = (FrameLayout.LayoutParams) actionModeTop.getLayoutParams();
layoutParams.height = AndroidUtilities.statusBarHeight;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
actionModeTop.setLayoutParams(layoutParams);
actionModeTop.setVisibility(INVISIBLE);
}
// if (occupyStatusBar && needTop && actionModeTop == null && !blurredBackground) {
// actionModeTop = new View(getContext());
// actionModeTop.setBackgroundColor(getThemedColor(Theme.key_actionBarActionModeDefaultTop));
// addView(actionModeTop);
// layoutParams = (FrameLayout.LayoutParams) actionModeTop.getLayoutParams();
// layoutParams.height = AndroidUtilities.statusBarHeight;
// layoutParams.width = LayoutHelper.MATCH_PARENT;
// layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
// actionModeTop.setLayoutParams(layoutParams);
// actionModeTop.setVisibility(INVISIBLE);
// }
return actionMode;
}

View File

@ -1640,11 +1640,11 @@ public class ActionBarLayout extends FrameLayout {
}
}
public void showLastFragment() {
public void showFragment(int i) {
if (fragmentsStack.isEmpty()) {
return;
}
for (int a = 0; a < fragmentsStack.size() - 1; a++) {
for (int a = 0; a < i; a++) {
BaseFragment previousFragment = fragmentsStack.get(a);
if (previousFragment.actionBar != null && previousFragment.actionBar.shouldAddToContainer()) {
ViewGroup parent = (ViewGroup) previousFragment.actionBar.getParent();
@ -1661,7 +1661,7 @@ public class ActionBarLayout extends FrameLayout {
}
}
}
BaseFragment previousFragment = fragmentsStack.get(fragmentsStack.size() - 1);
BaseFragment previousFragment = fragmentsStack.get(i);
previousFragment.setParentLayout(this);
View fragmentView = previousFragment.fragmentView;
if (fragmentView == null) {
@ -1695,6 +1695,13 @@ public class ActionBarLayout extends FrameLayout {
}
}
public void showLastFragment() {
if (fragmentsStack.isEmpty()) {
return;
}
showFragment(fragmentsStack.size() - 1);
}
private void removeFragmentFromStackInternal(BaseFragment fragment) {
fragment.onPause();
fragment.onFragmentDestroy();

View File

@ -1281,6 +1281,9 @@ public class BottomSheet extends Dialog {
onClickListener.onClick(BottomSheet.this, item);
}
AndroidUtilities.runOnUIThread(() -> {
if (onHideListener != null) {
onHideListener.onDismiss(BottomSheet.this);
}
try {
BottomSheet.super.dismiss();
} catch (Exception e) {
@ -1500,6 +1503,11 @@ public class BottomSheet extends Dialog {
bottomSheet.isFullscreen = value;
return bottomSheet;
}
public Builder setOnPreDismissListener(OnDismissListener onDismissListener) {
bottomSheet.setOnHideListener(onDismissListener);
return this;
}
}
public int getLeftInset() {

View File

@ -179,6 +179,7 @@ public final class FloatingToolbar {
}
}
private static final int TRANSLATE = 16908353; // android.R.id.textAssist;
private void doShow() {
List<MenuItem> menuItems = getVisibleAndEnabledMenuItems(mMenu);
Collections.sort(menuItems, mMenuItemComparator);
@ -219,7 +220,7 @@ public final class FloatingToolbar {
Menu subMenu = menuItem.getSubMenu();
if (subMenu != null) {
menuItems.addAll(getVisibleAndEnabledMenuItems(subMenu));
} else {
} else if (menuItem.getItemId() != TRANSLATE) {
menuItems.add(menuItem);
}
}
@ -833,17 +834,17 @@ public final class FloatingToolbar {
boolean isFirstItem = true;
while (!remainingMenuItems.isEmpty()) {
final MenuItem menuItem = remainingMenuItems.peek();
boolean isLastItem = remainingMenuItems.size() == 1;
/*if (!isFirstItem && menuItem.requiresOverflow()) {
break;
}*/
final View menuItemButton = createMenuItemButton(mContext, menuItem, mIconTextSpacing);
final View menuItemButton = createMenuItemButton(mContext, menuItem, mIconTextSpacing, isFirstItem, isLastItem);
if (menuItemButton instanceof LinearLayout) {
((LinearLayout) menuItemButton).setGravity(Gravity.CENTER);
}
if (isFirstItem) {
menuItemButton.setPaddingRelative((int) (1.5 * menuItemButton.getPaddingStart()), menuItemButton.getPaddingTop(), menuItemButton.getPaddingEnd(), menuItemButton.getPaddingBottom());
}
boolean isLastItem = remainingMenuItems.size() == 1;
if (isLastItem) {
menuItemButton.setPaddingRelative(menuItemButton.getPaddingStart(), menuItemButton.getPaddingTop(), (int) (1.5 * menuItemButton.getPaddingEnd()), menuItemButton.getPaddingBottom());
}
@ -1111,7 +1112,7 @@ public final class FloatingToolbar {
setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight(), AndroidUtilities.dp(6));
outline.setRoundRect(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight() + AndroidUtilities.dp(6), AndroidUtilities.dp(6));
}
});
setClipToOutline(true);
@ -1182,14 +1183,14 @@ public final class FloatingToolbar {
}
private View createMenuButton(MenuItem menuItem) {
View button = createMenuItemButton(mContext, menuItem, mIconTextSpacing);
View button = createMenuItemButton(mContext, menuItem, mIconTextSpacing, false, false);
button.setPadding(mSidePadding, 0, mSidePadding, 0);
return button;
}
}
}
private View createMenuItemButton(Context context, MenuItem menuItem, int iconTextSpacing) {
private View createMenuItemButton(Context context, MenuItem menuItem, int iconTextSpacing, boolean first, boolean last) {
LinearLayout menuItemButton = new LinearLayout(context);
menuItemButton.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
menuItemButton.setOrientation(LinearLayout.HORIZONTAL);
@ -1206,16 +1207,21 @@ public final class FloatingToolbar {
textView.setFocusable(false);
textView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
textView.setFocusableInTouchMode(false);
int selectorColor = Theme.getColor(Theme.key_listSelector);
if (currentStyle == STYLE_DIALOG) {
textView.setTextColor(getThemedColor(Theme.key_dialogTextBlack));
menuItemButton.setBackgroundDrawable(Theme.getSelectorDrawable(false));
} else if (currentStyle == STYLE_BLACK) {
textView.setTextColor(0xfffafafa);
menuItemButton.setBackgroundDrawable(Theme.getSelectorDrawable(0x40ffffff, false));
selectorColor = 0x40ffffff;
} else if (currentStyle == STYLE_THEME) {
textView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
menuItemButton.setBackgroundDrawable(Theme.getSelectorDrawable(false));
}
if (first) {
menuItemButton.setBackgroundDrawable(Theme.createRadSelectorDrawable(selectorColor, first ? 6 : 0, 0, 0, first ? 6 : 0));
} else {
menuItemButton.setBackgroundDrawable(Theme.getSelectorDrawable(selectorColor, false));
}
textView.setPaddingRelative(AndroidUtilities.dp(11), 0, 0, 0);
menuItemButton.addView(textView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, AndroidUtilities.dp(48)));
if (menuItem != null) {

View File

@ -2706,6 +2706,7 @@ public class Theme {
public static Drawable dialogs_verifiedCheckDrawable;
public static Drawable dialogs_pinnedDrawable;
public static Drawable dialogs_mentionDrawable;
public static Drawable dialogs_reactionsMentionDrawable;
public static Drawable dialogs_holidayDrawable;
public static RLottieDrawable dialogs_archiveAvatarDrawable;
public static RLottieDrawable dialogs_archiveDrawable;
@ -4458,7 +4459,7 @@ public class Theme {
defaultColors.put(key_chat_outTextSelectionHighlight, 0x2E3F9923);
defaultColors.put(key_chat_inTextSelectionHighlight, 0x5062A9E3);
defaultColors.put(key_chat_TextSelectionCursor, 0xFF419FE8);
defaultColors.put(key_chat_BlurAlpha, 0xAF000000);
defaultColors.put(key_chat_BlurAlpha, 0xFF000000);
defaultColors.put(key_statisticChartSignature, 0x7f252529);
defaultColors.put(key_statisticChartSignatureAlpha, 0x7f252529);
@ -6001,24 +6002,33 @@ public class Theme {
private Path path = new Path();
private RectF rect = new RectF();
private float[] radii = new float[8];
private int topRad;
private int bottomRad;
public RippleRadMaskDrawable(int top, int bottom) {
topRad = top;
bottomRad = bottom;
public RippleRadMaskDrawable(float top, float bottom) {
radii[0] = radii[1] = radii[2] = radii[3] = AndroidUtilities.dp(top);
radii[4] = radii[5] = radii[6] = radii[7] = AndroidUtilities.dp(bottom);
}
public RippleRadMaskDrawable(float topLeft, float topRight, float bottomRight, float bottomLeft) {
radii[0] = radii[1] = AndroidUtilities.dp(topLeft);
radii[2] = radii[3] = AndroidUtilities.dp(topRight);
radii[4] = radii[5] = AndroidUtilities.dp(bottomRight);
radii[6] = radii[7] = AndroidUtilities.dp(bottomLeft);
}
public void setRadius(int top, int bottom) {
topRad = top;
bottomRad = bottom;
public void setRadius(float top, float bottom) {
radii[0] = radii[1] = radii[2] = radii[3] = AndroidUtilities.dp(top);
radii[4] = radii[5] = radii[6] = radii[7] = AndroidUtilities.dp(bottom);
invalidateSelf();
}
public void setRadius(float topLeft, float topRight, float bottomRight, float bottomLeft) {
radii[0] = radii[1] = AndroidUtilities.dp(topLeft);
radii[2] = radii[3] = AndroidUtilities.dp(topRight);
radii[4] = radii[5] = AndroidUtilities.dp(bottomRight);
radii[6] = radii[7] = AndroidUtilities.dp(bottomLeft);
invalidateSelf();
}
@Override
public void draw(Canvas canvas) {
radii[0] = radii[1] = radii[2] = radii[3] = AndroidUtilities.dp(topRad);
radii[4] = radii[5] = radii[6] = radii[7] = AndroidUtilities.dp(bottomRad);
rect.set(getBounds());
path.addRoundRect(rect, radii, Path.Direction.CW);
canvas.drawPath(path, maskPaint);
@ -6058,7 +6068,6 @@ public class Theme {
}
public static Drawable createRadSelectorDrawable(int color, int topRad, int bottomRad) {
Drawable drawable;
if (Build.VERSION.SDK_INT >= 21) {
maskPaint.setColor(0xffffffff);
Drawable maskDrawable = new RippleRadMaskDrawable(topRad, bottomRad);
@ -6075,6 +6084,23 @@ public class Theme {
return stateListDrawable;
}
}
public static Drawable createRadSelectorDrawable(int color, int topLeftRad, int topRightRad, int bottomRightRad, int bottomLeftRad) {
if (Build.VERSION.SDK_INT >= 21) {
maskPaint.setColor(0xffffffff);
Drawable maskDrawable = new RippleRadMaskDrawable(topLeftRad, topRightRad, bottomRightRad, bottomLeftRad);
ColorStateList colorStateList = new ColorStateList(
new int[][]{StateSet.WILD_CARD},
new int[]{color}
);
return new RippleDrawable(colorStateList, null, maskDrawable);
} else {
StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(color));
stateListDrawable.addState(new int[]{android.R.attr.state_selected}, new ColorDrawable(color));
stateListDrawable.addState(StateSet.WILD_CARD, new ColorDrawable(0x00000000));
return stateListDrawable;
}
}
public static void applyPreviousTheme() {
if (previousTheme == null) {
@ -8170,6 +8196,7 @@ public class Theme {
dialogs_fakeDrawable = new ScamDrawable(11, 1);
dialogs_verifiedCheckDrawable = resources.getDrawable(R.drawable.verified_check).mutate();
dialogs_mentionDrawable = resources.getDrawable(R.drawable.mentionchatslist);
dialogs_reactionsMentionDrawable = resources.getDrawable(R.drawable.reactionchatslist);
dialogs_botDrawable = resources.getDrawable(R.drawable.list_bot);
dialogs_pinnedDrawable = resources.getDrawable(R.drawable.list_pin);
moveUpDrawable = resources.getDrawable(R.drawable.preview_open);
@ -8245,6 +8272,7 @@ public class Theme {
setDrawableColorByKey(dialogs_reorderDrawable, key_chats_pinnedIcon);
setDrawableColorByKey(dialogs_muteDrawable, key_chats_muteIcon);
setDrawableColorByKey(dialogs_mentionDrawable, key_chats_mentionIcon);
setDrawableColorByKey(dialogs_reactionsMentionDrawable, key_chats_mentionIcon);
setDrawableColorByKey(dialogs_verifiedDrawable, key_chats_verifiedBackground);
setDrawableColorByKey(dialogs_verifiedCheckDrawable, key_chats_verifiedCheck);
setDrawableColorByKey(dialogs_holidayDrawable, key_actionBarDefaultTitle);

View File

@ -30,6 +30,7 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
void didLoadSearchResult(ArrayList<TLRPC.TL_messageMediaVenue> places);
}
protected boolean searched = false;
protected boolean searching;
protected ArrayList<TLRPC.TL_messageMediaVenue> places = new ArrayList<>();
protected ArrayList<String> iconUrls = new ArrayList<>();
@ -109,6 +110,24 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
searchPlacesWithQuery(query, coordinate, searchUser, false);
}
protected void notifyStartSearch(boolean wasSearching, int oldItemCount, boolean animated) {
if (animated && Build.VERSION.SDK_INT >= 19) {
if (places.isEmpty() || wasSearching) {
if (!wasSearching) {
int fromIndex = Math.max(0, getItemCount() - 4);
notifyItemRangeRemoved(fromIndex, getItemCount() - fromIndex);
}
} else {
int placesCount = places.size() + 3;
int offset = oldItemCount - placesCount;
notifyItemInserted(offset);
notifyItemRangeRemoved(offset, placesCount);
}
} else {
notifyDataSetChanged();
}
}
public void searchPlacesWithQuery(final String query, final Location coordinate, boolean searchUser, boolean animated) {
if (coordinate == null || lastSearchLocation != null && coordinate.distanceTo(lastSearchLocation) < 200) {
return;
@ -125,6 +144,8 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
int oldItemCount = getItemCount();
boolean wasSearching = searching;
searching = true;
boolean wasSearched = searched;
searched = true;
TLObject object = MessagesController.getInstance(currentAccount).getUserOrChat(MessagesController.getInstance(currentAccount).venueSearchBot);
if (!(object instanceof TLRPC.User)) {
@ -152,14 +173,14 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
}
currentRequestNum = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
currentRequestNum = 0;
searching = false;
places.clear();
iconUrls.clear();
searchInProgress = false;
lastFoundQuery = query;
if (error == null) {
currentRequestNum = 0;
searching = false;
places.clear();
iconUrls.clear();
searchInProgress = false;
lastFoundQuery = query;
TLRPC.messages_BotResults res = (TLRPC.messages_BotResults) response;
for (int a = 0, size = res.results.size(); a < size; a++) {
TLRPC.BotInlineResult result = res.results.get(a);
@ -183,19 +204,8 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
}
notifyDataSetChanged();
}));
if (animated && Build.VERSION.SDK_INT >= 19) {
if (places.isEmpty() || wasSearching) {
if (!wasSearching) {
notifyItemChanged(getItemCount() - 1);
}
} else {
int placesCount = places.size() + 1;
int offset = oldItemCount - placesCount;
notifyItemInserted(offset);
notifyItemRangeRemoved(offset, placesCount);
}
} else {
notifyDataSetChanged();
}
notifyDataSetChanged();
// notifyStartSearch(wasSearched, wasSearching, oldItemCount, animated);
}
}

View File

@ -330,9 +330,13 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
return archiveHintCell != null ? archiveHintCell.getViewPager() : null;
}
public void updateHasHints() {
hasHints = folderId == 0 && dialogsType == 0 && !isOnlySelect && !MessagesController.getInstance(currentAccount).hintDialogs.isEmpty();
}
@Override
public void notifyDataSetChanged() {
hasHints = folderId == 0 && dialogsType == 0 && !isOnlySelect && !MessagesController.getInstance(currentAccount).hintDialogs.isEmpty();
updateHasHints();
super.notifyDataSetChanged();
}
@ -496,6 +500,19 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
return new RecyclerListView.Holder(view);
}
public int lastDialogsEmptyType = -1;
public int dialogsEmptyType() {
if (dialogsType == 7 || dialogsType == 8) {
if (MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId)) {
return 2;
} else {
return 3;
}
} else {
return onlineContacts != null ? 1 : 0;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) {
switch (holder.getItemViewType()) {
@ -519,15 +536,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
}
case 5: {
DialogsEmptyCell cell = (DialogsEmptyCell) holder.itemView;
if (dialogsType == 7 || dialogsType == 8) {
if (MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId)) {
cell.setType(2);
} else {
cell.setType(3);
}
} else {
cell.setType(onlineContacts != null ? 1 : 0);
}
cell.setType(lastDialogsEmptyType = dialogsEmptyType());
break;
}
case 4: {

View File

@ -361,6 +361,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
delegate.searchStateChanged(waitingResponseCount > 0, true);
delegate.runResultsEnterAnimation();
}
globalSearchCollapsed = true;
phoneCollapsed = true;
notifyDataSetChanged();
}
}
@ -703,6 +705,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
searchWas = false;
lastSearchId = 0;
waitingResponseCount = 0;
globalSearchCollapsed = true;
phoneCollapsed = true;
if (delegate != null) {
delegate.searchStateChanged(false, true);
}
@ -723,6 +727,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
for (int a = 0; a < hashtags.size(); a++) {
searchResultHashtags.add(hashtags.get(a).hashtag);
}
globalSearchCollapsed = true;
phoneCollapsed = true;
waitingResponseCount = 0;
notifyDataSetChanged();
if (delegate != null) {
@ -735,6 +741,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
final int searchId = ++lastSearchId;
waitingResponseCount = 3;
globalSearchCollapsed = true;
phoneCollapsed = true;
notifyDataSetChanged();
if (delegate != null) {
delegate.searchStateChanged(true, false);
@ -779,7 +787,13 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
count += searchResult.size();
int localServerCount = searchAdapterHelper.getLocalServerSearch().size();
int globalCount = searchAdapterHelper.getGlobalSearch().size();
if (globalCount > 3 && globalSearchCollapsed) {
globalCount = 3;
}
int phoneCount = searchAdapterHelper.getPhoneSearch().size();
if (phoneCount > 3 && phoneCollapsed) {
phoneCount = 3;
}
int messagesCount = searchResultMessages.size();
count += localServerCount;
if (globalCount != 0) {
@ -828,7 +842,13 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
int localCount = searchResult.size();
int localServerCount = localServerSearch.size();
int phoneCount = phoneSearch.size();
if (phoneCount > 3 && phoneCollapsed) {
phoneCount = 3;
}
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
if (globalCount > 4 && globalSearchCollapsed) {
globalCount = 4;
}
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
if (i >= 0 && i < localCount) {
return searchResult.get(i);
@ -868,7 +888,13 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
int localCount = searchResult.size();
int localServerCount = localServerSearch.size();
int phoneCount = searchAdapterHelper.getPhoneSearch().size();
if (phoneCount > 3 && phoneCollapsed) {
phoneCount = 3;
}
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
if (globalCount > 4 && globalSearchCollapsed) {
globalCount = 4;
}
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
if (i >= 0 && i < localCount) {
@ -940,6 +966,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return super.onInterceptTouchEvent(e);
}
};
horizontalListView.setSelectorRadius(AndroidUtilities.dp(4));
horizontalListView.setSelectorDrawableColor(Theme.getColor(Theme.key_listSelector));
horizontalListView.setTag(9);
horizontalListView.setItemAnimator(null);
horizontalListView.setLayoutAnimation(null);
@ -1019,11 +1047,17 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
int localCount = searchResult.size();
int localServerCount = searchAdapterHelper.getLocalServerSearch().size();
int phoneCount = phoneSearch.size();
if (phoneCount > 3 && phoneCollapsed) {
phoneCount = 3;
}
int phoneCount2 = phoneCount;
if (phoneCount > 0 && phoneSearch.get(phoneCount - 1) instanceof String) {
phoneCount2 -= 2;
}
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
if (globalCount > 4 && globalSearchCollapsed) {
globalCount = 4;
}
cell.useSeparator = (position != getItemCount() - 1 && position != localCount + phoneCount2 + localServerCount - 1 && position != localCount + globalCount + phoneCount + localServerCount - 1);
if (position < searchResult.size()) {
name = searchResultNames.get(position);
@ -1129,19 +1163,49 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
int localCount = searchResult.size();
int localServerCount = searchAdapterHelper.getLocalServerSearch().size();
int phoneCount = searchAdapterHelper.getPhoneSearch().size();
if (phoneCount > 3 && phoneCollapsed) {
phoneCount = 3;
}
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
if (globalCount > 4 && globalSearchCollapsed) {
globalCount = 4;
}
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
position -= localCount + localServerCount;
String title;
boolean showMore = false;
Runnable onClick = null;
if (position >= 0 && position < phoneCount) {
cell.setText(LocaleController.getString("PhoneNumberSearch", R.string.PhoneNumberSearch));
title = LocaleController.getString("PhoneNumberSearch", R.string.PhoneNumberSearch);
if (searchAdapterHelper.getPhoneSearch().size() > 3) {
showMore = phoneCollapsed;
onClick = () -> {
phoneCollapsed = !phoneCollapsed;
notifyDataSetChanged();
};
}
} else {
position -= phoneCount;
if (position >= 0 && position < globalCount) {
cell.setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch));
title = LocaleController.getString("GlobalSearch", R.string.GlobalSearch);
if (searchAdapterHelper.getGlobalSearch().size() > 3) {
showMore = globalSearchCollapsed;
onClick = () -> {
globalSearchCollapsed = !globalSearchCollapsed;
notifyDataSetChanged();
};
}
} else {
cell.setText(LocaleController.getString("SearchMessages", R.string.SearchMessages));
title = LocaleController.getString("SearchMessages", R.string.SearchMessages);
}
}
if (onClick == null) {
cell.setText(title);
} else {
final Runnable finalOnClick = onClick;
cell.setText(title, showMore ? LocaleController.getString("ShowMore", R.string.ShowMore) : LocaleController.getString("ShowLess", R.string.ShowLess), e -> finalOnClick.run());
}
}
break;
}
@ -1173,6 +1237,9 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
}
boolean globalSearchCollapsed = true;
boolean phoneCollapsed = true;
@Override
public int getItemViewType(int i) {
if (isRecentSearchDisplayed()) {
@ -1192,7 +1259,13 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
int localCount = searchResult.size();
int localServerCount = searchAdapterHelper.getLocalServerSearch().size();
int phoneCount = searchAdapterHelper.getPhoneSearch().size();
if (phoneCount > 3 && phoneCollapsed) {
phoneCount = 3;
}
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
if (globalCount > 4 && globalSearchCollapsed) {
globalCount = 4;
}
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
if (i >= 0 && i < localCount) {

View File

@ -17,7 +17,9 @@ import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.LocationController;
import org.telegram.messenger.MessageObject;
@ -35,6 +37,7 @@ import org.telegram.ui.Cells.SendLocationCell;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.SharingLiveLocationCell;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.LocationActivity;
@ -43,6 +46,8 @@ import java.util.Locale;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.gms.vision.Frame;
public class LocationActivityAdapter extends BaseLocationAdapter implements LocationController.LocationFetchCallback {
private int currentAccount = UserConfig.selectedAccount;
@ -65,6 +70,8 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
private Runnable updateRunnable;
private final Theme.ResourcesProvider resourcesProvider;
private FlickerLoadingView globalGradientView;
public LocationActivityAdapter(Context context, int type, long did, boolean emptyView, Theme.ResourcesProvider resourcesProvider) {
super();
mContext = context;
@ -72,10 +79,31 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
dialogId = did;
needEmptyView = emptyView;
this.resourcesProvider = resourcesProvider;
globalGradientView = new FlickerLoadingView(context);
globalGradientView.setIsSingleCell(true);
}
private boolean myLocationDenied = false;
public void setMyLocationDenied(boolean myLocationDenied) {
if (this.myLocationDenied == myLocationDenied)
return;
this.myLocationDenied = myLocationDenied;
notifyDataSetChanged();
}
public void setOverScrollHeight(int value) {
overScrollHeight = value;
if (emptyCell != null) {
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) emptyCell.getLayoutParams();
if (lp == null) {
lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, overScrollHeight);
} else {
lp.height = overScrollHeight;
}
emptyCell.setLayoutParams(lp);
emptyCell.forceLayout();
}
}
public void setUpdateRunnable(Runnable runnable) {
@ -143,7 +171,7 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
private void updateCell() {
if (sendLocationCell != null) {
if (locationType == LocationActivity.LOCATION_TYPE_GROUP || customLocation != null) {
String address;
String address = "";
if (!TextUtils.isEmpty(addressName)) {
address = addressName;
} else if (customLocation == null && gpsLocation == null || fetchingLocation) {
@ -152,7 +180,7 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
address = String.format(Locale.US, "(%f,%f)", customLocation.getLatitude(), customLocation.getLongitude());
} else if (gpsLocation != null) {
address = String.format(Locale.US, "(%f,%f)", gpsLocation.getLatitude(), gpsLocation.getLongitude());
} else {
} else if (!myLocationDenied) {
address = LocaleController.getString("Loading", R.string.Loading);
}
if (locationType == LocationActivity.LOCATION_TYPE_GROUP) {
@ -160,11 +188,14 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
} else {
sendLocationCell.setText(LocaleController.getString("SendSelectedLocation", R.string.SendSelectedLocation), address);
}
sendLocationCell.setHasLocation(true);
} else {
if (gpsLocation != null) {
sendLocationCell.setText(LocaleController.getString("SendLocation", R.string.SendLocation), LocaleController.formatString("AccurateTo", R.string.AccurateTo, LocaleController.formatPluralString("Meters", (int) gpsLocation.getAccuracy())));
sendLocationCell.setHasLocation(true);
} else {
sendLocationCell.setText(LocaleController.getString("SendLocation", R.string.SendLocation), LocaleController.getString("Loading", R.string.Loading));
sendLocationCell.setText(LocaleController.getString("SendLocation", R.string.SendLocation), myLocationDenied ? "" : LocaleController.getString("Loading", R.string.Loading));
sendLocationCell.setHasLocation(!myLocationDenied);
}
}
}
@ -231,36 +262,36 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
} else if (locationType == 2) {
return 2 + currentLiveLocations.size();
} else {
if (searching || places.isEmpty()) {
return (locationType != 0 ? 6 : 5) + (needEmptyView ? 1 : 0);
}
if (locationType == 1) {
return 6 + places.size() + (needEmptyView ? 1 : 0);
} else {
return 5 + places.size() + (needEmptyView ? 1 : 0);
if (searching || !searched || places.isEmpty()) {
return (locationType != LocationActivity.LOCATION_TYPE_SEND ? 6 : 5) + (!myLocationDenied && (searching || !searched) ? 2 : 0) + (needEmptyView ? 1 : 0) - (myLocationDenied ? 2 : 0);
}
return (locationType == LocationActivity.LOCATION_TYPE_SEND_WITH_LIVE ? 6 : 5) + places.size() + (needEmptyView ? 1 : 0);
}
}
private FrameLayout emptyCell;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case 0:
view = new EmptyCell(mContext) {
@Override
public ViewPropertyAnimator animate() {
ViewPropertyAnimator animator = super.animate();
if (Build.VERSION.SDK_INT >= 19) {
animator.setUpdateListener(animation -> {
if (updateRunnable != null) {
updateRunnable.run();
}
});
}
return animator;
}
};
// view = emptyCell = new EmptyCell(mContext) {
// @Override
// public ViewPropertyAnimator animate() {
// ViewPropertyAnimator animator = super.animate();
// if (Build.VERSION.SDK_INT >= 19) {
// animator.setUpdateListener(animation -> {
// if (updateRunnable != null) {
// updateRunnable.run();
// }
// });
// }
// return animator;
// }
// };
view = emptyCell = new FrameLayout(mContext);
emptyCell.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, overScrollHeight));
break;
case 1:
view = new SendLocationCell(mContext, false, resourcesProvider);
@ -269,7 +300,8 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
view = new HeaderCell(mContext, resourcesProvider);
break;
case 3:
view = new LocationCell(mContext, false, resourcesProvider);
LocationCell locationCell = new LocationCell(mContext, false, resourcesProvider);
view = locationCell;
break;
case 4:
view = new LocationLoadingCell(mContext, resourcesProvider);
@ -313,7 +345,13 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
((EmptyCell) holder.itemView).setHeight(overScrollHeight);
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
if (lp == null) {
lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, overScrollHeight);
} else {
lp.height = overScrollHeight;
}
holder.itemView.setLayoutParams(lp);
break;
case 1:
sendLocationCell = (SendLocationCell) holder.itemView;
@ -335,7 +373,9 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
} else {
position -= 5;
}
cell.setLocation(places.get(position), iconUrls.get(position), position, true);
TLRPC.TL_messageMediaVenue place = position < 0 || position >= places.size() || !searched ? null : places.get(position);
String iconUrl = position < 0 || position >= iconUrls.size() || !searched ? null : iconUrls.get(position);
cell.setLocation(place, iconUrl, position, true);
break;
}
case 4:
@ -347,15 +387,19 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
case 7:
SharingLiveLocationCell locationCell = (SharingLiveLocationCell) holder.itemView;
if (locationType == LocationActivity.LOCATION_TYPE_LIVE_VIEW) {
locationCell.setDialog(currentMessageObject, gpsLocation);
locationCell.setDialog(currentMessageObject, gpsLocation, myLocationDenied);
} else if (chatLocation != null) {
locationCell.setDialog(dialogId, chatLocation);
} else if (currentMessageObject != null && position == 1) {
locationCell.setDialog(currentMessageObject, gpsLocation);
locationCell.setDialog(currentMessageObject, gpsLocation, myLocationDenied);
} else {
locationCell.setDialog(currentLiveLocations.get(position - (currentMessageObject != null ? 5 : 2)), gpsLocation);
}
break;
case 10:
View emptyView = holder.itemView;
emptyView.setBackgroundColor(Theme.getColor(myLocationDenied ? Theme.key_dialogBackgroundGray : Theme.key_dialogBackground));
break;
}
}
@ -451,7 +495,9 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
return 9;
} else if (position == 4) {
return 2;
} else if (searching || places.isEmpty()) {
} else if (searching || places.isEmpty() || !searched) {
if (position <= 4 + 3 && (searching || !searched) && !myLocationDenied)
return 3;
return 4;
} else if (position == places.size() + 5) {
return 5;
@ -464,6 +510,8 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
} else if (position == 3) {
return 2;
} else if (searching || places.isEmpty()) {
if (position <= 3 + 3 && (searching || !searched) && !myLocationDenied)
return 3;
return 4;
} else if (position == places.size() + 4) {
return 5;

View File

@ -13,6 +13,7 @@ import android.view.ViewGroup;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Cells.LocationCell;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.RecyclerListView;
import androidx.recyclerview.widget.RecyclerView;
@ -21,27 +22,40 @@ public class LocationActivitySearchAdapter extends BaseLocationAdapter {
private Context mContext;
private FlickerLoadingView globalGradientView;
public LocationActivitySearchAdapter(Context context) {
super();
mContext = context;
globalGradientView = new FlickerLoadingView(context);
globalGradientView.setIsSingleCell(true);
}
@Override
public int getItemCount() {
return places.size();
return (isSearching() ? 3 : places.size());
}
public boolean isEmpty() { return places.size() == 0; }
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new RecyclerListView.Holder(new LocationCell(mContext, false, null));
LocationCell locationCell = new LocationCell(mContext, false, null);
return new RecyclerListView.Holder(locationCell);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((LocationCell) holder.itemView).setLocation(places.get(position), iconUrls.get(position), position, position != places.size() - 1);
TLRPC.TL_messageMediaVenue place = getItem(position);
String iconUrl = !isSearching() && position >= 0 && position < iconUrls.size() ? iconUrls.get(position) : null;
LocationCell locationCell = (LocationCell) holder.itemView;
locationCell.setLocation(place, iconUrl, position, position != getItemCount() - 1);
}
public TLRPC.TL_messageMediaVenue getItem(int i) {
if (isSearching())
return null;
if (i >= 0 && i < places.size()) {
return places.get(i);
}
@ -52,4 +66,11 @@ public class LocationActivitySearchAdapter extends BaseLocationAdapter {
public boolean isEnabled(RecyclerView.ViewHolder holder) {
return true;
}
@Override
protected void notifyStartSearch(boolean wasSearching, int oldItemCount, boolean animated) {
if (wasSearching)
return;
notifyDataSetChanged();
}
}

View File

@ -8,6 +8,8 @@
package org.telegram.ui.Adapters;
import android.util.Pair;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
@ -20,14 +22,17 @@ import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ChatUsersActivity;
import org.telegram.ui.Components.ShareAlert;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -62,8 +67,7 @@ public class SearchAdapterHelper {
private SearchAdapterHelperDelegate delegate;
private int reqId = 0;
private int lastReqId;
private ArrayList<Integer> pendingRequestIds = new ArrayList<>();
private String lastFoundUsername = null;
private ArrayList<TLObject> localServerSearch = new ArrayList<>();
private ArrayList<TLObject> globalSearch = new ArrayList<>();
@ -76,8 +80,6 @@ public class SearchAdapterHelper {
private int currentAccount = UserConfig.selectedAccount;
private int channelReqId = 0;
private int channelLastReqId;
private String lastFoundChannel;
private boolean allResultsAreGlobal;
@ -102,18 +104,16 @@ public class SearchAdapterHelper {
}
public boolean isSearchInProgress() {
return reqId != 0 || channelReqId != 0;
return pendingRequestIds.size() > 0;
}
public void queryServerSearch(String query, boolean allowUsername, boolean allowChats, boolean allowBots, boolean allowSelf, boolean canAddGroupsOnly, long channelId, boolean phoneNumbers, int type, int searchId) {
if (reqId != 0) {
queryServerSearch(query, allowUsername, allowChats, allowBots, allowSelf, canAddGroupsOnly, channelId, phoneNumbers, type, searchId, null);
}
public void queryServerSearch(String query, boolean allowUsername, boolean allowChats, boolean allowBots, boolean allowSelf, boolean canAddGroupsOnly, long channelId, boolean phoneNumbers, int type, int searchId, Runnable onEnd) {
for (int reqId : pendingRequestIds) {
ConnectionsManager.getInstance(currentAccount).cancelRequest(reqId, true);
reqId = 0;
}
if (channelReqId != 0) {
ConnectionsManager.getInstance(currentAccount).cancelRequest(channelReqId, true);
channelReqId = 0;
}
pendingRequestIds.clear();
if (query == null) {
groupSearch.clear();
groupSearchMap.clear();
@ -122,11 +122,12 @@ public class SearchAdapterHelper {
localServerSearch.clear();
phonesSearch.clear();
phoneSearchMap.clear();
lastReqId = 0;
channelLastReqId = 0;
delegate.onDataSetChanged(searchId);
return;
}
boolean hasChanged = false;
ArrayList<Pair<TLObject, RequestDelegate>> requests = new ArrayList<>();
if (query.length() > 0) {
if (channelId != 0) {
TLRPC.TL_channels_getParticipants req = new TLRPC.TL_channels_getParticipants();
@ -143,56 +144,42 @@ public class SearchAdapterHelper {
req.limit = 50;
req.offset = 0;
req.channel = MessagesController.getInstance(currentAccount).getInputChannel(channelId);
final int currentReqId = ++channelLastReqId;
channelReqId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (currentReqId == channelLastReqId) {
channelReqId = 0;
if (error == null) {
TLRPC.TL_channels_channelParticipants res = (TLRPC.TL_channels_channelParticipants) response;
lastFoundChannel = query.toLowerCase();
MessagesController.getInstance(currentAccount).putUsers(res.users, false);
MessagesController.getInstance(currentAccount).putChats(res.chats, false);
groupSearch.clear();
groupSearchMap.clear();
groupSearch.addAll(res.participants);
long currentUserId = UserConfig.getInstance(currentAccount).getClientUserId();
for (int a = 0, N = res.participants.size(); a < N; a++) {
TLRPC.ChannelParticipant participant = res.participants.get(a);
long peerId = MessageObject.getPeerId(participant.peer);
if (!allowSelf && peerId == currentUserId) {
groupSearch.remove(participant);
continue;
}
groupSearchMap.put(peerId, participant);
requests.add(new Pair<>(req, (response, error) -> {
if (error == null) {
TLRPC.TL_channels_channelParticipants res = (TLRPC.TL_channels_channelParticipants) response;
lastFoundChannel = query.toLowerCase();
MessagesController.getInstance(currentAccount).putUsers(res.users, false);
MessagesController.getInstance(currentAccount).putChats(res.chats, false);
groupSearch.clear();
groupSearchMap.clear();
groupSearch.addAll(res.participants);
long currentUserId = UserConfig.getInstance(currentAccount).getClientUserId();
for (int a = 0, N = res.participants.size(); a < N; a++) {
TLRPC.ChannelParticipant participant = res.participants.get(a);
long peerId = MessageObject.getPeerId(participant.peer);
if (!allowSelf && peerId == currentUserId) {
groupSearch.remove(participant);
continue;
}
removeGroupSearchFromGlobal();
if (localSearchResults != null) {
mergeResults(localSearchResults);
}
delegate.onDataSetChanged(searchId);
groupSearchMap.put(peerId, participant);
}
}
}), ConnectionsManager.RequestFlagFailOnServerErrors);
}));
} else {
lastFoundChannel = query.toLowerCase();
}
} else {
groupSearch.clear();
groupSearchMap.clear();
channelLastReqId = 0;
delegate.onDataSetChanged(searchId);
hasChanged = true;
}
if (allowUsername) {
if (query.length() > 0) {
TLRPC.TL_contacts_search req = new TLRPC.TL_contacts_search();
req.q = query;
req.limit = 50;
final int currentReqId = ++lastReqId;
reqId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (currentReqId == lastReqId) {
reqId = 0;
}
if (currentReqId == lastReqId && delegate.canApplySearchResults(searchId)) {
req.limit = 10;
requests.add(new Pair<>(req, (response, error) -> {
if (delegate.canApplySearchResults(searchId)) {
if (error == null) {
TLRPC.TL_contacts_found res = (TLRPC.TL_contacts_found) response;
globalSearch.clear();
@ -274,22 +261,15 @@ public class SearchAdapterHelper {
}
}
}
removeGroupSearchFromGlobal();
lastFoundUsername = query.toLowerCase();
if (localSearchResults != null) {
mergeResults(localSearchResults);
}
mergeExcludeResults();
delegate.onDataSetChanged(searchId);
}
}
}), ConnectionsManager.RequestFlagFailOnServerErrors);
}));
} else {
globalSearch.clear();
globalSearchMap.clear();
localServerSearch.clear();
lastReqId = 0;
delegate.onDataSetChanged(searchId);
hasChanged = false;
}
}
if (!canAddGroupsOnly && phoneNumbers && query.startsWith("+") && query.length() > 3) {
@ -316,8 +296,49 @@ public class SearchAdapterHelper {
phonesSearch.add("section");
phonesSearch.add(phone);
}
hasChanged = false;
}
if (hasChanged) {
delegate.onDataSetChanged(searchId);
}
final AtomicInteger gotResponses = new AtomicInteger(0);
final ArrayList<Pair<TLObject, TLRPC.TL_error>> responses = new ArrayList<>();
for (int i = 0; i < requests.size(); ++i) {
final int index = i;
Pair<TLObject, RequestDelegate> r = requests.get(i);
TLObject req = r.first;
responses.add(null);
AtomicInteger reqId = new AtomicInteger();
reqId.set(ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
responses.set(index, new Pair<>(response, error));
Integer reqIdValue = reqId.get();
if (!pendingRequestIds.contains(reqIdValue)) {
return;
}
pendingRequestIds.remove(reqIdValue);
if (gotResponses.incrementAndGet() == requests.size()) {
for (int j = 0; j < requests.size(); ++j) {
RequestDelegate callback = requests.get(j).second;
Pair<TLObject, TLRPC.TL_error> res = responses.get(j);
if (res == null)
continue;
callback.run(res.first, res.second);
}
removeGroupSearchFromGlobal();
if (localSearchResults != null) {
mergeResults(localSearchResults);
}
mergeExcludeResults();
delegate.onDataSetChanged(searchId);
if (onEnd != null) {
onEnd.run();
}
}
})));
pendingRequestIds.add(reqId.get());
}
}
private void removeGroupSearchFromGlobal() {

View File

@ -164,6 +164,7 @@ import org.telegram.ui.Components.TextPaintMarkSpan;
import org.telegram.ui.Components.TextPaintSpan;
import org.telegram.ui.Components.TextPaintUrlSpan;
import org.telegram.ui.Components.TextPaintWebpageUrlSpan;
import org.telegram.ui.Components.TranslateAlert;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.WebPlayerView;
@ -413,6 +414,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
searchPath.setCurrentLayout(textLayout, result.index, 0);
searchPath.setBaselineShift(0);
textLayout.getSelectionPath(result.index, result.index + searchText.length(), searchPath);
searchPath.onPathEnd();
searchPath.setAllowReset(true);
}
} else {
@ -1286,7 +1288,9 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
deleteView.setOnClickListener(v -> {
if (pressedLinkOwnerLayout != null) {
AndroidUtilities.addToClipboard(pressedLinkOwnerLayout.getText());
Toast.makeText(parentActivity, LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
Toast.makeText(parentActivity, LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show();
}
}
if (popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss(true);
@ -2574,6 +2578,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
int shift = innerSpans[a].getTextPaint() != null ? innerSpans[a].getTextPaint().baselineShift : 0;
textPath.setBaselineShift(shift != 0 ? shift + AndroidUtilities.dp(shift > 0 ? 5 : -2) : 0);
result.getSelectionPath(start, end, textPath);
textPath.onPathEnd();
}
textPath.setAllowReset(true);
}
@ -2592,6 +2597,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
int shift = innerSpans[a].getTextPaint() != null ? innerSpans[a].getTextPaint().baselineShift : 0;
markPath.setBaselineShift(shift != 0 ? shift + AndroidUtilities.dp(shift > 0 ? 5 : -2) : 0);
result.getSelectionPath(start, end, markPath);
markPath.onPathEnd();
}
markPath.setAllowReset(true);
}
@ -2680,6 +2686,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
int shift = pressedLink.getTextPaint() != null ? pressedLink.getTextPaint().baselineShift : 0;
urlPath.setBaselineShift(shift != 0 ? shift + AndroidUtilities.dp(shift > 0 ? 5 : -2) : 0);
layout.getSelectionPath(pressedStart, pressedEnd, urlPath);
urlPath.onPathEnd();
parentView.invalidate();
} catch (Exception e) {
FileLog.e(e);
@ -3702,6 +3709,11 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
textSelectionHelper = new TextSelectionHelper.ArticleTextSelectionHelper();
textSelectionHelper.setParentView(listView[0]);
if (MessagesController.getGlobalMainSettings().getBoolean("translate_button", false)) {
textSelectionHelper.setOnTranslate((text, fromLang, toLang, onAlertDismiss) -> {
TranslateAlert.showAlert(parentActivity, parentFragment, fromLang, toLang, text, false, null, onAlertDismiss);
});
}
textSelectionHelper.layoutManager = layoutManager[0];
textSelectionHelper.setCallback(new TextSelectionHelper.Callback() {
@Override
@ -3713,7 +3725,9 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
@Override
public void onTextCopied() {
BulletinFactory.of(containerView, null).createCopyBulletin(LocaleController.getString("TextCopied", R.string.TextCopied)).show();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
BulletinFactory.of(containerView, null).createCopyBulletin(LocaleController.getString("TextCopied", R.string.TextCopied)).show();
}
}
});
containerView.addView(textSelectionHelper.getOverlayView(activity));
@ -6145,7 +6159,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
File path = FileLoader.getPathToAttach(currentDocument, true);
if (autoDownload || path.exists()) {
imageView.setStrippedLocation(null);
imageView.setImage(ImageLocation.getForDocument(currentDocument), null, null, null, ImageLocation.getForDocument(thumb, currentDocument), "80_80_b", null, currentDocument.size, null, parentAdapter.currentPage, 1);
imageView.setImage(ImageLocation.getForDocument(currentDocument), ImageLoader.AUTOPLAY_FILTER, null, null, ImageLocation.getForDocument(thumb, currentDocument), "80_80_b", null, currentDocument.size, null, parentAdapter.currentPage, 1);
} else {
imageView.setStrippedLocation(ImageLocation.getForDocument(currentDocument));
imageView.setImage(null, null, null, null, ImageLocation.getForDocument(thumb, currentDocument), "80_80_b", null, currentDocument.size, null, parentAdapter.currentPage, 1);

View File

@ -313,6 +313,8 @@ public class BubbleActivity extends Activity implements ActionBarLayout.ActionBa
} else if (requestCode == 2) {
if (granted) {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.locationPermissionGranted);
} else {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.locationPermissionDenied);
}
}
if (actionBarLayout.fragmentsStack.size() != 0) {

View File

@ -442,6 +442,7 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
int shift = getText() != null ? getPaint().baselineShift : 0;
textPath.setBaselineShift(shift != 0 ? shift + AndroidUtilities.dp(shift > 0 ? 5 : -2) : 0);
getLayout().getSelectionPath(start, end, textPath);
textPath.onPathEnd();
}
textPath.setAllowReset(true);
}

View File

@ -8,9 +8,17 @@
package org.telegram.ui.Cells;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Layout;
import android.text.Spannable;
@ -22,11 +30,16 @@ import android.text.style.URLSpan;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
@ -45,6 +58,8 @@ import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.Components.StaticLayoutEx;
import org.telegram.ui.Components.URLSpanNoUnderline;
import java.util.concurrent.atomic.AtomicReference;
public class AboutLinkCell extends FrameLayout {
private StaticLayout textLayout;
@ -53,18 +68,80 @@ public class AboutLinkCell extends FrameLayout {
private int textY;
private SpannableStringBuilder stringBuilder;
private TextView valueTextView;
private TextView showMoreTextView;
private FrameLayout showMoreTextBackgroundView;
private FrameLayout bottomShadow;
private Drawable showMoreBackgroundDrawable;
private ClickableSpan pressedLink;
private LinkPath urlPath = new LinkPath();
private Point urlPathOffset = new Point();
private LinkPath urlPath = new LinkPath(true);
private BaseFragment parentFragment;
private FrameLayout container;
private Drawable rippleBackground;
public AboutLinkCell(Context context, BaseFragment fragment) {
super(context);
parentFragment = fragment;
container = new FrameLayout(context) {
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
boolean result = false;
if (textLayout != null || nextLinesLayouts != null) {
if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
if (x >= showMoreTextView.getLeft() && x <= showMoreTextView.getRight() &&
y >= showMoreTextView.getTop() && y <= showMoreTextView.getBottom()) {
return super.onTouchEvent(event);
}
if (getMeasuredWidth() > 0 && x > getMeasuredWidth() - AndroidUtilities.dp(23)) {
return super.onTouchEvent(event);
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (firstThreeLinesLayout != null && expandT < 1 && shouldExpand) {
if (checkTouchTextLayout(firstThreeLinesLayout, textX, textY, x, y)) {
result = true;
} else if (nextLinesLayouts != null) {
for (int i = 0; i < nextLinesLayouts.length; ++i) {
if (checkTouchTextLayout(nextLinesLayouts[i], nextLinesLayoutsPositions[i].x, nextLinesLayoutsPositions[i].y, x, y)) {
result = true;
break;
}
}
}
} else if (checkTouchTextLayout(textLayout, textX, textY, x, y)) {
result = true;
}
if (!result) {
resetPressedLink();
}
} else if (pressedLink != null) {
try {
onLinkClick(pressedLink);
} catch (Exception e) {
FileLog.e(e);
}
resetPressedLink();
result = true;
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
resetPressedLink();
}
}
return result || super.onTouchEvent(event);
}
};
container.setClickable(true);
rippleBackground = Theme.createRadSelectorDrawable(Theme.getColor(Theme.key_listSelector), 0, 0);
valueTextView = new EmojiTextView(context);
valueTextView.setVisibility(GONE);
valueTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2));
valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
valueTextView.setLines(1);
@ -72,18 +149,185 @@ public class AboutLinkCell extends FrameLayout {
valueTextView.setSingleLine(true);
valueTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
valueTextView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM, 23, 0, 23, 10));
container.addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM, 23, 0, 23, 10));
bottomShadow = new FrameLayout(context);
Drawable shadowDrawable = context.getResources().getDrawable(R.drawable.gradient_bottom).mutate();
shadowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhite), PorterDuff.Mode.SRC_ATOP));
bottomShadow.setBackground(shadowDrawable);
addView(bottomShadow, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 12, Gravity.BOTTOM | Gravity.FILL_HORIZONTAL, 0, 0, 0, 0));
addView(container, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.FILL_HORIZONTAL));
showMoreTextView = new TextView(context) {
private boolean pressed = false;
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean wasPressed = pressed;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
pressed = true;
} else if (event.getAction() != MotionEvent.ACTION_MOVE) {
pressed = false;
}
if (wasPressed != pressed) {
invalidate();
}
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
if (pressed) {
AndroidUtilities.rectTmp.set(0, 0, getWidth(), getHeight());
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(4), AndroidUtilities.dp(4), Theme.chat_urlPaint);
}
super.onDraw(canvas);
}
};
showMoreTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText));
showMoreTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
showMoreTextView.setLines(1);
showMoreTextView.setMaxLines(1);
showMoreTextView.setSingleLine(true);
showMoreTextView.setText(LocaleController.getString("DescriptionMore", R.string.DescriptionMore));
showMoreTextView.setOnClickListener(e -> {
updateCollapse(true, true);
});
showMoreTextView.setPadding(AndroidUtilities.dp(2), 0, AndroidUtilities.dp(2), 0);
showMoreTextBackgroundView = new FrameLayout(context);
showMoreBackgroundDrawable = context.getResources().getDrawable(R.drawable.gradient_left).mutate();
showMoreBackgroundDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhite), PorterDuff.Mode.MULTIPLY));
showMoreTextBackgroundView.setBackground(showMoreBackgroundDrawable);
showMoreTextBackgroundView.setPadding(
showMoreTextBackgroundView.getPaddingLeft() + AndroidUtilities.dp(4),
AndroidUtilities.dp(1),
0,
AndroidUtilities.dp(3)
);
showMoreTextBackgroundView.addView(showMoreTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
addView(showMoreTextBackgroundView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.RIGHT | Gravity.BOTTOM, 22 - showMoreTextBackgroundView.getPaddingLeft() / AndroidUtilities.density, 0, 22 - showMoreTextBackgroundView.getPaddingRight() / AndroidUtilities.density, 6));
backgroundPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite));
setWillNotDraw(false);
}
private void setShowMoreMarginBottom(int marginBottom) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) showMoreTextBackgroundView.getLayoutParams();
if (lp.bottomMargin != marginBottom) {
lp.bottomMargin = marginBottom;
showMoreTextBackgroundView.setLayoutParams(lp);
}
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
return false;
}
private Paint backgroundPaint = new Paint();
@Override
public void draw(Canvas canvas) {
View parent = (View) getParent();
float alpha = parent == null ? 1f : (float) Math.pow(parent.getAlpha(), 2f);
drawText(canvas);
float viewAlpha = showMoreTextBackgroundView.getAlpha();
if (viewAlpha > 0) {
canvas.save();
canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), (int) (viewAlpha * 255), Canvas.ALL_SAVE_FLAG);
showMoreBackgroundDrawable.setAlpha((int) (alpha * 255));
canvas.translate(showMoreTextBackgroundView.getLeft(), showMoreTextBackgroundView.getTop());
showMoreTextBackgroundView.draw(canvas);
canvas.restore();
}
viewAlpha = bottomShadow.getAlpha();
if (viewAlpha > 0) {
canvas.save();
canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), (int) (viewAlpha * 255), Canvas.ALL_SAVE_FLAG);
canvas.translate(bottomShadow.getLeft(), bottomShadow.getTop());
bottomShadow.draw(canvas);
canvas.restore();
}
container.draw(canvas);
super.draw(canvas);
}
final float SPACE = AndroidUtilities.dp(3f);
private void drawText(Canvas canvas) {
canvas.save();
AndroidUtilities.rectTmp.set(AndroidUtilities.dp(23 - 8), AndroidUtilities.dp(8), getWidth() - AndroidUtilities.dp(23), getHeight());
canvas.clipRect(AndroidUtilities.rectTmp);
if (pressedLink != null) {
canvas.save();
canvas.translate(urlPathOffset.x, urlPathOffset.y);
canvas.drawPath(urlPath, Theme.linkSelectionPaint);
canvas.restore();
}
canvas.translate(textX = AndroidUtilities.dp(23), textY = AndroidUtilities.dp(8));
try {
if (firstThreeLinesLayout == null || !shouldExpand) {
if (textLayout != null) {
textLayout.draw(canvas);
}
} else {
firstThreeLinesLayout.draw(canvas);
int lastLine = firstThreeLinesLayout.getLineCount() - 1;
float top = firstThreeLinesLayout.getLineTop(lastLine) + firstThreeLinesLayout.getTopPadding();
float x = firstThreeLinesLayout.getLineRight(lastLine) + (needSpace ? SPACE : 0),
y = firstThreeLinesLayout.getLineBottom(lastLine) - firstThreeLinesLayout.getLineTop(lastLine) - firstThreeLinesLayout.getBottomPadding();
float t = easeInOutCubic(1f - (float) Math.pow(expandT, 0.25f));
if (nextLinesLayouts != null) {
for (int line = 0; line < nextLinesLayouts.length; ++line) {
final StaticLayout layout = nextLinesLayouts[line];
if (layout != null) {
final int c = canvas.save();
if (nextLinesLayoutsPositions[line] != null) {
nextLinesLayoutsPositions[line].set((int) (textX + x * t), (int) (textY + top + y * (1f - t)));
}
if (lastInlineLine != -1 && lastInlineLine <= line) {
canvas.translate(0, top + y);
canvas.saveLayerAlpha(0, 0, layout.getWidth(), layout.getHeight(), (int) (255 * expandT), Canvas.ALL_SAVE_FLAG);
} else {
canvas.translate(x * t, top + y * (1f - t));
}
layout.draw(canvas);
canvas.restoreToCount(c);
x += layout.getLineRight(0) + SPACE;
y += layout.getLineBottom(0) + layout.getTopPadding();
}
}
}
}
} catch (Exception e) {
FileLog.e(e);
}
canvas.restore();
}
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
container.setOnClickListener(l);
}
protected void didPressUrl(String url) {
}
protected void didResizeStart() {
}
protected void didResizeEnd() {
}
protected void didExtend() {}
private void resetPressedLink() {
if (pressedLink != null) {
pressedLink = null;
container.invalidate();
}
AndroidUtilities.cancelRunOnUIThread(longPressedRunnable);
invalidate();
@ -105,6 +349,11 @@ public class AboutLinkCell extends FrameLayout {
stringBuilder = new SpannableStringBuilder(oldText);
MessageObject.addLinks(false, stringBuilder, false, false, !parseLinks);
Emoji.replaceEmoji(stringBuilder, Theme.profile_aboutTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
if (lastMaxWidth <= 0) {
lastMaxWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(23 + 23);
}
checkTextLayout(lastMaxWidth, true);
updateHeight();
if (TextUtils.isEmpty(value)) {
valueTextView.setVisibility(GONE);
} else {
@ -135,12 +384,14 @@ public class AboutLinkCell extends FrameLayout {
onLinkClick(pressedLinkFinal);
} else if (which == 1) {
AndroidUtilities.addToClipboard(url);
if (url.startsWith("@")) {
BulletinFactory.of(parentFragment).createSimpleBulletin(R.raw.copy, LocaleController.getString("UsernameCopied", R.string.UsernameCopied)).show();
} else if (url.startsWith("#") || url.startsWith("$")) {
BulletinFactory.of(parentFragment).createSimpleBulletin(R.raw.copy, LocaleController.getString("HashtagCopied", R.string.HashtagCopied)).show();
} else {
BulletinFactory.of(parentFragment).createSimpleBulletin(R.raw.copy, LocaleController.getString("LinkCopied", R.string.LinkCopied)).show();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
if (url.startsWith("@")) {
BulletinFactory.of(parentFragment).createSimpleBulletin(R.raw.copy, LocaleController.getString("UsernameCopied", R.string.UsernameCopied)).show();
} else if (url.startsWith("#") || url.startsWith("$")) {
BulletinFactory.of(parentFragment).createSimpleBulletin(R.raw.copy, LocaleController.getString("HashtagCopied", R.string.HashtagCopied)).show();
} else {
BulletinFactory.of(parentFragment).createSimpleBulletin(R.raw.copy, LocaleController.getString("LinkCopied", R.string.LinkCopied)).show();
}
}
}
});
@ -150,63 +401,42 @@ public class AboutLinkCell extends FrameLayout {
}
};
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
private boolean checkTouchTextLayout(StaticLayout textLayout, int textX, int textY, int ex, int ey) {
try {
int x = (int) (ex - textX);
int y = (int) (ey - textY);
final int line = textLayout.getLineForVertical(y);
final int off = textLayout.getOffsetForHorizontal(line, x);
boolean result = false;
if (textLayout != null) {
if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
final float left = textLayout.getLineLeft(line);
if (left <= x && left + textLayout.getLineWidth(line) >= x && y >= 0 && y <= textLayout.getHeight()) {
Spannable buffer = (Spannable) textLayout.getText();
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
resetPressedLink();
pressedLink = link[0];
try {
int x2 = (int) (x - textX);
int y2 = (int) (y - textY);
final int line = textLayout.getLineForVertical(y2);
final int off = textLayout.getOffsetForHorizontal(line, x2);
final float left = textLayout.getLineLeft(line);
if (left <= x2 && left + textLayout.getLineWidth(line) >= x2) {
Spannable buffer = (Spannable) textLayout.getText();
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
resetPressedLink();
pressedLink = link[0];
result = true;
try {
int start = buffer.getSpanStart(pressedLink);
urlPath.setCurrentLayout(textLayout, start, 0);
textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath);
} catch (Exception e) {
FileLog.e(e);
}
AndroidUtilities.runOnUIThread(longPressedRunnable, ViewConfiguration.getLongPressTimeout());
} else {
resetPressedLink();
}
} else {
resetPressedLink();
}
} catch (Exception e) {
resetPressedLink();
FileLog.e(e);
}
} else if (pressedLink != null) {
try {
onLinkClick(pressedLink);
int start = buffer.getSpanStart(pressedLink);
urlPathOffset.set(textX, textY);
urlPath.setCurrentLayout(textLayout, start, 0);
textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath);
urlPath.onPathEnd();
} catch (Exception e) {
FileLog.e(e);
}
resetPressedLink();
result = true;
container.invalidate();
AndroidUtilities.runOnUIThread(longPressedRunnable, ViewConfiguration.getLongPressTimeout());
return true;
} else {
return false;
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
resetPressedLink();
} else {
return false;
}
} catch (Exception e) {
FileLog.e(e);
return false;
}
return result || super.onTouchEvent(event);
}
private void onLinkClick(ClickableSpan pressedLink) {
@ -229,43 +459,240 @@ public class AboutLinkCell extends FrameLayout {
}
}
private static final int COLLAPSED_HEIGHT = AndroidUtilities.dp(8 + 20 * 3 + 8);
private static final int MAX_OPEN_HEIGHT = COLLAPSED_HEIGHT;// + AndroidUtilities.dp(20);
private class SpringInterpolator {
public float tension;
public float friction;
public SpringInterpolator(float tension, float friction) {
this.tension = tension;
this.friction = friction;
}
private final float mass = 1f;
private float position = 0, velocity = 0;
public float getValue(float deltaTime) {
deltaTime = Math.min(deltaTime, 250);
final float MAX_DELTA_TIME = 18;
while (deltaTime > 0) {
final float step = Math.min(deltaTime, MAX_DELTA_TIME);
step(step);
deltaTime -= step;
}
return position;
}
private void step(float delta) {
final float acceleration = (
-tension * 0.000001f * (position - 1f) + // spring force
-friction * 0.001f * velocity // damping force
) / mass; // pt/ms^2
velocity = velocity + acceleration * delta; // pt/ms
position = position + velocity * delta;
}
}
private float expandT = 0f;
private float rawCollapseT = 0f;
private ValueAnimator collapseAnimator;
private boolean expanded = false;
public void updateCollapse(boolean value, boolean animated) {
if (collapseAnimator != null) {
collapseAnimator.cancel();
collapseAnimator = null;
}
float fromValue = expandT,
toValue = value ? 1f : 0f;
if (animated) {
if (toValue > 0) {
didExtend();
}
float fullHeight = textHeight();
float collapsedHeight = Math.min(COLLAPSED_HEIGHT, fullHeight);
float fromHeight = AndroidUtilities.lerp(collapsedHeight, fullHeight, fromValue);
float toHeight = AndroidUtilities.lerp(collapsedHeight, fullHeight, toValue);
float dHeight = Math.abs(toHeight - fromHeight);
// float speedMultiplier = Math.min(Math.max(dHeight / AndroidUtilities.dp(76), 0.5f), 2f);
collapseAnimator = ValueAnimator.ofFloat(0, 1);
final float duration = Math.abs(fromValue - toValue) * 1250 * 2f;
final SpringInterpolator spring = new SpringInterpolator(380f, 20.17f);
final AtomicReference<Float> lastValue = new AtomicReference<>(fromValue);
collapseAnimator.addUpdateListener(a -> {
float now = (float) a.getAnimatedValue();
float deltaTime = (now - lastValue.getAndSet(now)) * 1000 * 8f;
rawCollapseT = AndroidUtilities.lerp(fromValue, toValue, (float) a.getAnimatedValue());
expandT = AndroidUtilities.lerp(fromValue, toValue, spring.getValue(deltaTime));
if (expandT > 0.8f && container.getBackground() == null) {
container.setBackground(rippleBackground);
}
showMoreTextBackgroundView.setAlpha(1f - expandT);
bottomShadow.setAlpha((float) Math.pow(1f - expandT, 2f));
updateHeight();
container.invalidate();
});
collapseAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
didResizeEnd();
if (container.getBackground() == null) {
container.setBackground(rippleBackground);
}
expanded = true;
}
@Override
public void onAnimationStart(Animator animation) {
didResizeStart();
}
});
collapseAnimator.setDuration((long) duration);
collapseAnimator.start();
} else {
expandT = toValue;
forceLayout();
}
}
private int updateHeight() {
int textHeight = textHeight();
float fromHeight = Math.min(COLLAPSED_HEIGHT, textHeight);
int height = shouldExpand ? (int) AndroidUtilities.lerp(fromHeight, textHeight, expandT) : textHeight;
setHeight(height);
return height;
}
private void setHeight(int height) {
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) getLayoutParams();
int wasHeight;
boolean newHeight;
if (lp == null) {
newHeight = true;
wasHeight = (getMinimumHeight() == 0 ? getHeight() : getMinimumHeight());
lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height);
} else {
wasHeight = lp.height;
newHeight = wasHeight != height;
lp.height = height;
}
if (newHeight) {
setLayoutParams(lp);
}
}
private static final int MOST_SPEC = View.MeasureSpec.makeMeasureSpec(999999, View.MeasureSpec.AT_MOST);
private int lastMaxWidth = 0;
@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (stringBuilder != null) {
int maxWidth = MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(23 + 23);
if (Build.VERSION.SDK_INT >= 24) {
textLayout = StaticLayout.Builder.obtain(stringBuilder, 0, stringBuilder.length(), Theme.profile_aboutTextPaint, maxWidth)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(LocaleController.isRTL ? StaticLayoutEx.ALIGN_RIGHT() : StaticLayoutEx.ALIGN_LEFT())
.build();
} else {
textLayout = new StaticLayout(stringBuilder, Theme.profile_aboutTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
checkTextLayout(MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(23 + 23), false);
int height = updateHeight();
super.onMeasure(
widthMeasureSpec,
// heightMeasureSpec
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
);
}
private StaticLayout makeTextLayout(CharSequence string, int width) {
if (Build.VERSION.SDK_INT >= 24) {
return StaticLayout.Builder.obtain(string, 0, string.length(), Theme.profile_aboutTextPaint, width)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(LocaleController.isRTL ? StaticLayoutEx.ALIGN_RIGHT() : StaticLayoutEx.ALIGN_LEFT())
.build();
} else {
return new StaticLayout(string, Theme.profile_aboutTextPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
}
private StaticLayout firstThreeLinesLayout;
private StaticLayout[] nextLinesLayouts = null;
private int lastInlineLine = -1;
private Point[] nextLinesLayoutsPositions;
private boolean needSpace = false;
private void checkTextLayout(int maxWidth, boolean force) {
if (stringBuilder != null && (maxWidth != lastMaxWidth || force)) {
textLayout = makeTextLayout(stringBuilder, maxWidth);
shouldExpand = textLayout.getLineCount() >= 4 && valueTextView.getVisibility() != View.VISIBLE;
if (textLayout.getLineCount() >= 3 && shouldExpand) {
int end = Math.max(textLayout.getLineStart(2), textLayout.getLineEnd(2));
if (stringBuilder.charAt(end - 1) == '\n')
end -= 1;
needSpace = stringBuilder.charAt(end - 1) != ' ' && stringBuilder.charAt(end - 1) != '\n';
firstThreeLinesLayout = makeTextLayout(stringBuilder.subSequence(0, end), maxWidth);
nextLinesLayouts = new StaticLayout[textLayout.getLineCount() - 3];
nextLinesLayoutsPositions = new Point[textLayout.getLineCount() - 3];
int lastLine = firstThreeLinesLayout.getLineCount() - 1;
float x = firstThreeLinesLayout.getLineRight(lastLine) + (needSpace ? SPACE : 0);
lastInlineLine = -1;
if (showMoreTextBackgroundView.getMeasuredWidth() <= 0) {
showMoreTextBackgroundView.measure(MOST_SPEC, MOST_SPEC);
}
for (int line = 3; line < textLayout.getLineCount(); ++line) {
int s = textLayout.getLineStart(line),
e = textLayout.getLineEnd(line);
final StaticLayout layout = makeTextLayout(stringBuilder.subSequence(Math.min(s, e), Math.max(s, e)), maxWidth);
nextLinesLayouts[line - 3] = layout;
nextLinesLayoutsPositions[line - 3] = new Point();
if (lastInlineLine == -1 && x > maxWidth - showMoreTextBackgroundView.getMeasuredWidth() + showMoreTextBackgroundView.getPaddingLeft()) {
lastInlineLine = line - 3;
}
x += layout.getLineRight(0) + SPACE;
}
if (x < maxWidth - showMoreTextBackgroundView.getMeasuredWidth() + showMoreTextBackgroundView.getPaddingLeft()) {
shouldExpand = false;
}
}
if (!shouldExpand) {
firstThreeLinesLayout = null;
nextLinesLayouts = null;
}
lastMaxWidth = maxWidth;
container.setMinimumHeight(textHeight());
if (shouldExpand) {
setShowMoreMarginBottom(textHeight() - AndroidUtilities.dp(8) - textLayout.getLineBottom(textLayout.getLineCount() - 1) - showMoreTextBackgroundView.getPaddingBottom());
}
}
showMoreTextView.setVisibility(shouldExpand ? View.VISIBLE : View.GONE);
if (!shouldExpand && container.getBackground() == null) {
container.setBackground(rippleBackground);
}
if (shouldExpand && expandT < 1 && container.getBackground() != null) {
container.setBackground(null);
}
}
private int textHeight() {
int height = (textLayout != null ? textLayout.getHeight() : AndroidUtilities.dp(20)) + AndroidUtilities.dp(16);
if (valueTextView.getVisibility() == VISIBLE) {
height += AndroidUtilities.dp(23);
}
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
return height;
}
private boolean shouldExpand = false;
// private boolean shouldCollapse() {
// return textLayout != null && textLayout.getLineCount() > 4/* && valueTextView.getVisibility() != View.VISIBLE*/;
// }
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.translate(textX = AndroidUtilities.dp(23), textY = AndroidUtilities.dp(8));
if (pressedLink != null) {
canvas.drawPath(urlPath, Theme.linkSelectionPaint);
public boolean onClick() {
if (shouldExpand && expandT <= 0) {
updateCollapse(true, true);
return true;
}
try {
if (textLayout != null) {
textLayout.draw(canvas);
}
} catch (Exception e) {
FileLog.e(e);
}
canvas.restore();
return false;
}
private float easeInOutCubic(float x) {
return x < 0.5 ? 4 * x * x * x : 1 - (float) Math.pow(-2 * x + 2, 3) / 2;
}
@Override

View File

@ -151,6 +151,7 @@ public class BotHelpCell extends View {
int start = buffer.getSpanStart(pressedLink);
urlPath.setCurrentLayout(textLayout, start, 0);
textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath);
urlPath.onPathEnd();
} catch (Exception e) {
FileLog.e(e);
}

View File

@ -16,6 +16,7 @@ import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
@ -251,8 +252,28 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
public void drawScrimReaction(Canvas canvas, String scrimViewReaction) {
reactionsLayoutInBubble.draw(canvas, transitionParams.animateChangeProgress, scrimViewReaction);
if ((currentPosition == null || ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0)) && !reactionsLayoutInBubble.isSmall) {
reactionsLayoutInBubble.draw(canvas, transitionParams.animateChangeProgress, scrimViewReaction);
}
}
public boolean checkUnreadReactions(float clipTop, int clipBottom) {
if (!reactionsLayoutInBubble.hasUnreadReactions) {
return false;
}
float y = getY() + reactionsLayoutInBubble.y;
if (y > clipTop && y + reactionsLayoutInBubble.height - AndroidUtilities.dp(16) < clipBottom) {
return true;
}
return false;
}
public void markReactionsAsRead() {
reactionsLayoutInBubble.hasUnreadReactions = false;
if (currentMessageObject == null) {
return;
}
currentMessageObject.markReactionsAsRead();
}
public interface ChatMessageCellDelegate {
@ -600,6 +621,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private TLObject photoParentObject;
private TLRPC.PhotoSize currentPhotoObject;
private TLRPC.PhotoSize currentPhotoObjectThumb;
private BitmapDrawable currentPhotoObjectThumbStripped;
private String currentPhotoFilter;
private String currentPhotoFilterThumb;
@ -882,6 +904,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private boolean edited;
private boolean imageDrawn;
private Runnable unregisterFlagSecure;
private Runnable diceFinishCallback = new Runnable() {
@Override
public void run() {
@ -1096,6 +1120,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
urlPathCache.remove(0);
} else {
linkPath = new LinkPath();
linkPath.setUseRoundRect(true);
}
linkPath.reset();
if (text) {
@ -1175,6 +1200,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
pos[1] -= block.charactersOffset;
path.setCurrentLayout(block.textLayout, pos[0], 0);
block.textLayout.getSelectionPath(pos[0], pos[1], path);
path.onPathEnd();
if (pos[1] >= block.charactersEnd) {
for (int a = blockNum + 1; a < currentMessageObject.textLayoutBlocks.size(); a++) {
MessageObject.TextLayoutBlock nextBlock = currentMessageObject.textLayoutBlocks.get(a);
@ -1191,6 +1217,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
path.setCurrentLayout(nextBlock.textLayout, 0, nextBlock.textYOffset - block.textYOffset);
int p1 = pos[1] + block.charactersOffset - nextBlock.charactersOffset;
nextBlock.textLayout.getSelectionPath(0, p1, path);
path.onPathEnd();
if (p1 < nextBlock.charactersEnd - 1) {
break;
}
@ -1215,6 +1242,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int p1 = pos[1] + block.charactersOffset - nextBlock.charactersOffset;
path.setCurrentLayout(nextBlock.textLayout, p0, offsetY);
nextBlock.textLayout.getSelectionPath(p0, p1, path);
path.onPathEnd();
if (p0 > nextBlock.charactersOffset) {
break;
}
@ -1279,6 +1307,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int[] pos = getRealSpanStartAndEnd(buffer, pressedLink);
path.setCurrentLayout(captionLayout, pos[0], 0);
captionLayout.getSelectionPath(pos[0], pos[1], path);
path.onPathEnd();
} catch (Exception e) {
FileLog.e(e);
}
@ -1341,6 +1370,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int[] pos = getRealSpanStartAndEnd(buffer, pressedLink);
path.setCurrentLayout(descriptionLayout, pos[0], 0);
descriptionLayout.getSelectionPath(pos[0], pos[1], path);
path.onPathEnd();
} catch (Exception e) {
FileLog.e(e);
}
@ -1423,6 +1453,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int[] pos = getRealSpanStartAndEnd(buffer, pressedLink);
path.setCurrentLayout(descriptionLayout, pos[0], 0);
descriptionLayout.getSelectionPath(pos[0], pos[1], path);
path.onPathEnd();
} catch (Exception e) {
FileLog.e(e);
}
@ -2488,6 +2519,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
id = 0;
}
delegate.didPressChannelAvatar(this, chat != null ? chat : currentChat, id, lastTouchX, lastTouchY);
} else if (currentMessageObject != null && currentMessageObject.sponsoredChatInvite != null) {
delegate.didPressInstantButton(this, drawInstantViewType);
}
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
@ -2645,7 +2678,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private boolean checkTextSelection(MotionEvent event) {
TextSelectionHelper.ChatListTextSelectionHelper textSelectionHelper = delegate.getTextSelectionHelper();
if (textSelectionHelper == null || MessagesController.getInstance(currentAccount).isChatNoForwards(currentMessageObject.getChatId())) {
if (textSelectionHelper == null || MessagesController.getInstance(currentAccount).isChatNoForwards(currentMessageObject.getChatId()) || (currentMessageObject.messageOwner != null && currentMessageObject.messageOwner.noforwards)) {
return false;
}
boolean hasTextBlocks = currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty();
@ -2993,7 +3026,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else if (buttonState == 0 || buttonState == 3) {
didPressButton(true, false);
}
} else if (currentMessageObject.type == 4) {
} else if (currentMessageObject.type == MessageObject.TYPE_GEO) {
delegate.didPressImage(this, lastTouchX, lastTouchY);
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
if (buttonState == -1) {
@ -3035,7 +3068,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (object.type == 0 || object.type == 14) {
return false;
}
if (object.type == 4) {
if (object.type == MessageObject.TYPE_GEO) {
if (currentUrl == null) {
return true;
}
@ -3261,6 +3294,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
reactionsLayoutInBubble.onDetachFromWindow();
statusDrawableAnimationInProgress = false;
if (unregisterFlagSecure != null) {
unregisterFlagSecure.run();
unregisterFlagSecure = null;
}
}
@Override
@ -3343,6 +3381,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
toSeekBarProgress = showSeekbar ? 1f : 0f;
}
reactionsLayoutInBubble.onAttachToWindow();
updateFlagSecure();
}
private boolean lastTranslated;
@ -3473,7 +3513,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawVideoSize = false;
canStreamVideo = false;
animatingNoSound = 0;
if (MessagesController.getInstance(currentAccount).isChatNoForwards(messageObject.getChatId())) {
if (MessagesController.getInstance(currentAccount).isChatNoForwards(messageObject.getChatId()) || (messageObject.messageOwner != null && messageObject.messageOwner.noforwards)) {
drawSideButton = 0;
} else {
drawSideButton = !isRepliesChat && checkNeedDrawShareButton(messageObject) && (currentPosition == null || currentPosition.last) && !needHide ? 1 : 0;
@ -3554,6 +3594,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentPhotoObject = null;
photoParentObject = null;
currentPhotoObjectThumb = null;
currentPhotoObjectThumbStripped = null;
if (messageChanged || messageIdChanged || dataChanged) {
currentPhotoFilter = null;
}
@ -3573,6 +3614,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawForwardedName = false;
drawCommentButton = false;
photoImage.setSideClip(0);
photoImage.setAspectFit(false);
gradientShader = null;
motionBackgroundDrawable = null;
@ -3778,6 +3820,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else if ("telegram_channel".equals(webpageType)) {
drawInstantView = true;
drawInstantViewType = 1;
} else if ("telegram_user".equals(webpageType)) {
drawInstantView = true;
drawInstantViewType = 13;
} else if ("telegram_megagroup".equals(webpageType)) {
drawInstantView = true;
drawInstantViewType = 2;
@ -3990,10 +4035,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (site_name != null && photo != null && site_name.toLowerCase().equals("instagram")) {
linkPreviewMaxWidth = Math.max(AndroidUtilities.displaySize.y / 3, currentMessageObject.textWidth);
}
boolean isSmallImageType = "app".equals(type) || "profile".equals(type) || "article".equals(type) ||
"telegram_bot".equals(type) || "telegram_user".equals(type) || "telegram_channel".equals(type) || "telegram_megagroup".equals(type) || "telegram_voicechat".equals(type);
smallImage = !slideshow && (!drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 11) && document == null && isSmallImageType;
isSmallImage = !slideshow && (!drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 11) && document == null && description != null && type != null && isSmallImageType && currentMessageObject.photoThumbs != null;
boolean isSmallImageType = "app".equals(type) || "profile".equals(type) ||
"article".equals(type) || "telegram_bot".equals(type) ||
"telegram_user".equals(type) || "telegram_channel".equals(type) ||
"telegram_megagroup".equals(type) || "telegram_voicechat".equals(type);
smallImage = !slideshow && (!drawInstantView || drawInstantViewType == 1 || drawInstantViewType == 9 || drawInstantViewType == 11 || drawInstantViewType == 13) && document == null && isSmallImageType;
isSmallImage = smallImage && (drawInstantViewType == 13 || description != null) && type != null && currentMessageObject.photoThumbs != null;
} else if (hasInvoicePreview) {
TLRPC.TL_messageMediaInvoice invoice = (TLRPC.TL_messageMediaInvoice) messageObject.messageOwner.media;
site_name = messageObject.messageOwner.media.title;
@ -4219,7 +4266,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
if (smallImage && (descriptionLayout == null || titleLayout == null && descriptionLayout != null && descriptionLayout.getLineCount() == 1)) {
if (smallImage && (descriptionLayout == null && titleLayout == null)) {
smallImage = false;
isSmallImage = false;
}
@ -4272,6 +4319,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentPhotoObject == currentPhotoObjectThumb) {
currentPhotoObjectThumb = null;
}
if (currentMessageObject.strippedThumb != null) {
currentPhotoObjectThumb = null;
currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
}
if (currentPhotoObject == null) {
currentPhotoObject = new TLRPC.TL_photoSize();
currentPhotoObject.type = "s";
@ -4338,7 +4389,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
videoInfoLayout = new StaticLayout(str, Theme.chat_durationPaint, durationWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
} else if (drawInstantViewType == 7) {
currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 700);
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 40);
if (currentMessageObject.strippedThumb == null) {
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 40);
} else {
currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
}
photoParentObject = document;
if (currentPhotoObject != null && (currentPhotoObject.w == 0 || currentPhotoObject.h == 0)) {
for (int a = 0; a < document.attributes.size(); a++) {
@ -4414,7 +4469,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, isPhoto || !smallImage ? AndroidUtilities.getPhotoSize() : maxPhotoWidth, !isPhoto);
photoParentObject = messageObject.photoThumbsObject;
checkOnlyButtonPressed = !isPhoto;
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
if (currentMessageObject.strippedThumb == null) {
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
} else {
currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
}
if (currentPhotoObjectThumb == currentPhotoObject) {
currentPhotoObjectThumb = null;
}
@ -4554,7 +4613,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (document instanceof DocumentObject.ThemeDocument) {
photoImage.setImage(ImageLocation.getForDocument(document), currentPhotoFilter, null, "b1", 0, "jpg", messageObject, 1);
} else {
photoImage.setImage(ImageLocation.getForDocument(currentPhotoObject, document), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), "b1", 0, "jpg", messageObject, 1);
photoImage.setImage(ImageLocation.getForDocument(currentPhotoObject, document), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), "b1", currentPhotoObjectThumbStripped, 0, "jpg", messageObject, 1);
}
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_STICKER) {
boolean isWebpSticker = messageObject.isSticker();
@ -4575,16 +4634,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoImage.setAllowDecodeSingleFrame(true);
photoImage.setAllowStartAnimation(true);
photoImage.startAnimation();
/*TODO*/
photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, documentAttach), currentPhotoFilterThumb, null, documentAttach.size, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, documentAttach), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, messageObject, 0);
autoPlayingMedia = true;
} else {
if (currentPhotoObjectThumb != null) {
/*TODO*/
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, 0, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
} else {
/*TODO*/
photoImage.setImage(null, null, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, 0, null, messageObject, 0);
photoImage.setImage(null, null, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
}
}
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
@ -4602,14 +4658,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
autoPlayingMedia = true;
TLRPC.VideoSize videoSize = MessageObject.getDocumentVideoThumb(document);
if (!messageObject.mediaExists && videoSize != null && (currentPhotoObject == null || currentPhotoObjectThumb == null)) {
/*TODO*/
photoImage.setImage(ImageLocation.getForDocument(document), document.size < 1024 * 32 ? null : ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(videoSize, documentAttach), null, ImageLocation.getForDocument(currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb, documentAttach), currentPhotoObject != null ? filter : currentPhotoFilterThumb, null, document.size, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(document), document.size < 1024 * 32 ? null : ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(videoSize, documentAttach), null, ImageLocation.getForDocument(currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb, documentAttach), currentPhotoObject != null ? filter : currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
} else {
/*TODO*/
photoImage.setImage(ImageLocation.getForDocument(document), document.size < 1024 * 32 ? null : ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(currentPhotoObject, documentAttach), filter, ImageLocation.getForDocument(currentPhotoObjectThumb, documentAttach), currentPhotoFilterThumb, null, document.size, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(document), document.size < 1024 * 32 ? null : ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(currentPhotoObject, documentAttach), filter, ImageLocation.getForDocument(currentPhotoObjectThumb, documentAttach), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
}
} else {
/*TODO*/
photoImage.setImage(null, null, ImageLocation.getForDocument(currentPhotoObject, documentAttach), filter, 0, null, currentMessageObject, 0);
}
} else {
@ -4617,13 +4670,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
String fileName = FileLoader.getAttachFileName(currentPhotoObject);
if (hasGamePreview || photoExist || DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject) || FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
photoNotSet = false;
/*TODO*/
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, 0, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
} else {
photoNotSet = true;
if (currentPhotoObjectThumb != null) {
/*TODO*/
photoImage.setImage(null, null, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), String.format(Locale.US, "%d_%d_b", w, h), 0, null, messageObject, 0);
photoImage.setImage(null, null, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), String.format(Locale.US, "%d_%d_b", w, h), currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
} else {
photoImage.setImageBitmap((Drawable) null);
}
@ -4637,9 +4688,21 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
durationWidth = (int) Math.ceil(Theme.chat_durationPaint.measureText(str));
videoInfoLayout = new StaticLayout(str, Theme.chat_durationPaint, durationWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
} else if (hasGamePreview) {
String str = LocaleController.getString("AttachGame", R.string.AttachGame).toUpperCase();
durationWidth = (int) Math.ceil(Theme.chat_gamePaint.measureText(str));
videoInfoLayout = new StaticLayout(str, Theme.chat_gamePaint, durationWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
boolean showGameOverlay = true;
try {
long bot_id = messageObject.messageOwner.via_bot_id != 0 ? messageObject.messageOwner.via_bot_id : messageObject.messageOwner.from_id.user_id;
if (bot_id != 0) {
TLRPC.User botUser = MessagesController.getInstance(currentAccount).getUser(bot_id);
if (botUser != null && botUser.username != null && botUser.username.equals("donate")) {
showGameOverlay = false;
}
}
} catch (Exception e) {}
if (showGameOverlay) {
String str = LocaleController.getString("AttachGame", R.string.AttachGame).toUpperCase();
durationWidth = (int) Math.ceil(Theme.chat_gamePaint.measureText(str));
videoInfoLayout = new StaticLayout(str, Theme.chat_gamePaint, durationWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
}
} else {
photoImage.setImageBitmap((Drawable) null);
@ -5349,10 +5412,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
if (!reactionsLayoutInBubble.isSmall && !reactionsLayoutInBubble.isEmpty) {
if (!drawPhotoImage) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(2);
}
if (captionLayout != null && currentPosition != null && currentMessagesGroup != null && currentMessagesGroup.isDocuments) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
}
if (!drawPhotoImage && !TextUtils.isEmpty(messageObject.caption) && docTitleLayout != null && docTitleLayout.getLineCount() > 1) {
} else if (!drawPhotoImage && !TextUtils.isEmpty(messageObject.caption) && ((docTitleLayout != null && docTitleLayout.getLineCount() > 1) || currentMessageObject.hasValidReplyMessageObject())) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
}
reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(8);
@ -5370,7 +5435,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
additionHeight += reactionsLayoutInBubble.totalHeight;
}
} else if (messageObject.type == 4) { //geo
} else if (messageObject.type == MessageObject.TYPE_GEO) {
TLRPC.GeoPoint point = messageObject.messageOwner.media.geo;
double lat = point.lat;
double lon = point._long;
@ -5527,7 +5592,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoImage.setImage(currentUrl, null, null, null, 0);
}
}
if (!reactionsLayoutInBubble.isSmall) {
if (!reactionsLayoutInBubble.isSmall && !reactionsLayoutInBubble.isEmpty) {
reactionsLayoutInBubble.measure(backgroundWidth - AndroidUtilities.dp(16));
reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(14);
measureTime(messageObject);
@ -5547,8 +5612,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoHeight = attribute.h;
break;
}
if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
photoWidth = attribute.w;
photoHeight = attribute.h;
break;
}
}
if (messageObject.isAnimatedSticker() && photoWidth == 0 && photoHeight == 0) {
if ((messageObject.isAnimatedSticker() || messageObject.isVideoSticker()) && photoWidth == 0 && photoHeight == 0) {
photoWidth = photoHeight = 512;
}
float maxHeight;
@ -5581,7 +5651,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int w = (int) (photoWidth / AndroidUtilities.density);
int h = (int) (photoHeight / AndroidUtilities.density);
boolean shouldRepeatSticker = delegate != null && delegate.shouldRepeatSticker(messageObject);
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
if (currentMessageObject.strippedThumb == null) {
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
} else {
currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
}
photoParentObject = messageObject.photoThumbsObject;
if (messageObject.isDice()) {
filter = String.format(Locale.US, "%d_%d_dice_%s_%s", w, h, messageObject.getDiceEmoji(), messageObject.toString());
@ -5619,17 +5693,23 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoImage.setRoundRadius(0);
canChangeRadius = false;
if (messageObject.pathThumb != null) {
if (messageObject.isVideoSticker()) {
// photoImage.setAspectFit(true);
photoImage.setImage(ImageLocation.getForDocument(messageObject.getDocument()), ImageLoader.AUTOPLAY_FILTER,
null, null,
messageObject.pathThumb,
messageObject.getDocument().size, isWebpSticker ? "webp" : null, parentObject, 1);
} else if (messageObject.pathThumb != null) {
photoImage.setImage(ImageLocation.getForDocument(messageObject.getDocument()), filter,
messageObject.pathThumb,
messageObject.getDocument().size, isWebpSticker ? "webp" : null, parentObject, 1);
} else if (messageObject.attachPathExists) {
photoImage.setImage(ImageLocation.getForPath(messageObject.messageOwner.attachPath), filter,
ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), "b1",
ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), "b1", currentPhotoObjectThumbStripped,
messageObject.getDocument().size, isWebpSticker ? "webp" : null, parentObject, 1);
} else if (messageObject.getDocument().id != 0) {
photoImage.setImage(ImageLocation.getForDocument(messageObject.getDocument()), filter,
ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), "b1",
ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), "b1", currentPhotoObjectThumbStripped,
messageObject.getDocument().size, isWebpSticker ? "webp" : null, parentObject, 1);
} else {
photoImage.setImage(null, null, null, null, messageObject, 0);
@ -5691,6 +5771,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
needQualityPreview = true;
}
if (currentMessageObject.strippedThumb != null) {
currentPhotoObjectThumb = null;
currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
}
int w;
int h;
if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
@ -5726,15 +5810,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentPhotoObject != null && currentPhotoObject == currentPhotoObjectThumb) {
if (messageObject.type == MessageObject.TYPE_PHOTO) {
currentPhotoObjectThumb = null;
currentPhotoObjectThumbStripped = null;
} else {
currentPhotoObject = null;
}
}
if (needQualityPreview) {
/*if ((DownloadController.getInstance(currentAccount).getAutodownloadMask() & DownloadController.AUTODOWNLOAD_TYPE_PHOTO) == 0) {
currentPhotoObject = null;
}*/
if (!messageObject.needDrawBluredPreview() && (currentPhotoObject == null || currentPhotoObject == currentPhotoObjectThumb) && (currentPhotoObjectThumb == null || !"m".equals(currentPhotoObjectThumb.type))) {
photoImage.setNeedsQualityThumb(true);
photoImage.setShouldGenerateQualityThumb(true);
@ -6109,15 +6191,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
TLRPC.Document document = messageObject.getDocument();
if (currentMessageObject.videoEditedInfo != null && currentMessageObject.videoEditedInfo.canAutoPlaySourceVideo()) {
/*TODO*/
photoImage.setImage(ImageLocation.getForPath(currentMessageObject.videoEditedInfo.originalPath), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), currentPhotoFilterThumb, null, messageObject.getDocument().size, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForPath(currentMessageObject.videoEditedInfo.originalPath), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, messageObject.getDocument().size, null, messageObject, 0);
photoImage.setMediaStartEndTime(currentMessageObject.videoEditedInfo.startTime / 1000, currentMessageObject.videoEditedInfo.endTime / 1000);
} else {
if (!messageIdChanged && !dataChanged) {
photoImage.setCrossfadeWithOldImage(true);
}
/*TODO*/
photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), currentPhotoFilterThumb, null, messageObject.getDocument().size, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, messageObject.getDocument().size, null, messageObject, 0);
}
} else if (messageObject.type == MessageObject.TYPE_PHOTO) {
if (messageObject.useCustomPhoto) {
@ -6132,11 +6212,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoExist = false;
}
if (photoExist || !currentMessageObject.loadingCancelled && DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject) || FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObject.size, null, currentMessageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, currentPhotoObject.size, null, currentMessageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
} else {
photoNotSet = true;
if (currentPhotoObjectThumb != null) {
photoImage.setImage(null, null, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, 0, null, currentMessageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
photoImage.setImage(null, null, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, currentMessageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
} else {
photoImage.setImageBitmap((Drawable) null);
}
@ -6168,55 +6248,45 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoImage.setCrossfadeDuration(250);
}
if (localFile == 0 && videoSize != null && (currentPhotoObject == null || currentPhotoObjectThumb == null)) {
/*TODO*/
photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(videoSize, documentAttach), null, ImageLocation.getForDocument(currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb, documentAttach), currentPhotoObject != null ? currentPhotoFilter : currentPhotoFilterThumb, null, document.size, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(videoSize, documentAttach), null, ImageLocation.getForDocument(currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb, documentAttach), currentPhotoObject != null ? currentPhotoFilter : currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
} else {
if (isRoundVideo && !messageIdChanged && photoImage.hasStaticThumb()) {
/*TODO*/
photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, null, null, photoImage.getStaticThumb(), document.size, null, messageObject, 0);
} else {
/*TODO*/
photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, null, document.size, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
}
}
} else if (localFile == 1) {
/*TODO*/
photoImage.setImage(ImageLocation.getForPath(messageObject.isSendError() ? null : messageObject.messageOwner.attachPath), null, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, null, 0, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForPath(messageObject.isSendError() ? null : messageObject.messageOwner.attachPath), null, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
} else {
if (videoSize != null && (currentPhotoObject == null || currentPhotoObjectThumb == null)) {
/*TODO*/
photoImage.setImage(ImageLocation.getForDocument(document), null, ImageLocation.getForDocument(videoSize, documentAttach), null, ImageLocation.getForDocument(currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb, documentAttach), currentPhotoObject != null ? currentPhotoFilter : currentPhotoFilterThumb, null, document.size, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(document), null, ImageLocation.getForDocument(videoSize, documentAttach), null, ImageLocation.getForDocument(currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb, documentAttach), currentPhotoObject != null ? currentPhotoFilter : currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
} else {
/*TODO*/
photoImage.setImage(ImageLocation.getForDocument(document), null, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, null, document.size, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(document), null, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
}
}
} else {
if (messageObject.videoEditedInfo != null && messageObject.type == MessageObject.TYPE_ROUND_VIDEO && !currentMessageObject.needDrawBluredPreview()) {
/*TODO*/
photoImage.setImage(ImageLocation.getForPath(messageObject.videoEditedInfo.originalPath), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, 0, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForPath(messageObject.videoEditedInfo.originalPath), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
photoImage.setMediaStartEndTime(currentMessageObject.videoEditedInfo.startTime / 1000, currentMessageObject.videoEditedInfo.endTime / 1000);
} else {
if (!messageIdChanged && !currentMessageObject.needDrawBluredPreview()) {
photoImage.setCrossfadeWithOldImage(true);
photoImage.setCrossfadeDuration(250);
}
/*TODO*/
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, 0, null, messageObject, 0);
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, 0);
}
}
} else {
if (messageObject.videoEditedInfo != null && messageObject.type == MessageObject.TYPE_ROUND_VIDEO && !currentMessageObject.needDrawBluredPreview()) {
/*TODO*/
photoImage.setImage(ImageLocation.getForPath(messageObject.videoEditedInfo.originalPath), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, 0, null, messageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
photoImage.setImage(ImageLocation.getForPath(messageObject.videoEditedInfo.originalPath), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
photoImage.setMediaStartEndTime(currentMessageObject.videoEditedInfo.startTime / 1000, currentMessageObject.videoEditedInfo.endTime / 1000);
} else {
if (!messageIdChanged && !currentMessageObject.needDrawBluredPreview()) {
photoImage.setCrossfadeWithOldImage(true);
photoImage.setCrossfadeDuration(250);
}
/*TODO*/
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, 0, null, messageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, messageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
}
}
}
@ -6649,6 +6719,19 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
accessibilityVirtualViewBounds.clear();
transitionParams.updatePhotoImageX = true;
updateFlagSecure();
}
private void updateFlagSecure() {
boolean flagSecure = currentMessageObject != null && currentMessageObject.messageOwner != null && currentMessageObject.messageOwner.noforwards;
Activity activity = AndroidUtilities.findActivity(getContext());
if (flagSecure && unregisterFlagSecure == null && activity != null) {
unregisterFlagSecure = AndroidUtilities.registerFlagSecure(activity.getWindow());
} else if (!flagSecure && unregisterFlagSecure != null) {
unregisterFlagSecure.run();
unregisterFlagSecure = null;
}
}
private boolean needHide;
@ -7116,7 +7199,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (drawPhotoImage) {
currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 320);
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
if (currentMessageObject.strippedThumb == null) {
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
} else {
currentPhotoObjectThumbStripped = currentMessageObject.strippedThumb;
}
if ((DownloadController.getInstance(currentAccount).getAutodownloadMask() & DownloadController.AUTODOWNLOAD_TYPE_PHOTO) == 0) {
currentPhotoObject = null;
@ -7127,7 +7214,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoImage.setShouldGenerateQualityThumb(true);
}
currentPhotoFilter = "86_86_b";
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), "86_86", ImageLocation.getForObject(currentPhotoObjectThumb, messageObject.photoThumbsObject), currentPhotoFilter, 0, null, messageObject, 1);
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), "86_86", ImageLocation.getForObject(currentPhotoObjectThumb, messageObject.photoThumbsObject), currentPhotoFilter, currentPhotoObjectThumbStripped, 0, null, messageObject, 1);
}
return width;
}
@ -7214,6 +7301,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
LinkPath path = obtainNewUrlPath(true);
path.setCurrentLayout(captionLayout, start, 0);
captionLayout.getSelectionPath(start, end, path);
path.onPathEnd();
} catch (Exception e) {
FileLog.e(e);
}
@ -7228,6 +7316,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
LinkPath path = obtainNewUrlPath(true);
path.setCurrentLayout(block.textLayout, start, 0);
block.textLayout.getSelectionPath(start, end, path);
path.onPathEnd();
if (end >= block.charactersOffset + length) {
for (int a = c + 1; a < messageObject.textLayoutBlocks.size(); a++) {
MessageObject.TextLayoutBlock nextBlock = messageObject.textLayoutBlocks.get(a);
@ -7235,6 +7324,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
path = obtainNewUrlPath(true);
path.setCurrentLayout(nextBlock.textLayout, 0, nextBlock.height);
nextBlock.textLayout.getSelectionPath(0, end - nextBlock.charactersOffset, path);
path.onPathEnd();
if (end < block.charactersOffset + length - 1) {
break;
}
@ -7408,6 +7498,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
str = LocaleController.getString("OpenChannelPost", R.string.OpenChannelPost);
} else if (drawInstantViewType == 1) {
str = LocaleController.getString("OpenChannel", R.string.OpenChannel);
} else if (drawInstantViewType == 13) {
str = LocaleController.getString("SendMessage", R.string.SendMessage).toUpperCase();
} else if (drawInstantViewType == 10) {
str = LocaleController.getString("OpenBot", R.string.OpenBot);
} else if (drawInstantViewType == 2) {
@ -8059,7 +8151,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
Theme.chat_docBackPaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outBubble : Theme.key_chat_inBubble));
canvas.drawCircle(photoImage.getCenterX(), photoImage.getCenterY(), photoImage.getImageWidth() / 2, Theme.chat_docBackPaint);
}
} else if (currentMessageObject.type == 4) {
} else if (currentMessageObject.type == MessageObject.TYPE_GEO) {
rect.set(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageX2(), photoImage.getImageY2());
Theme.chat_docBackPaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outLocationBackground : Theme.key_chat_inLocationBackground));
int[] rad = photoImage.getRoundRadius();
@ -8479,7 +8571,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
FileLog.e(e);
}
}
if (currentMessageObject.type == 4 && !(currentMessageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeoLive) && currentMapProvider == 2 && photoImage.hasNotThumb()) {
if (currentMessageObject.type == MessageObject.TYPE_GEO && !(currentMessageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeoLive) && currentMapProvider == 2 && photoImage.hasNotThumb()) {
int w = (int) (Theme.chat_redLocationIcon.getIntrinsicWidth() * 0.8f);
int h = (int) (Theme.chat_redLocationIcon.getIntrinsicHeight() * 0.8f);
int x = (int) (photoImage.getImageX() + (photoImage.getImageWidth() - w) / 2);
@ -8593,7 +8685,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
linkPreviewY += currentMessageObject.textHeight + AndroidUtilities.dp(4);
}
if (drawPhotoImage && drawInstantView && drawInstantViewType != 9 || drawInstantViewType == 6 && imageBackgroundColor != 0) {
if (drawPhotoImage && drawInstantView && drawInstantViewType != 9 && drawInstantViewType != 13 && drawInstantViewType != 1 || drawInstantViewType == 6 && imageBackgroundColor != 0) {
if (linkPreviewY != startY) {
linkPreviewY += AndroidUtilities.dp(2);
}
@ -8725,7 +8817,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
linkPreviewY += descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1);
}
if (drawPhotoImage && (!drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 11)) {
if (drawPhotoImage && (!drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 11 || drawInstantViewType == 13 || drawInstantViewType == 1)) {
if (linkPreviewY != startY) {
linkPreviewY += AndroidUtilities.dp(2);
}
@ -9543,6 +9635,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
if (!currentMessageObject.loadingCancelled && autoDownload) {
buttonState = 1;
} else if (currentMessageObject.type == MessageObject.TYPE_GEO) {
buttonState = -1;
} else {
buttonState = 0;
}
@ -9667,7 +9761,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (currentMessageObject.type == MessageObject.TYPE_PHOTO) {
photoImage.setForceLoading(true);
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObject.size, null, currentMessageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, currentPhotoObject.size, null, currentMessageObject, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
} else if (currentMessageObject.type == 8) {
FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, 1, 0);
if (currentMessageObject.loadedFileSize > 0) {
@ -9707,7 +9801,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
} else {
photoImage.setForceLoading(true);
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, 0, null, currentMessageObject, 0);
photoImage.setImage(ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, 0, null, currentMessageObject, 0);
}
currentMessageObject.loadingCancelled = false;
buttonState = 1;
@ -9819,13 +9913,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (!currentMessageObject.needDrawBluredPreview() && !autoPlayingMedia && documentAttach != null) {
if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, null, documentAttach.size, null, currentMessageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, currentMessageObject, 0);
photoImage.setAllowStartAnimation(true);
photoImage.startAnimation();
autoPlayingMedia = true;
} else if (SharedConfig.autoplayVideo && documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0)) {
animatingNoSound = 2;
photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, null, documentAttach.size, null, currentMessageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, currentMessageObject, 0);
if (!PhotoViewer.isPlayingMessage(currentMessageObject)) {
photoImage.setAllowStartAnimation(true);
photoImage.startAnimation();
@ -9834,7 +9928,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
autoPlayingMedia = true;
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, null, documentAttach.size, null, currentMessageObject, 0);
photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, currentMessageObject, 0);
if (SharedConfig.autoplayGifs) {
photoImage.setAllowStartAnimation(true);
photoImage.startAnimation();
@ -10314,6 +10408,17 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
avatarDrawable.setInfo(currentChat);
avatarImage.setForUserOrChat(currentChat, avatarDrawable);
} else if (messageObject != null && messageObject.isSponsored()) {
if (messageObject.sponsoredChatInvite != null && messageObject.sponsoredChatInvite.chat != null) {
avatarDrawable.setInfo(messageObject.sponsoredChatInvite.chat);
avatarImage.setForUserOrChat(messageObject.sponsoredChatInvite.chat, avatarDrawable);
} else {
avatarDrawable.setInfo(messageObject.sponsoredChatInvite);
TLRPC.Photo photo = messageObject.sponsoredChatInvite.photo;
if (photo != null) {
avatarImage.setImage(ImageLocation.getForPhoto(photo.sizes.get(0), photo), "50_50", avatarDrawable, null, null, 0);
}
}
} else {
currentPhoto = null;
avatarDrawable.setInfo(messageObject.getFromChatId(), null, null);
@ -10768,7 +10873,15 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return UserObject.getUserName(currentUser);
} else if (currentChat != null) {
return currentChat.title;
} else {
} else if (currentMessageObject != null && currentMessageObject.isSponsored()) {
if (currentMessageObject.sponsoredChatInvite != null && currentMessageObject.sponsoredChatInvite.title != null) {
return currentMessageObject.sponsoredChatInvite.title;
}
if (currentMessageObject.sponsoredChatInvite != null && currentMessageObject.sponsoredChatInvite.chat != null && currentMessageObject.sponsoredChatInvite.chat.title != null) {
return currentMessageObject.sponsoredChatInvite.chat.title;
}
return "";
} {
return "DELETED";
}
}
@ -13612,7 +13725,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
invalidate();
}
}
} else if (currentMessageObject.type == 4) {
} else if (currentMessageObject.type == MessageObject.TYPE_GEO) {
if (docTitleLayout != null) {
if (currentMessageObject.isOutOwner()) {
Theme.chat_locationTitlePaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));

View File

@ -27,6 +27,7 @@ import android.text.Spanned;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.text.style.ReplacementSpan;
import android.view.HapticFeedbackConstants;
import android.view.accessibility.AccessibilityEvent;
@ -151,6 +152,7 @@ public class DialogCell extends BaseCell {
private int unreadCount;
private boolean markUnread;
private int mentionCount;
private int reactionMentionCount;
private boolean lastUnreadState;
private int lastSendState;
private boolean dialogMuted;
@ -269,14 +271,18 @@ public class DialogCell extends BaseCell {
private int countLeftOld;
private boolean countAnimationIncrement;
private ValueAnimator countAnimator;
private ValueAnimator reactionsMentionsAnimator;
private float countChangeProgress = 1f;
private float reactionsMentionsChangeProgress = 1f;
private StaticLayout countLayout;
private StaticLayout countOldLayout;
private StaticLayout countAnimationStableLayout;
private StaticLayout countAnimationInLayout;
private boolean drawMention;
private boolean drawReactionMention;
private int mentionLeft;
private int reactionMentionLeft;
private int mentionWidth;
private StaticLayout mentionLayout;
@ -442,6 +448,7 @@ public class DialogCell extends BaseCell {
markUnread = false;
messageId = messageObject != null ? messageObject.getId() : 0;
mentionCount = 0;
reactionMentionCount = 0;
lastUnreadState = messageObject != null && messageObject.isUnread();
if (message != null) {
lastSendState = message.messageOwner.send_state;
@ -1310,6 +1317,7 @@ public class DialogCell extends BaseCell {
drawClock = false;
drawCount = false;
drawMention = false;
drawReactionMention = false;
drawError = false;
} else {
if (currentDialogFolderId != 0) {
@ -1346,6 +1354,11 @@ public class DialogCell extends BaseCell {
} else {
drawMention = false;
}
if (reactionMentionCount != 0) {
drawReactionMention = true;
} else {
drawReactionMention = false;
}
}
if (message.isOut() && draftMessage == null && showChecks && !(message.messageOwner.action instanceof TLRPC.TL_messageActionHistoryClear)) {
@ -1584,7 +1597,7 @@ public class DialogCell extends BaseCell {
messageLeft += w;
messageNameLeft += w;
}
} else if (countString != null || mentionString != null) {
} else if (countString != null || mentionString != null || drawReactionMention) {
if (countString != null) {
countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(Theme.dialogs_countTextPaint.measureText(countString)));
countLayout = new StaticLayout(countString, Theme.dialogs_countTextPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
@ -1619,6 +1632,17 @@ public class DialogCell extends BaseCell {
}
drawMention = true;
}
if (drawReactionMention) {
int w = AndroidUtilities.dp(24);
messageWidth -= w;
if (!LocaleController.isRTL) {
reactionMentionLeft = getMeasuredWidth() - AndroidUtilities.dp(32) - (mentionWidth != 0 ? (mentionWidth + AndroidUtilities.dp(20)) : 0) - (countWidth != 0 ? countWidth + AndroidUtilities.dp(18) : 0);
} else {
reactionMentionLeft = AndroidUtilities.dp(20) + (countWidth != 0 ? countWidth + AndroidUtilities.dp(18) : 0);
messageLeft += w;
messageNameLeft += w;
}
}
} else {
if (drawPin) {
int w = Theme.dialogs_pinnedDrawable.getIntrinsicWidth() + AndroidUtilities.dp(8);
@ -1690,6 +1714,14 @@ public class DialogCell extends BaseCell {
} else {
messageStringFinal = messageString;
}
// Removing links to get rid of underlining
if (messageStringFinal instanceof Spannable) {
Spannable messageStringSpannable = (Spannable) messageStringFinal;
ClickableSpan[] spans = messageStringSpannable.getSpans(0, messageStringSpannable.length(), ClickableSpan.class);
for (ClickableSpan span : spans) {
messageStringSpannable.removeSpan(span);
}
}
if (useForceThreeLines || SharedConfig.useThreeLinesLayout) {
if (hasMessageThumb && messageNameString != null) {
@ -2026,6 +2058,7 @@ public class DialogCell extends BaseCell {
thumbImage.setImageBitmap((BitmapDrawable) null);
} else {
int oldUnreadCount = unreadCount;
boolean oldHasReactionsMentions = reactionMentionCount != 0;
boolean oldMarkUnread = markUnread;
if (isDialogCell) {
TLRPC.Dialog dialog = MessagesController.getInstance(currentAccount).dialogs_dict.get(currentDialogId);
@ -2049,6 +2082,7 @@ public class DialogCell extends BaseCell {
} else {
unreadCount = dialog.unread_count;
mentionCount = dialog.unread_mentions_count;
reactionMentionCount = dialog.unread_reactions_count;
}
markUnread = dialog.unread_mark;
currentEditDate = message != null ? message.messageOwner.edit_date : 0;
@ -2280,6 +2314,34 @@ public class DialogCell extends BaseCell {
countAnimationIncrement = unreadCount > oldUnreadCount;
countAnimator.start();
}
boolean newHasReactionsMentions = reactionMentionCount != 0;
if (animated && (newHasReactionsMentions != oldHasReactionsMentions)) {
if (reactionsMentionsAnimator != null) {
reactionsMentionsAnimator.cancel();
}
reactionsMentionsChangeProgress = 0;
reactionsMentionsAnimator = ValueAnimator.ofFloat(0, 1f);
reactionsMentionsAnimator.addUpdateListener(valueAnimator -> {
reactionsMentionsChangeProgress = (float) valueAnimator.getAnimatedValue();
invalidate();
});
reactionsMentionsAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
reactionsMentionsChangeProgress = 1f;
invalidate();
}
});
if (newHasReactionsMentions) {
reactionsMentionsAnimator.setDuration(220);
reactionsMentionsAnimator.setInterpolator(new OvershootInterpolator());
} else {
reactionsMentionsAnimator.setDuration(150);
reactionsMentionsAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
}
reactionsMentionsAnimator.start();
}
}
if (getMeasuredWidth() != 0 || getMeasuredHeight() != 0) {
buildLayout();
@ -2289,6 +2351,9 @@ public class DialogCell extends BaseCell {
if (!animated) {
dialogMutedProgress = dialogMuted ? 1f : 0f;
if (countAnimator != null) {
countAnimator.cancel();
}
}
invalidate();
@ -2752,7 +2817,7 @@ public class DialogCell extends BaseCell {
canvas.drawRoundRect(rect, 11.5f * AndroidUtilities.density, 11.5f * AndroidUtilities.density, Theme.dialogs_errorPaint);
setDrawableBounds(Theme.dialogs_errorDrawable, errorLeft + AndroidUtilities.dp(5.5f), errorTop + AndroidUtilities.dp(5));
Theme.dialogs_errorDrawable.draw(canvas);
} else if (drawCount || drawMention || countChangeProgress != 1f) {
} else if (drawCount || drawMention || countChangeProgress != 1f || drawReactionMention || reactionsMentionsChangeProgress != 1f) {
if (drawCount || countChangeProgress != 1f) {
final float progressFinal = (unreadCount == 0 && !markUnread) ? 1f - countChangeProgress : countChangeProgress;
if (countOldLayout == null || unreadCount == 0) {
@ -2868,6 +2933,26 @@ public class DialogCell extends BaseCell {
Theme.dialogs_mentionDrawable.draw(canvas);
}
}
if (drawReactionMention || reactionsMentionsChangeProgress != 1f) {
Theme.dialogs_countPaint.setAlpha((int) ((1.0f - reorderIconProgress) * 255));
int x = reactionMentionLeft - AndroidUtilities.dp(5.5f);
rect.set(x, countTop, x + AndroidUtilities.dp(23), countTop + AndroidUtilities.dp(23));
Paint paint = dialogMuted && folderId != 0 ? Theme.dialogs_countGrayPaint : Theme.dialogs_countPaint;
canvas.save();
if (reactionsMentionsChangeProgress != 1f) {
float s = drawReactionMention ? reactionsMentionsChangeProgress : (1f - reactionsMentionsChangeProgress);
canvas.scale(s, s, rect.centerX(), rect.centerY());
}
canvas.drawRoundRect(rect, 11.5f * AndroidUtilities.density, 11.5f * AndroidUtilities.density, paint);
Theme.dialogs_reactionsMentionDrawable.setAlpha((int) ((1.0f - reorderIconProgress) * 255));
setDrawableBounds(Theme.dialogs_reactionsMentionDrawable, reactionMentionLeft - AndroidUtilities.dp(2), countTop + AndroidUtilities.dp(3.8f), AndroidUtilities.dp(16), AndroidUtilities.dp(16));
Theme.dialogs_reactionsMentionDrawable.draw(canvas);
canvas.restore();
}
} else if (drawPin) {
Theme.dialogs_pinnedDrawable.setAlpha((int) ((1.0f - reorderIconProgress) * 255));
setDrawableBounds(Theme.dialogs_pinnedDrawable, pinLeft, pinTop);

View File

@ -13,6 +13,7 @@ import android.os.Build;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -25,96 +26,169 @@ import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieImageView;
import java.util.ArrayList;
@SuppressWarnings("FieldCanBeLocal")
public class DialogsEmptyCell extends LinearLayout {
public class DialogsEmptyCell extends FrameLayout {
private RLottieImageView imageView;
private TextView emptyTextView1;
private TextView emptyTextView2;
private int currentType;
private int currentType = -1;
private int currentAccount = UserConfig.selectedAccount;
private DialogsEmptyCellContent currentContent = null;
private DialogsEmptyCellContent lastContent = null;
private static class DialogsEmptyCellContent extends LinearLayout {
private RLottieImageView imageView;
private TextView emptyTextView1;
private TextView emptyTextView2;
private int currentType = 0;
public DialogsEmptyCellContent(Context context) {
super(context);
setGravity(Gravity.CENTER);
setOrientation(VERTICAL);
setOnTouchListener((v, event) -> true);
imageView = new RLottieImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
addView(imageView, LayoutHelper.createLinear(100, 100, Gravity.CENTER, 52, 4, 52, 0));
imageView.setOnClickListener(v -> {
if (!imageView.isPlaying()) {
imageView.setProgress(0.0f);
imageView.playAnimation();
}
});
emptyTextView1 = new TextView(context);
emptyTextView1.setTextColor(Theme.getColor(Theme.key_chats_nameMessage_threeLines));
emptyTextView1.setText(LocaleController.getString("NoChats", R.string.NoChats));
emptyTextView1.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
emptyTextView1.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
emptyTextView1.setGravity(Gravity.CENTER);
addView(emptyTextView1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 52, 10, 52, 0));
emptyTextView2 = new TextView(context);
String help = LocaleController.getString("NoChatsHelp", R.string.NoChatsHelp);
if (AndroidUtilities.isTablet() && !AndroidUtilities.isSmallTablet()) {
help = help.replace('\n', ' ');
}
emptyTextView2.setText(help);
emptyTextView2.setTextColor(Theme.getColor(Theme.key_chats_message));
emptyTextView2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
emptyTextView2.setGravity(Gravity.CENTER);
emptyTextView2.setLineSpacing(AndroidUtilities.dp(2), 1);
addView(emptyTextView2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 52, 7, 52, 0));
}
public void setType(int value) {
if (currentType == value) {
return;
}
currentType = value;
String help;
int icon;
int translationY = 0;
if (currentType == 0) {
icon = 0;
help = LocaleController.getString("NoChatsHelp", R.string.NoChatsHelp);
emptyTextView1.setText(LocaleController.getString("NoChats", R.string.NoChats));
} else if (currentType == 1) {
icon = 0;
help = LocaleController.getString("NoChatsContactsHelp", R.string.NoChatsContactsHelp);
emptyTextView1.setText(LocaleController.getString("NoChats", R.string.NoChats));
} else if (currentType == 2) {
imageView.setAutoRepeat(false);
icon = R.raw.filter_no_chats;
help = LocaleController.getString("FilterNoChatsToDisplayInfo", R.string.FilterNoChatsToDisplayInfo);
emptyTextView1.setText(LocaleController.getString("FilterNoChatsToDisplay", R.string.FilterNoChatsToDisplay));
} else {
imageView.setAutoRepeat(true);
icon = R.raw.filter_new;
help = LocaleController.getString("FilterAddingChatsInfo", R.string.FilterAddingChatsInfo);
emptyTextView1.setText(LocaleController.getString("FilterAddingChats", R.string.FilterAddingChats));
translationY = AndroidUtilities.dp(8);
}
setTranslationY(translationY);
if (icon != 0) {
imageView.setVisibility(VISIBLE);
imageView.setAnimation(icon, 100, 100);
imageView.playAnimation();
} else {
imageView.setVisibility(GONE);
}
if (AndroidUtilities.isTablet() && !AndroidUtilities.isSmallTablet()) {
help = help.replace('\n', ' ');
}
emptyTextView2.setText(help);
}
public void setOffset(int offset) {
if (currentType == 2 || currentType == 3) {
imageView.setTranslationY(offset);
emptyTextView1.setTranslationY(offset);
emptyTextView2.setTranslationY(offset);
}
}
}
public DialogsEmptyCell(Context context) {
super(context);
setGravity(Gravity.CENTER);
setOrientation(VERTICAL);
setOnTouchListener((v, event) -> true);
imageView = new RLottieImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
addView(imageView, LayoutHelper.createFrame(100, 100, Gravity.CENTER, 52, 4, 52, 0));
imageView.setOnClickListener(v -> {
if (!imageView.isPlaying()) {
imageView.setProgress(0.0f);
imageView.playAnimation();
}
});
emptyTextView1 = new TextView(context);
emptyTextView1.setTextColor(Theme.getColor(Theme.key_chats_nameMessage_threeLines));
emptyTextView1.setText(LocaleController.getString("NoChats", R.string.NoChats));
emptyTextView1.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
emptyTextView1.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
emptyTextView1.setGravity(Gravity.CENTER);
addView(emptyTextView1, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 52, 10, 52, 0));
emptyTextView2 = new TextView(context);
String help = LocaleController.getString("NoChatsHelp", R.string.NoChatsHelp);
if (AndroidUtilities.isTablet() && !AndroidUtilities.isSmallTablet()) {
help = help.replace('\n', ' ');
}
emptyTextView2.setText(help);
emptyTextView2.setTextColor(Theme.getColor(Theme.key_chats_message));
emptyTextView2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
emptyTextView2.setGravity(Gravity.CENTER);
emptyTextView2.setLineSpacing(AndroidUtilities.dp(2), 1);
addView(emptyTextView2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 52, 7, 52, 0));
}
public void setType(int value) {
setType(value, true);
}
public void setType(int value, boolean animated) {
if (currentType == value) {
return;
}
// if (currentContent == null)
// animated = false;
currentType = value;
String help;
int icon;
if (currentType == 0) {
icon = 0;
help = LocaleController.getString("NoChatsHelp", R.string.NoChatsHelp);
emptyTextView1.setText(LocaleController.getString("NoChats", R.string.NoChats));
} else if (currentType == 1) {
icon = 0;
help = LocaleController.getString("NoChatsContactsHelp", R.string.NoChatsContactsHelp);
emptyTextView1.setText(LocaleController.getString("NoChats", R.string.NoChats));
} else if (currentType == 2) {
imageView.setAutoRepeat(false);
icon = R.raw.filter_no_chats;
help = LocaleController.getString("FilterNoChatsToDisplayInfo", R.string.FilterNoChatsToDisplayInfo);
emptyTextView1.setText(LocaleController.getString("FilterNoChatsToDisplay", R.string.FilterNoChatsToDisplay));
} else {
imageView.setAutoRepeat(true);
icon = R.raw.filter_new;
help = LocaleController.getString("FilterAddingChatsInfo", R.string.FilterAddingChatsInfo);
emptyTextView1.setText(LocaleController.getString("FilterAddingChats", R.string.FilterAddingChats));
// lastContent = currentContent;
if (currentContent == null) {
currentContent = new DialogsEmptyCellContent(getContext());
addView(currentContent, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL));
}
if (icon != 0) {
imageView.setVisibility(VISIBLE);
imageView.setAnimation(icon, 100, 100);
imageView.playAnimation();
} else {
imageView.setVisibility(GONE);
}
if (AndroidUtilities.isTablet() && !AndroidUtilities.isSmallTablet()) {
help = help.replace('\n', ' ');
}
emptyTextView2.setText(help);
currentContent.setType(value);
currentContent.setOffset(offset);
// if (animated) {
// currentContent.setAlpha(0f);
// currentContent.animate().alpha(1f).setDuration(220).setInterpolator(CubicBezierInterpolator.EASE_BOTH).start();
// } else {
// currentContent.setAlpha(1f);
// }
//
// if (lastContent != null) {
// if (animated) {
// float fromAlpha = lastContent.getAlpha();
// lastContent.clearAnimation();
// lastContent.animate()
// .alpha(0f)
// .withEndAction(() -> {
// if (lastContent.getParent() != null) {
// removeView(lastContent);
// }
// lastContent = null;
// })
// .setDuration((long) (150 * fromAlpha))
// .setInterpolator(CubicBezierInterpolator.EASE_BOTH)
// .start();
// } else {
// lastContent.setAlpha(0f);
// if (lastContent.getParent() != null) {
// removeView(lastContent);
// }
// lastContent = null;
// }
// }
}
@Override
@ -129,15 +203,17 @@ public class DialogsEmptyCell extends LinearLayout {
updateLayout();
}
public void updateLayout() {
if (getParent() instanceof View && (currentType == 2 || currentType == 3)) {
private int offset = 0;
private void updateLayout() {
if (getParent() instanceof View) {
View view = (View) getParent();
int paddingTop = view.getPaddingTop();
if (paddingTop != 0) {
int offset = -(getTop() / 2);
imageView.setTranslationY(offset);
emptyTextView1.setTranslationY(offset);
emptyTextView2.setTranslationY(offset);
offset = -(getTop() / 2);
if (currentContent != null)
currentContent.setOffset(offset);
if (lastContent != null)
lastContent.setOffset(offset);
}
}
}

View File

@ -8,12 +8,19 @@
package org.telegram.ui.Cells;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
@ -22,6 +29,7 @@ import org.telegram.messenger.LocaleController;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
public class LocationCell extends FrameLayout {
@ -62,6 +70,10 @@ public class LocationCell extends FrameLayout {
addressTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText3));
addressTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
addView(addressTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), (LocaleController.isRTL ? 16 : 73), 35, (LocaleController.isRTL ? 73 : 16), 0));
imageView.setAlpha(enterAlpha);
nameTextView.setAlpha(enterAlpha);
addressTextView.setAlpha(enterAlpha);
}
@Override
@ -101,23 +113,80 @@ public class LocationCell extends FrameLayout {
}
}
private float enterAlpha = 0f;
private ValueAnimator enterAnimator;
public void setLocation(TLRPC.TL_messageMediaVenue location, String icon, String label, int pos, boolean divider) {
needDivider = divider;
circleDrawable.getPaint().setColor(getColorForIndex(pos));
nameTextView.setText(location.title);
if (location != null)
nameTextView.setText(location.title);
if (label != null) {
addressTextView.setText(label);
} else {
} else if (location != null) {
addressTextView.setText(location.address);
}
imageView.setImage(icon, null, null);
setWillNotDraw(!divider);
if (icon != null)
imageView.setImage(icon, null, null);
setWillNotDraw(false);
setClickable(location == null);
if (enterAnimator != null)
enterAnimator.cancel();
boolean loading = location == null;
float fromEnterAlpha = enterAlpha,
toEnterAlpha = loading ? 0f : 1f;
long duration = (long) (Math.abs(fromEnterAlpha - toEnterAlpha) * 150);
enterAnimator = ValueAnimator.ofFloat(fromEnterAlpha, toEnterAlpha);
final long start = SystemClock.elapsedRealtime();
enterAnimator.addUpdateListener(a -> {
float t = Math.min(Math.max((float) (SystemClock.elapsedRealtime() - start) / duration, 0), 1);
if (duration <= 0)
t = 1f;
enterAlpha = AndroidUtilities.lerp(fromEnterAlpha, toEnterAlpha, t);
imageView.setAlpha(enterAlpha);
nameTextView.setAlpha(enterAlpha);
addressTextView.setAlpha(enterAlpha);
invalidate();
});
enterAnimator.setDuration(loading ? Long.MAX_VALUE : duration);
enterAnimator.start();
imageView.setAlpha(fromEnterAlpha);
nameTextView.setAlpha(fromEnterAlpha);
addressTextView.setAlpha(fromEnterAlpha);
invalidate();
}
private static FlickerLoadingView globalGradientView;
@Override
protected void onDraw(Canvas canvas) {
if (globalGradientView == null) {
globalGradientView = new FlickerLoadingView(getContext());
globalGradientView.setIsSingleCell(true);
}
int index = getParent() instanceof ViewGroup ? ((ViewGroup) getParent()).indexOfChild(this) : 0;
globalGradientView.setParentSize(getMeasuredWidth(), getMeasuredHeight(), -index * AndroidUtilities.dp(56));
globalGradientView.setViewType(FlickerLoadingView.AUDIO_TYPE);
globalGradientView.updateColors();
globalGradientView.updateGradient();
canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), (int) ((1f - enterAlpha) * 255), Canvas.ALL_SAVE_FLAG);
canvas.translate(AndroidUtilities.dp(2), (getMeasuredHeight() - AndroidUtilities.dp(56)) / 2);
globalGradientView.draw(canvas);
canvas.restore();
super.onDraw(canvas);
if (needDivider) {
canvas.drawLine(AndroidUtilities.dp(72), getHeight() - 1, getWidth(), getHeight() - 1, Theme.dividerPaint);
canvas.drawLine(
LocaleController.isRTL ? 0 : AndroidUtilities.dp(72),
getHeight() - 1,
LocaleController.isRTL ? getWidth() - AndroidUtilities.dp(72) : getWidth(),
getHeight() - 1,
Theme.dividerPaint
);
}
}

View File

@ -38,6 +38,7 @@ public class SendLocationCell extends FrameLayout {
private ImageView imageView;
private long dialogId;
private RectF rect;
private boolean live;
private final Theme.ResourcesProvider resourcesProvider;
private Runnable invalidateRunnable = new Runnable() {
@ -52,6 +53,7 @@ public class SendLocationCell extends FrameLayout {
public SendLocationCell(Context context, boolean live, Theme.ResourcesProvider resourcesProvider) {
super(context);
this.resourcesProvider = resourcesProvider;
this.live = live;
imageView = new ImageView(context);
@ -102,7 +104,9 @@ public class SendLocationCell extends FrameLayout {
accurateTextView.setAlpha(value ? 1.0f : 0.5f);
imageView.setAlpha(value ? 1.0f : 0.5f);
}
checkText();
if (live) {
checkText();
}
}
@Override
@ -131,7 +135,9 @@ public class SendLocationCell extends FrameLayout {
public void setDialogId(long did) {
dialogId = did;
checkText();
if (live) {
checkText();
}
}
private void checkText() {

View File

@ -564,7 +564,6 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
} else {
drawInternal(canvas);
super.dispatchDraw(canvas);
}
}

View File

@ -584,6 +584,7 @@ public class SharedLinkCell extends FrameLayout {
try {
urlPath.setCurrentLayout(layout, 0, 0);
layout.getSelectionPath(0, layout.getText().length(), urlPath);
urlPath.onPathEnd();
} catch (Exception e) {
FileLog.e(e);
}

View File

@ -143,7 +143,7 @@ public class SharingLiveLocationCell extends FrameLayout {
distanceTextView.setText(address);
}
public void setDialog(MessageObject messageObject, Location userLocation) {
public void setDialog(MessageObject messageObject, Location userLocation, boolean userLocationDenied) {
long fromId = messageObject.getFromChatId();
if (messageObject.isForwarded()) {
fromId = MessageObject.getPeerId(messageObject.messageOwner.fwd_from.from_id);
@ -198,8 +198,10 @@ public class SharingLiveLocationCell extends FrameLayout {
} else {
if (address != null) {
distanceTextView.setText(address);
} else {
} else if (!userLocationDenied) {
distanceTextView.setText(LocaleController.getString("Loading", R.string.Loading));
} else {
distanceTextView.setText("");
}
}
}

View File

@ -20,22 +20,22 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.R;
import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.EmojiTextView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.messenger.SvgHelper;
public class StickerEmojiCell extends FrameLayout {
@ -137,7 +137,8 @@ public class StickerEmojiCell extends FrameLayout {
} else if (document != null) {
sticker = document;
parentObject = parent;
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 90);
boolean isVideoSticker = MessageObject.isVideoSticker(document);
TLRPC.PhotoSize thumb = isVideoSticker ? null : FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 90);
SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(document, fromEmojiPanel ? Theme.key_emptyListPlaceholder : Theme.key_windowBackgroundGray, fromEmojiPanel ? 0.2f : 1.0f);
if (MessageObject.canAutoplayAnimatedSticker(document)) {
if (svgThumb != null) {
@ -150,14 +151,14 @@ public class StickerEmojiCell extends FrameLayout {
} else {
if (svgThumb != null) {
if (thumb != null) {
imageView.setImage(ImageLocation.getForDocument(thumb, document), null, "webp", svgThumb, parentObject);
imageView.setImage(ImageLocation.getForDocument(thumb, document), "66_66", "webp", svgThumb, parentObject);
} else {
imageView.setImage(ImageLocation.getForDocument(document), null, "webp", svgThumb, parentObject);
imageView.setImage(ImageLocation.getForDocument(document), "66_66", "webp", svgThumb, parentObject);
}
} else if (thumb != null) {
imageView.setImage(ImageLocation.getForDocument(thumb, document), null, "webp", null, parentObject);
imageView.setImage(ImageLocation.getForDocument(thumb, document), "66_66", "webp", null, parentObject);
} else {
imageView.setImage(ImageLocation.getForDocument(document), null, "webp", null, parentObject);
imageView.setImage(ImageLocation.getForDocument(document), "66_66", "webp", null, parentObject);
}
}
@ -232,7 +233,7 @@ public class StickerEmojiCell extends FrameLayout {
if (time > 1050) {
time = 1050;
}
alpha = 0.5f + interpolator.getInterpolation(time / 1050.0f) * 0.5f;
alpha = 0.5f + interpolator.getInterpolation(time / 150.0f) * 0.5f;
if (alpha >= 1.0f) {
changingAlpha = false;
alpha = 1.0f;

View File

@ -217,7 +217,7 @@ public class StickerSetCell extends FrameLayout {
imageLocation = ImageLocation.getForSticker(thumb, sticker, set.set.thumb_version);
}
if (object instanceof TLRPC.Document && MessageObject.isAnimatedStickerDocument(sticker, true)) {
if (object instanceof TLRPC.Document && MessageObject.isAnimatedStickerDocument(sticker, true) || MessageObject.isVideoSticker(sticker)) {
if (svgThumb != null) {
imageView.setImage(ImageLocation.getForDocument(sticker), "50_50", svgThumb, 0, set);
} else {

View File

@ -32,6 +32,7 @@ public class TextDetailCell extends FrameLayout {
private final TextView textView;
private final TextView valueTextView;
private final TextView showMoreTextView = null;
private final ImageView imageView;
private boolean needDivider;
private boolean contentDescriptionValueFirst;
@ -67,7 +68,10 @@ public class TextDetailCell extends FrameLayout {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
super.onMeasure(
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY)
);
}
public void setTextAndValue(String text, String value, boolean divider) {
@ -117,7 +121,11 @@ public class TextDetailCell extends FrameLayout {
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {
canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, Theme.dividerPaint);
canvas.drawLine(
0, getMeasuredHeight() - 1, getMeasuredWidth(),
getMeasuredHeight() - 1,
Theme.dividerPaint
);
}
}

View File

@ -1,5 +1,9 @@
package org.telegram.ui.Cells;
import static com.google.zxing.common.detector.MathUtils.distance;
import static org.telegram.ui.ActionBar.FloatingToolbar.STYLE_THEME;
import static org.telegram.ui.ActionBar.Theme.key_chat_inTextSelectionHighlight;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@ -39,6 +43,9 @@ import org.jetbrains.annotations.NotNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LanguageDetector;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
@ -50,6 +57,7 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ArticleViewer;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.RestrictedLanguagesSelectActivity;
import java.util.ArrayList;
@ -267,6 +275,14 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
touchSlop = ViewConfiguration.get(ApplicationLoader.applicationContext).getScaledTouchSlop();
}
public interface OnTranslateListener {
public void run(CharSequence text, String fromLang, String toLang, Runnable onAlertDismiss);
}
private OnTranslateListener onTranslateListener = null;
public void setOnTranslate(OnTranslateListener listener) {
onTranslateListener = listener;
}
public void setParentView(ViewGroup view) {
if (view instanceof RecyclerListView) {
parentRecyclerView = (RecyclerListView) view;
@ -1223,6 +1239,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
}
private static final int TRANSLATE = 3;
private ActionMode.Callback createActionCallback() {
final ActionMode.Callback callback = new ActionMode.Callback() {
@Override
@ -1230,6 +1247,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
menu.add(Menu.NONE, 0, 0, android.R.string.copy);
menu.add(Menu.NONE, 1, 1, android.R.string.selectAll);
menu.add(Menu.NONE, 2, 2, R.string.Translate);
menu.add(Menu.NONE, TRANSLATE, 2, LocaleController.getString("TranslateMessage", R.string.TranslateMessage));
return true;
}
@ -1244,9 +1262,37 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
menu.getItem(2).setVisible(selectedView instanceof View);
}
if (LanguageDetector.hasSupport() && getSelectedText() != null) {
LanguageDetector.detectLanguage(getSelectedText().toString(), lng -> {
translateFromLanguage = lng;
updateTranslateButton(menu);
}, err -> {
FileLog.e("mlkit: failed to detect language in selection");
FileLog.e(err);
translateFromLanguage = null;
updateTranslateButton(menu);
});
} else {
translateFromLanguage = null;
updateTranslateButton(menu);
}
return true;
}
private String translateFromLanguage = null;
private void updateTranslateButton(Menu menu) {
String translateToLanguage = LocaleController.getInstance().getCurrentLocale().getLanguage();
menu.getItem(2).setVisible(
onTranslateListener != null && (
(
translateFromLanguage != null &&
(!translateFromLanguage.equals(translateToLanguage) || translateFromLanguage.equals("und")) &&
!RestrictedLanguagesSelectActivity.getRestrictedLanguages().contains(translateFromLanguage)
) || !LanguageDetector.hasSupport()
)
);
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (!isSelectionMode()) {
@ -1269,7 +1315,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
return true;
}
case 2:
CharSequence textS = getTextForCopy();
CharSequence textS = getSelectedText();
if (textS == null) {
return true;
}
@ -1372,7 +1418,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (!isSelectionMode()) {
return;
}
CharSequence str = getTextForCopy();
CharSequence str = getSelectedText();
if (str == null) {
return;
}
@ -1386,7 +1432,17 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
}
protected CharSequence getTextForCopy() {
private void translateText() {
if (!isSelectionMode()) {
return;
}
CharSequence str = getSelectedText();
if (str == null) {
return;
}
}
protected CharSequence getSelectedText() {
CharSequence text = getText(selectedView, false);
if (text != null) {
return text.subSequence(selectionStart, selectionEnd);
@ -2426,7 +2482,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
@Override
protected CharSequence getTextForCopy() {
protected CharSequence getSelectedText() {
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
for (int i = startViewPosition; i <= endViewPosition; i++) {
if (i == startViewPosition) {

View File

@ -2156,7 +2156,9 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
MessageObject messageObject = cell.getMessageObject();
if (url instanceof URLSpanMono) {
((URLSpanMono) url).copyToClipboard();
Toast.makeText(getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
Toast.makeText(getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show();
}
} else if (url instanceof URLSpanUserMention) {
long peerId = Utilities.parseLong(((URLSpanUserMention) url).getURL());
if (peerId > 0) {

File diff suppressed because it is too large Load Diff

View File

@ -513,7 +513,11 @@ public class ChatPullingDownDrawable implements NotificationCenter.NotificationC
}
ArrayList<TLRPC.Dialog> dialogs;
if (filterId != 0) {
dialogs = messagesController.dialogFiltersById.get(filterId).dialogs;
MessagesController.DialogFilter filter = messagesController.dialogFiltersById.get(filterId);
if (filter == null) {
return null;
}
dialogs = filter.dialogs;
} else {
dialogs = messagesController.getDialogs(folderId);
}

View File

@ -23,7 +23,7 @@ import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.SparseArray;
import android.util.Log;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.Gravity;
@ -86,6 +86,8 @@ import org.telegram.ui.Components.UndoView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class ChatUsersActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate {
@ -185,6 +187,12 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
public final static int TYPE_ADMIN = 1;
public final static int TYPE_USERS = 2;
public final static int TYPE_KICKED = 3;
public final static int SELECT_TYPE_MEMBERS = 0; // "Subscribers" / "Members"
public final static int SELECT_TYPE_ADMIN = 1; // "Add Admin"
public final static int SELECT_TYPE_BLOCK = 2; // "Remove User"
public final static int SELECT_TYPE_EXCEPTION = 3; // "Add Exception"
private boolean openTransitionStarted;
private FlickerLoadingView flickerLoadingView;
private View progressBar;
@ -593,9 +601,12 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
loadingUserCellRow = rowCount++;
}
} else if (type == TYPE_USERS) {
if (selectType == 0 && ChatObject.canAddUsers(currentChat)) {
if (selectType == SELECT_TYPE_MEMBERS && ChatObject.canAddUsers(currentChat)) {
addNewRow = rowCount++;
}
if (selectType == SELECT_TYPE_MEMBERS && ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_INVITE)) {
addNew2Row = rowCount++;
}
if (!(loadingUsers && !firstLoaded)) {
boolean hasAnyOther = false;
if (!contacts.isEmpty()) {
@ -624,7 +635,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
participantsInfoRow = rowCount++;
}
} else if (!firstLoaded) {
if (selectType == 0) {
if (selectType == SELECT_TYPE_MEMBERS) {
loadingHeaderRow = rowCount++;
}
loadingUserCellRow = rowCount++;
@ -659,18 +670,18 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
} else if (type == TYPE_ADMIN) {
actionBar.setTitle(LocaleController.getString("ChannelAdministrators", R.string.ChannelAdministrators));
} else if (type == TYPE_USERS) {
if (selectType == 0) {
if (selectType == SELECT_TYPE_MEMBERS) {
if (isChannel) {
actionBar.setTitle(LocaleController.getString("ChannelSubscribers", R.string.ChannelSubscribers));
} else {
actionBar.setTitle(LocaleController.getString("ChannelMembers", R.string.ChannelMembers));
}
} else {
if (selectType == 1) {
if (selectType == SELECT_TYPE_ADMIN) {
actionBar.setTitle(LocaleController.getString("ChannelAddAdmin", R.string.ChannelAddAdmin));
} else if (selectType == 2) {
} else if (selectType == SELECT_TYPE_BLOCK) {
actionBar.setTitle(LocaleController.getString("ChannelBlockUser", R.string.ChannelBlockUser));
} else if (selectType == 3) {
} else if (selectType == SELECT_TYPE_EXCEPTION) {
actionBar.setTitle(LocaleController.getString("ChannelAddException", R.string.ChannelAddException));
}
}
@ -687,7 +698,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
}
});
if (selectType != 0 || type == TYPE_USERS || ChatObject.hasAdminRights(currentChat) && (type == TYPE_BANNED || type == TYPE_KICKED)) {
if (selectType != SELECT_TYPE_MEMBERS || type == TYPE_USERS || ChatObject.hasAdminRights(currentChat) && (type == TYPE_BANNED || type == TYPE_KICKED)) {
searchListViewAdapter = new SearchAdapter(context);
ActionBarMenu menu = actionBar.createMenu();
searchItem = menu.addItem(search_button, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() {
@ -858,7 +869,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
Bundle bundle = new Bundle();
bundle.putLong("chat_id", chatId);
bundle.putInt("type", ChatUsersActivity.TYPE_USERS);
bundle.putInt("selectType", type == TYPE_BANNED ? 2 : 3);
bundle.putInt("selectType", type == TYPE_BANNED ? ChatUsersActivity.SELECT_TYPE_BLOCK : ChatUsersActivity.SELECT_TYPE_EXCEPTION);
ChatUsersActivity fragment = new ChatUsersActivity(bundle);
fragment.setInfo(info);
fragment.setDelegate(new ChatUsersActivityDelegate() {
@ -901,7 +912,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
Bundle bundle = new Bundle();
bundle.putLong("chat_id", chatId);
bundle.putInt("type", ChatUsersActivity.TYPE_USERS);
bundle.putInt("selectType", 1);
bundle.putInt("selectType", ChatUsersActivity.SELECT_TYPE_ADMIN);
ChatUsersActivity fragment = new ChatUsersActivity(bundle);
fragment.setDelegate(new ChatUsersActivityDelegate() {
@Override
@ -1044,7 +1055,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
});
} else if (position == addNew2Row) {
presentFragment(new GroupInviteActivity(chatId));
ManageLinksActivity fragment = new ManageLinksActivity(chatId, 0, 0);
fragment.setInfo(info, info.exported_invite);
presentFragment(fragment);
return;
} else if (position > permissionsSectionRow && position <= changeInfoRow) {
TextCheckCell2 checkCell = (TextCheckCell2) view;
@ -1227,9 +1240,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
}
if (peerId != 0) {
if (selectType != 0) {
if (selectType == 3 || selectType == 1) {
if (selectType != 1 && canEditAdmin && (participant instanceof TLRPC.TL_channelParticipantAdmin || participant instanceof TLRPC.TL_chatParticipantAdmin)) {
if (selectType != SELECT_TYPE_MEMBERS) {
if (selectType == SELECT_TYPE_EXCEPTION || selectType == SELECT_TYPE_ADMIN) {
if (selectType != SELECT_TYPE_ADMIN && canEditAdmin && (participant instanceof TLRPC.TL_channelParticipantAdmin || participant instanceof TLRPC.TL_chatParticipantAdmin)) {
final TLRPC.User user = getMessagesController().getUser(peerId);
final TLRPC.TL_chatBannedRights br = bannedRights;
final TLRPC.TL_chatAdminRights ar = adminRights;
@ -1238,11 +1251,11 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setMessage(LocaleController.formatString("AdminWillBeRemoved", R.string.AdminWillBeRemoved, UserObject.getUserName(user)));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialog, which) -> openRightsEdit(user.id, participant, ar, br, rankFinal, canEdit, selectType == 1 ? 0 : 1, false));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialog, which) -> openRightsEdit(user.id, participant, ar, br, rankFinal, canEdit, selectType == SELECT_TYPE_ADMIN ? 0 : 1, false));
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
showDialog(builder.create());
} else {
openRightsEdit(peerId, participant, adminRights, bannedRights, rank, canEditAdmin, selectType == 1 ? 0 : 1, selectType == 1 || selectType == 3);
openRightsEdit(peerId, participant, adminRights, bannedRights, rank, canEditAdmin, selectType == SELECT_TYPE_ADMIN ? 0 : 1, selectType == SELECT_TYPE_ADMIN || selectType == SELECT_TYPE_EXCEPTION);
}
} else {
removeParticipant(peerId);
@ -1254,7 +1267,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
} else if (type == TYPE_BANNED || type == TYPE_KICKED) {
canEdit = ChatObject.canBlockUsers(currentChat);
}
if (type == TYPE_BANNED || type != TYPE_ADMIN && isChannel || type == TYPE_USERS && selectType == 0) {
if (type == TYPE_BANNED || type != TYPE_ADMIN && isChannel || type == TYPE_USERS && selectType == SELECT_TYPE_MEMBERS) {
if (peerId == getUserConfig().getClientUserId()) {
return;
}
@ -1727,7 +1740,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
private boolean createMenuForParticipant(final TLObject participant, boolean resultOnly) {
if (participant == null || selectType != 0) {
if (participant == null || selectType != SELECT_TYPE_MEMBERS) {
return false;
}
long peerId;
@ -1769,7 +1782,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
boolean canEditAdmin = !(participant instanceof TLRPC.TL_channelParticipantAdmin || participant instanceof TLRPC.TL_channelParticipantCreator || participant instanceof TLRPC.TL_chatParticipantCreator || participant instanceof TLRPC.TL_chatParticipantAdmin) || canEdit;
boolean editingAdmin = participant instanceof TLRPC.TL_channelParticipantAdmin || participant instanceof TLRPC.TL_chatParticipantAdmin;
if (selectType == 0) {
if (selectType == SELECT_TYPE_MEMBERS) {
allowSetAdmin &= !UserObject.isDeleted(user);
}
@ -2080,7 +2093,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
public boolean hasSelectType() {
return selectType != 0;
return selectType != SELECT_TYPE_MEMBERS;
}
private String formatUserPermissions(TLRPC.TL_chatBannedRights rights) {
@ -2207,7 +2220,54 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
loadChatParticipants(offset, count, true);
}
private ArrayList<TLRPC.TL_channels_getParticipants> loadChatParticipantsRequests(int offset, int count, boolean reset) {
TLRPC.TL_channels_getParticipants req = new TLRPC.TL_channels_getParticipants();
ArrayList<TLRPC.TL_channels_getParticipants> requests = new ArrayList<>();
requests.add(req);
req.channel = getMessagesController().getInputChannel(chatId);
if (type == TYPE_BANNED) {
req.filter = new TLRPC.TL_channelParticipantsKicked();
} else if (type == TYPE_ADMIN) {
req.filter = new TLRPC.TL_channelParticipantsAdmins();
} else if (type == TYPE_USERS) {
if (info != null && info.participants_count <= 200 && currentChat != null && currentChat.megagroup) {
req.filter = new TLRPC.TL_channelParticipantsRecent();
} else {
if (selectType == SELECT_TYPE_ADMIN) {
if (!contactsEndReached) {
delayResults = 2;
req.filter = new TLRPC.TL_channelParticipantsContacts();
contactsEndReached = true;
requests.addAll(loadChatParticipantsRequests(0, 200, false));
} else {
req.filter = new TLRPC.TL_channelParticipantsRecent();
}
} else {
if (!contactsEndReached) {
delayResults = 3;
req.filter = new TLRPC.TL_channelParticipantsContacts();
contactsEndReached = true;
requests.addAll(loadChatParticipantsRequests(0, 200, false));
} else if (!botsEndReached) {
req.filter = new TLRPC.TL_channelParticipantsBots();
botsEndReached = true;
requests.addAll(loadChatParticipantsRequests(0, 200, false));
} else {
req.filter = new TLRPC.TL_channelParticipantsRecent();
}
}
}
} else if (type == TYPE_KICKED) {
req.filter = new TLRPC.TL_channelParticipantsBanned();
}
req.filter.q = "";
req.offset = offset;
req.limit = count;
return requests;
}
private void loadChatParticipants(int offset, int count, boolean reset) {
Log.i("chat users", "loadChatParticipants(" + offset + ", " + count + ", " + reset + ")");
if (!ChatObject.isChannel(currentChat)) {
loadingUsers = false;
participants.clear();
@ -2231,13 +2291,13 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
long selfUserId = getUserConfig().clientUserId;
for (int a = 0, size = info.participants.participants.size(); a < size; a++) {
TLRPC.ChatParticipant participant = info.participants.participants.get(a);
if (selectType != 0 && participant.user_id == selfUserId) {
if (selectType != SELECT_TYPE_MEMBERS && participant.user_id == selfUserId) {
continue;
}
if (ignoredUsers != null && ignoredUsers.indexOfKey(participant.user_id) >= 0) {
continue;
}
if (selectType == 1) {
if (selectType == SELECT_TYPE_ADMIN) {
if (getContactsController().isContact(participant.user_id)) {
contacts.add(participant);
contactsMap.put(participant.user_id, participant);
@ -2278,56 +2338,22 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
if (listViewAdapter != null) {
listViewAdapter.notifyDataSetChanged();
}
TLRPC.TL_channels_getParticipants req = new TLRPC.TL_channels_getParticipants();
req.channel = getMessagesController().getInputChannel(chatId);
if (type == TYPE_BANNED) {
req.filter = new TLRPC.TL_channelParticipantsKicked();
} else if (type == TYPE_ADMIN) {
req.filter = new TLRPC.TL_channelParticipantsAdmins();
} else if (type == TYPE_USERS) {
if (info != null && info.participants_count <= 200 && currentChat != null && currentChat.megagroup) {
req.filter = new TLRPC.TL_channelParticipantsRecent();
} else {
if (selectType == 1) {
if (!contactsEndReached) {
delayResults = 2;
req.filter = new TLRPC.TL_channelParticipantsContacts();
contactsEndReached = true;
loadChatParticipants(0, 200, false);
} else {
req.filter = new TLRPC.TL_channelParticipantsRecent();
}
} else {
if (!contactsEndReached) {
delayResults = 3;
req.filter = new TLRPC.TL_channelParticipantsContacts();
contactsEndReached = true;
loadChatParticipants(0, 200, false);
} else if (!botsEndReached) {
req.filter = new TLRPC.TL_channelParticipantsBots();
botsEndReached = true;
loadChatParticipants(0, 200, false);
} else {
req.filter = new TLRPC.TL_channelParticipantsRecent();
}
}
}
} else if (type == TYPE_KICKED) {
req.filter = new TLRPC.TL_channelParticipantsBanned();
}
req.filter.q = "";
req.offset = offset;
req.limit = count;
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (error == null) {
TLRPC.TL_channels_channelParticipants res = (TLRPC.TL_channels_channelParticipants) response;
final ArrayList<TLRPC.TL_channels_getParticipants> requests = loadChatParticipantsRequests(offset, count, reset);
final ArrayList<TLRPC.TL_channels_channelParticipants> responses = new ArrayList<>();
Log.i("chat users", "requests.size() = " + requests.size());
final Runnable onRequestsEnd = () -> {
for (int i = 0; i < requests.size(); ++i) {
TLRPC.TL_channels_getParticipants req = requests.get(i);
TLRPC.TL_channels_channelParticipants res = responses.get(i);
if (req == null || res == null)
continue;
if (type == TYPE_ADMIN) {
getMessagesController().processLoadedAdminsResponse(chatId, (TLRPC.TL_channels_channelParticipants) response);
getMessagesController().processLoadedAdminsResponse(chatId, res);
}
getMessagesController().putUsers(res.users, false);
getMessagesController().putChats(res.chats, false);
long selfId = getUserConfig().getClientUserId();
if (selectType != 0) {
if (selectType != SELECT_TYPE_MEMBERS) {
for (int a = 0; a < res.participants.size(); a++) {
if (MessageObject.getPeerId(res.participants.get(a).peer) == selfId) {
res.participants.remove(a);
@ -2378,7 +2404,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
boolean remove = false;
if (contactsMap.get(peerId) != null || botsMap.get(peerId) != null) {
remove = true;
} else if (selectType == 1 && peerId > 0 && UserObject.isDeleted(getMessagesController().getUser(peerId))) {
} else if (selectType == SELECT_TYPE_ADMIN && peerId > 0 && UserObject.isDeleted(getMessagesController().getUser(peerId))) {
remove = true;
} else if (ignoredUsers != null && ignoredUsers.indexOfKey(peerId) >= 0) {
remove = true;
@ -2416,8 +2442,21 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
}
resumeDelayedFragmentAnimation();
}));
getConnectionsManager().bindRequestToGuid(reqId, classGuid);
};
AtomicInteger responsesReceived = new AtomicInteger(0);
for (int i = 0; i < requests.size(); ++i) {
responses.add(null);
final int index = i;
int reqId = getConnectionsManager().sendRequest(requests.get(index), (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (error == null && response instanceof TLRPC.TL_channels_channelParticipants)
responses.set(index, (TLRPC.TL_channels_channelParticipants) response);
responsesReceived.getAndIncrement();
if (responsesReceived.get() == requests.size()) {
onRequestsEnd.run();
}
}));
getConnectionsManager().bindRequestToGuid(reqId, classGuid);
}
}
}
@ -2585,10 +2624,11 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
searchRunnable = null;
final ArrayList<TLObject> participantsCopy = !ChatObject.isChannel(currentChat) && info != null ? new ArrayList<>(info.participants.participants) : null;
final ArrayList<TLRPC.TL_contact> contactsCopy = selectType == 1 ? new ArrayList<>(getContactsController().contacts) : null;
final ArrayList<TLRPC.TL_contact> contactsCopy = selectType == SELECT_TYPE_ADMIN ? new ArrayList<>(getContactsController().contacts) : null;
Runnable addContacts = null;
if (participantsCopy != null || contactsCopy != null) {
Utilities.searchQueue.postRunnable(() -> {
addContacts = () -> {
String search1 = query.trim().toLowerCase();
if (search1.length() == 0) {
updateSearchResults(new ArrayList<>(), new LongSparseArray<>(), new ArrayList<>(), new ArrayList<>());
@ -2702,11 +2742,11 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
}
updateSearchResults(resultArray, resultMap, resultArrayNames, resultArray2);
});
};
} else {
searchInProgress = false;
}
searchAdapterHelper.queryServerSearch(query, selectType != 0, false, true, false, false, ChatObject.isChannel(currentChat) ? chatId : 0, false, type, 1);
searchAdapterHelper.queryServerSearch(query, selectType != SELECT_TYPE_MEMBERS, false, true, false, false, ChatObject.isChannel(currentChat) ? chatId : 0, false, type, 1, addContacts);
});
}
@ -2833,7 +2873,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
View view;
switch (viewType) {
case 0:
ManageChatUserCell manageChatUserCell = new ManageChatUserCell(mContext, 2, 2, selectType == 0);
ManageChatUserCell manageChatUserCell = new ManageChatUserCell(mContext, 2, 2, selectType == SELECT_TYPE_MEMBERS);
manageChatUserCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
manageChatUserCell.setDelegate((cell, click) -> {
TLObject object = getItem((Integer) cell.getTag());
@ -3040,7 +3080,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
View view;
switch (viewType) {
case 0:
ManageChatUserCell manageChatUserCell = new ManageChatUserCell(mContext, type == TYPE_BANNED || type == TYPE_KICKED ? 7 : 6, type == TYPE_BANNED || type == TYPE_KICKED ? 6 : 2, selectType == 0);
ManageChatUserCell manageChatUserCell = new ManageChatUserCell(mContext, type == TYPE_BANNED || type == TYPE_KICKED ? 7 : 6, type == TYPE_BANNED || type == TYPE_KICKED ? 6 : 2, selectType == SELECT_TYPE_MEMBERS);
manageChatUserCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
manageChatUserCell.setDelegate((cell, click) -> {
TLObject participant = listViewAdapter.getItem((Integer) cell.getTag());
@ -3257,7 +3297,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
privacyCell.setBackgroundDrawable(Theme.getThemedDrawable(mContext, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
} else if (type == TYPE_USERS) {
if (!isChannel || selectType != 0) {
if (!isChannel || selectType != SELECT_TYPE_MEMBERS) {
privacyCell.setText("");
} else {
privacyCell.setText(LocaleController.getString("ChannelMembersInfo", R.string.ChannelMembersInfo));
@ -3291,7 +3331,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
actionCell.setText(LocaleController.getString("ChannelAddAdmin", R.string.ChannelAddAdmin), null, R.drawable.baseline_stars_24, showDivider);
} else if (type == TYPE_USERS) {
actionCell.setColors(Theme.key_windowBackgroundWhiteBlueIcon, Theme.key_windowBackgroundWhiteBlueButton);
boolean showDivider = !(loadingUsers && !firstLoaded) && membersHeaderRow == -1 && !participants.isEmpty();
boolean showDivider = addNew2Row != -1 || (!(loadingUsers && !firstLoaded) && membersHeaderRow == -1 && !participants.isEmpty());
if (isChannel) {
actionCell.setText(LocaleController.getString("AddSubscriber", R.string.AddSubscriber), null, R.drawable.baseline_person_add_24, showDivider);
} else {
@ -3301,7 +3341,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
} else if (position == recentActionsRow) {
actionCell.setText(LocaleController.getString("EventLog", R.string.EventLog), null, R.drawable.baseline_content_copy_24, false);
} else if (position == addNew2Row) {
actionCell.setText(LocaleController.getString("ChannelInviteViaLink", R.string.ChannelInviteViaLink), null, R.drawable.profile_link, true);
actionCell.setColors(Theme.key_windowBackgroundWhiteBlueIcon, Theme.key_windowBackgroundWhiteBlueButton);
boolean showDivider = !(loadingUsers && !firstLoaded) && membersHeaderRow == -1 && !participants.isEmpty();
actionCell.setText(LocaleController.getString("ChannelInviteViaLink", R.string.ChannelInviteViaLink), null, R.drawable.actions_link, showDivider);
} else if (position == gigaConvertRow) {
actionCell.setColors(Theme.key_windowBackgroundWhiteBlueIcon, Theme.key_windowBackgroundWhiteBlueButton);
actionCell.setText(LocaleController.getString("BroadcastGroupConvert", R.string.BroadcastGroupConvert), null, R.drawable.msg_channel, false);

View File

@ -552,7 +552,7 @@ public class AlertsCreator {
return dialog;
}
public static void showBlockReportSpamReplyAlert(ChatActivity fragment, MessageObject messageObject, long peerId, Theme.ResourcesProvider resourcesProvider) {
public static void showBlockReportSpamReplyAlert(ChatActivity fragment, MessageObject messageObject, long peerId, Theme.ResourcesProvider resourcesProvider, Runnable hideDim) {
if (fragment == null || fragment.getParentActivity() == null || messageObject == null) {
return;
}
@ -564,6 +564,12 @@ public class AlertsCreator {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getParentActivity(), resourcesProvider);
builder.setDimEnabled(hideDim == null);
builder.setOnPreDismissListener(di -> {
if (hideDim != null) {
hideDim.run();
}
});
builder.setTitle(LocaleController.getString("BlockUser", R.string.BlockUser));
if (user != null) {
@ -2971,16 +2977,22 @@ public class AlertsCreator {
});
}
public static void createReportAlert(final Context context, final long dialog_id, final int messageId, final BaseFragment parentFragment) {
createReportAlert(context, dialog_id, messageId, parentFragment, null);
public static void createReportAlert(final Context context, final long dialog_id, final int messageId, final BaseFragment parentFragment, Runnable hideDim) {
createReportAlert(context, dialog_id, messageId, parentFragment, null, hideDim);
}
public static void createReportAlert(final Context context, final long dialog_id, final int messageId, final BaseFragment parentFragment, Theme.ResourcesProvider resourcesProvider) {
public static void createReportAlert(final Context context, final long dialog_id, final int messageId, final BaseFragment parentFragment, Theme.ResourcesProvider resourcesProvider, Runnable hideDim) {
if (context == null || parentFragment == null) {
return;
}
BottomBuilder builder = new BottomBuilder(context);
builder.setDimBehind(hideDim == null);
builder.setOnPreDismissListener(di -> {
if (hideDim != null) {
hideDim.run();
}
});
builder.addTitle(LocaleController.getString("ReportChat", R.string.ReportChat), true);
String[] items;
int[] icons;
@ -4118,7 +4130,7 @@ public class AlertsCreator {
void didPressedNewCard();
}
public static void createDeleteMessagesAlert(BaseFragment fragment, TLRPC.User user, TLRPC.Chat chat, TLRPC.EncryptedChat encryptedChat, TLRPC.ChatFull chatInfo, long mergeDialogId, MessageObject selectedMessage, SparseArray<MessageObject>[] selectedMessages, MessageObject.GroupedMessages selectedGroup, boolean scheduled, int loadParticipant, Runnable onDelete, Theme.ResourcesProvider resourcesProvider) {
public static void createDeleteMessagesAlert(BaseFragment fragment, TLRPC.User user, TLRPC.Chat chat, TLRPC.EncryptedChat encryptedChat, TLRPC.ChatFull chatInfo, long mergeDialogId, MessageObject selectedMessage, SparseArray<MessageObject>[] selectedMessages, MessageObject.GroupedMessages selectedGroup, boolean scheduled, int loadParticipant, Runnable onDelete, Runnable hideDim, Theme.ResourcesProvider resourcesProvider) {
if (fragment == null || user == null && chat == null && encryptedChat == null) {
return;
}
@ -4129,6 +4141,7 @@ public class AlertsCreator {
int currentAccount = fragment.getCurrentAccount();
AlertDialog.Builder builder = new AlertDialog.Builder(activity, resourcesProvider);
builder.setDimEnabled(hideDim == null);
int count;
if (selectedGroup != null) {
count = selectedGroup.messages.size();
@ -4268,7 +4281,7 @@ public class AlertsCreator {
} else if (error != null && "USER_NOT_PARTICIPANT".equals(error.text)) {
loadType = 0;
}
createDeleteMessagesAlert(fragment, user, chat, encryptedChat, chatInfo, mergeDialogId, selectedMessage, selectedMessages, selectedGroup, scheduled, loadType, onDelete, resourcesProvider);
createDeleteMessagesAlert(fragment, user, chat, encryptedChat, chatInfo, mergeDialogId, selectedMessage, selectedMessages, selectedGroup, scheduled, loadType, onDelete, hideDim, resourcesProvider);
}));
AndroidUtilities.runOnUIThread(() -> {
if (progressDialog[0] == null) {
@ -4511,6 +4524,11 @@ public class AlertsCreator {
}
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
builder.setOnPreDismissListener(di -> {
if (hideDim != null) {
hideDim.run();
}
});
AlertDialog dialog = builder.create();
fragment.showDialog(dialog);
TextView button = (TextView) dialog.getButton(DialogInterface.BUTTON_POSITIVE);

View File

@ -31,6 +31,7 @@ import org.telegram.messenger.DispatchQueue;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.MessageObject;
import org.telegram.tgnet.TLRPC;
import java.io.File;
@ -119,6 +120,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable {
private int renderingHeight;
private int renderingWidth;
private float scaleFactor = 1f;
public final boolean isWebmSticker;
private View parentView;
private ArrayList<View> secondParentViews = new ArrayList<>();
@ -127,10 +129,12 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable {
private boolean useSharedQueue;
private boolean invalidatePath = true;
private boolean invalidateTaskIsRunning;
private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2, new ThreadPoolExecutor.DiscardPolicy());
private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(16, new ThreadPoolExecutor.DiscardPolicy());
protected final Runnable mInvalidateTask = () -> {
invalidateTaskIsRunning = false;
if (!secondParentViews.isEmpty()) {
for (int a = 0, N = secondParentViews.size(); a < N; a++) {
secondParentViews.get(a).invalidate();
@ -242,7 +246,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable {
}
if (renderingHeight > 0 && renderingWidth > 0 && metaData[0] > 0 && metaData[1] > 0) {
scaleFactor = Math.max(renderingWidth / (float) metaData[0], renderingHeight / (float) metaData[1]);
if (scaleFactor <= 0 || scaleFactor > 0.7) {
if (isWebmSticker || scaleFactor <= 0 || scaleFactor > 0.7) {
scaleFactor = 1;
}
} else {
@ -319,6 +323,10 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable {
currentAccount = account;
renderingHeight = h;
renderingWidth = w;
isWebmSticker = MessageObject.isVideoSticker(document);
if (isWebmSticker) {
useSharedQueue = true;
}
getPaint().setFlags(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
if (streamSize != 0 && (document != null || location != null)) {
stream = new AnimatedFileDrawableStream(document, location, parentObject, account, preview);
@ -331,7 +339,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable {
}
if (renderingHeight > 0 && renderingWidth > 0 && metaData[0] > 0 && metaData[1] > 0) {
scaleFactor = Math.max(renderingWidth / (float) metaData[0], renderingHeight / (float) metaData[1]);
if (scaleFactor <= 0 || scaleFactor > 0.7) {
if (isWebmSticker || scaleFactor <= 0 || scaleFactor > 0.7) {
scaleFactor = 1f;
}
} else {
@ -490,6 +498,9 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable {
}
public void setUseSharedQueue(boolean value) {
if (isWebmSticker) {
return;
}
useSharedQueue = value;
}
@ -598,6 +609,8 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable {
applyTransformation = true;
}
Paint paint;
@Override
public void draw(Canvas canvas) {
if (nativePtr == 0 && decoderCreated || destroyWhenDone) {
@ -641,8 +654,6 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable {
applyTransformation = false;
}
if (hasRoundRadius()) {
float scale = Math.max(scaleX, scaleY);
if (renderingShader == null) {
renderingShader = new BitmapShader(backgroundBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
}
@ -689,7 +700,8 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable {
canvas.scale(scaleX, scaleY);
canvas.drawBitmap(renderingBitmap, 0, 0, getPaint());
}
if (isRunning) {
if (isRunning && !invalidateTaskIsRunning) {
invalidateTaskIsRunning = true;
long timeToNextFrame = Math.max(1, invalidateAfter - (now - lastFrameTime) - 17);
uiHandler.removeCallbacks(mInvalidateTask);
uiHandler.postDelayed(mInvalidateTask, Math.min(timeToNextFrame, invalidateAfter));
@ -804,4 +816,8 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable {
public long getStartTime() {
return (long) (startTime * 1000);
}
public boolean isRecycled() {
return isRecycled;
}
}

View File

@ -151,6 +151,8 @@ public class AvatarDrawable extends Drawable {
setInfo((TLRPC.User) object);
} else if (object instanceof TLRPC.Chat) {
setInfo((TLRPC.Chat) object);
} else if (object instanceof TLRPC.ChatInvite) {
setInfo((TLRPC.ChatInvite) object);
}
}
@ -203,6 +205,11 @@ public class AvatarDrawable extends Drawable {
setInfo(chat.id, chat.title, null, null);
}
}
public void setInfo(TLRPC.ChatInvite chat) {
if (chat != null) {
setInfo(0, chat.title, null, null);
}
}
public void setColor(int value) {
color = value;

View File

@ -9,6 +9,7 @@ import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.OvershootInterpolator;

View File

@ -190,6 +190,9 @@ public final class BulletinFactory {
@CheckResult
public Bulletin createCopyBulletin(String message) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
return new Bulletin.EmptyBulletin();
}
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), null);
layout.setAnimation(R.raw.copy, 36, 36, "NULL ROTATION", "Back", "Front");
layout.textView.setText(message);

View File

@ -2371,6 +2371,9 @@ public class ChatActivityEnterView extends ChatBlurredFrameLayout implements Not
botCommandsMenuButton.setOnClickListener(view -> {
boolean open = !botCommandsMenuButton.isOpened();
botCommandsMenuButton.setOpened(open);
try {
performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
} catch (Exception ignore) {}
if (open) {
botCommandsMenuContainer.show();
} else {
@ -4052,11 +4055,11 @@ public class ChatActivityEnterView extends ChatBlurredFrameLayout implements Not
private ActionBarPopupWindow.ActionBarPopupWindowLayout sendPopupLayout;
private boolean onSendLongClick(View view) {
if (parentFragment == null || isInScheduleMode()) {
if (isInScheduleMode()) {
return false;
}
TLRPC.Chat chat = parentFragment.getCurrentChat();
TLRPC.User user = parentFragment.getCurrentUser();
boolean self = parentFragment != null && UserObject.isUserSelf(parentFragment.getCurrentUser());
if (sendPopupLayout == null) {
sendPopupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(parentActivity, resourcesProvider);
@ -4085,50 +4088,35 @@ public class ChatActivityEnterView extends ChatBlurredFrameLayout implements Not
});
sendPopupLayout.setShownFromBotton(false);
// long chatId;
// if (chat != null) {
// chatId = chat.id;
// } else if (user != null) {
// chatId = user.id;
// } else {
// chatId = -1;
// }
int a = 0;
ActionBarMenuSubItem cell = new ActionBarMenuSubItem(getContext(), a == 0, a == 1, resourcesProvider);
if (parentFragment.canScheduleMessage()) {
cell = new ActionBarMenuSubItem(getContext(), true, UserObject.isUserSelf(user) || slowModeTimer == 0 || isInScheduleMode());
if (UserObject.isUserSelf(user)) {
cell.setTextAndIcon(LocaleController.getString("SetReminder", R.string.SetReminder), R.drawable.baseline_date_range_24);
boolean scheduleButtonValue = parentFragment != null && parentFragment.canScheduleMessage();
boolean sendWithoutSoundButtonValue = !(self || slowModeTimer > 0 && !isInScheduleMode());
if (scheduleButtonValue) {
ActionBarMenuSubItem scheduleButton = new ActionBarMenuSubItem(getContext(), true, !sendWithoutSoundButtonValue, resourcesProvider);
if (self) {
scheduleButton.setTextAndIcon(LocaleController.getString("SetReminder", R.string.SetReminder), R.drawable.msg_schedule);
} else {
cell.setTextAndIcon(LocaleController.getString("ScheduleMessage", R.string.ScheduleMessage), R.drawable.baseline_date_range_24);
scheduleButton.setTextAndIcon(LocaleController.getString("ScheduleMessage", R.string.ScheduleMessage), R.drawable.msg_schedule);
}
cell.setOnClickListener(v -> {
scheduleButton.setMinimumWidth(AndroidUtilities.dp(196));
scheduleButton.setOnClickListener(v -> {
if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss();
}
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), this::sendMessageInternal, resourcesProvider);
});
cell.setMinimumWidth(AndroidUtilities.dp(196));
sendPopupLayout.addView(cell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 0, 48 * a++, 0, 0));
sendPopupLayout.addView(scheduleButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
}
if (!UserObject.isUserSelf(user) && slowModeTimer == 0 && !isInScheduleMode()) {
cell = new ActionBarMenuSubItem(getContext(), parentFragment.canScheduleMessage(), true);
cell.setTextAndIcon(LocaleController.getString("SendWithoutSound", R.string.SendWithoutSound), R.drawable.baseline_notifications_off_24);
cell.setOnClickListener(v -> {
if (sendWithoutSoundButtonValue) {
ActionBarMenuSubItem sendWithoutSoundButton = new ActionBarMenuSubItem(getContext(), !scheduleButtonValue, true, resourcesProvider);
sendWithoutSoundButton.setTextAndIcon(LocaleController.getString("SendWithoutSound", R.string.SendWithoutSound), R.drawable.input_notify_off);
sendWithoutSoundButton.setMinimumWidth(AndroidUtilities.dp(196));
sendWithoutSoundButton.setOnClickListener(v -> {
if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss();
}
sendMessageInternal(false, 0);
});
cell.setMinimumWidth(AndroidUtilities.dp(196));
sendPopupLayout.addView(cell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 0, 48 * a++, 0, 0));
sendPopupLayout.addView(sendWithoutSoundButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
}
sendPopupLayout.setupRadialSelectors(getThemedColor(Theme.key_dialogButtonSelector));
@ -4167,7 +4155,9 @@ public class ChatActivityEnterView extends ChatBlurredFrameLayout implements Not
sendPopupWindow.dimBehind();
sendButton.invalidate();
if (!NekoConfig.disableVibration.Bool()) {
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
try {
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
} catch (Exception ignore) {}
}
return false;

View File

@ -317,6 +317,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
}
boolean shouldHideBottomButtons() { return true; }
}
protected BaseFragment baseFragment;
@ -1046,12 +1048,14 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
containerView.invalidate();
if (frameLayout2 != null && buttonsRecyclerView != null) {
if (frameLayout2.getTag() == null) {
buttonsRecyclerView.setAlpha(1.0f - alpha);
shadow.setAlpha(1.0f - alpha);
buttonsRecyclerView.setTranslationY(AndroidUtilities.dp(44) * alpha);
if (currentAttachLayout == null || currentAttachLayout.shouldHideBottomButtons()) {
buttonsRecyclerView.setAlpha(1.0f - alpha);
shadow.setAlpha(1.0f - alpha);
buttonsRecyclerView.setTranslationY(AndroidUtilities.dp(44) * alpha);
}
frameLayout2.setTranslationY(AndroidUtilities.dp(48) * alpha);
shadow.setTranslationY(AndroidUtilities.dp(84) * alpha);
} else {
} else if (currentAttachLayout == null || currentAttachLayout.shouldHideBottomButtons()) {
float value = alpha == 0.0f ? 1.0f : 0.0f;
if (buttonsRecyclerView.getAlpha() != value) {
buttonsRecyclerView.setAlpha(value);
@ -2079,7 +2083,9 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
animators.add(ObjectAnimator.ofFloat(shadow, View.TRANSLATION_Y, show ? AndroidUtilities.dp(36) : AndroidUtilities.dp(48 + 36)));
animators.add(ObjectAnimator.ofFloat(shadow, View.ALPHA, show ? 1.0f : 0.0f));
} else if (typeButtonsAvailable) {
animators.add(ObjectAnimator.ofFloat(buttonsRecyclerView, View.TRANSLATION_Y, show ? AndroidUtilities.dp(36) : 0));
if (currentAttachLayout == null || currentAttachLayout.shouldHideBottomButtons()) {
animators.add(ObjectAnimator.ofFloat(buttonsRecyclerView, View.TRANSLATION_Y, show ? AndroidUtilities.dp(36) : 0));
}
animators.add(ObjectAnimator.ofFloat(shadow, View.TRANSLATION_Y, show ? AndroidUtilities.dp(36) : 0));
} else {
shadow.setTranslationY(AndroidUtilities.dp(36));
@ -2100,7 +2106,9 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
shadow.setVisibility(View.INVISIBLE);
}
} else if (typeButtonsAvailable) {
buttonsRecyclerView.setVisibility(View.INVISIBLE);
if (currentAttachLayout == null || currentAttachLayout.shouldHideBottomButtons()) {
buttonsRecyclerView.setVisibility(View.INVISIBLE);
}
}
commentsAnimator = null;
}
@ -2127,7 +2135,9 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
shadow.setTranslationY(show ? AndroidUtilities.dp(36) : AndroidUtilities.dp(48 + 36));
shadow.setAlpha(show ? 1.0f : 0.0f);
} else if (typeButtonsAvailable) {
buttonsRecyclerView.setTranslationY(show ? AndroidUtilities.dp(36) : 0);
if (currentAttachLayout == null || currentAttachLayout.shouldHideBottomButtons()) {
buttonsRecyclerView.setTranslationY(show ? AndroidUtilities.dp(36) : 0);
}
shadow.setTranslationY(show ? AndroidUtilities.dp(36) : 0);
} else {
shadow.setTranslationY(AndroidUtilities.dp(36));
@ -2461,7 +2471,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
public void onAnimationEnd(Animator animation) {
if (actionBarAnimation != null) {
if (show) {
if (typeButtonsAvailable) {
if (typeButtonsAvailable && (currentAttachLayout == null || currentAttachLayout.shouldHideBottomButtons())) {
buttonsRecyclerView.setVisibility(View.INVISIBLE);
}
} else {
@ -2481,7 +2491,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
actionBarAnimation.start();
} else {
if (show) {
if (typeButtonsAvailable) {
if (typeButtonsAvailable && (currentAttachLayout == null || currentAttachLayout.shouldHideBottomButtons())) {
buttonsRecyclerView.setVisibility(View.INVISIBLE);
}
}
@ -2730,8 +2740,10 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
avatarSearch = search;
if (avatarPicker != 0) {
typeButtonsAvailable = false;
buttonsRecyclerView.setVisibility(View.GONE);
shadow.setVisibility(View.GONE);
if (currentAttachLayout == null || currentAttachLayout.shouldHideBottomButtons()) {
buttonsRecyclerView.setVisibility(View.GONE);
shadow.setVisibility(View.GONE);
}
if (avatarPicker == 2) {
selectedTextView.setText(LocaleController.getString("ChoosePhotoOrVideo", R.string.ChoosePhotoOrVideo));
} else {

View File

@ -280,7 +280,7 @@ public class ChatAttachAlertAudioLayout extends ChatAttachAlert.AttachAlertLayou
} else {
visible = audioEntries.isEmpty();
}
currentEmptyView.setVisibility(visible ? VISIBLE : GONE);
currentEmptyView.setVisibility(visible ? VISIBLE : GONE);
updateEmptyViewPosition();
}
@ -590,10 +590,7 @@ public class ChatAttachAlertAudioLayout extends ChatAttachAlert.AttachAlertLayou
@Override
public int getItemCount() {
if (audioEntries.isEmpty()) {
return 1;
}
return audioEntries.size() + (audioEntries.isEmpty() ? 0 : 2);
return 1 + audioEntries.size() + (audioEntries.isEmpty() ? 0 : 1);
}
@Override
@ -767,10 +764,7 @@ public class ChatAttachAlertAudioLayout extends ChatAttachAlert.AttachAlertLayou
@Override
public int getItemCount() {
if (searchResult.isEmpty()) {
return 1;
}
return searchResult.size() + (searchResult.isEmpty() ? 0 : 2);
return 1 + searchResult.size() + (searchResult.isEmpty() ? 0 : 1);
}
@Override

View File

@ -48,6 +48,7 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -103,6 +104,9 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
import kotlin.Unit;
import tw.nekomimi.nekogram.ui.BottomBuilder;
@ -141,6 +145,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
private boolean currentMapStyleDark;
private boolean checkGpsEnabled = true;
private boolean locationDenied = false;
private boolean isFirstLocation = true;
private long dialogId;
@ -393,6 +398,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
locationType = LOCATION_TYPE_SEND;
}
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.locationPermissionGranted);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.locationPermissionDenied);
searchWas = false;
searching = false;
@ -404,6 +410,8 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
searchAdapter.destroy();
}
locationDenied = Build.VERSION.SDK_INT >= 23 && getParentActivity() != null && getParentActivity().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED;
ActionBarMenu menu = parentAlert.actionBar.createMenu();
overlayView = new MapOverlayView(context);
@ -421,6 +429,14 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
searchWas = false;
searchAdapter.searchDelayed(null, null);
updateEmptyView();
if (otherItem != null) {
otherItem.setVisibility(VISIBLE);
}
listView.setVisibility(VISIBLE);
mapViewClip.setVisibility(VISIBLE);
searchListView.setVisibility(GONE);
emptyView.setVisibility(GONE);
}
@Override
@ -442,7 +458,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
searchListView.setAdapter(searchAdapter);
}
searchListView.setVisibility(VISIBLE);
searchInProgress = searchAdapter.getItemCount() == 0;
searchInProgress = searchAdapter.isEmpty();
updateEmptyView();
} else {
if (otherItem != null) {
@ -457,6 +473,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
searchAdapter.searchDelayed(text, userLocation);
}
});
searchItem.setVisibility(locationDenied ? View.GONE : View.VISIBLE);
searchItem.setSearchFieldHint(LocaleController.getString("Search", R.string.Search));
searchItem.setContentDescription(LocaleController.getString("Search", R.string.Search));
EditTextBoldCursor editText = searchItem.getSearchField();
@ -708,6 +725,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
listView.setClipToPadding(false);
listView.setAdapter(adapter = new LocationActivityAdapter(context, locationType, dialogId, true, resourcesProvider));
adapter.setUpdateRunnable(this::updateClipView);
adapter.setMyLocationDenied(locationDenied);
listView.setVerticalScrollBarEnabled(false);
listView.setLayoutManager(layoutManager = new FillLastLinearLayoutManager(context, LinearLayoutManager.VERTICAL, false, 0, listView) {
@Override
@ -760,7 +778,6 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
parentAlert.updateLayout(ChatAttachAlertLocationLayout.this, true, dy);
}
});
((DefaultItemAnimator) listView.getItemAnimator()).setDelayAnimations(false);
listView.setOnItemClickListener((view, position) -> {
if (position == 1) {
if (delegate != null && userLocation != null) {
@ -781,13 +798,19 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
parentAlert.dismiss();
}
}
} else if (locationDenied) {
showPermissionAlert(true);
}
} else if (position == 2 && locationType == 1) {
} else if (position == 2 && locationType == LOCATION_TYPE_SEND_WITH_LIVE) {
if (getLocationController().isSharingLocation(dialogId)) {
getLocationController().removeSharingLocation(dialogId);
parentAlert.dismiss();
} else {
openShareLiveLocation();
if (myLocation == null && locationDenied) {
showPermissionAlert(true);
} else {
openShareLiveLocation();
}
}
} else {
Object object = adapter.getItem(position);
@ -907,6 +930,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
searchInProgress = false;
updateEmptyView();
});
searchListView.setItemAnimator(null);
addView(searchListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP));
searchListView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
@ -934,13 +958,9 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
updateEmptyView();
}
private TextView getAttributionOverlay(Context context) {
attributionOverlay = new TextView(context);
attributionOverlay.setText(Html.fromHtml("© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors"));
attributionOverlay.setShadowLayer(1, -1, -1, Color.WHITE);
attributionOverlay.setLinksClickable(true);
attributionOverlay.setMovementMethod(LinkMovementMethod.getInstance());
return attributionOverlay;
@Override
boolean shouldHideBottomButtons() {
return !locationDenied;
}
@Override
@ -962,6 +982,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
@Override
void onDestroy() {
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.locationPermissionGranted);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.locationPermissionDenied);
// TODO
// proper exit, like upstream does with
// setMyLocationEnabled(false);
@ -1105,7 +1126,6 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
if (searchInProgress) {
searchListView.setEmptyView(null);
emptyView.setVisibility(GONE);
searchListView.setVisibility(GONE);
} else {
searchListView.setEmptyView(emptyView);
}
@ -1165,7 +1185,6 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
}
private Bitmap[] bitmapCache = new Bitmap[7];
private Bitmap createPlaceBitmap(int num) {
if (bitmapCache[num % 7] != null) {
return bitmapCache[num % 7];
@ -1428,7 +1447,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
int top;
RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(0);
if (holder != null) {
top = (int) holder.itemView.getY();
top = (int) (holder.itemView.getY());
height = overScrollHeight + Math.min(top, 0);
} else {
top = -mapViewClip.getMeasuredHeight();
@ -1455,12 +1474,17 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
}
}
int trY = Math.max(0, -(top - mapHeight + overScrollHeight) / 2);
mapView.setTranslationY(trY);
int totalToMove = listView.getPaddingTop() - (mapHeight - overScrollHeight);
int maxClipSize = mapHeight - overScrollHeight;
int totalToMove = listView.getPaddingTop() - maxClipSize;
float moveProgress = 1.0f - (Math.max(0.0f, Math.min(1.0f, (listView.getPaddingTop() - top) / (float) totalToMove)));
int prevClipSize = clipSize;
clipSize = (int) ((mapHeight - overScrollHeight) * moveProgress);
nonClipSize = mapHeight - overScrollHeight - clipSize;
if (locationDenied && isTypeSend()) {
maxClipSize += Math.min(top, listView.getPaddingTop());
}
clipSize = (int) (maxClipSize * moveProgress);
mapView.setTranslationY(trY);
nonClipSize = maxClipSize - clipSize;
mapViewClip.invalidate();
mapViewClip.setTranslationY(top - nonClipSize);
@ -1491,21 +1515,49 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
controller.setCenter(location);
}
}
if (locationDenied && isTypeSend()) {
// adapter.setOverScrollHeight(overScrollHeight + top);
// // TODO(dkaraush): fix ripple effect on buttons
final int count = adapter.getItemCount();
for (int i = 1; i < count; ++i) {
holder = listView.findViewHolderForAdapterPosition(i);
if (holder != null) {
holder.itemView.setTranslationY(listView.getPaddingTop() - top);
}
}
}
}
}
private boolean isTypeSend() {
return locationType == LOCATION_TYPE_SEND || locationType == LOCATION_TYPE_SEND_WITH_LIVE;
}
private int buttonsHeight() {
int buttonsHeight = AndroidUtilities.dp(66);
if (locationType == LOCATION_TYPE_SEND_WITH_LIVE)
buttonsHeight += AndroidUtilities.dp(66);
return buttonsHeight;
}
private void fixLayoutInternal(final boolean resume) {
int viewHeight = getMeasuredHeight();
if (viewHeight == 0 || mapView == null) {
return;
}
int height = ActionBar.getCurrentActionBarHeight();
int maxMapHeight = AndroidUtilities.displaySize.y - height - buttonsHeight() - AndroidUtilities.dp(90);
overScrollHeight = AndroidUtilities.dp(189);
mapHeight = Math.max(overScrollHeight, Math.min(AndroidUtilities.dp(310), AndroidUtilities.displaySize.y - AndroidUtilities.dp(66) - height));
mapHeight = Math.max(overScrollHeight, locationDenied && isTypeSend() ? maxMapHeight : Math.min(AndroidUtilities.dp(310), maxMapHeight));
if (locationDenied && isTypeSend()) {
overScrollHeight = mapHeight;
}
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams();
layoutParams.topMargin = height;
listView.setLayoutParams(layoutParams);
layoutParams = (FrameLayout.LayoutParams) mapViewClip.getLayoutParams();
layoutParams.topMargin = height;
layoutParams.height = mapHeight;
@ -1515,7 +1567,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
layoutParams.topMargin = height;
searchListView.setLayoutParams(layoutParams);
adapter.setOverScrollHeight(overScrollHeight);
adapter.setOverScrollHeight(locationDenied && isTypeSend() ? overScrollHeight - listView.getPaddingTop() : overScrollHeight);
layoutParams = (FrameLayout.LayoutParams) mapView.getLayoutParams();
if (layoutParams != null) {
layoutParams.height = mapHeight + AndroidUtilities.dp(10);
@ -1528,6 +1580,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
overlayView.setLayoutParams(layoutParams);
}
}
adapter.notifyDataSetChanged();
updateClipView();
}
@ -1583,10 +1636,21 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.locationPermissionGranted) {
locationDenied = false;
if (adapter != null) {
adapter.setMyLocationDenied(locationDenied);
}
if (mapView != null && mapsInitialized) {
myLocationOverlay.enableMyLocation();
}
} else if (id == NotificationCenter.locationPermissionDenied) {
locationDenied = true;
if (adapter != null) {
adapter.setMyLocationDenied(locationDenied);
}
}
fixLayoutInternal(true);
searchItem.setVisibility(locationDenied ? View.GONE : View.VISIBLE);
}
@Override
@ -1755,4 +1819,15 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
return themeDescriptions;
}
// NekoX: OpenStreetMap
private TextView getAttributionOverlay(Context context) {
attributionOverlay = new TextView(context);
attributionOverlay.setText(Html.fromHtml("© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors"));
attributionOverlay.setShadowLayer(1, -1, -1, Color.WHITE);
attributionOverlay.setLinksClickable(true);
attributionOverlay.setMovementMethod(LinkMovementMethod.getInstance());
return attributionOverlay;
}
}

View File

@ -377,7 +377,19 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
@Override
public void onApplyCaption(CharSequence caption) {
parentAlert.commentTextView.setText(caption);
if (selectedPhotos.size() > 0 && selectedPhotosOrder.size() > 0) {
Object o = selectedPhotos.get(selectedPhotosOrder.get(0));
CharSequence firstPhotoCaption = null;
if (o instanceof MediaController.PhotoEntry) {
MediaController.PhotoEntry photoEntry1 = (MediaController.PhotoEntry) o;
firstPhotoCaption = photoEntry1.caption;
}
if (o instanceof MediaController.SearchImage) {
MediaController.SearchImage photoEntry1 = (MediaController.SearchImage) o;
firstPhotoCaption = photoEntry1.caption;
}
parentAlert.commentTextView.setText(firstPhotoCaption);
}
}
@Override
@ -666,9 +678,22 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
AndroidUtilities.hideKeyboard(parentAlert.baseFragment.getFragmentView().findFocus());
AndroidUtilities.hideKeyboard(parentAlert.getContainer().findFocus());
}
((MediaController.PhotoEntry) arrayList.get(position)).caption = parentAlert.getCommentTextView().getText();
if (selectedPhotos.size() > 0 && selectedPhotosOrder.size() > 0) {
Object o = selectedPhotos.get(selectedPhotosOrder.get(0));
CharSequence firstPhotoCaption = null;
if (o instanceof MediaController.PhotoEntry) {
MediaController.PhotoEntry photoEntry1 = (MediaController.PhotoEntry) o;
photoEntry1.caption = parentAlert.getCommentTextView().getText();
}
if (o instanceof MediaController.SearchImage) {
MediaController.SearchImage photoEntry1 = (MediaController.SearchImage) o;
photoEntry1.caption = parentAlert.getCommentTextView().getText();
}
}
PhotoViewer.getInstance().openPhotoForSelect(arrayList, position, type, false, photoViewerProvider, chatActivity);
PhotoViewer.getInstance().setCaption(parentAlert.getCommentTextView().getText());
if (captionForAllMedia()) {
PhotoViewer.getInstance().setCaption(parentAlert.getCommentTextView().getText());
}
} else {
if (SharedConfig.inappCamera) {
if (NekoConfig.disableInstantCamera.Bool()) {
@ -2541,27 +2566,40 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
@Override
void applyCaption(CharSequence text) {
for (int a = 0; a < selectedPhotosOrder.size(); a++) {
Object o = selectedPhotos.get(selectedPhotosOrder.get(a));
if (o instanceof MediaController.PhotoEntry) {
MediaController.PhotoEntry photoEntry1 = (MediaController.PhotoEntry) o;
if (a == 0) {
if (a == 0) {
Object o = selectedPhotos.get(selectedPhotosOrder.get(a));
if (o instanceof MediaController.PhotoEntry) {
MediaController.PhotoEntry photoEntry1 = (MediaController.PhotoEntry) o;
photoEntry1.caption = text;
photoEntry1.entities = MediaDataController.getInstance(UserConfig.selectedAccount).getEntities(new CharSequence[] {text}, false);
} else {
photoEntry1.caption = null;
}
} else if (o instanceof MediaController.SearchImage) {
MediaController.SearchImage photoEntry1 = (MediaController.SearchImage) o;
if (a == 0) {
photoEntry1.entities = MediaDataController.getInstance(UserConfig.selectedAccount).getEntities(new CharSequence[]{text}, false);
} else if (o instanceof MediaController.SearchImage) {
MediaController.SearchImage photoEntry1 = (MediaController.SearchImage) o;
photoEntry1.caption = text;
photoEntry1.entities = MediaDataController.getInstance(UserConfig.selectedAccount).getEntities(new CharSequence[] {text}, false);
} else {
photoEntry1.caption = null;
photoEntry1.entities = MediaDataController.getInstance(UserConfig.selectedAccount).getEntities(new CharSequence[]{text}, false);
}
}
}
}
private boolean captionForAllMedia() {
int captionCount = 0;
for (int a = 0; a < selectedPhotosOrder.size(); a++) {
Object o = selectedPhotos.get(selectedPhotosOrder.get(a));
CharSequence caption = null;
if (o instanceof MediaController.PhotoEntry) {
MediaController.PhotoEntry photoEntry1 = (MediaController.PhotoEntry) o;
caption = photoEntry1.caption;
} else if (o instanceof MediaController.SearchImage) {
MediaController.SearchImage photoEntry1 = (MediaController.SearchImage) o;
caption = photoEntry1.caption;
}
if (!TextUtils.isEmpty(caption)) {
captionCount++;
}
}
return captionCount <= 1;
}
@Override
void onDestroy() {
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.cameraInitied);

View File

@ -444,7 +444,7 @@ public class ChatAttachAlertPollLayout extends ChatAttachAlert.AttachAlertLayout
@Override
int getCurrentItemTop() {
if (listView.getChildCount() <= 0) {
if (listView.getChildCount() <= 1) {
return Integer.MAX_VALUE;
}
View child = listView.getChildAt(1);
@ -454,7 +454,7 @@ public class ChatAttachAlertPollLayout extends ChatAttachAlert.AttachAlertLayout
RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findContainingViewHolder(child);
int top = (int) child.getY() - AndroidUtilities.dp(8);
int newOffset = top > 0 && holder != null && holder.getAdapterPosition() == 1 ? top : 0;
if (top >= 0 && holder != null && holder.getAdapterPosition() == 0) {
if (top >= 0 && holder != null && holder.getAdapterPosition() == 1) {
newOffset = top;
}
return newOffset + AndroidUtilities.dp(25);
@ -811,6 +811,10 @@ public class ChatAttachAlertPollLayout extends ChatAttachAlert.AttachAlertLayout
checkCell.setEnabled(quizOnly == 0, null);
}
}
case 9: {
View view = (View) holder.itemView;
view.requestLayout();
}
}
}

View File

@ -15,7 +15,7 @@ import org.telegram.ui.ChatActivity;
public class ChatBlurredFrameLayout extends FrameLayout {
ChatActivity chatActivity;
Paint backgroundPaint;
protected Paint backgroundPaint;
public int backgroundColor;
public int backgroundPaddingBottom;
public int backgroundPaddingTop;
@ -65,7 +65,7 @@ public class ChatBlurredFrameLayout extends FrameLayout {
@Override
protected void onDetachedFromWindow() {
if (SharedConfig.chatBlurEnabled() && chatActivity != null) {
if (chatActivity != null) {
chatActivity.contentView.blurBehindViews.remove(this);
}
super.onDetachedFromWindow();

View File

@ -205,7 +205,6 @@ public class CounterView extends View {
countAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
animationType = -1;
countChangeProgress = 1f;
countOldLayout = null;
countAnimationStableLayout = null;
@ -216,6 +215,7 @@ public class CounterView extends View {
}
parent.invalidate();
}
animationType = -1;
}
});
if (currentCount <= 0) {
@ -436,4 +436,20 @@ public class CounterView extends View {
return color != null ? color : Theme.getColor(key);
}
}
public float getEnterProgress() {
if (counterDrawable.countChangeProgress != 1f && (counterDrawable.animationType == CounterDrawable.ANIMATION_TYPE_IN || counterDrawable.animationType == CounterDrawable.ANIMATION_TYPE_OUT)) {
if (counterDrawable.animationType == CounterDrawable.ANIMATION_TYPE_IN) {
return counterDrawable.countChangeProgress;
} else {
return 1f - counterDrawable.countChangeProgress;
}
} else {
return counterDrawable.currentCount == 0 ? 0 : 1f;
}
}
public boolean isInOutAnimation() {
return counterDrawable.animationType == CounterDrawable.ANIMATION_TYPE_IN || counterDrawable.animationType == CounterDrawable.ANIMATION_TYPE_OUT;
}
}

View File

@ -15,6 +15,7 @@ import androidx.recyclerview.widget.SimpleItemAnimator;
import org.telegram.ui.Adapters.DialogsAdapter;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Cells.DialogsEmptyCell;
import java.util.ArrayList;
import java.util.List;
@ -746,6 +747,6 @@ public class DialogsItemAnimator extends SimpleItemAnimator {
@Override
public boolean canReuseUpdatedViewHolder(ViewHolder viewHolder, List<Object> payloads) {
return false;
return viewHolder.itemView instanceof DialogsEmptyCell;
}
}

View File

@ -29,20 +29,6 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.os.Build;
import androidx.annotation.IntDef;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.LinearSmoothScrollerCustom;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@ -69,18 +55,30 @@ import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import androidx.annotation.IntDef;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.LinearSmoothScrollerCustom;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.EmojiData;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
@ -3359,7 +3357,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
TLRPC.TL_messages_stickerSet stickerSet = stickerSets.get(a);
TLRPC.Document document = stickerSet.documents.get(0);
TLObject thumb = FileLoader.getClosestPhotoSizeWithSize(stickerSet.set.thumbs, 90);
if (thumb == null) {
if (thumb == null || stickerSet.set.gifs) {
thumb = document;
}
stickersTab.addStickerTab(thumb, document, stickerSet).setContentDescription(stickerSet.set.title + ", " + LocaleController.getString("AccDescrStickerSet", R.string.AccDescrStickerSet));

View File

@ -223,7 +223,7 @@ public class FlickerLoadingView extends View {
break;
}
}
} else if (getViewType() == 3) {
} else if (getViewType() == FILES_TYPE) {
int k = 0;
while (h <= getMeasuredHeight()) {
rectF.set(AndroidUtilities.dp(12), h + AndroidUtilities.dp(8), AndroidUtilities.dp(52), h + AndroidUtilities.dp(48));
@ -250,7 +250,7 @@ public class FlickerLoadingView extends View {
break;
}
}
} else if (getViewType() == 4) {
} else if (getViewType() == AUDIO_TYPE) {
int k = 0;
while (h <= getMeasuredHeight()) {
int radius = AndroidUtilities.dp(44) >> 1;
@ -608,11 +608,11 @@ public class FlickerLoadingView extends View {
} else if (getViewType() == PHOTOS_TYPE) {
int photoWidth = (width - (AndroidUtilities.dp(2) * (getColumnsCount() - 1))) / getColumnsCount();
return photoWidth + AndroidUtilities.dp(2);
} else if (getViewType() == 3) {
} else if (getViewType() == FILES_TYPE) {
return AndroidUtilities.dp(56);
} else if (getViewType() == 4) {
} else if (getViewType() == AUDIO_TYPE) {
return AndroidUtilities.dp(56);
} else if (getViewType() == 5) {
} else if (getViewType() == LINKS_TYPE) {
return AndroidUtilities.dp(80);
} else if (getViewType() == USERS_TYPE) {
return AndroidUtilities.dp(64);

View File

@ -5,7 +5,6 @@ import android.os.Handler;
import android.os.Message;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
@ -250,7 +249,7 @@ public class GestureDetectorFixDoubleTap {
break;
case MotionEvent.ACTION_DOWN:
if (mDoubleTapListener != null) {
if (mDoubleTapListener != null && mListener.hasDoubleTap()) {
boolean hadTapMessage = mHandler.hasMessages(TAP);
if (hadTapMessage) mHandler.removeMessages(TAP);
if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null)
@ -427,35 +426,6 @@ public class GestureDetectorFixDoubleTap {
}
}
static class GestureDetectorCompatImplJellybeanMr2 implements GestureDetectorCompatImpl {
private final GestureDetector mDetector;
GestureDetectorCompatImplJellybeanMr2(Context context, OnGestureListener listener,
Handler handler) {
mDetector = new GestureDetector(context, listener, handler);
}
@Override
public boolean isLongpressEnabled() {
return mDetector.isLongpressEnabled();
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return mDetector.onTouchEvent(ev);
}
@Override
public void setIsLongpressEnabled(boolean enabled) {
mDetector.setIsLongpressEnabled(enabled);
}
@Override
public void setOnDoubleTapListener(OnDoubleTapListener listener) {
mDetector.setOnDoubleTapListener(listener);
}
}
private final GestureDetectorCompatImpl mImpl;
/**
@ -527,4 +497,10 @@ public class GestureDetectorFixDoubleTap {
public void setOnDoubleTapListener(OnDoubleTapListener listener) {
mImpl.setOnDoubleTapListener(listener);
}
public static class OnGestureListener extends GestureDetector.SimpleOnGestureListener {
public boolean hasDoubleTap() {
return false;
}
}
}

View File

@ -16,6 +16,8 @@ import android.text.StaticLayout;
import org.telegram.messenger.AndroidUtilities;
import java.util.ArrayList;
public class LinkPath extends Path {
private Layout currentLayout;
@ -23,10 +25,13 @@ public class LinkPath extends Path {
private float lastTop = -1;
private float heightOffset;
private boolean useRoundRect;
private RectF rect;
private boolean allowReset = true;
private int baselineShift;
private int lineHeight;
private ArrayList<RectF> rects = new ArrayList<>();
private final int radius = AndroidUtilities.dp(4);
private final int halfRadius = radius >> 1;
public LinkPath() {
super();
@ -103,11 +108,9 @@ public class LinkPath extends Path {
y += baselineShift;
}
if (useRoundRect) {
if (rect == null) {
rect = new RectF();
}
rect.set(left - AndroidUtilities.dp(4), y, right + AndroidUtilities.dp(4), y2);
super.addRoundRect(rect, AndroidUtilities.dp(4), AndroidUtilities.dp(4), dir);
RectF rect = new RectF();
rect.set(left - halfRadius, y, right + halfRadius, y2);
rects.add(rect);
} else {
super.addRect(left, y, right, y2, dir);
}
@ -119,5 +122,34 @@ public class LinkPath extends Path {
return;
}
super.reset();
rects.clear();
}
private boolean containsPoint(float x, float y) {
for (RectF rect : rects) {
if (rect.contains(x, y)) {
return true;
}
}
return false;
}
public void onPathEnd() {
if (useRoundRect) {
super.reset();
final int count = rects.size();
for (int i = 0; i < count; ++i) {
float[] radii = new float[8];
RectF rect = rects.get(i);
radii[0] = radii[1] = containsPoint(rect.left, rect.top - radius) ? 0 : radius; // top left
radii[2] = radii[3] = containsPoint(rect.right, rect.top - radius) ? 0 : radius; // top right
radii[4] = radii[5] = containsPoint(rect.right, rect.bottom + radius) ? 0 : radius; // bottom right
radii[6] = radii[7] = containsPoint(rect.left, rect.bottom + radius) ? 0 : radius; // bottom left
super.addRoundRect(rect, radii, Direction.CW);
}
}
}
}

View File

@ -91,7 +91,9 @@ public class MotionBackgroundDrawable extends Drawable {
private boolean rotatingPreview;
private Runnable updateAnimationRunnable = this::updateAnimation;
private Runnable updateAnimationRunnable = () -> {
updateAnimation(true);
};
private android.graphics.Rect patternBounds = new android.graphics.Rect();
@ -341,7 +343,7 @@ public class MotionBackgroundDrawable extends Drawable {
}
if (postInvalidateParent) {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.invalidateMotionBackground);
updateAnimation();
updateAnimation(false);
AndroidUtilities.cancelRunOnUIThread(updateAnimationRunnable);
AndroidUtilities.runOnUIThread(updateAnimationRunnable, 16);
}
@ -517,7 +519,7 @@ public class MotionBackgroundDrawable extends Drawable {
}
canvas.restore();
updateAnimation();
updateAnimation(true);
}
public void drawPattern(Canvas canvas) {
android.graphics.Rect bounds = getBounds();
@ -647,7 +649,7 @@ public class MotionBackgroundDrawable extends Drawable {
}
canvas.restore();
updateAnimation();
updateAnimation(true);
}
@Override
@ -807,10 +809,10 @@ public class MotionBackgroundDrawable extends Drawable {
}
canvas.restore();
updateAnimation();
updateAnimation(true);
}
public void updateAnimation() {
public void updateAnimation(boolean invalidate) {
long newTime = SystemClock.elapsedRealtime();
long dt = newTime - lastUpdateTime;
if (dt > 20) {
@ -931,7 +933,9 @@ public class MotionBackgroundDrawable extends Drawable {
}
}
}
invalidateParent();
if (invalidate) {
invalidateParent();
}
}
}

View File

@ -506,7 +506,9 @@ public class PhonebookShareAlert extends BottomSheet {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("label", item.getValue(false));
clipboard.setPrimaryClip(clip);
Toast.makeText(this.parentFragment.getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
Toast.makeText(this.parentFragment.getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
FileLog.e(e);
}
@ -562,7 +564,9 @@ public class PhonebookShareAlert extends BottomSheet {
layout.textView.setText(LocaleController.getString("TextCopied", R.string.TextCopied));
layout.imageView.setImageResource(R.drawable.menu_info);
}
Bulletin.make((FrameLayout) containerView, layout, Bulletin.DURATION_SHORT).show();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
Bulletin.make((FrameLayout) containerView, layout, Bulletin.DURATION_SHORT).show();
}
}
}
return true;

View File

@ -28,12 +28,14 @@ import android.text.TextWatcher;
import android.text.style.ImageSpan;
import android.util.TypedValue;
import android.view.ActionMode;
import android.view.DragEvent;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
@ -196,8 +198,15 @@ public class PhotoViewerCaptionEnterView extends FrameLayout implements Notifica
rectangle.bottom += AndroidUtilities.dp(1000);
return super.requestRectangleOnScreen(rectangle);
}
};
messageEditText.setOnFocusChangeListener((view, focused) -> {
if (focused) {
try {
messageEditText.setSelection(messageEditText.length(), messageEditText.length());
} catch (Exception ignore) {}
}
});
messageEditText.setSelectAllOnFocus(false);
messageEditText.setDelegate(new EditTextCaption.EditTextCaptionDelegate() {
@Override
@ -730,22 +739,10 @@ public class PhotoViewerCaptionEnterView extends FrameLayout implements Notifica
}
public void openKeyboard() {
int currentSelection;
try {
currentSelection = messageEditText.getSelectionStart();
} catch (Exception e) {
currentSelection = messageEditText.length();
FileLog.e(e);
}
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
messageEditText.onTouchEvent(event);
event.recycle();
event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0);
messageEditText.onTouchEvent(event);
event.recycle();
messageEditText.requestFocus();
AndroidUtilities.showKeyboard(messageEditText);
try {
messageEditText.setSelection(currentSelection);
messageEditText.setSelection(messageEditText.length(), messageEditText.length());
} catch (Exception e) {
FileLog.e(e);
}

View File

@ -50,7 +50,7 @@ public class ReactedUsersListView extends FrameLayout {
private FlickerLoadingView loadingView;
private List<TLRPC.TL_messageUserReaction> userReactions = new ArrayList<>();
private List<TLRPC.TL_messagePeerReaction> userReactions = new ArrayList<>();
private LongSparseArray<TLRPC.User> users = new LongSparseArray<>();
private String offset;
private boolean isLoading, isLoaded, canLoadMore = true;
@ -101,7 +101,7 @@ public class ReactedUsersListView extends FrameLayout {
});
listView.setOnItemClickListener((view, position) -> {
if (onProfileSelectedListener != null)
onProfileSelectedListener.onProfileSelected(this, userReactions.get(position).user_id);
onProfileSelectedListener.onProfileSelected(this, MessageObject.getPeerId(userReactions.get(position).peer_id));
});
listView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
@ -124,13 +124,14 @@ public class ReactedUsersListView extends FrameLayout {
@SuppressLint("NotifyDataSetChanged")
public ReactedUsersListView setSeenUsers(List<TLRPC.User> users) {
List<TLRPC.TL_messageUserReaction> nr = new ArrayList<>(users.size());
List<TLRPC.TL_messagePeerReaction> nr = new ArrayList<>(users.size());
for (TLRPC.User u : users) {
if (this.users.get(u.id) != null) continue;
this.users.put(u.id, u);
TLRPC.TL_messageUserReaction r = new TLRPC.TL_messageUserReaction();
TLRPC.TL_messagePeerReaction r = new TLRPC.TL_messagePeerReaction();
r.reaction = null;
r.user_id = u.id;
r.peer_id = new TLRPC.TL_peerUser();
r.peer_id.user_id = u.id;
nr.add(r);
}
if (userReactions.isEmpty())
@ -175,7 +176,7 @@ public class ReactedUsersListView extends FrameLayout {
// It's safer to create a new list to prevent inconsistency
int prev = userReactions.size();
List<TLRPC.TL_messageUserReaction> newReactions = new ArrayList<>(userReactions.size() + l.reactions.size());
List<TLRPC.TL_messagePeerReaction> newReactions = new ArrayList<>(userReactions.size() + l.reactions.size());
newReactions.addAll(userReactions);
newReactions.addAll(l.reactions);
@ -265,8 +266,8 @@ public class ReactedUsersListView extends FrameLayout {
addView(overlaySelectorView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
void setUserReaction(TLRPC.TL_messageUserReaction reaction) {
TLRPC.User u = users.get(reaction.user_id);
void setUserReaction(TLRPC.TL_messagePeerReaction reaction) {
TLRPC.User u = users.get(MessageObject.getPeerId(reaction.peer_id));
avatarDrawable.setInfo(u);
titleView.setText(UserObject.getUserName(u));
avatarView.setImage(ImageLocation.getForUser(u, ImageLocation.TYPE_SMALL), "50_50", avatarDrawable, u);

View File

@ -6,6 +6,7 @@ import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
@ -60,6 +61,8 @@ public class ReactionsEffectOverlay {
private boolean wasScrolled;
private ChatMessageCell cell;
private boolean finished;
private boolean useWindow;
private ViewGroup decorView;
private ReactionsEffectOverlay(Context context, BaseFragment fragment, ReactionsContainerLayout reactionsLayout, ChatMessageCell cell, float x, float y, String reaction, int currentAccount, int animationType) {
this.fragment = fragment;
@ -127,11 +130,7 @@ public class ReactionsEffectOverlay {
if (dismissProgress > 1f) {
dismissProgress = 1f;
AndroidUtilities.runOnUIThread(() -> {
try {
windowManager.removeView(windowView);
} catch (Exception e) {
}
removeCurrentView();
});
}
}
@ -153,7 +152,7 @@ public class ReactionsEffectOverlay {
}
ChatMessageCell drawingCell;
if (fragment instanceof ChatActivity) {
drawingCell = ((ChatActivity) fragment).findMessageCell(messageId);
drawingCell = ((ChatActivity) fragment).findMessageCell(messageId, false);
} else {
drawingCell = cell;
}
@ -301,11 +300,7 @@ public class ReactionsEffectOverlay {
((View) cell.getParent()).invalidate();
}
AndroidUtilities.runOnUIThread(() -> {
try {
windowManager.removeView(windowView);
} catch (Exception e) {
}
removeCurrentView();
});
}
}
@ -398,11 +393,25 @@ public class ReactionsEffectOverlay {
container.setPivotX(leftOffset);
container.setPivotY(topOffset);
//}
} else {
dismissed = true;
}
}
private void removeCurrentView() {
try {
if (useWindow) {
windowManager.removeView(windowView);
} else {
decorView.removeView(windowView);
}
} catch (Exception e) {
}
}
public static void show(BaseFragment baseFragment, ReactionsContainerLayout reactionsLayout, ChatMessageCell cell, float x, float y, String reaction, int currentAccount, int animationType) {
if (cell == null) {
if (cell == null || reaction == null || baseFragment == null || baseFragment.getParentActivity() == null) {
return;
}
boolean animationEnabled = MessagesController.getGlobalMainSettings().getBoolean("view_animations", true);
@ -420,14 +429,28 @@ public class ReactionsEffectOverlay {
currentOverlay = reactionsEffectOverlay;
}
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.width = lp.height = WindowManager.LayoutParams.MATCH_PARENT;
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
lp.format = PixelFormat.TRANSLUCENT;
boolean useWindow = false;
if (baseFragment instanceof ChatActivity) {
ChatActivity chatActivity = (ChatActivity) baseFragment;
if (chatActivity.scrimPopupWindow != null && chatActivity.scrimPopupWindow.isShowing()) {
useWindow = true;
}
}
reactionsEffectOverlay.windowManager = baseFragment.getParentActivity().getWindowManager();
reactionsEffectOverlay.windowManager.addView(reactionsEffectOverlay.windowView, lp);
reactionsEffectOverlay.useWindow = useWindow;
if (useWindow) {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.width = lp.height = WindowManager.LayoutParams.MATCH_PARENT;
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
lp.format = PixelFormat.TRANSLUCENT;
reactionsEffectOverlay.windowManager = baseFragment.getParentActivity().getWindowManager();
reactionsEffectOverlay.windowManager.addView(reactionsEffectOverlay.windowView, lp);
} else {
reactionsEffectOverlay.decorView = (FrameLayout) baseFragment.getParentActivity().getWindow().getDecorView();
reactionsEffectOverlay.decorView.addView(reactionsEffectOverlay.windowView);
}
cell.invalidate();
if (cell.getCurrentMessagesGroup() != null && cell.getParent() != null) {
((View) cell.getParent()).invalidate();
@ -460,11 +483,7 @@ public class ReactionsEffectOverlay {
ReactionsEffectOverlay overlay = i == 0 ? currentOverlay : currentShortOverlay;
if (overlay != null) {
if (instant) {
try {
overlay.windowManager.removeView(overlay.windowView);
} catch (Exception e) {
}
overlay.removeCurrentView();
} else {
overlay.dismissed = true;
}

View File

@ -10,6 +10,8 @@ import android.view.ViewConfiguration;
import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.DocumentObject;
@ -79,6 +81,7 @@ public class ReactionsLayoutInBubble {
HashMap<String, ImageReceiver> animatedReactions = new HashMap<>();
private int lastDrawTotalHeight;
private int animateFromTotalHeight;
public boolean hasUnreadReactions;
public ReactionsLayoutInBubble(ChatMessageCell parentView) {
this.parentView = parentView;
@ -97,6 +100,7 @@ public class ReactionsLayoutInBubble {
for (int i = 0; i < reactionButtons.size(); i++) {
reactionButtons.get(i).detach();
}
hasUnreadReactions = false;
reactionButtons.clear();
if (messageObject != null) {
if (messageObject.messageOwner.reactions != null && messageObject.messageOwner.reactions.results != null) {
@ -108,16 +112,16 @@ public class ReactionsLayoutInBubble {
TLRPC.TL_reactionCount reactionCount = messageObject.messageOwner.reactions.results.get(i);
ReactionButton button = new ReactionButton(reactionCount);
reactionButtons.add(button);
if (!isSmall && messageObject.messageOwner.reactions.recent_reactons != null) {
if (!isSmall && messageObject.messageOwner.reactions.recent_reactions != null) {
ArrayList<TLRPC.User> users = null;
if (reactionCount.count <= 3 && totalCount <= 3) {
for (int j = 0; j < messageObject.messageOwner.reactions.recent_reactons.size(); j++) {
TLRPC.TL_messageUserReaction reccent = messageObject.messageOwner.reactions.recent_reactons.get(j);
if (reccent.reaction.equals(reactionCount.reaction) && MessagesController.getInstance(currentAccount).getUser(reccent.user_id) != null) {
for (int j = 0; j < messageObject.messageOwner.reactions.recent_reactions.size(); j++) {
TLRPC.TL_messagePeerReaction reccent = messageObject.messageOwner.reactions.recent_reactions.get(j);
if (reccent.reaction.equals(reactionCount.reaction) && MessagesController.getInstance(currentAccount).getUser(MessageObject.getPeerId(reccent.peer_id)) != null) {
if (users == null) {
users = new ArrayList<>();
}
users.add(MessagesController.getInstance(currentAccount).getUser(reccent.user_id));
users.add(MessagesController.getInstance(currentAccount).getUser(MessageObject.getPeerId(reccent.peer_id)));
}
}
button.setUsers(users);
@ -148,6 +152,7 @@ public class ReactionsLayoutInBubble {
comparator.currentAccount = currentAccount;
Collections.sort(reactionButtons, comparator);
}
hasUnreadReactions = MessageObject.hasUnreadReactions(messageObject.messageOwner);
}
isEmpty = reactionButtons.isEmpty();
}

View File

@ -521,7 +521,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
public BackupImageView backupImageView;
public BackupImageView pressedBackupImageView;
public TLRPC.TL_availableReaction currentReaction;
public float sideScale;
public float sideScale = 1f;
private boolean isEnter;
Runnable playRunnable = new Runnable() {

View File

@ -30,7 +30,6 @@ import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.SparseIntArray;
import android.util.StateSet;
import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
@ -905,7 +904,7 @@ public class RecyclerListView extends RecyclerView {
private class RecyclerListViewItemClickListener implements OnItemTouchListener {
public RecyclerListViewItemClickListener(Context context) {
gestureDetector = new GestureDetectorFixDoubleTap(context, new GestureDetector.SimpleOnGestureListener() {
gestureDetector = new GestureDetectorFixDoubleTap(context, new GestureDetectorFixDoubleTap.OnGestureListener() {
private View doubleTapView;
@Override
@ -915,7 +914,7 @@ public class RecyclerListView extends RecyclerView {
doubleTapView = currentChildView;
} else {
onPressItem(currentChildView, e);
return true;
return false;
}
}
return false;
@ -1020,6 +1019,11 @@ public class RecyclerListView extends RecyclerView {
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public boolean hasDoubleTap() {
return onItemLongClickListenerExtended != null;
}
});
gestureDetector.setIsLongpressEnabled(false);
}
@ -1953,6 +1957,7 @@ public class RecyclerListView extends RecyclerView {
Theme.setMaskDrawableRad(selectorDrawable, position == 0 ? topBottomSelectorRadius : 0, position == getAdapter().getItemCount() - 2 ? topBottomSelectorRadius : 0);
}
selectorRect.set(sel.getLeft(), sel.getTop(), sel.getRight(), sel.getBottom() - bottomPadding);
selectorRect.offset((int) sel.getTranslationX(), (int) sel.getTranslationY());
final boolean enabled = sel.isEnabled();
if (isChildViewEnabled != enabled) {

View File

@ -676,7 +676,13 @@ public class ScrollSlidingTabStrip extends HorizontalScrollView {
tabView.inited = true;
SvgHelper.SvgDrawable svgThumb = tabView.svgThumb;
BackupImageView imageView = tabView.imageView;
if (object instanceof TLRPC.Document && MessageObject.isAnimatedStickerDocument(sticker, true)) {
if (object instanceof TLRPC.Document && MessageObject.isVideoSticker(sticker)) {
if (svgThumb != null) {
imageView.setImage(ImageLocation.getForDocument(sticker), "40_40", svgThumb, 0, parentObject);
} else {
imageView.setImage(ImageLocation.getForDocument(sticker), "40_40", imageLocation, null, 0, parentObject);
}
} else if (object instanceof TLRPC.Document && MessageObject.isAnimatedStickerDocument(sticker, true)) {
if (svgThumb != null) {
imageView.setImage(ImageLocation.getForDocument(sticker), "40_40", svgThumb, 0, parentObject);
} else {

View File

@ -35,11 +35,13 @@ import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
@ -81,6 +83,8 @@ import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.NativeByteBuffer;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBarMenuSubItem;
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.ActionBar.AdjustPanLayoutHelper;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BottomSheet;
@ -910,6 +914,8 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi
return y >= AndroidUtilities.dp(darkTheme && linkToCopy[1] != null ? 111 : 58) + (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0);
}
};
gridView.setSelectorRadius(AndroidUtilities.dp(8));
gridView.setSelectorDrawableColor(Theme.getColor(Theme.key_listSelector));
gridView.setPadding(0, 0, 0, AndroidUtilities.dp(48));
gridView.setClipToPadding(false);
gridView.setLayoutManager(layoutManager = new GridLayoutManager(getContext(), 4));
@ -1258,55 +1264,10 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi
});
}
writeButtonContainer.addView(writeButton, LayoutHelper.createFrame(Build.VERSION.SDK_INT >= 21 ? 56 : 60, Build.VERSION.SDK_INT >= 21 ? 56 : 60, Gravity.LEFT | Gravity.TOP, Build.VERSION.SDK_INT >= 21 ? 2 : 0, 0, 0, 0));
writeButton.setOnClickListener(v -> {
for (int a = 0; a < selectedDialogs.size(); a++) {
long key = selectedDialogs.keyAt(a);
if (AlertsCreator.checkSlowMode(getContext(), currentAccount, key, frameLayout2.getTag() != null && commentTextView.length() > 0)) {
return;
}
}
if (sendingMessageObjects != null) {
for (int a = 0; a < selectedDialogs.size(); a++) {
long key = selectedDialogs.keyAt(a);
if (NekoConfig.sendCommentAfterForward.Bool()) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(sendingMessageObjects, key, false, false, true, 0);
}
if (frameLayout2.getTag() != null && commentTextView.length() > 0) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(commentTextView.getText().toString(), key, null, null, null, true, null, null, null, true, 0, null);
}
if (!NekoConfig.sendCommentAfterForward.Bool()) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(sendingMessageObjects, key, false, false, true, 0);
}
}
onSend(selectedDialogs, sendingMessageObjects.size());
} else {
int num;
if (switchView != null) {
num = switchView.currentTab;
} else {
num = 0;
}
if (sendingText[num] != null) {
for (int a = 0; a < selectedDialogs.size(); a++) {
long key = selectedDialogs.keyAt(a);
if (NekoConfig.sendCommentAfterForward.Bool()) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(sendingText[num], key, null, null, null, true, null, null, null, true, 0, null);
}
if (frameLayout2.getTag() != null && commentTextView.length() > 0) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(commentTextView.getText().toString(), key, null, null, null, true, null, null, null, true, 0, null);
}
if (!NekoConfig.sendCommentAfterForward.Bool()) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(sendingText[num], key, null, null, null, true, null, null, null, true, 0, null);
}
}
onSend(selectedDialogs, 1);
}
}
if (delegate != null) {
delegate.didShare();
}
dismiss();
writeButton.setOnClickListener(v -> sendInternal(true));
writeButton.setOnLongClickListener(v -> {
onSendLongClick(writeButton);
return true;
});
textPaint.setTextSize(AndroidUtilities.dp(12));
@ -1424,6 +1385,189 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi
}
}
private boolean showSendersName = true;
private ActionBarPopupWindow sendPopupWindow;
private boolean onSendLongClick(View view) {
if (parentFragment == null) {
return false;
}
LinearLayout layout = new LinearLayout(getContext());
layout.setOrientation(LinearLayout.VERTICAL);
if (sendingMessageObjects != null) {
ActionBarPopupWindow.ActionBarPopupWindowLayout sendPopupLayout1 = new ActionBarPopupWindow.ActionBarPopupWindowLayout(parentActivity, resourcesProvider);
sendPopupLayout1.setAnimationEnabled(false);
sendPopupLayout1.setOnTouchListener(new View.OnTouchListener() {
private android.graphics.Rect popupRect = new android.graphics.Rect();
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
v.getHitRect(popupRect);
if (!popupRect.contains((int) event.getX(), (int) event.getY())) {
sendPopupWindow.dismiss();
}
}
}
return false;
}
});
sendPopupLayout1.setDispatchKeyEventListener(keyEvent -> {
if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_BACK && keyEvent.getRepeatCount() == 0 && sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss();
}
});
sendPopupLayout1.setShownFromBotton(false);
sendPopupLayout1.setupRadialSelectors(getThemedColor(Theme.key_dialogButtonSelector));
ActionBarMenuSubItem showSendersNameView = new ActionBarMenuSubItem(getContext(), true, true, false, resourcesProvider);
sendPopupLayout1.addView(showSendersNameView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
showSendersNameView.setTextAndIcon(false ? LocaleController.getString("ShowSenderNames", R.string.ShowSenderNames) : LocaleController.getString("ShowSendersName", R.string.ShowSendersName), 0);
showSendersNameView.setChecked(showSendersName = true);
ActionBarMenuSubItem hideSendersNameView = new ActionBarMenuSubItem(getContext(), true, false, true, resourcesProvider);
sendPopupLayout1.addView(hideSendersNameView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
hideSendersNameView.setTextAndIcon(false ? LocaleController.getString("HideSenderNames", R.string.HideSenderNames) : LocaleController.getString("HideSendersName", R.string.HideSendersName), 0);
hideSendersNameView.setChecked(!showSendersName);
showSendersNameView.setOnClickListener(e -> {
showSendersNameView.setChecked(showSendersName = true);
hideSendersNameView.setChecked(!showSendersName);
});
hideSendersNameView.setOnClickListener(e -> {
showSendersNameView.setChecked(showSendersName = false);
hideSendersNameView.setChecked(!showSendersName);
});
layout.addView(sendPopupLayout1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, -8));
}
ActionBarPopupWindow.ActionBarPopupWindowLayout sendPopupLayout2 = new ActionBarPopupWindow.ActionBarPopupWindowLayout(parentActivity, resourcesProvider);
sendPopupLayout2.setAnimationEnabled(false);
sendPopupLayout2.setOnTouchListener(new View.OnTouchListener() {
private android.graphics.Rect popupRect = new android.graphics.Rect();
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
v.getHitRect(popupRect);
if (!popupRect.contains((int) event.getX(), (int) event.getY())) {
sendPopupWindow.dismiss();
}
}
}
return false;
}
});
sendPopupLayout2.setDispatchKeyEventListener(keyEvent -> {
if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_BACK && keyEvent.getRepeatCount() == 0 && sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss();
}
});
sendPopupLayout2.setShownFromBotton(false);
sendPopupLayout2.setupRadialSelectors(getThemedColor(Theme.key_dialogButtonSelector));
ActionBarMenuSubItem sendWithoutSound = new ActionBarMenuSubItem(getContext(), true, true, resourcesProvider);
sendWithoutSound.setTextAndIcon(LocaleController.getString("SendWithoutSound", R.string.SendWithoutSound), R.drawable.input_notify_off);
sendWithoutSound.setMinimumWidth(AndroidUtilities.dp(196));
sendPopupLayout2.addView(sendWithoutSound, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
sendWithoutSound.setOnClickListener(v -> {
if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss();
}
sendInternal(false);
});
ActionBarMenuSubItem sendMessage = new ActionBarMenuSubItem(getContext(), true, true, resourcesProvider);
sendMessage.setTextAndIcon(LocaleController.getString("SendMessage", R.string.SendMessage), R.drawable.msg_forward_send);
sendMessage.setMinimumWidth(AndroidUtilities.dp(196));
sendPopupLayout2.addView(sendMessage, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
sendMessage.setOnClickListener(v -> {
if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss();
}
sendInternal(true);
});
layout.addView(sendPopupLayout2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
sendPopupWindow = new ActionBarPopupWindow(layout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
sendPopupWindow.setAnimationEnabled(false);
sendPopupWindow.setAnimationStyle(R.style.PopupContextAnimation2);
sendPopupWindow.setOutsideTouchable(true);
sendPopupWindow.setClippingEnabled(true);
sendPopupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED);
sendPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
sendPopupWindow.getContentView().setFocusableInTouchMode(true);
SharedConfig.removeScheduledOrNoSuoundHint();
layout.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST));
sendPopupWindow.setFocusable(true);
int[] location = new int[2];
view.getLocationInWindow(location);
int y;
if (keyboardVisible && parentFragment.contentView.getMeasuredHeight() > AndroidUtilities.dp(58)) {
y = location[1] + view.getMeasuredHeight();
} else {
y = location[1] - layout.getMeasuredHeight() - AndroidUtilities.dp(2);
}
sendPopupWindow.showAtLocation(view, Gravity.LEFT | Gravity.TOP, location[0] + view.getMeasuredWidth() - layout.getMeasuredWidth() + AndroidUtilities.dp(8), y);
sendPopupWindow.dimBehind();
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
return false;
}
private void sendInternal(boolean withSound) {
for (int a = 0; a < selectedDialogs.size(); a++) {
long key = selectedDialogs.keyAt(a);
if (AlertsCreator.checkSlowMode(getContext(), currentAccount, key, frameLayout2.getTag() != null && commentTextView.length() > 0)) {
return;
}
}
if (sendingMessageObjects != null) {
for (int a = 0; a < selectedDialogs.size(); a++) {
long key = selectedDialogs.keyAt(a);
if (NekoConfig.sendCommentAfterForward.Bool()) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(sendingMessageObjects, key, false, false, true, 0);
}
if (frameLayout2.getTag() != null && commentTextView.length() > 0) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(commentTextView.getText().toString(), key, null, null, null, true, null, null, null, true, 0, null);
}
if (!NekoConfig.sendCommentAfterForward.Bool()) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(sendingMessageObjects, key, false, false, true, 0);
}
}
onSend(selectedDialogs, sendingMessageObjects.size());
} else {
int num;
if (switchView != null) {
num = switchView.currentTab;
} else {
num = 0;
}
if (sendingText[num] != null) {
for (int a = 0; a < selectedDialogs.size(); a++) {
long key = selectedDialogs.keyAt(a);
if (NekoConfig.sendCommentAfterForward.Bool()) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(sendingText[num], key, null, null, null, true, null, null, null, true, 0, null);
}
if (frameLayout2.getTag() != null && commentTextView.length() > 0) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(commentTextView.getText().toString(), key, null, null, null, true, null, null, null, true, 0, null);
}
if (!NekoConfig.sendCommentAfterForward.Bool()) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(sendingText[num], key, null, null, null, true, null, null, null, true, 0, null);
}
}
onSend(selectedDialogs, 1);
}
}
if (delegate != null) {
delegate.didShare();
}
dismiss();
}
protected void onSend(LongSparseArray<TLRPC.Dialog> dids, int count) {
}

View File

@ -1501,16 +1501,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
actionModeViews.add(forwardItem);
forwardItem.setOnClickListener(v -> onActionBarItemClick(v, forward));
boolean noforwards = profileActivity.getMessagesController().isChatNoForwards(-dialog_id);
forwardItem.setAlpha(noforwards ? 0.5f : 1f);
forwardNoQuoteItem.setAlpha(noforwards ? 0.5f : 1f);
if (noforwards) {
if (forwardItem.getBackground() != null) forwardItem.setBackground(null);
if (forwardNoQuoteItem.getBackground() != null) forwardNoQuoteItem.setBackground(null);
} else if (forwardItem.getBackground() == null) {
forwardItem.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), 5));
forwardNoQuoteItem.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), 5));
}
updateForwardItem();
}
deleteItem = new ActionBarMenuItem(context, null, Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2), false);
deleteItem.setIcon(R.drawable.baseline_delete_24);
@ -2242,6 +2233,40 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
return 0;
}
private void updateForwardItem() {
boolean noforwards = profileActivity.getMessagesController().isChatNoForwards(-dialog_id);
forwardItem.setAlpha(noforwards ? 0.5f : 1f);
forwardNoQuoteItem.setAlpha(noforwards ? 0.5f : 1f);
if (noforwards) {
if (forwardItem.getBackground() != null) forwardItem.setBackground(null);
if (forwardNoQuoteItem.getBackground() != null) forwardNoQuoteItem.setBackground(null);
} else if (forwardItem.getBackground() == null) {
forwardItem.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), 5));
forwardNoQuoteItem.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), 5));
}
}
private boolean hasNoforwardsMessage() {
boolean hasNoforwardsMessage = false;
for (int a = 1; a >= 0; a--) {
ArrayList<Integer> ids = new ArrayList<>();
for (int b = 0; b < selectedFiles[a].size(); b++) {
ids.add(selectedFiles[a].keyAt(b));
}
for (Integer id1 : ids) {
if (id1 > 0) {
MessageObject msg = selectedFiles[a].get(id1);
if (msg != && msg.messageOwner != null && msg.messageOwner.noforwards) {
hasNoforwardsMessage = true;
break;
}
}
}
if (hasNoforwardsMessage)
break;
}
return hasNoforwardsMessage;
}
private boolean changeTypeAnimation;
private void changeMediaFilterType() {
@ -3090,7 +3115,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
showActionMode(false);
actionBar.closeSearchField();
cantDeleteMessagesCount = 0;
}, null);
}, null, null);
} else if (id == forward || id == forward_noquote) {
if (info != null) {
TLRPC.Chat chat = profileActivity.getMessagesController().getChat(info.id);
@ -3103,6 +3128,14 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
return;
}
}
if (hasNoforwardsMessage()) {
if (fwdRestrictedHint != null) {
fwdRestrictedHint.setText(LocaleController.getString("ForwardsRestrictedInfoBot", R.string.ForwardsRestrictedInfoBot));
fwdRestrictedHint.showForView(v, true);
}
return;
}
Bundle args = new Bundle();
args.putBoolean("onlySelect", true);
args.putInt("dialogsType", 3);
@ -4570,6 +4603,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
if (!isActionModeShowed) {
showActionMode(true);
}
updateForwardItem();
return true;
}
@ -4691,6 +4725,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
}
}
}
updateForwardItem();
}
private void openUrl(String link) {

View File

@ -63,6 +63,7 @@ public class SizeNotifierFrameLayout extends FrameLayout {
private boolean animationInProgress;
private boolean skipBackgroundDrawing;
SnowflakesEffect snowflakesEffect;
protected View backgroundView;
public void invalidateBlur() {
invalidateBlur = true;
@ -82,6 +83,130 @@ public class SizeNotifierFrameLayout extends FrameLayout {
setWillNotDraw(false);
parentLayout = layout;
adjustPanLayoutHelper = createAdjustPanLayoutHelper();
backgroundView = new View(context) {
@Override
protected void onDraw(Canvas canvas) {
if (backgroundDrawable == null || skipBackgroundDrawing) {
super.onDraw(canvas);
return;
}
Drawable newDrawable = getNewDrawable();
if (newDrawable != backgroundDrawable && newDrawable != null) {
if (Theme.isAnimatingColor()) {
oldBackgroundDrawable = backgroundDrawable;
}
if (newDrawable instanceof MotionBackgroundDrawable) {
MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) newDrawable;
motionBackgroundDrawable.setParentView(backgroundView);
}
backgroundDrawable = newDrawable;
}
checkLayerType();
float themeAnimationValue = parentLayout != null ? parentLayout.getThemeAnimationValue() : 1.0f;
for (int a = 0; a < 2; a++) {
Drawable drawable = a == 0 ? oldBackgroundDrawable : backgroundDrawable;
if (drawable == null) {
continue;
}
if (a == 1 && oldBackgroundDrawable != null && parentLayout != null) {
drawable.setAlpha((int) (255 * themeAnimationValue));
} else {
drawable.setAlpha(255);
}
if (drawable instanceof MotionBackgroundDrawable) {
MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) drawable;
if (motionBackgroundDrawable.hasPattern()) {
int actionBarHeight = (isActionBarVisible() ? ActionBar.getCurrentActionBarHeight() : 0) + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0);
int viewHeight = getRootView().getMeasuredHeight() - actionBarHeight;
float scaleX = (float) getMeasuredWidth() / (float) drawable.getIntrinsicWidth();
float scaleY = (float) (viewHeight) / (float) drawable.getIntrinsicHeight();
float scale = Math.max(scaleX, scaleY);
int width = (int) Math.ceil(drawable.getIntrinsicWidth() * scale * parallaxScale);
int height = (int) Math.ceil(drawable.getIntrinsicHeight() * scale * parallaxScale);
int x = (getMeasuredWidth() - width) / 2 + (int) translationX;
int y = backgroundTranslationY + (viewHeight - height) / 2 + actionBarHeight + (int) translationY;
canvas.save();
canvas.clipRect(0, actionBarHeight, width, getMeasuredHeight() - bottomClip);
drawable.setBounds(x, y, x + width, y + height);
drawable.draw(canvas);
checkSnowflake(canvas);
canvas.restore();
} else {
if (bottomClip != 0) {
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getRootView().getMeasuredHeight() - bottomClip);
}
motionBackgroundDrawable.setTranslationY(backgroundTranslationY);
int bottom = getMeasuredHeight() - backgroundTranslationY;
if (animationInProgress) {
bottom -= emojiOffset;
} else if (emojiHeight != 0) {
bottom -= emojiHeight;
}
drawable.setBounds(0, 0, getMeasuredWidth(), bottom);
drawable.draw(canvas);
if (bottomClip != 0) {
canvas.restore();
}
}
} else if (drawable instanceof ColorDrawable) {
if (bottomClip != 0) {
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight() - bottomClip);
}
drawable.setBounds(0, 0, getMeasuredWidth(), getRootView().getMeasuredHeight());
drawable.draw(canvas);
checkSnowflake(canvas);
if (bottomClip != 0) {
canvas.restore();
}
} else if (drawable instanceof GradientDrawable) {
if (bottomClip != 0) {
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getRootView().getMeasuredHeight() - bottomClip);
}
drawable.setBounds(0, backgroundTranslationY, getMeasuredWidth(), backgroundTranslationY + getRootView().getMeasuredHeight());
drawable.draw(canvas);
checkSnowflake(canvas);
if (bottomClip != 0) {
canvas.restore();
}
} else if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if (bitmapDrawable.getTileModeX() == Shader.TileMode.REPEAT) {
canvas.save();
float scale = 2.0f / AndroidUtilities.density;
canvas.scale(scale, scale);
drawable.setBounds(0, 0, (int) Math.ceil(getMeasuredWidth() / scale), (int) Math.ceil(getRootView().getMeasuredHeight() / scale));
drawable.draw(canvas);
checkSnowflake(canvas);
canvas.restore();
} else {
int actionBarHeight = (isActionBarVisible() ? ActionBar.getCurrentActionBarHeight() : 0) + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0);
int viewHeight = getRootView().getMeasuredHeight() - actionBarHeight;
float scaleX = (float) getMeasuredWidth() / (float) drawable.getIntrinsicWidth();
float scaleY = (float) (viewHeight) / (float) drawable.getIntrinsicHeight();
float scale = Math.max(scaleX, scaleY);
int width = (int) Math.ceil(drawable.getIntrinsicWidth() * scale * parallaxScale);
int height = (int) Math.ceil(drawable.getIntrinsicHeight() * scale * parallaxScale);
int x = (getMeasuredWidth() - width) / 2 + (int) translationX;
int y = backgroundTranslationY + (viewHeight - height) / 2 + actionBarHeight + (int) translationY;
canvas.save();
canvas.clipRect(0, actionBarHeight, width, getMeasuredHeight() - bottomClip);
drawable.setBounds(x, y, x + width, y + height);
drawable.draw(canvas);
checkSnowflake(canvas);
canvas.restore();
}
}
if (a == 0 && oldBackgroundDrawable != null && themeAnimationValue >= 1.0f) {
oldBackgroundDrawable = null;
backgroundView.invalidate();
}
}
}
};
addView(backgroundView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
public void setBackgroundImage(Drawable bitmap, boolean motion) {
@ -90,9 +215,10 @@ public class SizeNotifierFrameLayout extends FrameLayout {
}
if (bitmap instanceof MotionBackgroundDrawable) {
MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) bitmap;
motionBackgroundDrawable.setParentView(this);
motionBackgroundDrawable.setParentView(backgroundView);
}
backgroundDrawable = bitmap;
checkLayerType();
if (motion) {
if (parallaxEffect == null) {
parallaxEffect = new WallpaperParallaxEffect(getContext());
@ -100,7 +226,7 @@ public class SizeNotifierFrameLayout extends FrameLayout {
translationX = offsetX;
translationY = offsetY;
bgAngle = angle;
invalidate();
backgroundView.invalidate();
});
if (getMeasuredWidth() != 0 && getMeasuredHeight() != 0) {
parallaxScale = parallaxEffect.getScale(getMeasuredWidth(), getMeasuredHeight());
@ -116,7 +242,15 @@ public class SizeNotifierFrameLayout extends FrameLayout {
translationX = 0;
translationY = 0;
}
invalidate();
backgroundView.invalidate();
}
private void checkLayerType() {
// if (parallaxEffect == null && backgroundDrawable instanceof MotionBackgroundDrawable && SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_HIGH) {
// backgroundView.setLayerType(LAYER_TYPE_HARDWARE, null);
// } else {
// backgroundView.setLayerType(LAYER_TYPE_NONE, null);
// }
}
public Drawable getBackgroundImage() {
@ -181,11 +315,17 @@ public class SizeNotifierFrameLayout extends FrameLayout {
}
public void setBottomClip(int value) {
bottomClip = value;
if (value != bottomClip) {
bottomClip = value;
backgroundView.invalidate();
}
}
public void setBackgroundTranslation(int translation) {
backgroundTranslationY = translation;
if (translation != backgroundTranslationY) {
backgroundTranslationY = translation;
backgroundView.invalidate();
}
}
public int getBackgroundTranslationY() {
@ -232,128 +372,6 @@ public class SizeNotifierFrameLayout extends FrameLayout {
animationInProgress = animInProgress;
}
@Override
protected void onDraw(Canvas canvas) {
if (backgroundDrawable == null || skipBackgroundDrawing) {
super.onDraw(canvas);
return;
}
//int kbHeight = SharedConfig.smoothKeyboard ? 0 : keyboardHeight;
Drawable newDrawable = getNewDrawable();
if (newDrawable != backgroundDrawable && newDrawable != null) {
if (Theme.isAnimatingColor()) {
oldBackgroundDrawable = backgroundDrawable;
}
if (newDrawable instanceof MotionBackgroundDrawable) {
MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) newDrawable;
motionBackgroundDrawable.setParentView(this);
}
backgroundDrawable = newDrawable;
}
float themeAnimationValue = parentLayout != null ? parentLayout.getThemeAnimationValue() : 1.0f;
for (int a = 0; a < 2; a++) {
Drawable drawable = a == 0 ? oldBackgroundDrawable : backgroundDrawable;
if (drawable == null) {
continue;
}
if (a == 1 && oldBackgroundDrawable != null && parentLayout != null) {
drawable.setAlpha((int) (255 * themeAnimationValue));
} else {
drawable.setAlpha(255);
}
if (drawable instanceof MotionBackgroundDrawable) {
MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) drawable;
if (motionBackgroundDrawable.hasPattern()) {
int actionBarHeight = (isActionBarVisible() ? ActionBar.getCurrentActionBarHeight() : 0) + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0);
int viewHeight = getRootView().getMeasuredHeight() - actionBarHeight;
float scaleX = (float) getMeasuredWidth() / (float) drawable.getIntrinsicWidth();
float scaleY = (float) (viewHeight) / (float) drawable.getIntrinsicHeight();
float scale = Math.max(scaleX, scaleY);
int width = (int) Math.ceil(drawable.getIntrinsicWidth() * scale * parallaxScale);
int height = (int) Math.ceil(drawable.getIntrinsicHeight() * scale * parallaxScale);
int x = (getMeasuredWidth() - width) / 2 + (int) translationX;
int y = backgroundTranslationY + (viewHeight - height) / 2 + actionBarHeight + (int) translationY;
canvas.save();
canvas.clipRect(0, actionBarHeight, width, getMeasuredHeight() - bottomClip);
drawable.setBounds(x, y, x + width, y + height);
drawable.draw(canvas);
checkSnowflake(canvas);
canvas.restore();
} else {
if (bottomClip != 0) {
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getRootView().getMeasuredHeight() - bottomClip);
}
motionBackgroundDrawable.setTranslationY(backgroundTranslationY);
int bottom = getMeasuredHeight() - backgroundTranslationY;
if (animationInProgress) {
bottom -= emojiOffset;
} else if (emojiHeight != 0) {
bottom -= emojiHeight;
}
drawable.setBounds(0, 0, getMeasuredWidth(), bottom);
drawable.draw(canvas);
if (bottomClip != 0) {
canvas.restore();
}
}
} else if (drawable instanceof ColorDrawable) {
if (bottomClip != 0) {
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight() - bottomClip);
}
drawable.setBounds(0, 0, getMeasuredWidth(), getRootView().getMeasuredHeight());
drawable.draw(canvas);
checkSnowflake(canvas);
if (bottomClip != 0) {
canvas.restore();
}
} else if (drawable instanceof GradientDrawable) {
if (bottomClip != 0) {
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getRootView().getMeasuredHeight() - bottomClip);
}
drawable.setBounds(0, backgroundTranslationY, getMeasuredWidth(), backgroundTranslationY + getRootView().getMeasuredHeight());
drawable.draw(canvas);
checkSnowflake(canvas);
if (bottomClip != 0) {
canvas.restore();
}
} else if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if (bitmapDrawable.getTileModeX() == Shader.TileMode.REPEAT) {
canvas.save();
float scale = 2.0f / AndroidUtilities.density;
canvas.scale(scale, scale);
drawable.setBounds(0, 0, (int) Math.ceil(getMeasuredWidth() / scale), (int) Math.ceil(getRootView().getMeasuredHeight() / scale));
drawable.draw(canvas);
checkSnowflake(canvas);
canvas.restore();
} else {
int actionBarHeight = (isActionBarVisible() ? ActionBar.getCurrentActionBarHeight() : 0) + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0);
int viewHeight = getRootView().getMeasuredHeight() - actionBarHeight;
float scaleX = (float) getMeasuredWidth() / (float) drawable.getIntrinsicWidth();
float scaleY = (float) (viewHeight) / (float) drawable.getIntrinsicHeight();
float scale = Math.max(scaleX, scaleY);
int width = (int) Math.ceil(drawable.getIntrinsicWidth() * scale * parallaxScale);
int height = (int) Math.ceil(drawable.getIntrinsicHeight() * scale * parallaxScale);
int x = (getMeasuredWidth() - width) / 2 + (int) translationX;
int y = backgroundTranslationY + (viewHeight - height) / 2 + actionBarHeight + (int) translationY;
canvas.save();
canvas.clipRect(0, actionBarHeight, width, getMeasuredHeight() - bottomClip);
drawable.setBounds(x, y, x + width, y + height);
drawable.draw(canvas);
checkSnowflake(canvas);
canvas.restore();
}
}
if (a == 0 && oldBackgroundDrawable != null && themeAnimationValue >= 1.0f) {
oldBackgroundDrawable = null;
invalidate();
}
}
}
private void checkSnowflake(Canvas canvas) {
if (Theme.canStartHolidayAnimation()) {
if (snowflakesEffect == null) {
@ -372,8 +390,10 @@ public class SizeNotifierFrameLayout extends FrameLayout {
}
public void setSkipBackgroundDrawing(boolean skipBackgroundDrawing) {
this.skipBackgroundDrawing = skipBackgroundDrawing;
invalidate();
if (this.skipBackgroundDrawing != skipBackgroundDrawing) {
this.skipBackgroundDrawing = skipBackgroundDrawing;
backgroundView.invalidate();
}
}
protected Drawable getNewDrawable() {
@ -390,16 +410,19 @@ public class SizeNotifierFrameLayout extends FrameLayout {
public boolean blurIsRunning;
public boolean blurGeneratingTuskIsRunning;
BlurBitmap currentBitmap;
BlurBitmap prevBitmap;
public ArrayList<BlurBitmap> unusedBitmaps = new ArrayList<>(10);
public ArrayList<View> blurBehindViews = new ArrayList<>();
Matrix matrix = new Matrix();
Matrix matrix2 = new Matrix();
public Paint blurPaintTop = new Paint();
public Paint blurPaintTop2 = new Paint();
public Paint blurPaintBottom = new Paint();
public Paint blurPaintBottom2 = new Paint();
public float blurCrossfadeProgress;
private final float DOWN_SCALE = 12f;
private final int TOP_CLIP_OFFSET = (int) (10 + DOWN_SCALE);
private static DispatchQueue blurQueue;
ValueAnimator blurCrossfade;
public boolean invalidateBlur;
@ -407,18 +430,28 @@ public class SizeNotifierFrameLayout extends FrameLayout {
int count;
int times;
int count2;
int times2;
final BlurBackgroundTask blurBackgroundTask = new BlurBackgroundTask();
public void startBlur() {
if (!blurIsRunning || blurGeneratingTuskIsRunning || !invalidateBlur || !SharedConfig.chatBlurEnabled()) {
return;
}
int blurAlpha = Color.alpha(Theme.getColor(Theme.key_chat_BlurAlpha));
if (blurAlpha == 0) {
return;
}
invalidateBlur = false;
blurGeneratingTuskIsRunning = true;
int lastW = getMeasuredWidth();
int lastH = ActionBar.getCurrentActionBarHeight() + AndroidUtilities.statusBarHeight + AndroidUtilities.dp(100);
int bitmapH = (int) (lastH / DOWN_SCALE) + 10;
int bitmapH = (int) (lastH / DOWN_SCALE) + TOP_CLIP_OFFSET ;
int bitmapW = (int) (lastW / DOWN_SCALE);
long time = System.currentTimeMillis();
BlurBitmap bitmap = null;
if (unusedBitmaps.size() > 0) {
bitmap = unusedBitmaps.remove(unusedBitmaps.size() - 1);
@ -438,25 +471,27 @@ public class SizeNotifierFrameLayout extends FrameLayout {
BlurBitmap finalBitmap = bitmap;
float sX = (float) finalBitmap.topBitmap.getWidth() / (float) lastW;
float sY = (float) (finalBitmap.topBitmap.getHeight() - 10) / (float) lastH;
float sY = (float) (finalBitmap.topBitmap.getHeight() - TOP_CLIP_OFFSET) / (float) lastH;
finalBitmap.topCanvas.save();
finalBitmap.pixelFixOffset = getScrollOffset() % (int) DOWN_SCALE;
finalBitmap.topCanvas.clipRect(0, 10 * sY, finalBitmap.topBitmap.getWidth(), finalBitmap.topBitmap.getHeight());
finalBitmap.topCanvas.scale(sX, sY);
finalBitmap.topCanvas.translate(0, 10 * sY + finalBitmap.pixelFixOffset);
finalBitmap.topScaleX = 1f / sX;
finalBitmap.topScaleY = 1f / sY;
// finalBitmap.pixelFixOffset = getScrollOffset() % (int) DOWN_SCALE;
finalBitmap.topCanvas.translate(0, finalBitmap.pixelFixOffset);
drawList(finalBitmap.topCanvas, true);
finalBitmap.topCanvas.restore();
sX = (float) finalBitmap.bottomBitmap.getWidth() / (float) lastW;
sY = (float) (finalBitmap.bottomBitmap.getHeight() - 10) / (float) lastH;
sY = (float) (finalBitmap.bottomBitmap.getHeight() - TOP_CLIP_OFFSET) / (float) lastH;
finalBitmap.bottomOffset = getBottomOffset() - lastH;
finalBitmap.bottomCanvas.save();
finalBitmap.bottomCanvas.clipRect(0, 10 * sY, finalBitmap.bottomBitmap.getWidth(), finalBitmap.bottomBitmap.getHeight());
finalBitmap.bottomCanvas.scale(sX, sY);
finalBitmap.bottomCanvas.translate(0, 10 - finalBitmap.bottomOffset);
finalBitmap.bottomCanvas.translate(0, 10 * sY - finalBitmap.bottomOffset + finalBitmap.pixelFixOffset);
finalBitmap.bottomScaleX = 1f / sX;
finalBitmap.bottomScaleY = 1f / sY;
@ -464,69 +499,84 @@ public class SizeNotifierFrameLayout extends FrameLayout {
finalBitmap.bottomCanvas.restore();
int radius = (int) (Math.max(6, Math.max(lastH, lastW) / 180) * 2.5f);
times2 += System.currentTimeMillis() - time;
count2++;
if (count2 >= 20) {
count2 = 0;
times2 = 0;
}
if (blurQueue == null) {
blurQueue = new DispatchQueue("BlurQueue");
}
blurQueue.postRunnable(new Runnable() {
@Override
public void run() {
long time = System.currentTimeMillis();
Utilities.stackBlurBitmap(finalBitmap.topBitmap, radius);
Utilities.stackBlurBitmap(finalBitmap.bottomBitmap, radius);
times += System.currentTimeMillis() - time;
count++;
if (count > 1000) {
FileLog.d("chat blur generating average time" + (times / (float) count));
count = 0;
times = 0;
blurBackgroundTask.radius = (int) (Math.max(6, Math.max(lastH, lastW) / 180) * 2.5f);
blurBackgroundTask.finalBitmap = finalBitmap;
blurQueue.postRunnable(blurBackgroundTask);
}
private class BlurBackgroundTask implements Runnable {
int radius;
BlurBitmap finalBitmap;
@Override
public void run() {
long time = System.currentTimeMillis();
Utilities.stackBlurBitmap(finalBitmap.topBitmap, radius);
Utilities.stackBlurBitmap(finalBitmap.bottomBitmap, radius);
times += System.currentTimeMillis() - time;
count++;
if (count > 1000) {
FileLog.d("chat blur generating average time" + (times / (float) count));
count = 0;
times = 0;
}
AndroidUtilities.runOnUIThread(() -> {
prevBitmap = currentBitmap;
BlurBitmap oldBitmap = currentBitmap;
blurPaintTop2.setShader(blurPaintTop.getShader());
blurPaintBottom2.setShader(blurPaintBottom.getShader());
BitmapShader bitmapShader = new BitmapShader(finalBitmap.topBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
blurPaintTop.setShader(bitmapShader);
bitmapShader = new BitmapShader(finalBitmap.bottomBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
blurPaintBottom.setShader(bitmapShader);
blurCrossfadeProgress = 0;
if (blurCrossfade != null) {
blurCrossfade.cancel();
}
AndroidUtilities.runOnUIThread(() -> {
BlurBitmap oldBitmap = currentBitmap;
blurPaintTop2.setShader(blurPaintTop.getShader());
blurPaintBottom2.setShader(blurPaintBottom.getShader());
BitmapShader bitmapShader = new BitmapShader(finalBitmap.topBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
blurPaintTop.setShader(bitmapShader);
bitmapShader = new BitmapShader(finalBitmap.bottomBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
blurPaintBottom.setShader(bitmapShader);
blurCrossfadeProgress = 0;
if (blurCrossfade != null) {
blurCrossfade.cancel();
}
blurCrossfade = ValueAnimator.ofFloat(0, 1f);
blurCrossfade.addUpdateListener(valueAnimator -> {
blurCrossfadeProgress = (float) valueAnimator.getAnimatedValue();
for (int i = 0; i < blurBehindViews.size(); i++) {
blurBehindViews.get(i).invalidate();
}
});
blurCrossfade.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
unusedBitmaps.add(oldBitmap);
super.onAnimationEnd(animation);
}
});
blurCrossfade.setDuration(50);
blurCrossfade.start();
blurCrossfade = ValueAnimator.ofFloat(0, 1f);
blurCrossfade.addUpdateListener(valueAnimator -> {
blurCrossfadeProgress = (float) valueAnimator.getAnimatedValue();
for (int i = 0; i < blurBehindViews.size(); i++) {
blurBehindViews.get(i).invalidate();
}
currentBitmap = finalBitmap;
AndroidUtilities.runOnUIThread(() -> {
blurGeneratingTuskIsRunning = false;
startBlur();
}, 32);
});
}
});
}
blurCrossfade.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
blurCrossfadeProgress = 1f;
unusedBitmaps.add(oldBitmap);
super.onAnimationEnd(animation);
}
});
blurCrossfade.setDuration(50);
blurCrossfade.start();
for (int i = 0; i < blurBehindViews.size(); i++) {
blurBehindViews.get(i).invalidate();
}
currentBitmap = finalBitmap;
AndroidUtilities.runOnUIThread(() -> {
blurGeneratingTuskIsRunning = false;
startBlur();
}, 32);
});
}
};
protected float getBottomOffset() {
return getMeasuredHeight();
@ -586,7 +636,8 @@ public class SizeNotifierFrameLayout extends FrameLayout {
}
public void drawBlur(Canvas canvas, float y, Rect rectTmp, Paint blurScrimPaint, boolean top) {
if (currentBitmap == null || !SharedConfig.chatBlurEnabled()) {
int blurAlpha = Color.alpha(Theme.getColor(Theme.key_chat_BlurAlpha));
if (currentBitmap == null || !SharedConfig.chatBlurEnabled() || blurAlpha == 0) {
canvas.drawRect(rectTmp, blurScrimPaint);
return;
}
@ -595,14 +646,24 @@ public class SizeNotifierFrameLayout extends FrameLayout {
if (blurPaint.getShader() != null) {
matrix.reset();
matrix2.reset();
if (!top) {
matrix.setTranslate(0, -y + currentBitmap.bottomOffset - currentBitmap.pixelFixOffset);
matrix.setTranslate(0, -y + currentBitmap.bottomOffset - currentBitmap.pixelFixOffset - TOP_CLIP_OFFSET);
matrix.preScale(currentBitmap.bottomScaleX, currentBitmap.bottomScaleY);
} else {
matrix.setTranslate(0, -y);
matrix.preScale(currentBitmap.topScaleX, currentBitmap.topScaleY);
}
if (prevBitmap != null) {
matrix2.setTranslate(0, -y + prevBitmap.bottomOffset - prevBitmap.pixelFixOffset - TOP_CLIP_OFFSET);
matrix2.preScale(prevBitmap.bottomScaleX, prevBitmap.bottomScaleY);
}
} else {
matrix.setTranslate(0, -y - currentBitmap.pixelFixOffset - TOP_CLIP_OFFSET);
matrix.preScale(currentBitmap.topScaleX, currentBitmap.topScaleY);
if (prevBitmap != null) {
matrix.setTranslate(0, -y - prevBitmap.pixelFixOffset - TOP_CLIP_OFFSET);
matrix.preScale(prevBitmap.topScaleX, prevBitmap.topScaleY);
}
}
blurPaint.getShader().setLocalMatrix(matrix);
if (blurPaint2.getShader() != null) {
@ -613,8 +674,6 @@ public class SizeNotifierFrameLayout extends FrameLayout {
canvas.drawRect(rectTmp, blurScrimPaint);
canvas.drawRect(rectTmp, blurPaint2);
canvas.saveLayerAlpha(rectTmp.left, rectTmp.top, rectTmp.right, rectTmp.bottom, (int) (blurCrossfadeProgress * 255), Canvas.ALL_SAVE_FLAG);
// blurScrimPaint.setAlpha((int) (blurCrossfadeProgress * 255));
// blurPaint.setAlpha((int) (blurCrossfadeProgress * 255));
canvas.drawRect(rectTmp, blurScrimPaint);
canvas.drawRect(rectTmp, blurPaint);
canvas.restore();
@ -623,8 +682,7 @@ public class SizeNotifierFrameLayout extends FrameLayout {
canvas.drawRect(rectTmp, blurPaint);
}
blurScrimPaint.setAlpha(Color.alpha(Theme.getColor(Theme.key_chat_BlurAlpha)));
blurScrimPaint.setAlpha(blurAlpha);
canvas.drawRect(rectTmp, blurScrimPaint);
}

View File

@ -90,7 +90,7 @@ public class StickerSetBulletinLayout extends Bulletin.TwoLineLayout {
imageLocation = ImageLocation.getForSticker(thumb, sticker, thumbVersion);
}
if (object instanceof TLRPC.Document && MessageObject.isAnimatedStickerDocument(sticker, true)) {
if (object instanceof TLRPC.Document && MessageObject.isAnimatedStickerDocument(sticker, true) || MessageObject.isVideoSticker(sticker)) {
imageView.setImage(ImageLocation.getForDocument(sticker), "50_50", imageLocation, null, 0, setObject);
} else if (imageLocation != null && imageLocation.imageType == FileLoader.IMAGE_TYPE_LOTTIE) {
imageView.setImage(imageLocation, "50_50", "tgs", null, setObject);

View File

@ -1343,9 +1343,17 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.stopAllHeavyOperations, 4);
}
private Runnable onDismissListener;
public void setOnDismissListener(Runnable onDismissListener) {
this.onDismissListener = onDismissListener;
}
@Override
public void dismiss() {
super.dismiss();
if (onDismissListener != null) {
onDismissListener.run();
}
if (reqId != 0) {
ConnectionsManager.getInstance(currentAccount).cancelRequest(reqId, true);
reqId = 0;

View File

@ -984,6 +984,9 @@ public class UndoView extends FrameLayout {
timeLeft = 3000;
infoTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
} else if (currentAction == ACTION_MESSAGE_COPIED || currentAction == ACTION_USERNAME_COPIED || currentAction == ACTION_HASHTAG_COPIED || currentAction == ACTION_TEXT_COPIED || currentAction == ACTION_LINK_COPIED || currentAction == ACTION_PHONE_COPIED || currentAction == ACTION_EMAIL_COPIED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
return;
}
int iconRawId = R.raw.copy;
if (currentAction == ACTION_EMAIL_COPIED) {
infoTextView.setText(LocaleController.getString("EmailCopied", R.string.EmailCopied));

View File

@ -395,12 +395,12 @@ public class GroupCallMiniTextureView extends FrameLayout implements GroupCallSt
textureView.scaleType = SCALE_TYPE_FIT;
} else if (showingInFullscreen) {
textureView.scaleType = SCALE_TYPE_FIT;
} else if (parentContainer.inFullscreenMode && !showingInFullscreen) {
} else if (parentContainer.inFullscreenMode) {
textureView.scaleType = SCALE_TYPE_FILL;
} else if (!parentContainer.inFullscreenMode) {
textureView.scaleType = participant.presentation ? SCALE_TYPE_FIT : SCALE_TYPE_ADAPTIVE;
} else {
} else if (participant.presentation) {
textureView.scaleType = SCALE_TYPE_FIT;
} else {
textureView.scaleType = SCALE_TYPE_ADAPTIVE;
}
checkScale = false;
}
@ -1004,11 +1004,11 @@ public class GroupCallMiniTextureView extends FrameLayout implements GroupCallSt
if (participant.participant.self && !participant.presentation && VoIPService.getSharedInstance() != null) {
textureView.renderer.setMirror(VoIPService.getSharedInstance().isFrontFaceCamera());
textureView.renderer.setRotateTextureWitchScreen(true);
textureView.renderer.setRotateTextureWithScreen(true);
textureView.renderer.setUseCameraRotation(true);
} else {
textureView.renderer.setMirror(false);
textureView.renderer.setRotateTextureWitchScreen(true);
textureView.renderer.setRotateTextureWithScreen(true);
textureView.renderer.setUseCameraRotation(false);
}
textureView.updateRotation();

View File

@ -131,7 +131,7 @@ public abstract class PrivateVideoPreviewDialog extends FrameLayout implements V
textureView.scaleType = VoIPTextureView.SCALE_TYPE_FIT;
textureView.clipToTexture = true;
textureView.renderer.setAlpha(0);
textureView.renderer.setRotateTextureWitchScreen(true);
textureView.renderer.setRotateTextureWithScreen(true);
textureView.renderer.setUseCameraRotation(true);
addView(textureView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));

Some files were not shown because too many files have changed in this diff Show More