1
0
mirror of https://github.com/MGislv/NekoX.git synced 2024-07-02 10:33:36 +00:00

Update to 8.5.0

This commit is contained in:
xaxtix 2022-02-01 16:00:45 +03:00
parent f0f858ad3f
commit ad05eea682
159 changed files with 5963 additions and 3085 deletions

View File

@ -300,7 +300,7 @@ android {
}
}
defaultConfig.versionCode = 2538
defaultConfig.versionCode = 2547
applicationVariants.all { variant ->
variant.outputs.all { output ->
@ -319,7 +319,7 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 30
versionName "8.4.4"
versionName "8.5.0"
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']

View File

@ -12,6 +12,7 @@ ${CMAKE_HOME_DIRECTORY}/ffmpeg/${ANDROID_ABI}/libavcodec.a,
${CMAKE_HOME_DIRECTORY}/ffmpeg/${ANDROID_ABI}/libavresample.a,
${CMAKE_HOME_DIRECTORY}/ffmpeg/${ANDROID_ABI}/libavutil.a,
${CMAKE_HOME_DIRECTORY}/ffmpeg/${ANDROID_ABI}/libswresample.a,
${CMAKE_HOME_DIRECTORY}/ffmpeg/${ANDROID_ABI}/libvpx.a,
${CMAKE_HOME_DIRECTORY}/boringssl/lib/libssl_${ANDROID_ABI}.a,
${CMAKE_HOME_DIRECTORY}/boringssl/lib/libcrypto_${ANDROID_ABI}.a")
@ -45,6 +46,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/lib/libssl_${ANDROID_ABI}.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
@ -399,7 +404,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
@ -685,6 +690,7 @@ target_link_libraries(${NATIVE_LIB}
avcodec
avresample
swresample
libvpx
avutil
ssl
crypto
@ -697,11 +703,6 @@ target_link_libraries(${NATIVE_LIB}
OpenSLES
cpufeatures)
if (${ANDROID_ABI} STREQUAL "x86" OR ${ANDROID_ABI} STREQUAL "x86_64")
target_link_libraries(${NATIVE_LIB}
-Wl,--whole-archive 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

@ -134,6 +134,7 @@ int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const;
*
* The operation is mathematically equivalent to `a * b / c`, but writing that
* directly can overflow, and does not support different rounding methods.
* If the result is not representable then INT64_MIN is returned.
*
* @see av_rescale(), av_rescale_q(), av_rescale_q_rnd()
*/

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;
}
@ -921,7 +935,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];
@ -968,13 +982,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];
}
@ -984,14 +998,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;
@ -1015,9 +1029,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;
}
@ -1166,7 +1180,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) {
@ -1181,7 +1197,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);
@ -1337,7 +1365,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) {
initWebRTC(env);
@ -473,6 +474,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) {
@ -482,6 +484,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) {
@ -496,6 +499,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) {
@ -522,6 +526,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) {
@ -531,6 +536,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) {
@ -562,6 +568,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) {
@ -580,6 +587,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) {
@ -594,6 +602,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);
@ -730,20 +739,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) {
@ -752,6 +764,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) {
@ -761,6 +774,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) {
@ -768,6 +782,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) {
@ -776,6 +791,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) {
@ -784,6 +800,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) {
@ -792,6 +809,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) {
@ -800,6 +818,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) {
@ -808,6 +827,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) {
@ -816,6 +836,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) {
@ -824,6 +845,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) {
@ -839,6 +861,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) {
@ -849,6 +872,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) {
@ -884,6 +908,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) {
@ -900,6 +925,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;
@ -913,6 +939,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) {
@ -924,6 +951,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) {
@ -933,21 +961,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) {
@ -956,6 +988,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) {
@ -964,6 +997,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;
@ -973,6 +1007,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;
@ -998,6 +1033,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;
@ -1015,6 +1051,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;
@ -146,6 +146,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;
@ -381,8 +382,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;
}
@ -3609,6 +3610,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

@ -20,11 +20,12 @@ public class BuildVars {
public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 2538;
public static String BUILD_VERSION_STRING = "8.4.4";
public static int BUILD_VERSION = 2547;
public static String BUILD_VERSION_STRING = "8.5.0";
public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
public static String APPCENTER_HASH = "a5b5c4f5-51da-dedc-9918-d9766a22ca7c";
public static String SMS_HASH = isStandaloneApp() ? "w0lkcmTZkKh" : (DEBUG_VERSION ? "O2P2z+/jBpJ" : "oLeq9AcOZkT");
public static String PLAYSTORE_APP_URL = "https://play.google.com/store/apps/details?id=org.telegram.messenger";

View File

@ -87,7 +87,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<>();
@ -954,7 +954,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);
@ -1459,7 +1459,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);
@ -1511,6 +1524,9 @@ public class ImageLoader {
if (drawable == null) {
drawable = wallpaperMemCache.get(key);
}
if (drawable == null) {
drawable = getFromLottieCahce(key);
}
return drawable;
}
@ -1788,17 +1804,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();
}
}
}
};
@ -2224,7 +2245,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;
}
@ -2539,13 +2560,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;
@ -2751,8 +2772,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) {
@ -2784,8 +2805,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) {
@ -2818,8 +2839,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) {
@ -3032,6 +3053,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);
@ -705,7 +707,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();
}
@ -718,6 +720,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
fileDrawable.setAllowDecodeSingleFrame(true);
}
thumbShader = null;
staticThumbDrawable = bitmap;
updateDrawableRadius(bitmap);
currentMediaLocation = null;
@ -812,14 +815,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);
@ -895,7 +902,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);
@ -985,6 +995,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()) {
@ -1412,6 +1425,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) {
@ -1473,6 +1487,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
} else {
checkAlphaAnimation(animationNotReady);
}
if (drawable == null && animationNotReady && parentView != null) {
parentView.invalidate();
}
} catch (Exception e) {
FileLog.e(e);
}
@ -2069,7 +2087,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) {
@ -2085,13 +2107,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)) {
@ -2100,7 +2127,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);
@ -2109,13 +2140,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) {
@ -2145,13 +2181,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) {
@ -2159,13 +2198,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);
@ -2232,7 +2273,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);
@ -2317,6 +2369,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
AnimatedFileDrawable animatedFileDrawable = getAnimation();
if (allowStartAnimation && animatedFileDrawable != null) {
animatedFileDrawable.start();
if (parentView != null) {
parentView.invalidate();
}
}
}
}

View File

@ -1535,6 +1535,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

@ -2730,7 +2730,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

@ -59,14 +59,10 @@ import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import androidx.collection.LongSparseArray;
import androidx.core.math.MathUtils;
public class MessageObject {
public static final int MESSAGE_SEND_STATE_SENT = 0;
@ -76,6 +72,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 +220,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;
}
@ -231,6 +247,29 @@ public class MessageObject {
return getDialogId() < 0;
}
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;
@ -3163,7 +3202,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()) {
@ -3287,6 +3326,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));
}
@ -4257,6 +4299,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) {
@ -4633,6 +4677,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);
}
@ -4946,12 +4993,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);
}
}
}
@ -5172,6 +5227,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);
}
@ -5402,7 +5460,7 @@ public class MessageObject {
if (type != 1000) {
return type == TYPE_STICKER;
}
return isStickerDocument(getDocument());
return isStickerDocument(getDocument()) || isVideoSticker(getDocument());
}
public boolean isAnimatedSticker() {
@ -5756,7 +5814,7 @@ public class MessageObject {
}
public boolean canForwardMessage() {
return !(messageOwner instanceof TLRPC.TL_message_secret) && !needDrawBluredPreview() && !isLiveLocation() && type != 16 && !isSponsored();
return !(messageOwner instanceof TLRPC.TL_message_secret) && !needDrawBluredPreview() && !isLiveLocation() && type != 16 && !isSponsored() && !messageOwner.noforwards;
}
public boolean canEditMedia() {
@ -6268,9 +6326,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--;
}
}
@ -6286,9 +6344,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--;
}
}
@ -6304,9 +6362,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;
@ -94,7 +97,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<>();
public LongSparseArray<MessageObject> dialogMessagesByRandomIds = new LongSparseArray<>();
public LongSparseIntArray deletedHistory = new LongSparseIntArray();
@ -329,6 +338,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;
@ -2737,11 +2786,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;
}
@ -6600,6 +6652,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);
@ -8287,6 +8340,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;
@ -8452,6 +8506,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);
@ -8556,6 +8614,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);
}
});
@ -12196,13 +12259,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;
@ -12220,13 +12276,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) {
@ -12886,6 +12935,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<>();
}
@ -13526,14 +13580,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;
@ -13702,7 +13749,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++) {
@ -13944,6 +14004,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);
}
@ -13970,6 +14123,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

@ -69,6 +69,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);
}
@ -117,7 +194,7 @@ public class MessagesStorage extends BaseController {
private CountDownLatch openSync = new CountDownLatch(1);
private static volatile MessagesStorage[] Instance = new MessagesStorage[UserConfig.MAX_ACCOUNT_COUNT];
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) {
@ -335,7 +412,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();
@ -423,6 +500,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 {
@ -1556,6 +1634,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;
@ -2151,7 +2243,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();
@ -2178,6 +2270,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);
@ -8012,7 +8105,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);
@ -8027,6 +8120,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();
}
@ -9336,7 +9430,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<>();
@ -9415,6 +9509,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);
}
@ -9565,7 +9660,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);
}
@ -10258,7 +10353,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;
@ -10292,6 +10387,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);
@ -10972,7 +11068,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);
@ -10987,6 +11083,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();
@ -11323,7 +11420,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;
@ -11369,6 +11466,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) {
@ -11536,7 +11634,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(?, ?, ?)");
@ -11702,6 +11800,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

@ -22,7 +22,7 @@ import java.util.zip.ZipFile;
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

@ -206,6 +206,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++;
@ -230,6 +231,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++;
private SparseArray<ArrayList<NotificationCenterDelegate>> observers = new SparseArray<>();
private SparseArray<ArrayList<NotificationCenterDelegate>> removeAfterBroadcast = new SparseArray<>();
@ -403,7 +405,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

@ -2658,7 +2658,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
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;
}
@ -2674,6 +2674,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
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);
@ -3360,7 +3364,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
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

@ -106,7 +106,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;
@ -349,7 +349,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);
@ -933,7 +933,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

@ -175,7 +175,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

@ -64,7 +64,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;
@ -2236,28 +2236,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) {
@ -22745,14 +22783,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) {
@ -22796,11 +22923,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);
}
}
}
@ -22818,15 +22945,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;
@ -28649,6 +28812,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);
@ -39297,6 +39461,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;
@ -39356,13 +39521,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);
}
@ -39403,6 +39568,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);
@ -43051,11 +43217,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;
@ -43084,7 +43251,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;
}
@ -43098,6 +43265,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) {
@ -43121,6 +43303,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++) {
@ -49520,6 +49708,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;
@ -49530,6 +49719,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);
@ -49572,6 +49762,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;
@ -54116,7 +54346,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);
@ -55134,7 +55364,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);
@ -55297,7 +55527,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);
@ -56338,6 +56568,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;
@ -56349,7 +56580,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:
@ -56367,8 +56598,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);
@ -56380,6 +56610,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);
@ -56403,6 +56634,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

@ -488,7 +488,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;
@ -504,17 +533,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

@ -1623,11 +1623,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();
@ -1644,7 +1644,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) {
@ -1675,6 +1675,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

@ -1265,6 +1265,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) {
@ -1484,6 +1487,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

@ -2694,6 +2694,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;
@ -4445,7 +4446,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);
@ -5932,24 +5933,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);
@ -5989,7 +5999,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);
@ -6006,6 +6015,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) {
@ -8094,6 +8120,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);
@ -8169,6 +8196,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

@ -355,6 +355,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
delegate.searchStateChanged(waitingResponseCount > 0, true);
delegate.runResultsEnterAnimation();
}
globalSearchCollapsed = true;
phoneCollapsed = true;
notifyDataSetChanged();
}
}
@ -697,6 +699,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
searchWas = false;
lastSearchId = 0;
waitingResponseCount = 0;
globalSearchCollapsed = true;
phoneCollapsed = true;
if (delegate != null) {
delegate.searchStateChanged(false, true);
}
@ -717,6 +721,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) {
@ -729,6 +735,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);
@ -773,7 +781,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) {
@ -822,7 +836,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);
@ -862,7 +882,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) {
@ -934,6 +960,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);
@ -1013,11 +1041,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);
@ -1117,19 +1151,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;
}
@ -1161,6 +1225,9 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
}
boolean globalSearchCollapsed = true;
boolean phoneCollapsed = true;
@Override
public int getItemViewType(int i) {
if (isRecentSearchDisplayed()) {
@ -1180,7 +1247,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

@ -163,6 +163,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;
@ -400,6 +401,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 {
@ -1264,7 +1266,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);
@ -2533,6 +2537,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);
}
@ -2551,6 +2556,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);
}
@ -2639,6 +2645,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);
@ -3648,6 +3655,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
@ -3659,7 +3671,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));
@ -6090,7 +6104,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

@ -390,6 +390,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;
@ -44,6 +57,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;
@ -52,18 +67,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 TextView(context);
valueTextView.setVisibility(GONE);
valueTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2));
valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
valueTextView.setLines(1);
@ -71,18 +148,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();
@ -104,6 +348,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 {
@ -134,12 +383,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();
}
}
}
});
@ -149,63 +400,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) {
@ -228,43 +458,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;
@ -64,7 +65,6 @@ import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.animation.Interpolator;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.graphics.ColorUtils;
@ -250,8 +250,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 {
@ -599,6 +619,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;
@ -881,6 +902,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() {
@ -1088,6 +1111,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
urlPathCache.remove(0);
} else {
linkPath = new LinkPath();
linkPath.setUseRoundRect(true);
}
linkPath.reset();
if (text) {
@ -1167,6 +1191,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);
@ -1183,6 +1208,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;
}
@ -1207,6 +1233,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;
}
@ -1271,6 +1298,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);
}
@ -1333,6 +1361,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);
}
@ -1415,6 +1444,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);
}
@ -2480,6 +2510,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) {
@ -2637,7 +2669,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();
@ -2985,7 +3017,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) {
@ -3027,7 +3059,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;
}
@ -3266,6 +3298,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
reactionsLayoutInBubble.onDetachFromWindow();
statusDrawableAnimationInProgress = false;
if (unregisterFlagSecure != null) {
unregisterFlagSecure.run();
unregisterFlagSecure = null;
}
}
@Override
@ -3348,6 +3385,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
toSeekBarProgress = showSeekbar ? 1f : 0f;
}
reactionsLayoutInBubble.onAttachToWindow();
updateFlagSecure();
}
private void setMessageContent(MessageObject messageObject, MessageObject.GroupedMessages groupedMessages, boolean bottomNear, boolean topNear) {
@ -3471,7 +3510,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) ? 1 : 0;
@ -3552,6 +3591,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentPhotoObject = null;
photoParentObject = null;
currentPhotoObjectThumb = null;
currentPhotoObjectThumbStripped = null;
if (messageChanged || messageIdChanged || dataChanged) {
currentPhotoFilter = null;
}
@ -3571,6 +3611,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawForwardedName = false;
drawCommentButton = false;
photoImage.setSideClip(0);
photoImage.setAspectFit(false);
gradientShader = null;
motionBackgroundDrawable = null;
@ -3776,6 +3817,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;
@ -3988,10 +4032,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;
@ -4216,7 +4262,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;
}
@ -4269,6 +4315,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";
@ -4335,7 +4385,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++) {
@ -4411,7 +4465,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;
}
@ -4551,7 +4609,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();
@ -4572,16 +4630,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) {
@ -4599,14 +4654,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 {
@ -4614,13 +4666,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);
}
@ -4634,9 +4684,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);
@ -5324,10 +5386,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);
@ -5345,7 +5409,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;
@ -5496,7 +5560,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);
@ -5516,8 +5580,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;
@ -5548,7 +5617,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());
@ -5586,17 +5659,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);
@ -5655,6 +5734,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) {
@ -5690,15 +5773,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);
@ -6073,15 +6154,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) {
@ -6096,11 +6175,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);
}
@ -6132,55 +6211,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);
}
}
}
@ -6592,6 +6661,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;
}
}
public void checkVideoPlayback(boolean allowStart, Bitmap thumb) {
@ -7057,7 +7139,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;
@ -7068,7 +7154,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;
}
@ -7155,6 +7241,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);
}
@ -7169,6 +7256,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);
@ -7176,6 +7264,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;
}
@ -7349,6 +7438,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) {
@ -7999,7 +8090,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();
@ -8419,7 +8510,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);
@ -8533,7 +8624,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);
}
@ -8665,7 +8756,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);
}
@ -9483,6 +9574,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;
}
@ -9607,7 +9700,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) {
@ -9647,7 +9740,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;
@ -9759,13 +9852,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();
@ -9774,7 +9867,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();
@ -10252,6 +10345,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);
@ -10688,7 +10792,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";
}
}
@ -13532,7 +13644,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;
@ -148,6 +149,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;
@ -266,14 +268,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;
@ -439,6 +445,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;
@ -1302,6 +1309,7 @@ public class DialogCell extends BaseCell {
drawClock = false;
drawCount = false;
drawMention = false;
drawReactionMention = false;
drawError = false;
} else {
if (currentDialogFolderId != 0) {
@ -1338,6 +1346,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)) {
@ -1575,7 +1588,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);
@ -1610,6 +1623,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);
@ -1680,6 +1704,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) {
@ -2013,6 +2045,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);
@ -2027,6 +2060,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;
@ -2258,6 +2292,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();
@ -2267,6 +2329,9 @@ public class DialogCell extends BaseCell {
if (!animated) {
dialogMutedProgress = dialogMuted ? 1f : 0f;
if (countAnimator != null) {
countAnimator.cancel();
}
}
invalidate();
@ -2730,7 +2795,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) {
@ -2846,6 +2911,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

@ -580,6 +580,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,21 +20,21 @@ 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.LayoutHelper;
import org.telegram.messenger.SvgHelper;
public class StickerEmojiCell extends FrameLayout {
@ -136,7 +136,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) {
@ -149,14 +150,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);
}
}
@ -231,7 +232,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

@ -196,7 +196,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

@ -31,6 +31,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;
@ -66,7 +67,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) {
@ -116,7 +120,13 @@ public class TextDetailCell extends FrameLayout {
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(20) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
canvas.drawLine(
LocaleController.isRTL ? 0 : AndroidUtilities.dp(20),
getMeasuredHeight() - 1,
getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(20) : 0),
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;
@ -37,6 +41,9 @@ import androidx.recyclerview.widget.LinearLayoutManager;
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;
@ -47,13 +54,10 @@ 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;
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;
public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.SelectableView> {
protected int textX;
@ -256,6 +260,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;
@ -1212,12 +1224,14 @@ 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
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.add(Menu.NONE, android.R.id.copy, 0, android.R.string.copy);
menu.add(Menu.NONE, android.R.id.selectAll, 1, android.R.string.selectAll);
menu.add(Menu.NONE, TRANSLATE, 2, LocaleController.getString("TranslateMessage", R.string.TranslateMessage));
return true;
}
@ -1231,9 +1245,37 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
menu.getItem(1).setVisible(true);
}
}
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()) {
@ -1254,6 +1296,13 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
invalidate();
showActions();
return true;
case TRANSLATE:
if (onTranslateListener != null) {
String translateToLanguage = LocaleController.getInstance().getCurrentLocale().getLanguage();
onTranslateListener.run(getSelectedText(), translateFromLanguage, translateToLanguage, () -> showActions());
}
hideActions();
return true;
default:
clear();
}
@ -1328,7 +1377,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (!isSelectionMode()) {
return;
}
CharSequence str = getTextForCopy();
CharSequence str = getSelectedText();
if (str == null) {
return;
}
@ -1342,7 +1391,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);
@ -2375,7 +2434,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

@ -2159,7 +2159,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.parseInt(((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 {
@ -182,6 +184,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;
@ -583,9 +591,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()) {
@ -614,7 +625,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++;
@ -649,18 +660,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));
}
}
@ -677,7 +688,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
}
});
if (selectType != 0 || type == TYPE_USERS || type == TYPE_BANNED || type == TYPE_KICKED) {
if (selectType != SELECT_TYPE_MEMBERS || type == TYPE_USERS || 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() {
@ -848,7 +859,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() {
@ -891,7 +902,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
@ -1034,7 +1045,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;
@ -1190,9 +1203,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;
@ -1201,11 +1214,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);
@ -1217,7 +1230,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;
}
@ -1690,7 +1703,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;
@ -1732,7 +1745,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);
}
@ -2043,7 +2056,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) {
@ -2170,7 +2183,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();
@ -2194,13 +2254,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);
@ -2241,56 +2301,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);
@ -2341,7 +2367,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;
@ -2379,8 +2405,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);
}
}
}
@ -2548,10 +2587,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<>());
@ -2665,11 +2705,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);
});
}
@ -2796,7 +2836,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());
@ -3003,7 +3043,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());
@ -3220,7 +3260,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));
@ -3254,7 +3294,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
actionCell.setText(LocaleController.getString("ChannelAddAdmin", R.string.ChannelAddAdmin), null, R.drawable.add_admin, 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.actions_addmember2, showDivider);
} else {
@ -3264,7 +3304,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
} else if (position == recentActionsRow) {
actionCell.setText(LocaleController.getString("EventLog", R.string.EventLog), null, R.drawable.group_log, 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

@ -547,7 +547,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;
}
@ -559,6 +559,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) {
@ -2941,16 +2947,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;
}
BottomSheet.Builder builder = new BottomSheet.Builder(context, true, resourcesProvider);
builder.setDimBehind(hideDim == null);
builder.setOnPreDismissListener(di -> {
if (hideDim != null) {
hideDim.run();
}
});
builder.setTitle(LocaleController.getString("ReportChat", R.string.ReportChat), true);
CharSequence[] items;
int[] icons;
@ -4082,7 +4094,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;
}
@ -4093,6 +4105,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();
@ -4218,7 +4231,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) {
@ -4458,6 +4471,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

@ -150,6 +150,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);
}
}
@ -202,6 +204,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

@ -189,6 +189,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

@ -99,6 +99,8 @@ import androidx.recyclerview.widget.ChatListItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
@ -2311,6 +2313,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 {
@ -3670,11 +3675,11 @@ public class ChatActivityEnterView extends ChatBlurredFrameLayout implements Not
}
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);
@ -3703,33 +3708,35 @@ public class ChatActivityEnterView extends ChatBlurredFrameLayout implements Not
});
sendPopupLayout.setShownFromBotton(false);
for (int a = 0; a < 2; a++) {
if (a == 0 && !parentFragment.canScheduleMessage() || a == 1 && (UserObject.isUserSelf(user) || slowModeTimer > 0 && !isInScheduleMode())) {
continue;
}
int num = a;
ActionBarMenuSubItem cell = new ActionBarMenuSubItem(getContext(), a == 0, a == 1, resourcesProvider);
if (num == 0) {
if (UserObject.isUserSelf(user)) {
cell.setTextAndIcon(LocaleController.getString("SetReminder", R.string.SetReminder), R.drawable.msg_schedule);
} else {
cell.setTextAndIcon(LocaleController.getString("ScheduleMessage", R.string.ScheduleMessage), R.drawable.msg_schedule);
}
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("SendWithoutSound", R.string.SendWithoutSound), R.drawable.input_notify_off);
scheduleButton.setTextAndIcon(LocaleController.getString("ScheduleMessage", R.string.ScheduleMessage), R.drawable.msg_schedule);
}
cell.setMinimumWidth(AndroidUtilities.dp(196));
sendPopupLayout.addView(cell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
cell.setOnClickListener(v -> {
scheduleButton.setMinimumWidth(AndroidUtilities.dp(196));
scheduleButton.setOnClickListener(v -> {
if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss();
}
if (num == 0) {
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), this::sendMessageInternal, resourcesProvider);
} else {
sendMessageInternal(false, 0);
}
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), this::sendMessageInternal, resourcesProvider);
});
sendPopupLayout.addView(scheduleButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
}
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);
});
sendPopupLayout.addView(sendWithoutSoundButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
}
sendPopupLayout.setupRadialSelectors(getThemedColor(Theme.key_dialogButtonSelector));
@ -3766,7 +3773,9 @@ public class ChatActivityEnterView extends ChatBlurredFrameLayout implements Not
sendPopupWindow.showAtLocation(view, Gravity.LEFT | Gravity.TOP, location[0] + view.getMeasuredWidth() - sendPopupLayout.getMeasuredWidth() + AndroidUtilities.dp(8), y);
sendPopupWindow.dimBehind();
sendButton.invalidate();
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

@ -28,14 +28,12 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Vibrator;
import android.text.Editable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.ImageSpan;
import android.text.util.Linkify;
import android.util.Property;
import android.util.TypedValue;
import android.view.Gravity;
@ -46,7 +44,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
@ -307,6 +304,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;
@ -1036,12 +1035,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);
@ -2004,7 +2005,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));
@ -2025,7 +2028,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;
}
@ -2052,7 +2057,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));
@ -2386,7 +2393,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 {
@ -2406,7 +2413,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);
}
}
@ -2655,8 +2662,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

@ -44,6 +44,7 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
@ -93,7 +94,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
@ -133,6 +133,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;
@ -382,6 +383,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;
@ -393,6 +395,7 @@ 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();
@ -411,6 +414,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
@ -432,7 +443,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) {
@ -447,6 +458,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();
@ -681,6 +693,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
@ -733,7 +746,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) {
@ -754,13 +766,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);
@ -898,6 +916,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
@ -925,6 +944,11 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
updateEmptyView();
}
@Override
boolean shouldHideBottomButtons() {
return !locationDenied;
}
@Override
void onPause() {
if (mapView != null && mapsInitialized) {
@ -940,6 +964,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
@Override
void onDestroy() {
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.locationPermissionGranted);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.locationPermissionDenied);
try {
if (googleMap != null) {
googleMap.setMyLocationEnabled(false);
@ -1091,7 +1116,6 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
if (searchInProgress) {
searchListView.setEmptyView(null);
emptyView.setVisibility(GONE);
searchListView.setVisibility(GONE);
} else {
searchListView.setEmptyView(emptyView);
}
@ -1379,7 +1403,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();
@ -1406,12 +1430,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);
@ -1441,21 +1470,49 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
googleMap.moveCamera(CameraUpdateFactory.newLatLng(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;
@ -1465,7 +1522,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);
@ -1478,6 +1535,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
overlayView.setLayoutParams(layoutParams);
}
}
adapter.notifyDataSetChanged();
updateClipView();
}
@ -1528,6 +1586,10 @@ 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 (googleMap != null) {
try {
googleMap.setMyLocationEnabled(true);
@ -1535,7 +1597,14 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
FileLog.e(e);
}
}
} else if (id == NotificationCenter.locationPermissionDenied) {
locationDenied = true;
if (adapter != null) {
adapter.setMyLocationDenied(locationDenied);
}
}
fixLayoutInternal(true);
searchItem.setVisibility(locationDenied ? View.GONE : View.VISIBLE);
}
@Override

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