1
0
mirror of https://github.com/NekoX-Dev/NekoX.git synced 2024-11-23 03:35:24 +01:00

Update to 7.2.0 (2128)

This commit is contained in:
DrKLO 2020-10-30 13:26:29 +03:00
parent 19599e6ea4
commit aaa5dc0328
252 changed files with 15209 additions and 5425 deletions

View File

@ -1,4 +1,4 @@
FROM gradle:6.1.1-jdk8
FROM gradle:6.5.0-jdk8
ENV ANDROID_SDK_URL https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
ENV ANDROID_API_LEVEL android-30

View File

@ -17,7 +17,7 @@ configurations.all {
dependencies {
implementation 'androidx.core:core:1.3.2'
implementation 'androidx.palette:palette:1.0.0'
implementation 'androidx.exifinterface:exifinterface:1.3.0'
implementation 'androidx.exifinterface:exifinterface:1.3.1'
implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation "androidx.sharetarget:sharetarget:1.0.0"
@ -33,6 +33,7 @@ dependencies {
implementation 'com.google.android.gms:play-services-vision:16.2.0'
implementation 'com.google.android.gms:play-services-wearable:17.0.0'
implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.google.android.gms:play-services-wallet:18.1.2'
implementation "com.microsoft.appcenter:appcenter-distribute:3.3.1"
implementation "com.microsoft.appcenter:appcenter-crashes:3.3.1"
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
@ -284,28 +285,12 @@ android {
}
}
defaultConfig.versionCode = 2103
defaultConfig.versionCode = 2128
applicationVariants.all { variant ->
variant.outputs.all { output ->
outputFileName = "app.apk"
output.getProcessManifestProvider().get().doLast {
def abiVersion = variant.productFlavors.get(0).abiVersionCode
def outputDir = manifestOutputDirectory
File directory
if (outputDir instanceof File) {
directory = outputDir
} else {
directory = outputDir.get().asFile
}
String manifestPath = directory.toString() + "/AndroidManifest.xml"
def manifestContent = file(manifestPath).getText()
manifestContent = manifestContent.replace(String.format('android:versionCode="%d"', defaultConfig.versionCode), String.format('android:versionCode="%s"', defaultConfig.versionCode * 10 + abiVersion))
file(manifestPath).write(manifestContent)
}
output.versionCodeOverride = defaultConfig.versionCode * 10 + variant.productFlavors.get(0).abiVersionCode
}
}
@ -319,7 +304,7 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionName "7.1.3"
versionName "7.2.0"
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']

View File

@ -395,7 +395,7 @@ target_compile_definitions(sqlite PUBLIC
#voip
include(${CMAKE_HOME_DIRECTORY}/voip/CMakeLists.txt)
set(NATIVE_LIB "tmessages.33")
set(NATIVE_LIB "tmessages.34")
#tmessages
add_library(${NATIVE_LIB} SHARED

View File

@ -80,6 +80,10 @@ jint getCurrentTime(JNIEnv *env, jclass c, jint instanceNum) {
return ConnectionsManager::getInstance(instanceNum).getCurrentTime();
}
jint getCurrentDatacenterId(JNIEnv *env, jclass c, jint instanceNum) {
return ConnectionsManager::getInstance(instanceNum).getCurrentDatacenterId();
}
jint isTestBackend(JNIEnv *env, jclass c, jint instanceNum) {
return ConnectionsManager::getInstance(instanceNum).isTestBackend() ? 1 : 0;
}
@ -424,6 +428,7 @@ static const char *ConnectionsManagerClassPathName = "org/telegram/tgnet/Connect
static JNINativeMethod ConnectionsManagerMethods[] = {
{"native_getCurrentTimeMillis", "(I)J", (void *) getCurrentTimeMillis},
{"native_getCurrentTime", "(I)I", (void *) getCurrentTime},
{"native_getCurrentDatacenterId", "(I)I", (void *) getCurrentDatacenterId},
{"native_isTestBackend", "(I)I", (void *) isTestBackend},
{"native_getTimeDifference", "(I)I", (void *) getTimeDifference},
{"native_sendRequest", "(IJLorg/telegram/tgnet/RequestDelegateInternal;Lorg/telegram/tgnet/QuickAckDelegate;Lorg/telegram/tgnet/WriteToSocketDelegate;IIIZI)V", (void *) sendRequest},

View File

@ -299,7 +299,7 @@ JNIEXPORT void Java_org_telegram_ui_Components_RLottieDrawable_createCache(JNIEn
for (size_t a = 0; a < info->frameCount; a += framesPerUpdate) {
Surface &surfaceToRender = num % 2 == 0 ? surface1 : surface2;
num++;
info->animation->renderSync(a, surfaceToRender);
info->animation->renderSync(a, surfaceToRender, true);
if (a != 0) {
std::unique_lock<std::mutex> lk(cacheDoneMutex);
cacheDoneCv.wait(lk, [] { return !frameReady.load(); });
@ -317,6 +317,7 @@ JNIEXPORT void Java_org_telegram_ui_Components_RLottieDrawable_createCache(JNIEn
//DEBUG_D("sticker time = %d", (int) (ConnectionsManager::getInstance(0).getCurrentTimeMonotonicMillis() - time));
delete[] info->compressBuffer;
delete[] firstBuffer;
delete[] secondBuffer;
fseek(info->precacheFile, 0, SEEK_SET);
uint8_t byte = 1;
@ -332,7 +333,7 @@ JNIEXPORT void Java_org_telegram_ui_Components_RLottieDrawable_createCache(JNIEn
}
}
JNIEXPORT jint Java_org_telegram_ui_Components_RLottieDrawable_getFrame(JNIEnv *env, jclass clazz, jlong ptr, jint frame, jobject bitmap, jint w, jint h, jint stride) {
JNIEXPORT jint Java_org_telegram_ui_Components_RLottieDrawable_getFrame(JNIEnv *env, jclass clazz, jlong ptr, jint frame, jobject bitmap, jint w, jint h, jint stride, jboolean clear) {
if (!ptr || bitmap == nullptr) {
return 0;
}
@ -384,7 +385,7 @@ JNIEXPORT jint Java_org_telegram_ui_Components_RLottieDrawable_getFrame(JNIEnv *
if (!loadedFromCache) {
if (!info->nextFrameIsCacheFrame || !info->precache) {
Surface surface((uint32_t *) pixels, (size_t) w, (size_t) h, (size_t) stride);
info->animation->renderSync((size_t) frame, surface);
info->animation->renderSync((size_t) frame, surface, clear);
info->nextFrameIsCacheFrame = true;
}
}

View File

@ -345,7 +345,7 @@ public:
*
* @internal
*/
void renderSync(size_t frameNo, Surface &surface);
void renderSync(size_t frameNo, Surface &surface, bool clear);
/**
* @brief Returns root layer of the composition updated with

View File

@ -44,7 +44,7 @@ public:
double frameRate() const { return mModel->frameRate(); }
size_t totalFrame() const { return mModel->totalFrame(); }
size_t frameAtPos(double pos) const { return mModel->frameAtPos(pos); }
Surface render(size_t frameNo, const Surface &surface);
Surface render(size_t frameNo, const Surface &surface, bool clear);
const LOTLayerNode * renderTree(size_t frameNo, const VSize &size);
const LayerInfoList &layerInfoList() const
@ -93,7 +93,7 @@ bool AnimationImpl::update(size_t frameNo, const VSize &size)
return mCompItem->update(frameNo);
}
Surface AnimationImpl::render(size_t frameNo, const Surface &surface)
Surface AnimationImpl::render(size_t frameNo, const Surface &surface, bool clear)
{
bool renderInProgress = mRenderInProgress.load();
if (renderInProgress) {
@ -104,7 +104,7 @@ Surface AnimationImpl::render(size_t frameNo, const Surface &surface)
mRenderInProgress.store(true);
update(frameNo,
VSize(surface.drawRegionWidth(), surface.drawRegionHeight()));
mCompItem->render(surface);
mCompItem->render(surface, clear);
mRenderInProgress.store(false);
return surface;
@ -201,9 +201,9 @@ const LOTLayerNode *Animation::renderTree(size_t frameNo, size_t width,
return d->renderTree(frameNo, VSize(width, height));
}
void Animation::renderSync(size_t frameNo, Surface &surface)
void Animation::renderSync(size_t frameNo, Surface &surface, bool clear)
{
d->render(frameNo, surface);
d->render(frameNo, surface, clear);
}
const LayerInfoList &Animation::layers() const

View File

@ -175,7 +175,7 @@ const LOTLayerNode *LOTCompItem::renderTree() const
return mRootLayer->layerNode();
}
bool LOTCompItem::render(const rlottie::Surface &surface)
bool LOTCompItem::render(const rlottie::Surface &surface, bool clear)
{
VBitmap bitmap(reinterpret_cast<uchar *>(surface.buffer()), surface.width(),
surface.height(), surface.bytesPerLine(),
@ -190,7 +190,7 @@ bool LOTCompItem::render(const rlottie::Surface &surface)
e->preprocess(clip);
}
VPainter painter(&bitmap);
VPainter painter(&bitmap, clear);
// set sub surface area for drawing.
painter.setDrawRegion(
VRect(surface.drawRegionPosX(), surface.drawRegionPosY(),
@ -609,7 +609,7 @@ void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask,
VPainter srcPainter;
VBitmap srcBitmap(size.width(), size.height(),
VBitmap::Format::ARGB32);
srcPainter.begin(&srcBitmap);
srcPainter.begin(&srcBitmap, true);
renderHelper(&srcPainter, inheritMask, matteRle);
srcPainter.end();
painter->drawBitmap(VPoint(), srcBitmap, combinedAlpha() * 255);
@ -669,7 +669,7 @@ void LOTCompLayerItem::renderMatteLayer(VPainter *painter, const VRle &mask,
VPainter srcPainter;
src->bitmap().reset(size.width(), size.height(),
VBitmap::Format::ARGB32);
srcPainter.begin(&src->bitmap());
srcPainter.begin(&src->bitmap(), true);
src->render(&srcPainter, mask, matteRle);
srcPainter.end();
@ -677,7 +677,7 @@ void LOTCompLayerItem::renderMatteLayer(VPainter *painter, const VRle &mask,
VPainter layerPainter;
layer->bitmap().reset(size.width(), size.height(),
VBitmap::Format::ARGB32);
layerPainter.begin(&layer->bitmap());
layerPainter.begin(&layer->bitmap(), true);
layer->render(&layerPainter, mask, matteRle);
// 2.1update composition mode

View File

@ -70,7 +70,7 @@ public:
VSize size() const;
void buildRenderTree();
const LOTLayerNode * renderTree()const;
bool render(const rlottie::Surface &surface);
bool render(const rlottie::Surface &surface, bool clear);
void setValue(const std::string &keypath, LOTVariant &value);
void resetCurrentFrame();
private:

View File

@ -115,17 +115,19 @@ VPainter::VPainter()
mImpl = new VPainterImpl;
}
VPainter::VPainter(VBitmap *buffer)
VPainter::VPainter(VBitmap *buffer, bool clear)
{
mImpl = new VPainterImpl;
begin(buffer);
begin(buffer, clear);
}
bool VPainter::begin(VBitmap *buffer)
bool VPainter::begin(VBitmap *buffer, bool clear)
{
mImpl->mBuffer.prepare(buffer);
mImpl->mSpanData.init(&mImpl->mBuffer);
// TODO find a better api to clear the surface
mImpl->mBuffer.clear();
if (clear) {
mImpl->mBuffer.clear();
}
return true;
}
void VPainter::end() {}

View File

@ -37,8 +37,8 @@ public:
};
~VPainter();
VPainter();
VPainter(VBitmap *buffer);
bool begin(VBitmap *buffer);
VPainter(VBitmap *buffer, bool clear);
bool begin(VBitmap *buffer, bool clear);
void end();
void setDrawRegion(const VRect &region); // sub surface rendering area.
void setBrush(const VBrush &brush);

View File

@ -564,6 +564,11 @@ int32_t ConnectionsManager::getCurrentTime() {
return (int32_t) (getCurrentTimeMillis() / 1000) + timeDifference;
}
uint32_t ConnectionsManager::getCurrentDatacenterId() {
Datacenter *datacenter = getDatacenterWithId(DEFAULT_DATACENTER_ID);
return datacenter != nullptr ? datacenter->getDatacenterId() : INT_MAX;
}
bool ConnectionsManager::isTestBackend() {
return testBackend;
}
@ -2796,7 +2801,7 @@ std::unique_ptr<TLObject> ConnectionsManager::wrapInLayer(TLObject *object, Data
invokeWithLayer *request2 = new invokeWithLayer();
request2->layer = currentLayer;
request2->query = std::unique_ptr<TLObject>(request);
if (LOGS_ENABLED) DEBUG_D("wrap in layer %s", typeid(*object).name());
if (LOGS_ENABLED) DEBUG_D("wrap in layer %s, flags = %d", typeid(*object).name(), request->flags);
return std::unique_ptr<TLObject>(request2);
}
}

View File

@ -45,6 +45,7 @@ public:
int64_t getCurrentTimeMillis();
int64_t getCurrentTimeMonotonicMillis();
int32_t getCurrentTime();
uint32_t getCurrentDatacenterId();
bool isTestBackend();
int32_t getTimeDifference();
int32_t sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate);

View File

@ -394,7 +394,7 @@
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_W" android:value="632dp" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_H" android:value="598dp" />
<!--<meta-data android:name="com.google.android.gms.wallet.api.enabled" android:value="true" />-->
<meta-data android:name="com.google.android.gms.wallet.api.enabled" android:value="true" />
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon" android:resource="@drawable/ic_player" />
<meta-data android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc" />

View File

@ -92,7 +92,7 @@ dialogProgressCircle=-12281108
avatar_subtitleInProfilePink=-16777216
player_progress=-14441474
chat_inReplyLine=-12478487
dialogLineProgressBackground=-3875601
dialogLineProgressBackground=-3152133
chat_inReplyNameText=-13464859
chat_outAudioPerfomerSelectedText=-1
profile_title=-13224394
@ -122,6 +122,7 @@ dialogTextBlue2=-14772773
dialogTextBlue3=-14839830
dialogTextBlue4=-15625752
actionBarTabActiveText=-13590803
chat_topPanelMessage=-8354167
statisticChartLine_golden=-1853657
calls_callReceivedGreenIcon=-13645978
chats_pinnedOverlay=100663296
@ -279,6 +280,7 @@ windowBackgroundWhiteBlueText4=-12675352
chat_replyPanelMessage=-13355980
chat_inViewsSelected=-6373686
windowBackgroundWhiteLinkSelection=560114147
inappPlayerClose=-7563878
chat_outMediaIcon=-13332255
chat_outAudioCacheSeekbar=738197503
chats_sentClock=2066650878

View File

@ -48,7 +48,7 @@ chat_inLoaderSelected=-12277262
chat_outLocationIcon=-2105761599
chat_outAudioProgress=-6239505
chat_inReplyLine=-348807706
dialogLineProgressBackground=-2825240
dialogLineProgressBackground=-2035723
chat_inReplyNameText=-14643754
statisticChartLine_lightgreen=-7352519
chats_onlineCircle=-13192972

View File

@ -3,14 +3,17 @@ chat_inFileBackgroundSelected=-12757128
windowBackgroundChecked=-11632213
radioBackgroundChecked=-10177041
dialogTextBlue=-10177041
dialog_inlineProgressBackground=-15393241
chat_inSentClockSelected=-7490861
windowBackgroundWhiteBlueIcon=-528890628
avatar_backgroundActionBarGreen=-14602949
chat_goDownButtonCounterBackground=-11425042
actionBarActionModeDefault=-14273984
actionBarActionModeDefaultTop=-14536643
statisticChartHintLine=452984831
chats_menuPhone=-1816080163
chat_outViews=-7357217
statisticChartLine_red=-832444
chat_secretTimerBackground=-1239540194
avatar_actionBarSelectorCyan=-12758164
chat_outViaBotNameText=-7551233
@ -42,8 +45,10 @@ chat_outTimeSelectedText=-4268038
chat_inFileProgressSelected=-1
changephoneinfo_image=-12693922
chat_inAudioPerfomerText=-8812393
statisticChartBackZoomColor=-12145938
player_button=-1
key_sheet_other=1140850687
statisticChartLine_lightblue=-12814100
chat_inContactNameText=-8796932
chats_menuPhoneCats=-8613724
chat_outPreviewLine=-6631937
@ -59,11 +64,12 @@ chat_inFileProgress=-1
dialogIcon=-7627862
chat_emojiPanelEmptyText=-8549479
chat_emojiPanelBackspace=-9996665
chat_replyPanelClose=-10062202
chat_replyPanelClose=-9798770
chat_inContactPhoneSelectedText=-7490861
dialogSearchText=-1
actionBarTabUnactiveText=-7628894
chat_outAudioTitleText=-1
statisticChartActivePickerChart=-665688455
chat_emojiPanelBackground=-14866637
chats_unreadCounter=-10177041
groupcreate_hintText=-8549479
@ -89,7 +95,7 @@ dialogShadowLine=335544320
groupcreate_onlineText=-10177041
profile_status=-9192457
divider=-1795162112
chat_topPanelLine=-11108183
chat_topPanelLine=-10576428
chat_inReplyMessageText=-1
dialogInputField=-8549479
windowBackgroundWhiteInputFieldActivated=-9522449
@ -109,6 +115,7 @@ chat_inContactPhoneText=-8812393
chat_inlineResultIcon=-8796932
chat_outBubbleGradientSelectedOverlay=352321535
chats_draft=-637778102
dialogLineProgress=-10576428
listSelector=771751936
chat_outPreviewInstantText=-6631937
chat_inMenuSelected=-1517440301
@ -127,13 +134,14 @@ player_progress=-10177041
chat_inReplyLine=-8796932
chat_inAudioPerfomerSelectedText=-7490861
dialogBackground=-14602949
dialogLineProgressBackground=-6242341
dialogLineProgressBackground=-13548718
chat_inReplyNameText=-8796932
chat_outAudioPerfomerSelectedText=-4268038
actionBarActionModeDefaultIcon=-1
windowBackgroundWhiteRedText4=-3187617
chat_goDownButtonIcon=-1
windowBackgroundWhiteRedText5=-1152913
statisticChartLine_lightgreen=-7352519
chat_outAudioSelectedProgress=-1
chat_messageTextOut=-328966
chat_inInstant=-8796932
@ -172,12 +180,15 @@ chat_attachUnactiveTab=-9596506
windowBackgroundWhiteGreenText=-10371737
actionBarTabActiveText=-9781249
chat_emojiPanelIcon=-9996665
chat_topPanelMessage=-7628894
chat_topPanelMessage=-8220258
statisticChartLine_golden=-2184161
statisticChartSignatureAlpha=-1946157057
chat_emojiPanelTrendingDescription=-8549479
calls_callReceivedGreenIcon=-12001930
chats_pinnedOverlay=16777215
windowBackgroundWhiteInputField=-12035217
avatar_backgroundRed=-2326437
statisticChartLine_green=-12729793
chat_emojiPanelIconSelector=-10177041
chat_emojiPanelBadgeBackground=-11291403
chat_inForwardedNameText=-8796932
@ -189,6 +200,7 @@ chat_linkSelectBackground=1516415459
windowBackgroundWhiteBlueText=-10177041
avatar_nameInMessageCyan=-10623523
chat_inLocationBackground=-13417903
statisticChartHighlightColor=-2030043137
radioBackground=-1635939431
profile_tabText=-8549479
contextProgressOuter1=-9914632
@ -236,7 +248,8 @@ chat_attachCameraIcon1=-32171
undo_background=-182112197
avatar_actionBarSelectorPink=-12758164
dialogTextHint=-8549479
chat_topPanelTitle=-11164709
statisticChartLine_orange=-1720817
chat_topPanelTitle=-9719066
chat_inAudioCacheSeekbar=-11443856
chat_outContactIcon=-1
chat_inFileInfoText=-8812137
@ -246,12 +259,13 @@ profile_creatorIcon=-10177041
profile_actionBackground=-10376479
avatar_subtitleInProfileGreen=-7628894
chats_sentCheck=-10177041
statisticChartInactivePickerChart=-936297140
chats_unreadCounterMuted=-12692893
chat_outVoiceSeekbarFill=-7944965
chat_outReplyLine=-6631937
chat_messagePanelIcons=-9733492
chat_inReplyMediaMessageText=-8812393
inappPlayerTitle=-8549479
inappPlayerTitle=-8220258
chat_emojiPanelIconSelected=-10177041
progressCircle=-10177027
chat_inContactBackground=-10445358
@ -266,7 +280,7 @@ chat_mediaSentClock=-1291845633
files_folderIcon=-1
chats_menuCloudBackgroundCats=-11232035
switchTrackBlue=-10984850
chat_topPanelClose=-10590606
chat_topPanelClose=-9074276
profile_adminIcon=-8549479
chats_verifiedBackground=-10177041
chat_inTimeSelectedText=-7490861
@ -282,6 +296,7 @@ picker_enabledButton=-9781249
inappPlayerBackground=-14602949
avatar_nameInMessagePink=-624741
windowBackgroundWhiteGrayText=-8549479
statisticChartSignature=-1214008894
avatar_actionBarSelectorViolet=-12758164
chat_attachPollBackground=-2183099
avatar_nameInMessageBlue=-8796932
@ -311,6 +326,7 @@ dialogBadgeBackground=-10177041
chat_outBubbleSelected=-11829841
avatar_backgroundInProfileBlue=-11232035
chat_inFileNameText=-1
statisticChartLine_blue=-11362305
inappPlayerPerformer=-1
chat_inInstantSelected=-5648402
chat_outFileInfoText=-7357217
@ -319,6 +335,7 @@ groupcreate_checkboxCheck=-1
chat_outContactPhoneSelectedText=-4268038
chat_unreadMessagesStartBackground=-14339006
chat_inLoaderPhoto=-14404542
statisticChartCheckboxInactive=-6579301
chat_inFileInfoSelectedText=-7490861
chat_wallpaper=-15393241
chat_outMenuSelected=-541138950
@ -347,6 +364,7 @@ chat_outBubble=-12689014
avatar_backgroundActionBarCyan=-14602949
chat_attachFileBackground=-10830604
chat_attachHideBackground=-14074026
statisticChartChevronColor=-9012091
chats_menuItemText=-184549377
chats_message=-8549479
chat_outReplyNameText=-6631937
@ -369,11 +387,11 @@ windowBackgroundWhiteBlueText3=-10177041
windowBackgroundWhiteBlueText2=-8796932
windowBackgroundWhiteBlueText5=-10177041
windowBackgroundWhiteBlueText4=-10177041
chat_replyPanelMessage=-8812137
chat_replyPanelMessage=-7628894
chat_inViewsSelected=-7490861
windowBackgroundWhiteLinkSelection=862238205
player_background=-14734794
inappPlayerClose=-8549479
inappPlayerClose=-9336677
chat_outMediaIcon=-1
chats_message_threeLines=-8549479
player_actionBarSubtitle=-8549479
@ -383,6 +401,7 @@ chats_sentClock=-11772054
chat_inAudioSeekbar=-11443856
avatar_subtitleInProfileRed=-7628894
avatar_backgroundActionBarRed=-14602949
statisticChartLine_indigo=-7906078
dialogSearchIcon=-8945521
chat_inPreviewInstantText=-8796932
chats_archiveBackground=-11036980
@ -407,6 +426,7 @@ windowBackgroundWhiteGrayText3=-8549479
windowBackgroundWhiteGrayText4=-931296359
chat_inTimeText=-645885536
dialogRadioBackground=-11245959
statisticChartRipple=748994002
chat_outReplyMessageText=-1
chat_recordedVoiceDot=-1221292
chat_messagePanelBackground=-14602949
@ -426,6 +446,7 @@ windowBackgroundWhiteValueText=-528890628
chat_outAudioDurationText=-7357217
chat_outMenu=-9594162
chat_goDownButton=-14602949
statisticChartActiveLine=855638015
chats_secretName=-9316522
chat_inMenu=2039722445
chat_recordVoiceCancel=-8549479
@ -441,22 +462,3 @@ chat_outSentClock=-8213557
dialogBackgroundGray=-14932431
chat_searchPanelText=-8796932
chat_inContactIcon=-1
statisticChartSignatureAlpha=-1946157057
statisticChartRipple=748994002
statisticChartCheckboxInactive=-6579301
statisticChartBackZoomColor=-12145938
statisticChartChevronColor=-9012091
statisticChartHighlightColor=-2030043137
statisticChartHintLine=452984831
statisticChartLine_red=-832444
statisticChartLine_lightblue=-12814100
statisticChartActivePickerChart=-665688455
statisticChartLine_lightgreen=-7352519
statisticChartLine_golden=-2184161
statisticChartLine_green=-12729793
statisticChartLine_orange=-1720817
statisticChartInactivePickerChart=-936297140
statisticChartSignature=-1214008894
statisticChartLine_blue=-11362305
statisticChartLine_indigo=-7906078
statisticChartActiveLine=855638015

View File

@ -98,7 +98,7 @@ avatar_subtitleInProfilePink=-16777216
player_progress=-14574092
chat_stickerReplyMessageText=-7565679
chat_inReplyLine=-12676640
dialogLineProgressBackground=-3875601
dialogLineProgressBackground=-3348999
chat_inReplyNameText=-13531425
chat_outAudioPerfomerSelectedText=-1
profile_title=-13224394
@ -129,6 +129,7 @@ dialogTextBlue2=-14772773
dialogTextBlue3=-14839830
dialogTextBlue4=-15625752
actionBarTabActiveText=-15755027
chat_topPanelMessage=-8419703
chat_stickerNameText=-1
statisticChartLine_golden=-1853657
calls_callReceivedGreenIcon=-13645978
@ -204,6 +205,7 @@ chats_sentCheck=-15032337
chat_outVoiceSeekbarFill=-1
chat_outReplyLine=-1
chat_inAudioSeekbarFill=-11426840
inappPlayerTitle=-14276824
progressCircle=-12605954
chat_inContactBackground=-13393417
chat_outVenueInfoSelectedText=-3676417
@ -301,6 +303,7 @@ windowBackgroundWhiteBlueText4=-12675352
chat_replyPanelMessage=-13355980
chat_inViewsSelected=-258105181
windowBackgroundWhiteLinkSelection=560114147
inappPlayerClose=-7563878
chat_outMediaIcon=-14707997
chat_outAudioCacheSeekbar=738197503
chats_sentClock=2073474246

View File

@ -9,8 +9,10 @@ avatar_backgroundActionBarGreen=-14602949
chat_goDownButtonCounterBackground=-11425042
actionBarActionModeDefault=-14211289
actionBarActionModeDefaultTop=-14277082
statisticChartHintLine=452984831
chats_menuPhone=-1815557944
chat_outViews=-7357217
statisticChartLine_red=-832444
chat_secretTimerBackground=-1239540194
avatar_actionBarSelectorCyan=-12758164
chat_outViaBotNameText=-5448193
@ -43,8 +45,10 @@ chat_outTimeSelectedText=-7023626
chat_inFileProgressSelected=-1
changephoneinfo_image=-11184811
chat_inAudioPerfomerText=-8618883
statisticChartBackZoomColor=-12145938
player_button=-1
key_sheet_other=1140850687
statisticChartLine_lightblue=-12814100
chat_inContactNameText=-8796932
chats_menuPhoneCats=-8224126
chat_outPreviewLine=-6631937
@ -62,11 +66,12 @@ chat_inFileProgress=-1
dialogIcon=-7566196
chat_emojiPanelEmptyText=-8553090
chat_emojiPanelBackspace=-9539985
chat_replyPanelClose=-9539985
chat_replyPanelClose=-9013383
chat_inContactPhoneSelectedText=-7490861
dialogSearchText=-1
actionBarTabUnactiveText=-7434609
chat_outAudioTitleText=-1
statisticChartActivePickerChart=-665229191
chat_emojiPanelBackground=-14803425
chats_unreadCounter=-13000973
groupcreate_hintText=-8553091
@ -134,13 +139,14 @@ player_progress=-11292689
chat_inReplyLine=-8796932
chat_inAudioPerfomerSelectedText=-7490861
dialogBackground=-14803426
dialogLineProgressBackground=-10132123
dialogLineProgressBackground=-12303292
chat_inReplyNameText=-8796932
chat_outAudioPerfomerSelectedText=-7023626
actionBarActionModeDefaultIcon=-1
windowBackgroundWhiteRedText4=-3187617
chat_goDownButtonIcon=-1
windowBackgroundWhiteRedText5=-1152913
statisticChartLine_lightgreen=-7352519
chats_onlineCircle=-13130503
chat_outAudioSelectedProgress=-1
chat_messageTextOut=-328966
@ -168,7 +174,7 @@ chats_nameMessageArchived=-8553091
avatar_nameInMessageOrange=-13984
chats_pinnedIcon=-10197916
chat_attachActiveTab=-9781249
chat_replyPanelLine=1779898909
chat_replyPanelLine=-1509949440
avatar_subtitleInProfileOrange=-7628894
chat_outSentCheckSelected=-5841921
dialogSearchHint=-8421505
@ -183,13 +189,16 @@ chat_attachUnactiveTab=-9596506
windowBackgroundWhiteGreenText=-10371737
actionBarTabActiveText=-10698241
chat_emojiPanelIcon=-9539985
chat_topPanelMessage=-7895160
chat_topPanelMessage=-8618626
statisticChartLine_golden=-2184161
statisticChartSignatureAlpha=-1946157057
chat_emojiSearchIcon=-9211020
chat_emojiPanelTrendingDescription=-8553090
calls_callReceivedGreenIcon=-12001930
chats_pinnedOverlay=16777215
windowBackgroundWhiteInputField=-11513776
avatar_backgroundRed=-2326437
statisticChartLine_green=-12729793
chat_emojiPanelIconSelector=-10177041
chat_emojiPanelBadgeBackground=-11291403
chat_inForwardedNameText=-8930052
@ -203,6 +212,7 @@ chats_archivePullDownBackground=-14145496
windowBackgroundWhiteBlueText=-10177041
avatar_nameInMessageCyan=-10623523
chat_inLocationBackground=-12829636
statisticChartHighlightColor=-2030043137
radioBackground=-1635939431
contextProgressOuter1=-11555592
chat_inFileIcon=-14145496
@ -253,6 +263,7 @@ chat_attachCameraIcon1=-32171
undo_background=-181917656
avatar_actionBarSelectorPink=-12758164
dialogTextHint=-8553091
statisticChartLine_orange=-1457126
chat_topPanelTitle=-10638868
chat_inAudioCacheSeekbar=-10461088
chat_outContactIcon=-1
@ -264,12 +275,13 @@ profile_creatorIcon=-10177041
profile_actionBackground=-11560229
avatar_subtitleInProfileGreen=-7628894
chats_sentCheck=-12145165
statisticChartInactivePickerChart=-667862461
chats_unreadCounterMuted=-12237499
chat_outVoiceSeekbarFill=-1
chat_outReplyLine=-8466689
chat_messagePanelIcons=-8947847
chat_inReplyMediaMessageText=-8355711
inappPlayerTitle=-8553090
inappPlayerTitle=-8618626
chat_emojiPanelIconSelected=-10177041
progressCircle=-10177027
chat_inContactBackground=-11494936
@ -285,7 +297,7 @@ files_folderIcon=-1
chat_outTextSelectionHighlight=2122236141
chats_menuCloudBackgroundCats=-11232035
switchTrackBlue=-9934742
chat_topPanelClose=-10461087
chat_topPanelClose=-9013383
profile_adminIcon=-8549479
chats_verifiedBackground=-12145929
chat_inTimeSelectedText=-7490861
@ -301,6 +313,7 @@ picker_enabledButton=-9781249
inappPlayerBackground=-15066597
avatar_nameInMessagePink=-624741
windowBackgroundWhiteGrayText=-8553091
statisticChartSignature=-1214008894
actionBarDefaultSubmenuItemIcon=-8421504
avatar_actionBarSelectorViolet=-12758164
chat_attachPollBackground=-2183099
@ -331,6 +344,7 @@ dialogBadgeBackground=-10177041
chat_outBubbleSelected=-11829841
avatar_backgroundInProfileBlue=-11232035
chat_inFileNameText=-1
statisticChartLine_blue=-11362305
inappPlayerPerformer=-1
chat_inInstantSelected=-5648402
chat_outFileInfoText=-7357217
@ -339,6 +353,7 @@ groupcreate_checkboxCheck=-1
chat_outContactPhoneSelectedText=-7023626
chat_unreadMessagesStartBackground=-14606046
chat_inLoaderPhoto=-13882324
statisticChartCheckboxInactive=-6579301
chat_inFileInfoSelectedText=-7490861
chat_wallpaper=-16316665
chat_outMenuSelected=-541138950
@ -369,6 +384,7 @@ chat_outBubble=-13210449
avatar_backgroundActionBarCyan=-14602949
chat_attachFileBackground=-10830604
chat_attachHideBackground=-14074026
statisticChartChevronColor=-9012091
chats_menuItemText=-184549377
chats_message=-8224126
chat_outReplyNameText=-6301185
@ -398,7 +414,7 @@ chat_inViewsSelected=-7490861
chat_emojiBottomPanelIcon=-9539985
windowBackgroundWhiteLinkSelection=1030010365
player_background=-14474461
inappPlayerClose=-8553090
inappPlayerClose=-9013383
chat_outMediaIcon=-1
chats_message_threeLines=-8224126
player_actionBarSubtitle=-8553091
@ -408,6 +424,7 @@ chats_sentClock=-9539986
chat_inAudioSeekbar=-11119018
avatar_subtitleInProfileRed=-7628894
avatar_backgroundActionBarRed=-14602949
statisticChartLine_indigo=-7906075
dialogSearchIcon=-8882056
chat_inPreviewInstantText=-8796932
chats_archiveBackground=-12219694
@ -432,6 +449,7 @@ windowBackgroundWhiteGrayText3=-8553091
windowBackgroundWhiteGrayText4=-10987432
chat_inTimeText=-8355711
dialogRadioBackground=-10855846
statisticChartRipple=748994002
chat_outBubbleGradient=-12874567
chat_outReplyMessageText=-1
chat_recordedVoiceDot=-1221292
@ -470,22 +488,3 @@ chat_outSentClock=-8213557
dialogBackgroundGray=-14013910
chat_searchPanelText=-10767620
chat_inContactIcon=-1
statisticChartSignatureAlpha=-1946157057
statisticChartRipple=748994002
statisticChartCheckboxInactive=-6579301
statisticChartBackZoomColor=-12145938
statisticChartChevronColor=-9012091
statisticChartHighlightColor=-2030043137
statisticChartHintLine=452984831
statisticChartLine_red=-832444
statisticChartLine_lightblue=-12814100
statisticChartActivePickerChart=-665229191
statisticChartLine_lightgreen=-7352519
statisticChartLine_golden=-2184161
statisticChartLine_green=-12729793
statisticChartLine_orange=-1457126
statisticChartInactivePickerChart=-667862461
statisticChartSignature=-1214008894
statisticChartLine_blue=-11362305
statisticChartLine_indigo=-7906075
statisticChartActiveLine=855638015

View File

@ -6,8 +6,6 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Build;
import android.util.SparseArray;
import android.util.SparseLongArray;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.animation.OvershootInterpolator;
@ -16,8 +14,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageReceiver;
@ -255,6 +251,10 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
if (!shouldAnimateEnterFromBottom) {
holder.itemView.setScaleX(0.9f);
holder.itemView.setScaleY(0.9f);
} else {
if (holder.itemView instanceof ChatMessageCell) {
((ChatMessageCell) holder.itemView).getTransitionParams().messageEntering = true;
}
}
mPendingAdditions.add(holder);
return true;
@ -281,16 +281,21 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
@Override
public void onAnimationCancel(Animator animator) {
view.setTranslationY(0);
if (view instanceof ChatMessageCell) {
((ChatMessageCell) view).getTransitionParams().messageEntering = false;
}
}
@Override
public void onAnimationEnd(Animator animator) {
if (view instanceof ChatMessageCell) {
((ChatMessageCell) view).getTransitionParams().messageEntering = false;
}
animation.setListener(null);
if (mAddAnimations.remove(holder)) {
dispatchAddFinished(holder);
dispatchFinishedWhenDone();
}
}
}).start();
}
@ -341,8 +346,13 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
FileLog.d("animate move");
}
final View view = holder.itemView;
ChatMessageCell chatMessageCell = null;
if (holder.itemView instanceof ChatMessageCell) {
fromX += (int) ((ChatMessageCell) holder.itemView).getAnimationOffsetX();
chatMessageCell = ((ChatMessageCell) holder.itemView);
fromX += (int) chatMessageCell.getAnimationOffsetX();
if (chatMessageCell.getTransitionParams().lastTopOffset != chatMessageCell.getTopMediaOffset()) {
fromY += chatMessageCell.getTransitionParams().lastTopOffset - chatMessageCell.getTopMediaOffset();
}
} else {
fromX += (int) holder.itemView.getTranslationX();
}
@ -356,8 +366,7 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
MoveInfoExtended moveInfo = new MoveInfoExtended(holder, fromX, fromY, toX, toY);
if (holder.itemView instanceof ChatMessageCell) {
ChatMessageCell chatMessageCell = (ChatMessageCell) holder.itemView;
if (chatMessageCell != null) {
ChatMessageCell.TransitionParams params = chatMessageCell.getTransitionParams();
if (!params.supportChangeAnimation()) {
@ -563,6 +572,7 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
moveInfo.animateChangeInternal = chatMessageCell.getTransitionParams().animateChange();
if (moveInfo.animateChangeInternal) {
chatMessageCell.getTransitionParams().animateChange = true;
chatMessageCell.getTransitionParams().animateChangeProgress = 0f;
}
@ -610,7 +620,7 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
if (holder.itemView instanceof BotHelpCell) {
BotHelpCell botCell = (BotHelpCell) holder.itemView ;
int top = recyclerListView.getMeasuredHeight() / 2 - botCell.getMeasuredHeight() / 2 + recyclerListView.getPaddingTop();
int top = recyclerListView.getMeasuredHeight() / 2 - botCell.getMeasuredHeight() / 2 + activity.getChatListViewPadding();
float animateTo = 0;
if (botCell.getTop() > top) {
animateTo = top - botCell.getTop();
@ -748,6 +758,7 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
if (moveInfoExtended.animateChangeInternal) {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f);
params.animateChange = true;
valueAnimator.addUpdateListener(animation -> {
params.animateChangeProgress = (float) animation.getAnimatedValue();
chatMessageCell.invalidate();
@ -950,9 +961,7 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
FileLog.d("all animations done");
}
if (!reset) {
recyclerListView.setClipChildren(true);
}
recyclerListView.setClipChildren(true);
while (!runOnAnimationsEnd.isEmpty()) {
runOnAnimationsEnd.remove(0).run();
}

View File

@ -295,9 +295,6 @@ public class ChildHelper {
final int offset = getOffset(index);
mBucket.remove(offset);
mCallback.detachViewFromParent(offset);
if (DEBUG) {
Log.d(TAG, "detach view from parent " + index + ", off:" + offset);
}
}
/**

View File

@ -966,12 +966,16 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
return fixOffset;
}
public int getStarForFixGap() {
return mOrientationHelper.getStartAfterPadding();
}
/**
* @return The final offset amount for children
*/
private int fixLayoutStartGap(int startOffset, RecyclerView.Recycler recycler,
RecyclerView.State state, boolean canOffsetChildren) {
int gap = startOffset - mOrientationHelper.getStartAfterPadding();
int gap = startOffset - getStarForFixGap();
int fixOffset = 0;
if (gap > 0) {
// check if we should fix this gap.
@ -1459,21 +1463,33 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
if (mShouldReverseLayout) {
for (int i = childCount - 1; i >= 0; i--) {
View child = getChildAt(i);
if (mOrientationHelper.getDecoratedEnd(child) > limit
|| mOrientationHelper.getTransformedEndWithDecoration(child) > limit) {
// stop here
recycleChildren(recycler, childCount - 1, i);
return;
if (child != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(child);
if (holder == null || holder.shouldIgnore()) {
continue;
}
if (mOrientationHelper.getDecoratedEnd(child) > limit
|| mOrientationHelper.getTransformedEndWithDecoration(child) > limit) {
// stop here
recycleChildren(recycler, childCount - 1, i);
return;
}
}
}
} else {
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (mOrientationHelper.getDecoratedEnd(child) > limit
|| mOrientationHelper.getTransformedEndWithDecoration(child) > limit) {
// stop here
recycleChildren(recycler, 0, i);
return;
if (child != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(child);
if (holder == null || holder.shouldIgnore()) {
continue;
}
if (mOrientationHelper.getDecoratedEnd(child) > limit
|| mOrientationHelper.getTransformedEndWithDecoration(child) > limit) {
// stop here
recycleChildren(recycler, 0, i);
return;
}
}
}
}
@ -1507,21 +1523,33 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
if (mShouldReverseLayout) {
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (mOrientationHelper.getDecoratedStart(child) < limit
|| mOrientationHelper.getTransformedStartWithDecoration(child) < limit) {
// stop here
recycleChildren(recycler, 0, i);
return;
if (child != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(child);
if (holder == null || holder.shouldIgnore()) {
continue;
}
if (mOrientationHelper.getDecoratedStart(child) < limit
|| mOrientationHelper.getTransformedStartWithDecoration(child) < limit) {
// stop here
recycleChildren(recycler, 0, i);
return;
}
}
}
} else {
for (int i = childCount - 1; i >= 0; i--) {
View child = getChildAt(i);
if (mOrientationHelper.getDecoratedStart(child) < limit
|| mOrientationHelper.getTransformedStartWithDecoration(child) < limit) {
// stop here
recycleChildren(recycler, childCount - 1, i);
return;
if (child != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(child);
if (holder == null || holder.shouldIgnore()) {
continue;
}
if (mOrientationHelper.getDecoratedStart(child) < limit
|| mOrientationHelper.getTransformedStartWithDecoration(child) < limit) {
// stop here
recycleChildren(recycler, childCount - 1, i);
return;
}
}
}
}

View File

@ -371,7 +371,7 @@ public abstract class OrientationHelper {
@Override
public int getStartAfterPadding() {
return mLayoutManager.getPaddingTop();
return mLayoutManager.getStartAfterPadding();
}
@Override
@ -418,8 +418,7 @@ public abstract class OrientationHelper {
@Override
public int getTotalSpace() {
return mLayoutManager.getHeight() - mLayoutManager.getPaddingTop()
- mLayoutManager.getPaddingBottom();
return mLayoutManager.getTotalSpace();
}
@Override

View File

@ -899,13 +899,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView,
// lazy detach occurs, it will receive invalid attach/detach sequencing.
child.clearAnimation();
}
if (VERBOSE_TRACING) {
TraceCompat.beginSection("RV removeViewAt");
}
RecyclerView.this.removeViewAt(index);
if (VERBOSE_TRACING) {
TraceCompat.endSection();
}
}
@Override
@ -942,9 +936,6 @@ public class RecyclerView extends ViewGroup implements ScrollingView,
throw new IllegalArgumentException("Called attach on a child which is not"
+ " detached: " + vh + exceptionLabel());
}
if (DEBUG) {
Log.d(TAG, "reAttach " + vh);
}
vh.clearTmpDetachFlag();
}
RecyclerView.this.attachViewToParent(child, index, layoutParams);
@ -960,9 +951,6 @@ public class RecyclerView extends ViewGroup implements ScrollingView,
throw new IllegalArgumentException("called detach on an already"
+ " detached child " + vh + exceptionLabel());
}
if (DEBUG) {
Log.d(TAG, "tmpDetach " + vh);
}
vh.addFlags(ViewHolder.FLAG_TMP_DETACHED);
}
}
@ -7558,7 +7546,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView,
@Override
public int getParentStart() {
return LayoutManager.this.getPaddingTop();
return LayoutManager.this.getParentStart();
}
@Override
@ -8835,6 +8823,10 @@ public class RecyclerView extends ViewGroup implements ScrollingView,
*/
public void removeAndRecycleViewAt(int index, @NonNull Recycler recycler) {
final View view = getChildAt(index);
ViewHolder holder = getChildViewHolderInt(view);
if (holder.shouldIgnore()) {
return;
}
removeViewAt(index);
recycler.recycleView(view);
}
@ -10591,6 +10583,22 @@ public class RecyclerView extends ViewGroup implements ScrollingView,
/** {@link androidx.recyclerview.R.attr#stackFromEnd} */
public boolean stackFromEnd;
}
/**
* Custom methods for ignoring padding
*/
protected int getParentStart() {
return getPaddingTop();
}
public int getStartAfterPadding() {
return getPaddingTop();
}
public int getTotalSpace() {
return getHeight() - getPaddingTop() - getPaddingBottom();
}
}
/**
@ -11030,7 +11038,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView,
}
}
boolean shouldIgnore() {
public boolean shouldIgnore() {
return (mFlags & FLAG_IGNORE) != 0;
}

View File

@ -63,7 +63,6 @@ import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.util.DisplayMetrics;
@ -101,6 +100,7 @@ import com.microsoft.appcenter.crashes.Crashes;
import com.microsoft.appcenter.distribute.Distribute;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
@ -244,16 +244,22 @@ public class AndroidUtilities {
return false;
}
public static CharSequence ellipsizeCenterEnd(CharSequence str, String query, int availableWidth, TextPaint textPaint) {
public static CharSequence ellipsizeCenterEnd(CharSequence str, String query, int availableWidth, TextPaint textPaint, int maxSymbols) {
try {
StaticLayout staticLayout = new StaticLayout(str, textPaint, Integer.MAX_VALUE, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
int lastIndex = str.length();
int startHighlightedIndex = str.toString().toLowerCase().indexOf(query);
if (lastIndex > maxSymbols) {
str = str.subSequence(Math.max(0, startHighlightedIndex - maxSymbols / 2), Math.min(lastIndex, startHighlightedIndex + maxSymbols / 2));
startHighlightedIndex -= Math.max(0, startHighlightedIndex - maxSymbols / 2);
lastIndex = str.length();
}
StaticLayout staticLayout = new StaticLayout(str, textPaint, Integer.MAX_VALUE, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
float endOfTextX = staticLayout.getPrimaryHorizontal(lastIndex);
if (endOfTextX + textPaint.measureText("...") < availableWidth) {
return str;
}
int startHighlightedIndex = str.toString().toLowerCase().indexOf(query);
int i = startHighlightedIndex + 1;
while (i < str.length() - 1 && !Character.isWhitespace(str.charAt(i))) {
i++;
@ -361,7 +367,7 @@ public class AndroidUtilities {
return url;
}
private static void gatherLinks(ArrayList<LinkSpec> links, Spannable s, Pattern pattern, String[] schemes, Linkify.MatchFilter matchFilter) {
private static void gatherLinks(ArrayList<LinkSpec> links, Spannable s, Pattern pattern, String[] schemes, Linkify.MatchFilter matchFilter, boolean internalOnly) {
Matcher m = pattern.matcher(s);
while (m.find()) {
int start = m.start();
@ -370,7 +376,11 @@ public class AndroidUtilities {
if (matchFilter == null || matchFilter.acceptMatch(s, start, end)) {
LinkSpec spec = new LinkSpec();
spec.url = makeUrl(m.group(0), schemes, m);
String url = makeUrl(m.group(0), schemes, m);
if (internalOnly && !Browser.isInternalUrl(url, null)) {
continue;
}
spec.url = url;
spec.start = start;
spec.end = end;
@ -390,7 +400,11 @@ public class AndroidUtilities {
};
public static boolean addLinks(Spannable text, int mask) {
if (text != null && containsUnsupportedCharacters(text.toString()) || mask == 0) {
return addLinks(text, mask, false);
}
public static boolean addLinks(Spannable text, int mask, boolean internalOnly) {
if (text == null || containsUnsupportedCharacters(text.toString()) || mask == 0) {
return false;
}
final URLSpan[] old = text.getSpans(0, text.length(), URLSpan.class);
@ -398,11 +412,11 @@ public class AndroidUtilities {
text.removeSpan(old[i]);
}
final ArrayList<LinkSpec> links = new ArrayList<>();
if ((mask & Linkify.PHONE_NUMBERS) != 0) {
if (!internalOnly && (mask & Linkify.PHONE_NUMBERS) != 0) {
Linkify.addLinks(text, Linkify.PHONE_NUMBERS);
}
if ((mask & Linkify.WEB_URLS) != 0) {
gatherLinks(links, text, LinkifyPort.WEB_URL, new String[]{"http://", "https://", "ton://", "tg://"}, sUrlMatchFilter);
gatherLinks(links, text, LinkifyPort.WEB_URL, new String[]{"http://", "https://", "ton://", "tg://"}, sUrlMatchFilter, internalOnly);
}
pruneOverlaps(links);
if (links.size() == 0) {
@ -638,6 +652,14 @@ public class AndroidUtilities {
adjustOwnerClassGuid = classGuid;
}
public static void requestAdjustNothing(Activity activity, int classGuid) {
if (activity == null || isTablet()) {
return;
}
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
adjustOwnerClassGuid = classGuid;
}
public static void setAdjustResizeToNothing(Activity activity, int classGuid) {
if (activity == null || isTablet()) {
return;

View File

@ -18,8 +18,8 @@ public class BuildVars {
public static boolean LOGS_ENABLED = false;
public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true;
public static int BUILD_VERSION = 2103;
public static String BUILD_VERSION_STRING = "7.1.0";
public static int BUILD_VERSION = 2129;
public static String BUILD_VERSION_STRING = "7.2.0";
public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
public static String APPCENTER_HASH = "a5b5c4f5-51da-dedc-9918-d9766a22ca7c";

View File

@ -251,7 +251,7 @@ public class ChatObject {
public static boolean canAddBotsToChat(TLRPC.Chat chat) {
if (isChannel(chat)) {
if (chat != null && chat.megagroup && (chat.admin_rights != null && (chat.admin_rights.post_messages || chat.admin_rights.add_admins) || chat.creator)) {
if (chat.megagroup && (chat.admin_rights != null && (chat.admin_rights.post_messages || chat.admin_rights.add_admins) || chat.creator)) {
return true;
}
} else {
@ -273,7 +273,7 @@ public class ChatObject {
public static boolean isCanWriteToChannel(int chatId, int currentAccount) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chatId);
return ChatObject.canSendMessages(chat) || chat != null && chat.megagroup;
return ChatObject.canSendMessages(chat) || chat.megagroup;
}
public static boolean canWriteToChat(TLRPC.Chat chat) {

View File

@ -768,12 +768,12 @@ public class DownloadController extends BaseController implements NotificationCe
}
if (downloadObject.object instanceof TLRPC.Document) {
TLRPC.Document document = (TLRPC.Document) downloadObject.object;
getFileLoader().cancelLoadFile(document);
getFileLoader().cancelLoadFile(document, true);
} else if (downloadObject.object instanceof TLRPC.Photo) {
TLRPC.Photo photo = (TLRPC.Photo) downloadObject.object;
TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(photo.sizes, AndroidUtilities.getPhotoSize());
if (photoSize != null) {
getFileLoader().cancelLoadFile(photoSize);
getFileLoader().cancelLoadFile(photoSize, true);
}
}
}
@ -783,14 +783,14 @@ public class DownloadController extends BaseController implements NotificationCe
if (objects.isEmpty()) {
return;
}
ArrayList<DownloadObject> queue = null;
ArrayList<DownloadObject> queue;
if (type == AUTODOWNLOAD_TYPE_PHOTO) {
queue = photoDownloadQueue;
} else if (type == AUTODOWNLOAD_TYPE_AUDIO) {
queue = audioDownloadQueue;
} else if (type == AUTODOWNLOAD_TYPE_VIDEO) {
queue = videoDownloadQueue;
} else if (type == AUTODOWNLOAD_TYPE_DOCUMENT) {
} else {
queue = documentDownloadQueue;
}
for (int a = 0; a < objects.size(); a++) {

View File

@ -803,6 +803,10 @@ public class EmojiData {
return "\uD83C\uDF51".equals(emoji);
}
public static boolean isCofinEmoji(String emoji) {
return "⚰️".equals(emoji);
}
static {
for (int a = 0; a < emojiToFE0F.length; a++) {
emojiToFE0FMap.put(emojiToFE0F[a], true);

View File

@ -8,6 +8,8 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import androidx.core.content.ContextCompat;
import android.os.Environment;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@ -34,6 +36,10 @@ public class EmuDetector {
void onResult(boolean isEmulator);
}
private enum EmulatorTypes {
GENY, ANDY, NOX, BLUE, PIPES, X86
}
private static final String[] PHONE_NUMBERS = {
"15555215554", "15555215556", "15555215558", "15555215560", "15555215562", "15555215564",
"15555215566", "15555215568", "15555215570", "15555215572", "15555215574", "15555215576",
@ -81,7 +87,14 @@ public class EmuDetector {
private static final String[] NOX_FILES = {
"fstab.nox",
"init.nox.rc",
"ueventd.nox.rc"
"ueventd.nox.rc",
"/BigNoxGameHD",
"/YSLauncher"
};
private static final String[] BLUE_FILES = {
"/Android/data/com.bluestacks.home",
"/Android/data/com.bluestacks.settings"
};
private static final Property[] PROPERTIES = {
@ -132,6 +145,7 @@ public class EmuDetector {
mListPackageName.add("com.google.android.launcher.layouts.genymotion");
mListPackageName.add("com.bluestacks");
mListPackageName.add("com.bignox.app");
mListPackageName.add("com.vphone.launcher");
}
public boolean isCheckTelephony() {
@ -185,23 +199,25 @@ public class EmuDetector {
}
private boolean checkBasic() {
boolean result = Build.FINGERPRINT.startsWith("generic")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.toLowerCase().contains("droid4x")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion")
|| Build.HARDWARE.equals("goldfish")
|| Build.HARDWARE.equals("vbox86")
|| Build.PRODUCT.equals("sdk")
|| Build.PRODUCT.equals("google_sdk")
|| Build.PRODUCT.equals("sdk_x86")
|| Build.PRODUCT.equals("vbox86p")
|| Build.BOARD.toLowerCase().contains("nox")
|| Build.BOOTLOADER.toLowerCase().contains("nox")
|| Build.HARDWARE.toLowerCase().contains("nox")
|| Build.PRODUCT.toLowerCase().contains("nox")
|| Build.SERIAL.toLowerCase().contains("nox");
boolean result =
Build.BOARD.toLowerCase().contains("nox")
|| Build.BOOTLOADER.toLowerCase().contains("nox")
|| Build.FINGERPRINT.startsWith("generic")
|| Build.MODEL.toLowerCase().contains("google_sdk")
|| Build.MODEL.toLowerCase().contains("droid4x")
|| Build.MODEL.toLowerCase().contains("emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.toLowerCase().contains("genymotion")
|| Build.HARDWARE.toLowerCase().contains("goldfish")
|| Build.HARDWARE.toLowerCase().contains("vbox86")
|| Build.HARDWARE.toLowerCase().contains("android_x86")
|| Build.HARDWARE.toLowerCase().contains("nox")
|| Build.PRODUCT.equals("sdk")
|| Build.PRODUCT.equals("google_sdk")
|| Build.PRODUCT.equals("sdk_x86")
|| Build.PRODUCT.equals("vbox86p")
|| Build.PRODUCT.toLowerCase().contains("nox")
|| Build.SERIAL.toLowerCase().contains("nox");
if (result) {
return true;
@ -216,13 +232,14 @@ public class EmuDetector {
private boolean checkAdvanced() {
return checkTelephony()
|| checkFiles(GENY_FILES, "Geny")
|| checkFiles(ANDY_FILES, "Andy")
|| checkFiles(NOX_FILES, "Nox")
|| checkFiles(GENY_FILES, EmulatorTypes.GENY)
|| checkFiles(ANDY_FILES, EmulatorTypes.ANDY)
|| checkFiles(NOX_FILES, EmulatorTypes.NOX)
|| checkFiles(BLUE_FILES, EmulatorTypes.BLUE)
|| checkQEmuDrivers()
|| checkFiles(PIPES, "Pipes")
|| checkFiles(PIPES, EmulatorTypes.PIPES)
|| checkIp()
|| (checkQEmuProps() && checkFiles(X86_FILES, "X86"));
|| (checkQEmuProps() && checkFiles(X86_FILES, EmulatorTypes.X86));
}
private boolean checkPackageName() {
@ -313,9 +330,18 @@ public class EmuDetector {
return false;
}
private boolean checkFiles(String[] targets, String type) {
private boolean checkFiles(String[] targets, EmulatorTypes type) {
for (String pipe : targets) {
File qemu_file = new File(pipe);
File qemu_file;
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
if ((pipe.contains("/") && type == EmulatorTypes.NOX) || type == EmulatorTypes.BLUE) {
qemu_file = new File(Environment.getExternalStorageDirectory() + pipe);
} else {
qemu_file = new File(pipe);
}
} else {
qemu_file = new File(pipe);
}
if (qemu_file.exists()) {
return true;
}

View File

@ -1016,19 +1016,69 @@ public class FileLoadOperation {
}
public void cancel() {
cancel(false);
}
public void cancel(boolean deleteFiles) {
Utilities.stageQueue.postRunnable(() -> {
if (state == stateFinished || state == stateFailed) {
return;
if (state != stateFinished && state != stateFailed) {
if (requestInfos != null) {
for (int a = 0; a < requestInfos.size(); a++) {
RequestInfo requestInfo = requestInfos.get(a);
if (requestInfo.requestToken != 0) {
ConnectionsManager.getInstance(currentAccount).cancelRequest(requestInfo.requestToken, true);
}
}
}
onFail(false, 1);
}
if (requestInfos != null) {
for (int a = 0; a < requestInfos.size(); a++) {
RequestInfo requestInfo = requestInfos.get(a);
if (requestInfo.requestToken != 0) {
ConnectionsManager.getInstance(currentAccount).cancelRequest(requestInfo.requestToken, true);
if (deleteFiles) {
if (cacheFileFinal != null) {
try {
if (!cacheFileFinal.delete()) {
cacheFileFinal.deleteOnExit();
}
} catch (Exception e) {
FileLog.e(e);
}
}
if (cacheFileTemp != null) {
try {
if (!cacheFileTemp.delete()) {
cacheFileTemp.deleteOnExit();
}
} catch (Exception e) {
FileLog.e(e);
}
}
if (cacheFileParts != null) {
try {
if (!cacheFileParts.delete()) {
cacheFileParts.deleteOnExit();
}
} catch (Exception e) {
FileLog.e(e);
}
}
if (cacheIvTemp != null) {
try {
if (!cacheIvTemp.delete()) {
cacheIvTemp.deleteOnExit();
}
} catch (Exception e) {
FileLog.e(e);
}
}
if (cacheFilePreload != null) {
try {
if (!cacheFilePreload.delete()) {
cacheFilePreload.deleteOnExit();
}
} catch (Exception e) {
FileLog.e(e);
}
}
}
onFail(false, 1);
});
}

View File

@ -117,7 +117,7 @@ public class FileLoader extends BaseController {
dir = mediaDirs.get(FileLoader.MEDIA_DIR_CACHE);
}
try {
if (!dir.isDirectory()) {
if (dir != null && !dir.isDirectory()) {
dir.mkdirs();
}
} catch (Exception e) {
@ -407,25 +407,23 @@ public class FileLoader extends BaseController {
int queueType = operation.getQueueType();
LinkedList<FileLoadOperation> downloadQueue = getLoadOperationQueue(datacenterId, queueType);
SparseIntArray count = getLoadOperationCount(queueType);
if (downloadQueue != null) {
int index = downloadQueue.indexOf(operation);
if (index >= 0) {
downloadQueue.remove(index);
if (operation.start()) {
count.put(datacenterId, count.get(datacenterId) + 1);
}
if (queueType == QUEUE_TYPE_FILE) {
if (operation.wasStarted() && !activeFileLoadOperation.contains(operation)) {
pauseCurrentFileLoadOperations(operation);
activeFileLoadOperation.add(operation);
}
}
} else {
pauseCurrentFileLoadOperations(operation);
operation.start();
if (queueType == QUEUE_TYPE_FILE && !activeFileLoadOperation.contains(operation)) {
activeFileLoadOperation.add(operation);
int index = downloadQueue.indexOf(operation);
if (index >= 0) {
downloadQueue.remove(index);
if (operation.start()) {
count.put(datacenterId, count.get(datacenterId) + 1);
}
if (queueType == QUEUE_TYPE_FILE) {
if (operation.wasStarted() && !activeFileLoadOperation.contains(operation)) {
pauseCurrentFileLoadOperations(operation);
activeFileLoadOperation.add(operation);
}
}
} else {
pauseCurrentFileLoadOperations(operation);
operation.start();
if (queueType == QUEUE_TYPE_FILE && !activeFileLoadOperation.contains(operation)) {
activeFileLoadOperation.add(operation);
}
}
}
@ -433,27 +431,49 @@ public class FileLoader extends BaseController {
}
public void cancelLoadFile(TLRPC.Document document) {
cancelLoadFile(document, null, null, null, null);
cancelLoadFile(document, false);
}
public void cancelLoadFile(TLRPC.Document document, boolean deleteFile) {
cancelLoadFile(document, null, null, null, null, null, deleteFile);
}
public void cancelLoadFile(SecureDocument document) {
cancelLoadFile(null, document, null, null, null);
cancelLoadFile(null, document, null, null, null, null, false);
}
public void cancelLoadFile(WebFile document) {
cancelLoadFile(null, null, document, null, null);
cancelLoadFile(null, null, document, null, null, null, false);
}
public void cancelLoadFile(TLRPC.PhotoSize photo) {
cancelLoadFile(null, null, null, photo.location, null);
cancelLoadFile(photo, false);
}
public void cancelLoadFile(TLRPC.PhotoSize photo, boolean deleteFile) {
cancelLoadFile(null, null, null, photo.location, null, null, deleteFile);
}
public void cancelLoadFile(TLRPC.FileLocation location, String ext) {
cancelLoadFile(null, null, null, location, ext);
cancelLoadFile(location, ext, false);
}
private void cancelLoadFile(final TLRPC.Document document, final SecureDocument secureDocument, final WebFile webDocument, final TLRPC.FileLocation location, final String locationExt) {
if (location == null && document == null && webDocument == null && secureDocument == null) {
public void cancelLoadFile(TLRPC.FileLocation location, String ext, boolean deleteFile) {
cancelLoadFile(null, null, null, location, ext, null, deleteFile);
}
public void cancelLoadFile(String fileName) {
cancelLoadFile(null, null, null, null, null, fileName, true);
}
public void cancelLoadFiles(ArrayList<String> fileNames) {
for (int a = 0, N = fileNames.size(); a < N; a++) {
cancelLoadFile(null, null, null, null, null, fileNames.get(a), true);
}
}
private void cancelLoadFile(final TLRPC.Document document, final SecureDocument secureDocument, final WebFile webDocument, final TLRPC.FileLocation location, final String locationExt, String name, boolean deleteFile) {
if (location == null && document == null && webDocument == null && secureDocument == null && TextUtils.isEmpty(name)) {
return;
}
final String fileName;
@ -466,10 +486,7 @@ public class FileLoader extends BaseController {
} else if (webDocument != null) {
fileName = getAttachFileName(webDocument);
} else {
fileName = null;
}
if (fileName == null) {
return;
fileName = name;
}
loadOperationPathsUI.remove(fileName);
fileLoaderQueue.postRunnable(() -> {
@ -485,7 +502,7 @@ public class FileLoader extends BaseController {
if (queueType == QUEUE_TYPE_FILE) {
activeFileLoadOperation.remove(operation);
}
operation.cancel();
operation.cancel(deleteFile);
}
});
}
@ -589,33 +606,29 @@ public class FileLoader extends BaseController {
int queueType = operation.getQueueType();
LinkedList<FileLoadOperation> downloadQueue = getLoadOperationQueue(datacenterId, queueType);
SparseIntArray count = getLoadOperationCount(queueType);
if (downloadQueue != null) {
int index = downloadQueue.indexOf(operation);
if (index >= 0) {
downloadQueue.remove(index);
if (stream != null) {
if (operation.start(stream, streamOffset, streamPriority)) {
count.put(datacenterId, count.get(datacenterId) + 1);
int index = downloadQueue.indexOf(operation);
if (index >= 0) {
downloadQueue.remove(index);
if (stream != null) {
if (operation.start(stream, streamOffset, streamPriority)) {
count.put(datacenterId, count.get(datacenterId) + 1);
}
if (queueType == QUEUE_TYPE_FILE) {
if (operation.wasStarted() && !activeFileLoadOperation.contains(operation)) {
pauseCurrentFileLoadOperations(operation);
activeFileLoadOperation.add(operation);
}
if (queueType == QUEUE_TYPE_FILE) {
if (operation.wasStarted() && !activeFileLoadOperation.contains(operation)) {
if (stream != null) {
pauseCurrentFileLoadOperations(operation);
}
activeFileLoadOperation.add(operation);
}
}
} else {
downloadQueue.add(0, operation);
}
} else {
if (stream != null) {
pauseCurrentFileLoadOperations(operation);
}
operation.start(stream, streamOffset, streamPriority);
if (queueType == QUEUE_TYPE_FILE && !activeFileLoadOperation.contains(operation)) {
activeFileLoadOperation.add(operation);
}
downloadQueue.add(0, operation);
}
} else {
if (stream != null) {
pauseCurrentFileLoadOperations(operation);
}
operation.start(stream, streamOffset, streamPriority);
if (queueType == QUEUE_TYPE_FILE && !activeFileLoadOperation.contains(operation)) {
activeFileLoadOperation.add(operation);
}
}
}
@ -626,14 +639,6 @@ public class FileLoader extends BaseController {
File tempDir = getDirectory(MEDIA_DIR_CACHE);
File storeDir = tempDir;
int type = MEDIA_DIR_CACHE;
int queueType;
if (type == MEDIA_DIR_AUDIO) {
queueType = QUEUE_TYPE_AUDIO;
} else if (secureDocument != null || location != null && (imageLocation == null || imageLocation.imageType != IMAGE_TYPE_ANIMATION) || MessageObject.isImageWebDocument(webDocument)) {
queueType = QUEUE_TYPE_IMAGE;
} else {
queueType = QUEUE_TYPE_FILE;
}
if (secureDocument != null) {
operation = new FileLoadOperation(secureDocument);
@ -652,7 +657,9 @@ public class FileLoader extends BaseController {
}
} else if (webDocument != null) {
operation = new FileLoadOperation(currentAccount, webDocument);
if (MessageObject.isVoiceWebDocument(webDocument)) {
if (webDocument.location != null) {
type = MEDIA_DIR_CACHE;
} else if (MessageObject.isVoiceWebDocument(webDocument)) {
type = MEDIA_DIR_AUDIO;
} else if (MessageObject.isVideoWebDocument(webDocument)) {
type = MEDIA_DIR_VIDEO;
@ -662,6 +669,14 @@ public class FileLoader extends BaseController {
type = MEDIA_DIR_DOCUMENT;
}
}
int queueType;
if (type == MEDIA_DIR_AUDIO) {
queueType = QUEUE_TYPE_AUDIO;
} else if (secureDocument != null || location != null && (imageLocation == null || imageLocation.imageType != IMAGE_TYPE_ANIMATION) || MessageObject.isImageWebDocument(webDocument)) {
queueType = QUEUE_TYPE_IMAGE;
} else {
queueType = QUEUE_TYPE_FILE;
}
if (cacheType == 0 || cacheType == 10) {
storeDir = getDirectory(type);
} else if (cacheType == 2) {
@ -881,8 +896,6 @@ public class FileLoader extends BaseController {
return getAttachFileName(sizeFull);
}
}
} else if (message.media instanceof TLRPC.TL_messageMediaInvoice) {
return getAttachFileName(((TLRPC.TL_messageMediaInvoice) message.media).photo);
}
} else if (message.media instanceof TLRPC.TL_messageMediaInvoice) {
TLRPC.WebDocument document = ((TLRPC.TL_messageMediaInvoice) message.media).photo;
@ -966,7 +979,7 @@ public class FileLoader extends BaseController {
}
} else if (attach instanceof TLRPC.Photo) {
TLRPC.PhotoSize photoSize = getClosestPhotoSizeWithSize(((TLRPC.Photo) attach).sizes, AndroidUtilities.getPhotoSize());
return getPathToAttach(photoSize, ext, forceCache);
return getPathToAttach(photoSize, ext, false);
} else if (attach instanceof TLRPC.PhotoSize) {
TLRPC.PhotoSize photoSize = (TLRPC.PhotoSize) attach;
if (photoSize instanceof TLRPC.TL_photoStrippedSize) {
@ -1127,15 +1140,13 @@ public class FileLoader extends BaseController {
public static String getAttachFileName(TLObject attach, String ext) {
if (attach instanceof TLRPC.Document) {
TLRPC.Document document = (TLRPC.Document) attach;
String docExt = null;
if (docExt == null) {
docExt = getDocumentFileName(document);
int idx;
if (docExt == null || (idx = docExt.lastIndexOf('.')) == -1) {
docExt = "";
} else {
docExt = docExt.substring(idx);
}
String docExt;
docExt = getDocumentFileName(document);
int idx;
if ((idx = docExt.lastIndexOf('.')) == -1) {
docExt = "";
} else {
docExt = docExt.substring(idx);
}
if (docExt.length() <= 1) {
docExt = getExtensionByMimeType(document.mime_type);

View File

@ -493,7 +493,7 @@ public class FileRefController extends BaseController {
TLRPC.TL_inputMediaPhoto mediaPhoto = (TLRPC.TL_inputMediaPhoto) req.media;
mediaPhoto.id.file_reference = file_reference;
}
AndroidUtilities.runOnUIThread(() -> getSendMessagesHelper().performSendMessageRequest((TLObject) requester.args[0], (MessageObject) requester.args[1], (String) requester.args[2], (SendMessagesHelper.DelayedMessage) requester.args[3], (Boolean) requester.args[4], (SendMessagesHelper.DelayedMessage) requester.args[5], null, (Boolean) requester.args[6]));
AndroidUtilities.runOnUIThread(() -> getSendMessagesHelper().performSendMessageRequest((TLObject) requester.args[0], (MessageObject) requester.args[1], (String) requester.args[2], (SendMessagesHelper.DelayedMessage) requester.args[3], (Boolean) requester.args[4], (SendMessagesHelper.DelayedMessage) requester.args[5], null, null, (Boolean) requester.args[6]));
} else if (requester.args[0] instanceof TLRPC.TL_messages_editMessage) {
TLRPC.TL_messages_editMessage req = (TLRPC.TL_messages_editMessage) requester.args[0];
if (req.media instanceof TLRPC.TL_inputMediaDocument) {
@ -503,7 +503,7 @@ public class FileRefController extends BaseController {
TLRPC.TL_inputMediaPhoto mediaPhoto = (TLRPC.TL_inputMediaPhoto) req.media;
mediaPhoto.id.file_reference = file_reference;
}
AndroidUtilities.runOnUIThread(() -> getSendMessagesHelper().performSendMessageRequest((TLObject) requester.args[0], (MessageObject) requester.args[1], (String) requester.args[2], (SendMessagesHelper.DelayedMessage) requester.args[3], (Boolean) requester.args[4], (SendMessagesHelper.DelayedMessage) requester.args[5], null, (Boolean) requester.args[6]));
AndroidUtilities.runOnUIThread(() -> getSendMessagesHelper().performSendMessageRequest((TLObject) requester.args[0], (MessageObject) requester.args[1], (String) requester.args[2], (SendMessagesHelper.DelayedMessage) requester.args[3], (Boolean) requester.args[4], (SendMessagesHelper.DelayedMessage) requester.args[5], null, null, (Boolean) requester.args[6]));
} else if (requester.args[0] instanceof TLRPC.TL_messages_saveGif) {
TLRPC.TL_messages_saveGif req = (TLRPC.TL_messages_saveGif) requester.args[0];
req.id.file_reference = file_reference;
@ -554,7 +554,7 @@ public class FileRefController extends BaseController {
AndroidUtilities.runOnUIThread(() -> getSendMessagesHelper().performSendMessageRequestMulti(req, (ArrayList<MessageObject>) objects[1], (ArrayList<String>) objects[2], null, (SendMessagesHelper.DelayedMessage) objects[4], (Boolean) objects[5]));
}
} else if (args[0] instanceof TLRPC.TL_messages_sendMedia || args[0] instanceof TLRPC.TL_messages_editMessage) {
AndroidUtilities.runOnUIThread(() -> getSendMessagesHelper().performSendMessageRequest((TLObject) args[0], (MessageObject) args[1], (String) args[2], (SendMessagesHelper.DelayedMessage) args[3], (Boolean) args[4], (SendMessagesHelper.DelayedMessage) args[5], null, (Boolean) args[6]));
AndroidUtilities.runOnUIThread(() -> getSendMessagesHelper().performSendMessageRequest((TLObject) args[0], (MessageObject) args[1], (String) args[2], (SendMessagesHelper.DelayedMessage) args[3], (Boolean) args[4], (SendMessagesHelper.DelayedMessage) args[5], null, null, (Boolean) args[6]));
} else if (args[0] instanceof TLRPC.TL_messages_saveGif) {
TLRPC.TL_messages_saveGif req = (TLRPC.TL_messages_saveGif) args[0];
//do nothing

View File

@ -620,9 +620,6 @@ public class FileUploadOperation {
startUploadRequest();
}
} else {
if (finalRequest != null) {
FileLog.e("23123");
}
state = 4;
delegate.didFailedUploadingFile(FileUploadOperation.this);
cleanup();

View File

@ -339,7 +339,7 @@ public class GcmPushListenerService extends FirebaseMessagingService {
name = args[1];
}
} else if (loc_key.startsWith("PINNED_")) {
supergroup = isGroup;
supergroup = channel_id != 0;
pinned = true;
} else if (loc_key.startsWith("CHANNEL_")) {
channel = true;
@ -469,6 +469,16 @@ public class GcmPushListenerService extends FirebaseMessagingService {
localMessage = true;
break;
}
case "MESSAGE_PLAYLIST": {
messageText = LocaleController.formatString("NotificationMessageFew", R.string.NotificationMessageFew, args[0], LocaleController.formatPluralString("MusicFiles", Utilities.parseInt(args[1])));
localMessage = true;
break;
}
case "MESSAGE_DOCS": {
messageText = LocaleController.formatString("NotificationMessageFew", R.string.NotificationMessageFew, args[0], LocaleController.formatPluralString("Files", Utilities.parseInt(args[1])));
localMessage = true;
break;
}
case "MESSAGES": {
messageText = LocaleController.formatString("NotificationMessageAlbum", R.string.NotificationMessageAlbum, args[0]);
localMessage = true;
@ -564,6 +574,16 @@ public class GcmPushListenerService extends FirebaseMessagingService {
localMessage = true;
break;
}
case "CHANNEL_MESSAGE_PLAYLIST": {
messageText = LocaleController.formatString("ChannelMessageFew", R.string.ChannelMessageFew, args[0], LocaleController.formatPluralString("MusicFiles", Utilities.parseInt(args[1])));
localMessage = true;
break;
}
case "CHANNEL_MESSAGE_DOCS": {
messageText = LocaleController.formatString("ChannelMessageFew", R.string.ChannelMessageFew, args[0], LocaleController.formatPluralString("Files", Utilities.parseInt(args[1])));
localMessage = true;
break;
}
case "CHANNEL_MESSAGES": {
messageText = LocaleController.formatString("ChannelMessageAlbum", R.string.ChannelMessageAlbum, args[0]);
localMessage = true;
@ -710,152 +730,234 @@ public class GcmPushListenerService extends FirebaseMessagingService {
localMessage = true;
break;
}
case "CHAT_MESSAGE_PLAYLIST": {
messageText = LocaleController.formatString("NotificationGroupFew", R.string.NotificationGroupFew, args[0], args[1], LocaleController.formatPluralString("MusicFiles", Utilities.parseInt(args[2])));
localMessage = true;
break;
}
case "CHAT_MESSAGE_DOCS": {
messageText = LocaleController.formatString("NotificationGroupFew", R.string.NotificationGroupFew, args[0], args[1], LocaleController.formatPluralString("Files", Utilities.parseInt(args[2])));
localMessage = true;
break;
}
case "CHAT_MESSAGES": {
messageText = LocaleController.formatString("NotificationGroupAlbum", R.string.NotificationGroupAlbum, args[0], args[1]);
localMessage = true;
break;
}
case "PINNED_TEXT": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedText", R.string.NotificationActionPinnedText, args[0], args[1], args[2]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedTextChannel", R.string.NotificationActionPinnedTextChannel, args[0], args[1]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedText", R.string.NotificationActionPinnedText, args[0], args[1], args[2]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedTextChannel", R.string.NotificationActionPinnedTextChannel, args[0], args[1]);
}
}
break;
}
case "PINNED_NOTEXT": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedNoText", R.string.NotificationActionPinnedNoText, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedNoTextUser", R.string.NotificationActionPinnedNoTextUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedNoTextChannel", R.string.NotificationActionPinnedNoTextChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedNoText", R.string.NotificationActionPinnedNoText, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedNoTextChannel", R.string.NotificationActionPinnedNoTextChannel, args[0]);
}
}
break;
}
case "PINNED_PHOTO": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedPhoto", R.string.NotificationActionPinnedPhoto, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedPhotoUser", R.string.NotificationActionPinnedPhotoUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedPhotoChannel", R.string.NotificationActionPinnedPhotoChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedPhoto", R.string.NotificationActionPinnedPhoto, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedPhotoChannel", R.string.NotificationActionPinnedPhotoChannel, args[0]);
}
}
break;
}
case "PINNED_VIDEO": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedVideo", R.string.NotificationActionPinnedVideo, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedVideoUser", R.string.NotificationActionPinnedVideoUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedVideoChannel", R.string.NotificationActionPinnedVideoChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedVideo", R.string.NotificationActionPinnedVideo, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedVideoChannel", R.string.NotificationActionPinnedVideoChannel, args[0]);
}
}
break;
}
case "PINNED_ROUND": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedRound", R.string.NotificationActionPinnedRound, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedRoundUser", R.string.NotificationActionPinnedRoundUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedRoundChannel", R.string.NotificationActionPinnedRoundChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedRound", R.string.NotificationActionPinnedRound, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedRoundChannel", R.string.NotificationActionPinnedRoundChannel, args[0]);
}
}
break;
}
case "PINNED_DOC": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedFile", R.string.NotificationActionPinnedFile, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedFileUser", R.string.NotificationActionPinnedFileUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedFileChannel", R.string.NotificationActionPinnedFileChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedFile", R.string.NotificationActionPinnedFile, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedFileChannel", R.string.NotificationActionPinnedFileChannel, args[0]);
}
}
break;
}
case "PINNED_STICKER": {
if (isGroup) {
if (args.length > 2 && !TextUtils.isEmpty(args[2])) {
messageText = LocaleController.formatString("NotificationActionPinnedStickerEmoji", R.string.NotificationActionPinnedStickerEmoji, args[0], args[2], args[1]);
if (dialogId > 0) {
if (args.length > 1 && !TextUtils.isEmpty(args[1])) {
messageText = LocaleController.formatString("NotificationActionPinnedStickerEmojiUser", R.string.NotificationActionPinnedStickerEmojiUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedSticker", R.string.NotificationActionPinnedSticker, args[0], args[1]);
messageText = LocaleController.formatString("NotificationActionPinnedStickerUser", R.string.NotificationActionPinnedStickerUser, args[0]);
}
} else {
if (args.length > 1 && !TextUtils.isEmpty(args[1])) {
messageText = LocaleController.formatString("NotificationActionPinnedStickerEmojiChannel", R.string.NotificationActionPinnedStickerEmojiChannel, args[0], args[1]);
if (isGroup) {
if (args.length > 2 && !TextUtils.isEmpty(args[2])) {
messageText = LocaleController.formatString("NotificationActionPinnedStickerEmoji", R.string.NotificationActionPinnedStickerEmoji, args[0], args[2], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedSticker", R.string.NotificationActionPinnedSticker, args[0], args[1]);
}
} else {
messageText = LocaleController.formatString("NotificationActionPinnedStickerChannel", R.string.NotificationActionPinnedStickerChannel, args[0]);
if (args.length > 1 && !TextUtils.isEmpty(args[1])) {
messageText = LocaleController.formatString("NotificationActionPinnedStickerEmojiChannel", R.string.NotificationActionPinnedStickerEmojiChannel, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedStickerChannel", R.string.NotificationActionPinnedStickerChannel, args[0]);
}
}
}
break;
}
case "PINNED_AUDIO": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedVoice", R.string.NotificationActionPinnedVoice, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedVoiceUser", R.string.NotificationActionPinnedVoiceUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedVoiceChannel", R.string.NotificationActionPinnedVoiceChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedVoice", R.string.NotificationActionPinnedVoice, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedVoiceChannel", R.string.NotificationActionPinnedVoiceChannel, args[0]);
}
}
break;
}
case "PINNED_CONTACT": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedContact2", R.string.NotificationActionPinnedContact2, args[0], args[2], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedContactUser", R.string.NotificationActionPinnedContactUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedContactChannel2", R.string.NotificationActionPinnedContactChannel2, args[0], args[1]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedContact2", R.string.NotificationActionPinnedContact2, args[0], args[2], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedContactChannel2", R.string.NotificationActionPinnedContactChannel2, args[0], args[1]);
}
}
break;
}
case "PINNED_QUIZ": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedQuiz2", R.string.NotificationActionPinnedQuiz2, args[0], args[2], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedQuizUser", R.string.NotificationActionPinnedQuizUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedQuizChannel2", R.string.NotificationActionPinnedQuizChannel2, args[0], args[1]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedQuiz2", R.string.NotificationActionPinnedQuiz2, args[0], args[2], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedQuizChannel2", R.string.NotificationActionPinnedQuizChannel2, args[0], args[1]);
}
}
break;
}
case "PINNED_POLL": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedPoll2", R.string.NotificationActionPinnedPoll2, args[0], args[2], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedPollUser", R.string.NotificationActionPinnedPollUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedPollChannel2", R.string.NotificationActionPinnedPollChannel2, args[0], args[1]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedPoll2", R.string.NotificationActionPinnedPoll2, args[0], args[2], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedPollChannel2", R.string.NotificationActionPinnedPollChannel2, args[0], args[1]);
}
}
break;
}
case "PINNED_GEO": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedGeo", R.string.NotificationActionPinnedGeo, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedGeoUser", R.string.NotificationActionPinnedGeoUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedGeoChannel", R.string.NotificationActionPinnedGeoChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedGeo", R.string.NotificationActionPinnedGeo, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedGeoChannel", R.string.NotificationActionPinnedGeoChannel, args[0]);
}
}
break;
}
case "PINNED_GEOLIVE": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedGeoLive", R.string.NotificationActionPinnedGeoLive, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedGeoLiveUser", R.string.NotificationActionPinnedGeoLiveUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedGeoLiveChannel", R.string.NotificationActionPinnedGeoLiveChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedGeoLive", R.string.NotificationActionPinnedGeoLive, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedGeoLiveChannel", R.string.NotificationActionPinnedGeoLiveChannel, args[0]);
}
}
break;
}
case "PINNED_GAME": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedGame", R.string.NotificationActionPinnedGame, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedGameUser", R.string.NotificationActionPinnedGameUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedGameChannel", R.string.NotificationActionPinnedGameChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedGame", R.string.NotificationActionPinnedGame, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedGameChannel", R.string.NotificationActionPinnedGameChannel, args[0]);
}
}
break;
}
case "PINNED_GAME_SCORE": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedGameScore", R.string.NotificationActionPinnedGameScore, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedGameScoreUser", R.string.NotificationActionPinnedGameScoreUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedGameScoreChannel", R.string.NotificationActionPinnedGameScoreChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedGameScore", R.string.NotificationActionPinnedGameScore, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedGameScoreChannel", R.string.NotificationActionPinnedGameScoreChannel, args[0]);
}
}
break;
}
case "PINNED_INVOICE": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedInvoice", R.string.NotificationActionPinnedInvoice, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedInvoiceUser", R.string.NotificationActionPinnedInvoiceUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedInvoiceChannel", R.string.NotificationActionPinnedInvoiceChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedInvoice", R.string.NotificationActionPinnedInvoice, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedInvoiceChannel", R.string.NotificationActionPinnedInvoiceChannel, args[0]);
}
}
break;
}
case "PINNED_GIF": {
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedGif", R.string.NotificationActionPinnedGif, args[0], args[1]);
if (dialogId > 0) {
messageText = LocaleController.formatString("NotificationActionPinnedGifUser", R.string.NotificationActionPinnedGifUser, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedGifChannel", R.string.NotificationActionPinnedGifChannel, args[0]);
if (isGroup) {
messageText = LocaleController.formatString("NotificationActionPinnedGif", R.string.NotificationActionPinnedGif, args[0], args[1]);
} else {
messageText = LocaleController.formatString("NotificationActionPinnedGifChannel", R.string.NotificationActionPinnedGifChannel, args[0]);
}
}
break;
}

View File

@ -38,6 +38,7 @@ import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.Point;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.SlotsDrawable;
import org.telegram.ui.Components.SvgHelper;
import org.telegram.ui.Components.ThemePreviewDrawable;
@ -828,7 +829,11 @@ public class ImageLoader {
}
RLottieDrawable lottieDrawable;
if (diceEmoji != null) {
lottieDrawable = new RLottieDrawable(diceEmoji, w, h);
if ("\uD83C\uDFB0".equals(diceEmoji)) {
lottieDrawable = new SlotsDrawable(diceEmoji, w, h);
} else {
lottieDrawable = new RLottieDrawable(diceEmoji, w, h);
}
} else {
lottieDrawable = new RLottieDrawable(cacheImage.finalFilePath, w, h, precache, limitFps, colors);
}
@ -1035,7 +1040,8 @@ public class ImageLoader {
int photoW2 = opts.outWidth;
int photoH2 = opts.outHeight;
opts.inJustDecodeBounds = false;
float scaleFactor = Math.max(photoW2 / 200, photoH2 / 200);
int screenSize = Math.max(66, Math.min(AndroidUtilities.getRealScreenSize().x, AndroidUtilities.getRealScreenSize().y));
float scaleFactor = (Math.min(photoH2, photoW2) / (float) screenSize) * 6f;
if (scaleFactor < 1) {
scaleFactor = 1;
}
@ -1043,7 +1049,7 @@ public class ImageLoader {
int sample = 1;
do {
sample *= 2;
} while (sample * 2 < scaleFactor);
} while (sample * 2 <= scaleFactor);
opts.inSampleSize = sample;
} else {
opts.inSampleSize = (int) scaleFactor;
@ -2345,7 +2351,7 @@ public class ImageLoader {
} else if (BuildVars.DEBUG_PRIVATE_VERSION) {
String name = FileLoader.getDocumentFileName(imageLocation.document);
if (name.endsWith(".svg")) {
img.imageType = FileLoader.IMAGE_TYPE_SVG_WHITE;
img.imageType = FileLoader.IMAGE_TYPE_SVG;
}
}
}
@ -2377,7 +2383,7 @@ public class ImageLoader {
} else if (BuildVars.DEBUG_PRIVATE_VERSION) {
String name = FileLoader.getDocumentFileName(imageLocation.document);
if (name.endsWith(".svg")) {
img.imageType = FileLoader.IMAGE_TYPE_SVG_WHITE;
img.imageType = FileLoader.IMAGE_TYPE_SVG;
}
}
fileSize = document.size;
@ -2466,6 +2472,37 @@ public class ImageLoader {
});
}
public void preloadArtwork(String athumbUrl) {
imageLoadQueue.postRunnable(() -> {
String ext = getHttpUrlExtension(athumbUrl, "jpg");
String url = Utilities.MD5(athumbUrl) + "." + ext;
File cacheFile = new File(FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE), url);
if (cacheFile.exists()) {
return;
}
ImageLocation imageLocation = ImageLocation.getForPath(athumbUrl);
CacheImage img = new CacheImage();
img.type = ImageReceiver.TYPE_THUMB;
img.key = Utilities.MD5(athumbUrl);
img.filter = null;
img.imageLocation = imageLocation;
img.ext = ext;
img.parentObject = null;
if (imageLocation.imageType != 0) {
img.imageType = imageLocation.imageType;
}
img.url = url;
imageLoadingByUrl.put(url, img);
String file = Utilities.MD5(imageLocation.path);
File cacheDir = FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE);
img.tempFilePath = new File(cacheDir, file + "_temp.jpg");
img.finalFilePath = cacheFile;
img.artworkTask = new ArtworkLoadTask(img);
artworkTasks.add(img.artworkTask);
runArtworkTasks(false);
});
}
public void loadImageForImageReceiver(ImageReceiver imageReceiver) {
if (imageReceiver == null) {
return;

View File

@ -620,7 +620,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
} else if (bitmap instanceof RLottieDrawable) {
RLottieDrawable fileDrawable = (RLottieDrawable) bitmap;
fileDrawable.addParentView(parentView);
if (allowStartLottieAnimation && currentOpenedLayerFlags == 0) {
if (allowStartLottieAnimation && (!fileDrawable.isHeavyDrawable() || currentOpenedLayerFlags == 0)) {
fileDrawable.start();
}
fileDrawable.setAllowDecodeSingleFrame(true);
@ -749,11 +749,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
setImage(temp.mediaLocation, temp.mediaFilter, temp.imageLocation, temp.imageFilter, temp.thumbLocation, temp.thumbFilter, temp.thumb, temp.size, temp.ext, temp.parentObject, temp.cacheType);
temp.clear();
setImageBackup = temp;
if (allowStartLottieAnimation && currentOpenedLayerFlags == 0) {
RLottieDrawable lottieDrawable = getLottieAnimation();
if (lottieDrawable != null) {
lottieDrawable.start();
}
RLottieDrawable lottieDrawable = getLottieAnimation();
if (lottieDrawable != null && allowStartLottieAnimation && (!lottieDrawable.isHeavyDrawable() || currentOpenedLayerFlags == 0)) {
lottieDrawable.start();
}
return true;
}
@ -769,11 +767,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (setBackupImage()) {
return true;
}
if (allowStartLottieAnimation && currentOpenedLayerFlags == 0) {
RLottieDrawable lottieDrawable = getLottieAnimation();
if (lottieDrawable != null) {
lottieDrawable.start();
}
RLottieDrawable lottieDrawable = getLottieAnimation();
if (lottieDrawable != null && allowStartLottieAnimation && (!lottieDrawable.isHeavyDrawable() || currentOpenedLayerFlags == 0)) {
lottieDrawable.start();
}
if (NotificationCenter.getGlobalInstance().isAnimationInProgress()) {
didReceivedNotification(NotificationCenter.stopAllHeavyOperations, currentAccount, 512);
@ -1122,6 +1118,14 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
}
public void skipDraw() {
RLottieDrawable lottieDrawable = getLottieAnimation();
if (lottieDrawable != null) {
lottieDrawable.setCurrentParentView(parentView);
lottieDrawable.updateCurrentFrame();
}
}
public boolean draw(Canvas canvas) {
try {
Drawable drawable = null;
@ -1890,7 +1894,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
} else if (drawable instanceof RLottieDrawable) {
RLottieDrawable fileDrawable = (RLottieDrawable) drawable;
fileDrawable.addParentView(parentView);
if (allowStartLottieAnimation && currentOpenedLayerFlags == 0) {
if (allowStartLottieAnimation && (!fileDrawable.isHeavyDrawable() || currentOpenedLayerFlags == 0)) {
fileDrawable.start();
}
fileDrawable.setAllowDecodeSingleFrame(true);
@ -2016,7 +2020,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentOpenedLayerFlags |= layer;
if (currentOpenedLayerFlags != 0) {
RLottieDrawable lottieDrawable = getLottieAnimation();
if (lottieDrawable != null) {
if (lottieDrawable != null && lottieDrawable.isHeavyDrawable()) {
lottieDrawable.stop();
}
}
@ -2028,7 +2032,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentOpenedLayerFlags &=~ layer;
if (currentOpenedLayerFlags == 0) {
RLottieDrawable lottieDrawable = getLottieAnimation();
if (allowStartLottieAnimation && lottieDrawable != null) {
if (allowStartLottieAnimation && lottieDrawable != null && lottieDrawable.isHeavyDrawable()) {
lottieDrawable.start();
}
}

View File

@ -233,9 +233,9 @@ public class LocaleController {
"nl", "nn", "no", "sv", "af", "bg", "bn", "ca", "eu", "fur", "fy", "gu", "ha", "is", "ku",
"lb", "ml", "mr", "nah", "ne", "om", "or", "pa", "pap", "ps", "so", "sq", "sw", "ta", "te",
"tk", "ur", "zu", "mn", "gsw", "chr", "rm", "pt", "an", "ast"}, new PluralRules_One());
addRules(new String[]{"cs", "sk"}, new PluralRules_Czech());
addRules(new String[]{"cs", "sk", "sr", "hr", "bs"}, new PluralRules_Czech());
addRules(new String[]{"ff", "fr", "kab"}, new PluralRules_French());
addRules(new String[]{"hr", "ru", "sr", "uk", "be", "bs", "sh"}, new PluralRules_Balkan());
addRules(new String[]{"ru", "uk", "be", "sh"}, new PluralRules_Balkan());
addRules(new String[]{"lv"}, new PluralRules_Latvian());
addRules(new String[]{"lt"}, new PluralRules_Lithuanian());
addRules(new String[]{"pl"}, new PluralRules_Polish());
@ -887,7 +887,7 @@ public class LocaleController {
currentLocale = newLocale;
currentLocaleInfo = localeInfo;
if (currentLocaleInfo != null && !TextUtils.isEmpty(currentLocaleInfo.pluralLangCode)) {
if (!TextUtils.isEmpty(currentLocaleInfo.pluralLangCode)) {
currentPluralRules = allRules.get(currentLocaleInfo.pluralLangCode);
}
if (currentPluralRules == null) {
@ -934,12 +934,21 @@ public class LocaleController {
}
private String getStringInternal(String key, int res) {
return getStringInternal(key, null, res);
}
private String getStringInternal(String key, String fallback, int res) {
String value = BuildVars.USE_CLOUD_STRINGS ? localeValues.get(key) : null;
if (value == null) {
try {
value = ApplicationLoader.applicationContext.getString(res);
} catch (Exception e) {
FileLog.e(e);
if (BuildVars.USE_CLOUD_STRINGS && fallback != null) {
value = localeValues.get(fallback);
}
if (value == null) {
try {
value = ApplicationLoader.applicationContext.getString(res);
} catch (Exception e) {
FileLog.e(e);
}
}
}
if (value == null) {
@ -963,6 +972,10 @@ public class LocaleController {
return getInstance().getStringInternal(key, res);
}
public static String getString(String key, String fallback, int res) {
return getInstance().getStringInternal(key, fallback, res);
}
public static String getString(String key) {
if (TextUtils.isEmpty(key)) {
return "LOC_ERR:" + key;
@ -981,7 +994,7 @@ public class LocaleController {
String param = getInstance().stringForQuantity(getInstance().currentPluralRules.quantityForNumber(plural));
param = key + "_" + param;
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName());
return getString(param, resourceId);
return getString(param, key + "_other", resourceId);
}
public static String formatPluralString(String key, int plural) {
@ -991,7 +1004,7 @@ public class LocaleController {
String param = getInstance().stringForQuantity(getInstance().currentPluralRules.quantityForNumber(plural));
param = key + "_" + param;
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName());
return formatString(param, resourceId, plural);
return formatString(param, key + "_other", resourceId, plural);
}
public static String formatPluralStringComma(String key, int plural) {
@ -1007,6 +1020,9 @@ public class LocaleController {
}
String value = BuildVars.USE_CLOUD_STRINGS ? getInstance().localeValues.get(param) : null;
if (value == null) {
value = BuildVars.USE_CLOUD_STRINGS ? getInstance().localeValues.get(key + "_other") : null;
}
if (value == null) {
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName());
value = ApplicationLoader.applicationContext.getString(resourceId);
@ -1025,10 +1041,19 @@ public class LocaleController {
}
public static String formatString(String key, int res, Object... args) {
return formatString(key, null, res, args);
}
public static String formatString(String key, String fallback, int res, Object... args) {
try {
String value = BuildVars.USE_CLOUD_STRINGS ? getInstance().localeValues.get(key) : null;
if (value == null) {
value = ApplicationLoader.applicationContext.getString(res);
if (BuildVars.USE_CLOUD_STRINGS && fallback != null) {
value = getInstance().localeValues.get(fallback);
}
if (value == null) {
value = ApplicationLoader.applicationContext.getString(res);
}
}
if (getInstance().currentLocale != null) {
@ -1790,12 +1815,10 @@ public class LocaleController {
valuesToSet.putAll(getLocaleFileStrings(localeInfo.getPathToFile()));
}
AndroidUtilities.runOnUIThread(() -> {
if (localeInfo != null) {
if (type == 0) {
localeInfo.version = difference.version;
} else {
localeInfo.baseVersion = difference.version;
}
if (type == 0) {
localeInfo.version = difference.version;
} else {
localeInfo.baseVersion = difference.version;
}
saveOtherLanguages();
try {
@ -1814,34 +1837,31 @@ public class LocaleController {
} else {
newLocale = new Locale(args[0], args[1]);
}
if (newLocale != null) {
languageOverride = localeInfo.shortName;
languageOverride = localeInfo.shortName;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putString("language", localeInfo.getKey());
editor.commit();
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putString("language", localeInfo.getKey());
editor.commit();
localeValues = valuesToSet;
currentLocale = newLocale;
currentLocaleInfo = localeInfo;
if (!TextUtils.isEmpty(currentLocaleInfo.pluralLangCode)) {
currentPluralRules = allRules.get(currentLocaleInfo.pluralLangCode);
}
if (newLocale != null) {
localeValues = valuesToSet;
currentLocale = newLocale;
currentLocaleInfo = localeInfo;
if (currentLocaleInfo != null && !TextUtils.isEmpty(currentLocaleInfo.pluralLangCode)) {
currentPluralRules = allRules.get(currentLocaleInfo.pluralLangCode);
}
if (currentPluralRules == null) {
currentPluralRules = allRules.get(currentLocale.getLanguage());
if (currentPluralRules == null) {
currentPluralRules = allRules.get(currentLocale.getLanguage());
if (currentPluralRules == null) {
currentPluralRules = allRules.get("en");
}
currentPluralRules = allRules.get("en");
}
changingConfiguration = true;
Locale.setDefault(currentLocale);
Configuration config = new Configuration();
config.locale = currentLocale;
ApplicationLoader.applicationContext.getResources().updateConfiguration(config, ApplicationLoader.applicationContext.getResources().getDisplayMetrics());
changingConfiguration = false;
}
changingConfiguration = true;
Locale.setDefault(currentLocale);
Configuration config = new Configuration();
config.locale = currentLocale;
ApplicationLoader.applicationContext.getResources().updateConfiguration(config, ApplicationLoader.applicationContext.getResources().getDisplayMetrics());
changingConfiguration = false;
}
} catch (Exception e) {
FileLog.e(e);
@ -1929,7 +1949,7 @@ public class LocaleController {
}
private void applyRemoteLanguage(LocaleInfo localeInfo, String langCode, boolean force, final int currentAccount) {
if (localeInfo == null || localeInfo != null && !localeInfo.isRemote() && !localeInfo.isUnofficial()) {
if (localeInfo == null || !localeInfo.isRemote() && !localeInfo.isUnofficial()) {
return;
}
if (localeInfo.hasBaseLang() && (langCode == null || langCode.equals(localeInfo.baseLangCode))) {
@ -2819,32 +2839,49 @@ public class LocaleController {
useImperialSystemType = null;
}
public static String formatDistance(float distance, int type) {
if (useImperialSystemType == null) {
if (SharedConfig.distanceSystemType == 0) {
try {
TelephonyManager telephonyManager = (TelephonyManager) ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
String country = telephonyManager.getSimCountryIso().toUpperCase();
useImperialSystemType = "US".equals(country) || "GB".equals(country) || "MM".equals(country) || "LR".equals(country);
}
} catch (Exception e) {
useImperialSystemType = false;
FileLog.e(e);
}
} else {
useImperialSystemType = SharedConfig.distanceSystemType == 2;
}
public static boolean getUseImperialSystemType() {
ensureImperialSystemInit();
return useImperialSystemType;
}
public static void ensureImperialSystemInit() {
if (useImperialSystemType != null) {
return;
}
if (useImperialSystemType) {
if (SharedConfig.distanceSystemType == 0) {
try {
TelephonyManager telephonyManager = (TelephonyManager) ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
String country = telephonyManager.getSimCountryIso().toUpperCase();
useImperialSystemType = "US".equals(country) || "GB".equals(country) || "MM".equals(country) || "LR".equals(country);
}
} catch (Exception e) {
useImperialSystemType = false;
FileLog.e(e);
}
} else {
useImperialSystemType = SharedConfig.distanceSystemType == 2;
}
}
public static String formatDistance(float distance, int type) {
return formatDistance(distance, type, null);
}
public static String formatDistance(float distance, int type, Boolean useImperial) {
ensureImperialSystemInit();
boolean imperial = useImperial != null && useImperial || useImperial == null && useImperialSystemType;
if (imperial) {
distance *= 3.28084f;
if (distance < 1000) {
switch (type) {
case 0:
return formatString("FootsAway", R.string.FootsAway, String.format("%d", (int) Math.max(1, distance)));
case 1:
default:
return formatString("FootsFromYou", R.string.FootsFromYou, String.format("%d", (int) Math.max(1, distance)));
case 2:
default:
return formatString("FootsShort", R.string.FootsShort, String.format("%d", (int) Math.max(1, distance)));
}
} else {
String arg;
@ -2857,8 +2894,10 @@ public class LocaleController {
case 0:
return formatString("MilesAway", R.string.MilesAway, arg);
case 1:
default:
return formatString("MilesFromYou", R.string.MilesFromYou, arg);
default:
case 2:
return formatString("MilesShort", R.string.MilesShort, arg);
}
}
@ -2868,8 +2907,10 @@ public class LocaleController {
case 0:
return formatString("MetersAway2", R.string.MetersAway2, String.format("%d", (int) Math.max(1, distance)));
case 1:
default:
return formatString("MetersFromYou2", R.string.MetersFromYou2, String.format("%d", (int) Math.max(1, distance)));
case 2:
default:
return formatString("MetersShort", R.string.MetersShort, String.format("%d", (int) Math.max(1, distance)));
}
} else {
String arg;
@ -2882,8 +2923,10 @@ public class LocaleController {
case 0:
return formatString("KMetersAway2", R.string.KMetersAway2, arg);
case 1:
default:
return formatString("KMetersFromYou2", R.string.KMetersFromYou2, arg);
case 2:
default:
return formatString("KMetersShort", R.string.KMetersShort, arg);
}
}
}

View File

@ -108,6 +108,8 @@ public class LocationController extends BaseController implements NotificationCe
public int stopTime;
public int period;
public int account;
public int proximityMeters;
public int lastSentProximityMeters;
public MessageObject messageObject;
}
@ -211,6 +213,11 @@ public class LocationController extends BaseController implements NotificationCe
if (!replaced) {
messages.add(messageObject.messageOwner);
}
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGeoProximityReached) {
int lowerId = (int) messageObject.getDialogId();
if (lowerId > 0) {
setProximityLocation(messageObject.getDialogId(), 0, false);
}
}
}
if (added) {
@ -379,7 +386,7 @@ public class LocationController extends BaseController implements NotificationCe
float[] result = new float[1];
for (int a = 0; a < sharingLocations.size(); a++) {
final SharingLocationInfo info = sharingLocations.get(a);
if (info.messageObject.messageOwner.media != null && info.messageObject.messageOwner.media.geo != null) {
if (info.messageObject.messageOwner.media != null && info.messageObject.messageOwner.media.geo != null && info.lastSentProximityMeters == info.proximityMeters) {
int messageDate = info.messageObject.messageOwner.edit_date != 0 ? info.messageObject.messageOwner.edit_date : info.messageObject.messageOwner.date;
TLRPC.GeoPoint point = info.messageObject.messageOwner.media.geo;
if (Math.abs(date - messageDate) < 10) {
@ -398,6 +405,16 @@ public class LocationController extends BaseController implements NotificationCe
req.media.geo_point = new TLRPC.TL_inputGeoPoint();
req.media.geo_point.lat = AndroidUtilities.fixLocationCoord(lastKnownLocation.getLatitude());
req.media.geo_point._long = AndroidUtilities.fixLocationCoord(lastKnownLocation.getLongitude());
req.media.geo_point.accuracy_radius = (int) lastKnownLocation.getAccuracy();
if (req.media.geo_point.accuracy_radius != 0) {
req.media.geo_point.flags |= 1;
}
if (info.lastSentProximityMeters != info.proximityMeters) {
req.media.proximity_notification_radius = info.proximityMeters;
req.media.flags |= 8;
}
req.media.heading = getHeading(lastKnownLocation);
req.media.flags |= 4;
final int[] reqId = new int[1];
reqId[0] = getConnectionsManager().sendRequest(req, (response, error) -> {
if (error != null) {
@ -417,6 +434,9 @@ public class LocationController extends BaseController implements NotificationCe
}
return;
}
if ((req.flags & 8) != 0) {
info.lastSentProximityMeters = req.media.proximity_notification_radius;
}
TLRPC.Updates updates = (TLRPC.Updates) response;
boolean updated = false;
for (int a1 = 0; a1 < updates.updates.size(); a1++) {
@ -563,11 +583,12 @@ public class LocationController extends BaseController implements NotificationCe
return cachedNearbyChats;
}
protected void addSharingLocation(long did, int mid, int period, TLRPC.Message message) {
protected void addSharingLocation(long did, int mid, int period, int radius, TLRPC.Message message) {
final SharingLocationInfo info = new SharingLocationInfo();
info.did = did;
info.mid = mid;
info.period = period;
info.lastSentProximityMeters = info.proximityMeters = radius;
info.account = currentAccount;
info.messageObject = new MessageObject(currentAccount, message, false, false);
info.stopTime = getConnectionsManager().getCurrentTime() + period;
@ -598,6 +619,41 @@ public class LocationController extends BaseController implements NotificationCe
return sharingLocationsMapUI.get(did);
}
public boolean setProximityLocation(long did, int meters, boolean broadcast) {
SharingLocationInfo info = sharingLocationsMapUI.get(did);
if (info != null) {
info.proximityMeters = meters;
}
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("UPDATE sharing_locations SET proximity = ? WHERE uid = ?");
state.requery();
state.bindInteger(1, meters);
state.bindLong(2, did);
state.step();
state.dispose();
} catch (Exception e) {
FileLog.e(e);
}
});
if (broadcast) {
Utilities.stageQueue.postRunnable(() -> broadcastLastKnownLocation(true));
}
return info != null;
}
public static int getHeading(Location location) {
float val = location.getBearing();
if (val > 0 && val < 1.0f) {
if (val < 0.5f) {
return 360;
} else {
return 1;
}
}
return (int) val;
}
private void loadSharingLocations() {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
final ArrayList<SharingLocationInfo> result = new ArrayList<>();
@ -606,13 +662,14 @@ public class LocationController extends BaseController implements NotificationCe
try {
ArrayList<Integer> usersToLoad = new ArrayList<>();
ArrayList<Integer> chatsToLoad = new ArrayList<>();
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized("SELECT uid, mid, date, period, message FROM sharing_locations WHERE 1");
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized("SELECT uid, mid, date, period, message, proximity FROM sharing_locations WHERE 1");
while (cursor.next()) {
SharingLocationInfo info = new SharingLocationInfo();
info.did = cursor.longValue(0);
info.mid = cursor.intValue(1);
info.stopTime = cursor.intValue(2);
info.period = cursor.intValue(3);
info.proximityMeters = cursor.intValue(5);
info.account = currentAccount;
NativeByteBuffer data = cursor.byteBufferValue(4);
if (data != null) {
@ -688,7 +745,7 @@ public class LocationController extends BaseController implements NotificationCe
if (info == null) {
return;
}
SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("REPLACE INTO sharing_locations VALUES(?, ?, ?, ?, ?)");
SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("REPLACE INTO sharing_locations VALUES(?, ?, ?, ?, ?, ?)");
state.requery();
NativeByteBuffer data = new NativeByteBuffer(info.messageObject.messageOwner.getObjectSize());
@ -699,6 +756,7 @@ public class LocationController extends BaseController implements NotificationCe
state.bindInteger(3, info.stopTime);
state.bindInteger(4, info.period);
state.bindByteBuffer(5, data);
state.bindInteger(6, info.proximityMeters);
state.step();
state.dispose();
@ -922,7 +980,7 @@ public class LocationController extends BaseController implements NotificationCe
return;
}
ArrayList<TLRPC.Message> messages = locationsCache.get(dialogId);
if (messages.isEmpty() || messages == null) {
if (messages == null || messages.isEmpty()) {
return;
}
Integer date = lastReadLocationTime.get(dialogId);
@ -977,9 +1035,7 @@ public class LocationController extends BaseController implements NotificationCe
callbacks.remove(callback);
}
if (location == null) {
if (callback != null) {
callback.onLocationAddressAvailable(null, null, null);
}
callback.onLocationAddressAvailable(null, null, null);
return;
}
@ -1084,9 +1140,7 @@ public class LocationController extends BaseController implements NotificationCe
final String displayNameFinal = displayName;
AndroidUtilities.runOnUIThread(() -> {
callbacks.remove(callback);
if (callback != null) {
callback.onLocationAddressAvailable(nameFinal, displayNameFinal, location);
}
callback.onLocationAddressAvailable(nameFinal, displayNameFinal, location);
});
}, 300);
callbacks.put(callback, fetchLocationRunnable);

View File

@ -94,6 +94,7 @@ public class LocationSharingService extends Service implements NotificationCente
}
String param;
ArrayList<LocationController.SharingLocationInfo> infos = getInfos();
String str;
if (infos.size() == 1) {
LocationController.SharingLocationInfo info = infos.get(0);
int lower_id = (int) info.messageObject.getDialogId();
@ -101,6 +102,7 @@ public class LocationSharingService extends Service implements NotificationCente
if (lower_id > 0) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(lower_id);
param = UserObject.getFirstName(user);
str = LocaleController.getString("AttachLiveLocationIsSharing", R.string.AttachLiveLocationIsSharing);
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-lower_id);
if (chat != null) {
@ -108,13 +110,15 @@ public class LocationSharingService extends Service implements NotificationCente
} else {
param = "";
}
str = LocaleController.getString("AttachLiveLocationIsSharingChat", R.string.AttachLiveLocationIsSharingChat);
}
} else {
param = LocaleController.formatPluralString("Chats", infos.size());
str = LocaleController.getString("AttachLiveLocationIsSharingChats", R.string.AttachLiveLocationIsSharingChats);
}
String str = String.format(LocaleController.getString("AttachLiveLocationIsSharing", R.string.AttachLiveLocationIsSharing), LocaleController.getString("AttachLiveLocation", R.string.AttachLiveLocation), param);
builder.setTicker(str);
builder.setContentText(str);
String text = String.format(str, LocaleController.getString("AttachLiveLocation", R.string.AttachLiveLocation), param);
builder.setTicker(text);
builder.setContentText(text);
if (post) {
NotificationManagerCompat.from(ApplicationLoader.applicationContext).notify(6, builder.build());
}

View File

@ -90,6 +90,7 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;
public class MediaController implements AudioManager.OnAudioFocusChangeListener, NotificationCenter.NotificationCenterDelegate, SensorEventListener {
@ -474,6 +475,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
private boolean isPaused = false;
private VideoPlayer audioPlayer = null;
private VideoPlayer emojiSoundPlayer = null;
private int emojiSoundPlayerNum = 0;
private boolean isStreamingCurrentAudio;
private int playerNum;
private String shouldSavePositionForCurrentAudio;
@ -2089,10 +2092,11 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
currentPlaylistNum = index;
playMusicAgain = true;
if (playingMessageObject != null) {
MessageObject messageObject = playlist.get(currentPlaylistNum);
if (playingMessageObject != null && !isSamePlayingMessage(messageObject)) {
playingMessageObject.resetPlayingProgress();
}
playMessage(playlist.get(currentPlaylistNum));
playMessage(messageObject);
}
private void playNextMessageWithoutOrder(boolean byStop) {
@ -2583,6 +2587,91 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}*/
}
public void playEmojiSound(AccountInstance accountInstance, String emoji, MessagesController.EmojiSound sound, boolean loadOnly) {
if (sound == null) {
return;
}
Utilities.stageQueue.postRunnable(() -> {
TLRPC.Document document = new TLRPC.TL_document();
document.access_hash = sound.accessHash;
document.id = sound.id;
document.mime_type = "sound/ogg";
document.file_reference = sound.fileReference;
document.dc_id = accountInstance.getConnectionsManager().getCurrentDatacenterId();
File file = FileLoader.getPathToAttach(document, true);
if (file.exists()) {
if (loadOnly) {
return;
}
AndroidUtilities.runOnUIThread(() -> {
try {
int tag = ++emojiSoundPlayerNum;
if (emojiSoundPlayer != null) {
emojiSoundPlayer.releasePlayer(true);
}
emojiSoundPlayer = new VideoPlayer(false);
emojiSoundPlayer.setDelegate(new VideoPlayer.VideoPlayerDelegate() {
@Override
public void onStateChanged(boolean playWhenReady, int playbackState) {
AndroidUtilities.runOnUIThread(() -> {
if (tag != emojiSoundPlayerNum) {
return;
}
if (playbackState == ExoPlayer.STATE_ENDED) {
if (emojiSoundPlayer != null) {
try {
emojiSoundPlayer.releasePlayer(true);
emojiSoundPlayer = null;
} catch (Exception e) {
FileLog.e(e);
}
}
}
});
}
@Override
public void onError(VideoPlayer player, Exception e) {
}
@Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
}
@Override
public void onRenderedFirstFrame() {
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
@Override
public boolean onSurfaceDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
});
emojiSoundPlayer.preparePlayer(Uri.fromFile(file), "other");
emojiSoundPlayer.setStreamType(AudioManager.STREAM_MUSIC);
emojiSoundPlayer.play();
} catch (Exception e) {
FileLog.e(e);
if (emojiSoundPlayer != null) {
emojiSoundPlayer.releasePlayer(true);
emojiSoundPlayer = null;
}
}
});
} else {
AndroidUtilities.runOnUIThread(() -> accountInstance.getFileLoader().loadFile(document, null, 1, 1));
}
});
}
public boolean playMessage(final MessageObject messageObject) {
if (messageObject == null) {
return false;
@ -3343,7 +3432,226 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
});
}
private static class MediaLoader implements NotificationCenter.NotificationCenterDelegate {
private AccountInstance currentAccount;
private AlertDialog progressDialog;
private ArrayList<MessageObject> messageObjects;
private HashMap<String, MessageObject> loadingMessageObjects = new HashMap<>();
private float finishedProgress;
private boolean cancelled;
private boolean finished;
private int copiedFiles;
private CountDownLatch waitingForFile;
private MessagesStorage.IntCallback onFinishRunnable;
private boolean isMusic;
public MediaLoader(Context context, AccountInstance accountInstance, ArrayList<MessageObject> messages, MessagesStorage.IntCallback onFinish) {
currentAccount = accountInstance;
messageObjects = messages;
onFinishRunnable = onFinish;
isMusic = messages.get(0).isMusic();
currentAccount.getNotificationCenter().addObserver(this, NotificationCenter.fileDidLoad);
currentAccount.getNotificationCenter().addObserver(this, NotificationCenter.FileLoadProgressChanged);
currentAccount.getNotificationCenter().addObserver(this, NotificationCenter.fileDidFailToLoad);
progressDialog = new AlertDialog(context, 2);
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(d -> cancelled = true);
}
public void start() {
AndroidUtilities.runOnUIThread(() -> {
if (!finished) {
progressDialog.show();
}
}, 250);
new Thread(() -> {
try {
File dir;
if (isMusic) {
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
} else {
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
}
dir.mkdir();
for (int b = 0, N = messageObjects.size(); b < N; b++) {
MessageObject message = messageObjects.get(b);
String name = message.getDocumentName();
File destFile = new File(dir, name);
if (destFile.exists()) {
int idx = name.lastIndexOf('.');
for (int a = 0; a < 10; a++) {
String newName;
if (idx != -1) {
newName = name.substring(0, idx) + "(" + (a + 1) + ")" + name.substring(idx);
} else {
newName = name + "(" + (a + 1) + ")";
}
destFile = new File(dir, newName);
if (!destFile.exists()) {
break;
}
}
}
if (!destFile.exists()) {
destFile.createNewFile();
}
String path = message.messageOwner.attachPath;
if (path != null && path.length() > 0) {
File temp = new File(path);
if (!temp.exists()) {
path = null;
}
}
if (path == null || path.length() == 0) {
path = FileLoader.getPathToMessage(message.messageOwner).toString();
}
File sourceFile = new File(path);
if (!sourceFile.exists()) {
waitingForFile = new CountDownLatch(1);
addMessageToLoad(message);
waitingForFile.await();
}
copyFile(sourceFile, destFile, message.getMimeType());
}
checkIfFinished();
} catch (Exception e) {
FileLog.e(e);
}
}).start();
}
private void checkIfFinished() {
if (!loadingMessageObjects.isEmpty()) {
return;
}
AndroidUtilities.runOnUIThread(() -> {
try {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
} else {
finished = true;
}
if (onFinishRunnable != null) {
AndroidUtilities.runOnUIThread(() -> onFinishRunnable.run(copiedFiles));
}
} catch (Exception e) {
FileLog.e(e);
}
currentAccount.getNotificationCenter().removeObserver(this, NotificationCenter.fileDidLoad);
currentAccount.getNotificationCenter().removeObserver(this, NotificationCenter.FileLoadProgressChanged);
currentAccount.getNotificationCenter().removeObserver(this, NotificationCenter.fileDidFailToLoad);
});
}
private void addMessageToLoad(MessageObject messageObject) {
AndroidUtilities.runOnUIThread(() -> {
TLRPC.Document document = messageObject.getDocument();
if (document == null) {
return;
}
String fileName = FileLoader.getAttachFileName(document);
loadingMessageObjects.put(fileName, messageObject);
currentAccount.getFileLoader().loadFile(document, messageObject, 1, 0);
});
}
private boolean copyFile(File sourceFile, File destFile, String mime) {
if (AndroidUtilities.isInternalUri(Uri.fromFile(sourceFile))) {
return false;
}
try (FileInputStream inputStream = new FileInputStream(sourceFile); FileChannel source = inputStream.getChannel(); FileChannel destination = new FileOutputStream(destFile).getChannel()) {
long size = source.size();
try {
@SuppressLint("DiscouragedPrivateApi") Method getInt = FileDescriptor.class.getDeclaredMethod("getInt$");
int fdint = (Integer) getInt.invoke(inputStream.getFD());
if (AndroidUtilities.isInternalUri(fdint)) {
if (progressDialog != null) {
AndroidUtilities.runOnUIThread(() -> {
try {
progressDialog.dismiss();
} catch (Exception e) {
FileLog.e(e);
}
});
}
return false;
}
} catch (Throwable e) {
FileLog.e(e);
}
long lastProgress = 0;
for (long a = 0; a < size; a += 4096) {
if (cancelled) {
break;
}
destination.transferFrom(source, a, Math.min(4096, size - a));
}
if (!cancelled) {
if (isMusic) {
AndroidUtilities.addMediaToGallery(Uri.fromFile(destFile));
} else {
DownloadManager downloadManager = (DownloadManager) ApplicationLoader.applicationContext.getSystemService(Context.DOWNLOAD_SERVICE);
downloadManager.addCompletedDownload(destFile.getName(), destFile.getName(), false, mime, destFile.getAbsolutePath(), destFile.length(), true);
}
finishedProgress += 100.0f / messageObjects.size();
final int progress = (int) (finishedProgress);
AndroidUtilities.runOnUIThread(() -> {
try {
progressDialog.setProgress(progress);
} catch (Exception e) {
FileLog.e(e);
}
});
copiedFiles++;
return true;
}
} catch (Exception e) {
FileLog.e(e);
}
destFile.delete();
return false;
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.fileDidLoad || id == NotificationCenter.fileDidFailToLoad) {
String fileName = (String) args[0];
if (loadingMessageObjects.remove(fileName) != null) {
waitingForFile.countDown();
}
} else if (id == NotificationCenter.FileLoadProgressChanged) {
String fileName = (String) args[0];
if (loadingMessageObjects.containsKey(fileName)) {
Long loadedSize = (Long) args[1];
Long totalSize = (Long) args[2];
float loadProgress = loadedSize / (float) totalSize;
final int progress = (int) (finishedProgress + loadProgress / messageObjects.size() * 100);
AndroidUtilities.runOnUIThread(() -> {
try {
progressDialog.setProgress(progress);
} catch (Exception e) {
FileLog.e(e);
}
});
}
}
}
}
public static void saveFilesFromMessages(Context context, AccountInstance accountInstance, ArrayList<MessageObject> messageObjects, final MessagesStorage.IntCallback onSaved) {
new MediaLoader(context, accountInstance, messageObjects, onSaved).start();
}
public static void saveFile(String fullPath, Context context, final int type, final String name, final String mime) {
saveFile(fullPath, context, type, name, mime, null);
}
public static void saveFile(String fullPath, Context context, final int type, final String name, final String mime, final Runnable onSaved) {
if (fullPath == null) {
return;
}
@ -3364,14 +3672,20 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
final boolean[] cancelled = new boolean[] {false};
if (sourceFile.exists()) {
AlertDialog progressDialog = null;
final boolean[] finished = new boolean[1];
if (context != null && type != 0) {
try {
progressDialog = new AlertDialog(context, 2);
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(dialog -> cancelled[0] = true);
progressDialog.show();
final AlertDialog dialog = new AlertDialog(context, 2);
dialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
dialog.setCanceledOnTouchOutside(false);
dialog.setCancelable(true);
dialog.setOnCancelListener(d -> cancelled[0] = true);
AndroidUtilities.runOnUIThread(() -> {
if (!finished[0]) {
dialog.show();
}
}, 250);
progressDialog = dialog;
} catch (Exception e) {
FileLog.e(e);
}
@ -3471,6 +3785,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
} else {
AndroidUtilities.addMediaToGallery(Uri.fromFile(destFile));
}
if (onSaved != null) {
AndroidUtilities.runOnUIThread(onSaved);
}
}
} catch (Exception e) {
FileLog.e(e);
@ -3478,7 +3795,11 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (finalProgress != null) {
AndroidUtilities.runOnUIThread(() -> {
try {
finalProgress.dismiss();
if (finalProgress.isShowing()) {
finalProgress.dismiss();
} else {
finished[0] = true;
}
} catch (Exception e) {
FileLog.e(e);
}

View File

@ -199,6 +199,7 @@ public class MediaDataController extends BaseController {
stickersLoaded[a] = false;
}
featuredStickerSets.clear();
loadingPinnedMessages.clear();
loadFeaturedDate = 0;
loadFeaturedHash = 0;
allStickers.clear();
@ -1871,7 +1872,7 @@ public class MediaDataController extends BaseController {
} else {
final StickerSetBulletinLayout bulletinLayout = new StickerSetBulletinLayout(context, stickerSetObject, toggle);
final int finalCurrentIndex = currentIndex;
final Bulletin.UndoButton undoButton = new Bulletin.UndoButton(context).setUndoAction(() -> {
final Bulletin.UndoButton undoButton = new Bulletin.UndoButton(context, false).setUndoAction(() -> {
stickerSet.archived = false;
stickerSets[type].add(finalCurrentIndex, messages_stickerSet);
@ -1999,6 +2000,7 @@ public class MediaDataController extends BaseController {
private int lastReqId;
private int lastGuid;
private TLRPC.User lastSearchUser;
private TLRPC.Chat lastSearchChat;
private int[] messagesSearchCount = new int[]{0, 0};
private boolean[] messagesSearchEndReached = new boolean[]{false, false};
private ArrayList<MessageObject> searchResultMessages = new ArrayList<>();
@ -2030,8 +2032,8 @@ public class MediaDataController extends BaseController {
return searchResultMessagesMap[mergeDialog ? 1 : 0].indexOfKey(messageId) >= 0;
}
public void searchMessagesInChat(String query, final long dialogId, final long mergeDialogId, final int guid, final int direction, int replyMessageId, TLRPC.User user) {
searchMessagesInChat(query, dialogId, mergeDialogId, guid, direction, replyMessageId, false, user, true);
public void searchMessagesInChat(String query, final long dialogId, final long mergeDialogId, final int guid, final int direction, int replyMessageId, TLRPC.User user, TLRPC.Chat chat) {
searchMessagesInChat(query, dialogId, mergeDialogId, guid, direction, replyMessageId, false, user, chat, true);
}
public void jumpToSearchedMessage(int guid, int index) {
@ -2049,12 +2051,12 @@ public class MediaDataController extends BaseController {
}
int temp = searchResultMessages.size();
lastReturnedNum = searchResultMessages.size();
searchMessagesInChat(null, lastDialogId, lastMergeDialogId, lastGuid, 1, lastReplyMessageId, false, lastSearchUser, false);
searchMessagesInChat(null, lastDialogId, lastMergeDialogId, lastGuid, 1, lastReplyMessageId, false, lastSearchUser, lastSearchChat, false);
lastReturnedNum = temp;
loadingMoreSearchMessages = true;
}
private void searchMessagesInChat(String query, final long dialogId, final long mergeDialogId, final int guid, final int direction, int replyMessageId, final boolean internal, final TLRPC.User user, boolean jumpToMessage) {
private void searchMessagesInChat(String query, final long dialogId, final long mergeDialogId, final int guid, final int direction, int replyMessageId, final boolean internal, final TLRPC.User user, final TLRPC.Chat chat, boolean jumpToMessage) {
int max_id = 0;
long queryWithDialog = dialogId;
boolean firstQuery = !internal;
@ -2131,9 +2133,12 @@ public class MediaDataController extends BaseController {
req.peer = inputPeer;
lastMergeDialogId = mergeDialogId;
req.limit = 1;
req.q = query != null ? query : "";
req.q = query;
if (user != null) {
req.from_id = getMessagesController().getInputUser(user);
req.from_id = MessagesController.getInputPeer(user);
req.flags |= 1;
} else if (chat != null) {
req.from_id = MessagesController.getInputPeer(chat);
req.flags |= 1;
}
req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
@ -2144,7 +2149,7 @@ public class MediaDataController extends BaseController {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
messagesSearchEndReached[1] = res.messages.isEmpty();
messagesSearchCount[1] = res instanceof TLRPC.TL_messages_messagesSlice ? res.count : res.messages.size();
searchMessagesInChat(req.q, dialogId, mergeDialogId, guid, direction, replyMessageId, true, user, jumpToMessage);
searchMessagesInChat(req.q, dialogId, mergeDialogId, guid, direction, replyMessageId, true, user, chat, jumpToMessage);
}
}
}), ConnectionsManager.RequestFlagFailOnServerErrors);
@ -2163,12 +2168,16 @@ public class MediaDataController extends BaseController {
lastGuid = guid;
lastDialogId = dialogId;
lastSearchUser = user;
lastSearchChat = chat;
lastReplyMessageId = replyMessageId;
req.limit = 21;
req.q = query != null ? query : "";
req.offset_id = max_id;
if (user != null) {
req.from_id = getMessagesController().getInputUser(user);
req.from_id = MessagesController.getInputPeer(user);
req.flags |= 1;
} else if (chat != null) {
req.from_id = MessagesController.getInputPeer(chat);
req.flags |= 1;
}
if (lastReplyMessageId != 0) {
@ -2242,7 +2251,7 @@ public class MediaDataController extends BaseController {
}
}
if (queryWithDialogFinal == dialogId && messagesSearchEndReached[0] && mergeDialogId != 0 && !messagesSearchEndReached[1]) {
searchMessagesInChat(lastSearchQuery, dialogId, mergeDialogId, guid, 0, replyMessageId, true, user, jumpToMessage);
searchMessagesInChat(lastSearchQuery, dialogId, mergeDialogId, guid, 0, replyMessageId, true, user, chat, jumpToMessage);
}
}
}
@ -3629,35 +3638,102 @@ public class MediaDataController extends BaseController {
return 0;
};
public MessageObject loadPinnedMessage(final long dialogId, final int channelId, final int mid, boolean useQueue) {
private LongSparseArray<Boolean> loadingPinnedMessages = new LongSparseArray<>();
public void loadPinnedMessages(long dialogId, int maxId, int fallback) {
if (loadingPinnedMessages.indexOfKey(dialogId) >= 0) {
return;
}
loadingPinnedMessages.put(dialogId, true);
TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
req.peer = getMessagesController().getInputPeer((int) dialogId);
req.limit = 40;
req.offset_id = maxId;
req.q = "";
req.filter = new TLRPC.TL_inputMessagesFilterPinned();
getConnectionsManager().sendRequest(req, (response, error) -> {
ArrayList<Integer> ids = new ArrayList<>();
HashMap<Integer, MessageObject> messages = new HashMap<>();
int totalCount = 0;
boolean endReached;
if (response instanceof TLRPC.messages_Messages) {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
final SparseArray<TLRPC.User> usersDict = new SparseArray<>();
for (int a = 0; a < res.users.size(); a++) {
TLRPC.User user = res.users.get(a);
usersDict.put(user.id, user);
}
final SparseArray<TLRPC.Chat> chatsDict = new SparseArray<>();
for (int a = 0; a < res.chats.size(); a++) {
TLRPC.Chat chat = res.chats.get(a);
chatsDict.put(chat.id, chat);
}
getMessagesStorage().putUsersAndChats(res.users, res.chats, true, true);
getMessagesController().putUsers(res.users, false);
getMessagesController().putChats(res.chats, false);
for (int a = 0, N = res.messages.size(); a < N; a++) {
TLRPC.Message message = res.messages.get(a);
if (message instanceof TLRPC.TL_messageService || message instanceof TLRPC.TL_messageEmpty) {
continue;
}
ids.add(message.id);
messages.put(message.id, new MessageObject(currentAccount, message, usersDict, chatsDict, false, false));
}
if (fallback != 0 && ids.isEmpty()) {
ids.add(fallback);
}
endReached = res.messages.size() < req.limit;
totalCount = Math.max(res.count, res.messages.size());
} else {
if (fallback != 0) {
ids.add(fallback);
totalCount = 1;
}
endReached = false;
}
getMessagesStorage().updatePinnedMessages(dialogId, ids, true, totalCount, maxId, endReached, messages);
AndroidUtilities.runOnUIThread(() -> loadingPinnedMessages.remove(dialogId));
});
}
public ArrayList<MessageObject> loadPinnedMessages(long dialogId, int channelId, ArrayList<Integer> mids, boolean useQueue) {
if (useQueue) {
getMessagesStorage().getStorageQueue().postRunnable(() -> loadPinnedMessageInternal(dialogId, channelId, mid, false));
getMessagesStorage().getStorageQueue().postRunnable(() -> loadPinnedMessageInternal(dialogId, channelId, mids, false));
} else {
return loadPinnedMessageInternal(dialogId, channelId, mid, true);
return loadPinnedMessageInternal(dialogId, channelId, mids, true);
}
return null;
}
private MessageObject loadPinnedMessageInternal(final long dialogId, final int channelId, final int mid, boolean returnValue) {
private ArrayList<MessageObject> loadPinnedMessageInternal(long dialogId, int channelId, ArrayList<Integer> mids, boolean returnValue) {
try {
long messageId;
ArrayList<Integer> midsCopy = new ArrayList<>(mids);
CharSequence longIds;
if (channelId != 0) {
messageId = ((long) mid) | ((long) channelId) << 32;
StringBuilder builder = new StringBuilder();
for (int a = 0, N = mids.size(); a < N; a++) {
long messageId = ((long) mids.get(a)) | ((long) channelId) << 32;
if (builder.length() != 0) {
builder.append(",");
}
builder.append(messageId);
}
longIds = builder;
} else {
messageId = mid;
longIds = TextUtils.join(",", mids);
}
TLRPC.Message result = null;
ArrayList<TLRPC.Message> results = new ArrayList<>();
final ArrayList<TLRPC.User> users = new ArrayList<>();
final ArrayList<TLRPC.Chat> chats = new ArrayList<>();
ArrayList<Integer> usersToLoad = new ArrayList<>();
ArrayList<Integer> chatsToLoad = new ArrayList<>();
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid, date FROM messages WHERE mid = %d", messageId));
if (cursor.next()) {
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid, date FROM messages WHERE mid IN (%s)", longIds));
while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
result = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
TLRPC.Message result = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
result.readAttachPath(data, getUserConfig().clientUserId);
data.reuse();
if (result.action instanceof TLRPC.TL_messageActionHistoryClear) {
@ -3667,55 +3743,66 @@ public class MediaDataController extends BaseController {
result.date = cursor.intValue(2);
result.dialog_id = dialogId;
MessagesStorage.addUsersAndChatsFromMessage(result, usersToLoad, chatsToLoad);
results.add(result);
}
midsCopy.remove((Integer) result.id);
}
}
cursor.dispose();
if (result == null) {
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data FROM chat_pinned WHERE uid = %d", dialogId));
if (cursor.next()) {
if (!midsCopy.isEmpty()) {
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data FROM chat_pinned_v2 WHERE uid = %d AND mid IN (%s)", dialogId, TextUtils.join(",", midsCopy)));
while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
result = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
TLRPC.Message result = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
result.readAttachPath(data, getUserConfig().clientUserId);
data.reuse();
if (result.id != mid || result.action instanceof TLRPC.TL_messageActionHistoryClear) {
if (result.action instanceof TLRPC.TL_messageActionHistoryClear) {
result = null;
} else {
result.dialog_id = dialogId;
MessagesStorage.addUsersAndChatsFromMessage(result, usersToLoad, chatsToLoad);
results.add(result);
}
midsCopy.remove((Integer) result.id);
}
}
cursor.dispose();
}
if (result == null) {
if (!midsCopy.isEmpty()) {
if (channelId != 0) {
final TLRPC.TL_channels_getMessages req = new TLRPC.TL_channels_getMessages();
req.channel = getMessagesController().getInputChannel(channelId);
req.id.add(mid);
req.id = midsCopy;
getConnectionsManager().sendRequest(req, (response, error) -> {
boolean ok = false;
if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
removeEmptyMessages(messagesRes.messages);
if (!messagesRes.messages.isEmpty()) {
TLRPC.Chat chat = getMessagesController().getChat(channelId);
if (chat != null && chat.megagroup) {
for (int a = 0, N = messagesRes.messages.size(); a < N; a++) {
TLRPC.Message message = messagesRes.messages.get(a);
message.flags |= TLRPC.MESSAGE_FLAG_MEGAGROUP;
}
}
ImageLoader.saveMessagesThumbs(messagesRes.messages);
broadcastPinnedMessage(messagesRes.messages.get(0), messagesRes.users, messagesRes.chats, false, false);
broadcastPinnedMessage(messagesRes.messages, messagesRes.users, messagesRes.chats, false, false);
getMessagesStorage().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true);
savePinnedMessage(messagesRes.messages.get(0));
savePinnedMessages(dialogId, messagesRes.messages);
ok = true;
}
}
if (!ok) {
getMessagesStorage().updateChatPinnedMessage(channelId, 0);
getMessagesStorage().updatePinnedMessages(dialogId, req.id, false, -1, 0, false, null);
}
});
} else {
final TLRPC.TL_messages_getMessages req = new TLRPC.TL_messages_getMessages();
req.id.add(mid);
req.id = midsCopy;
getConnectionsManager().sendRequest(req, (response, error) -> {
boolean ok = false;
if (error == null) {
@ -3723,20 +3810,21 @@ public class MediaDataController extends BaseController {
removeEmptyMessages(messagesRes.messages);
if (!messagesRes.messages.isEmpty()) {
ImageLoader.saveMessagesThumbs(messagesRes.messages);
broadcastPinnedMessage(messagesRes.messages.get(0), messagesRes.users, messagesRes.chats, false, false);
broadcastPinnedMessage(messagesRes.messages, messagesRes.users, messagesRes.chats, false, false);
getMessagesStorage().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true);
savePinnedMessage(messagesRes.messages.get(0));
savePinnedMessages(dialogId, messagesRes.messages);
ok = true;
}
}
if (!ok) {
getMessagesStorage().updateChatPinnedMessage(channelId, 0);
getMessagesStorage().updatePinnedMessages(dialogId, req.id, false, -1, 0, false, null);
}
});
}
} else {
}
if (!results.isEmpty()) {
if (returnValue) {
return broadcastPinnedMessage(result, users, chats, true, returnValue);
return broadcastPinnedMessage(results, users, chats, true, true);
} else {
if (!usersToLoad.isEmpty()) {
getMessagesStorage().getUsersInternal(TextUtils.join(",", usersToLoad), users);
@ -3744,7 +3832,7 @@ public class MediaDataController extends BaseController {
if (!chatsToLoad.isEmpty()) {
getMessagesStorage().getChatsInternal(TextUtils.join(",", chatsToLoad), chats);
}
broadcastPinnedMessage(result, users, chats, true, false);
broadcastPinnedMessage(results, users, chats, true, false);
}
}
} catch (Exception e) {
@ -3753,29 +3841,26 @@ public class MediaDataController extends BaseController {
return null;
}
private void savePinnedMessage(final TLRPC.Message result) {
private void savePinnedMessages(long dialogId, ArrayList<TLRPC.Message> arrayList) {
if (arrayList.isEmpty()) {
return;
}
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
long dialogId;
if (result.peer_id.channel_id != 0) {
dialogId = -result.peer_id.channel_id;
} else if (result.peer_id.chat_id != 0) {
dialogId = -result.peer_id.chat_id;
} else if (result.peer_id.user_id != 0) {
dialogId = result.peer_id.user_id;
} else {
return;
}
getMessagesStorage().getDatabase().beginTransaction();
SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("REPLACE INTO chat_pinned VALUES(?, ?, ?)");
NativeByteBuffer data = new NativeByteBuffer(result.getObjectSize());
result.serializeToStream(data);
state.requery();
state.bindLong(1, dialogId);
state.bindInteger(2, result.id);
state.bindByteBuffer(3, data);
state.step();
data.reuse();
//SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("UPDATE chat_pinned_v2 SET data = ? WHERE uid = ? AND mid = ?");
SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("REPLACE INTO chat_pinned_v2 VALUES(?, ?, ?)");
for (int a = 0, N = arrayList.size(); a < N; a++) {
TLRPC.Message message = arrayList.get(a);
NativeByteBuffer data = new NativeByteBuffer(message.getObjectSize());
message.serializeToStream(data);
state.requery();
state.bindLong(1, dialogId);
state.bindInteger(2, message.id);
state.bindByteBuffer(3, data);
state.step();
data.reuse();
}
state.dispose();
getMessagesStorage().getDatabase().commitTransaction();
} catch (Exception e) {
@ -3784,7 +3869,10 @@ public class MediaDataController extends BaseController {
});
}
private MessageObject broadcastPinnedMessage(final TLRPC.Message result, final ArrayList<TLRPC.User> users, final ArrayList<TLRPC.Chat> chats, final boolean isCache, boolean returnValue) {
private ArrayList<MessageObject> broadcastPinnedMessage(final ArrayList<TLRPC.Message> results, final ArrayList<TLRPC.User> users, final ArrayList<TLRPC.Chat> chats, final boolean isCache, boolean returnValue) {
if (results.isEmpty()) {
return null;
}
final SparseArray<TLRPC.User> usersDict = new SparseArray<>();
for (int a = 0; a < users.size(); a++) {
TLRPC.User user = users.get(a);
@ -3795,13 +3883,24 @@ public class MediaDataController extends BaseController {
TLRPC.Chat chat = chats.get(a);
chatsDict.put(chat.id, chat);
}
ArrayList<MessageObject> messageObjects = new ArrayList<>();
if (returnValue) {
return new MessageObject(currentAccount, result, usersDict, chatsDict, false, false);
AndroidUtilities.runOnUIThread(() -> {
getMessagesController().putUsers(users, isCache);
getMessagesController().putChats(chats, isCache);
});
for (int a = 0, N = results.size(); a < N; a++) {
messageObjects.add(new MessageObject(currentAccount, results.get(a), usersDict, chatsDict, false, false));
}
return messageObjects;
} else {
AndroidUtilities.runOnUIThread(() -> {
getMessagesController().putUsers(users, isCache);
getMessagesController().putChats(chats, isCache);
getNotificationCenter().postNotificationName(NotificationCenter.pinnedMessageDidLoad, new MessageObject(currentAccount, result, usersDict, chatsDict, false, false));
for (int a = 0, N = results.size(); a < N; a++) {
messageObjects.add(new MessageObject(currentAccount, results.get(a), usersDict, chatsDict, false, false));
}
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.didLoadPinnedMessages, messageObjects.get(0).getDialogId(), null, true, messageObjects, null, 0, -1, false));
});
}
return null;
@ -3823,6 +3922,9 @@ public class MediaDataController extends BaseController {
final LongSparseArray<ArrayList<MessageObject>> replyMessageRandomOwners = new LongSparseArray<>();
for (int a = 0; a < messages.size(); a++) {
MessageObject messageObject = messages.get(a);
if (messageObject == null) {
continue;
}
if (messageObject.isReply() && messageObject.replyMessageObject == null) {
long id = messageObject.messageOwner.reply_to.reply_to_random_id;
ArrayList<MessageObject> messageObjects = replyMessageRandomOwners.get(id);
@ -3899,6 +4001,9 @@ public class MediaDataController extends BaseController {
final StringBuilder stringBuilder = new StringBuilder();
for (int a = 0; a < messages.size(); a++) {
MessageObject messageObject = messages.get(a);
if (messageObject == null) {
continue;
}
if (messageObject.getId() > 0 && messageObject.isReply() && messageObject.replyMessageObject == null) {
int id = messageObject.messageOwner.reply_to.reply_to_msg_id;
long messageId = id;
@ -4767,8 +4872,8 @@ public class MediaDataController extends BaseController {
FileLog.e(e);
}
}
SparseArray<TLRPC.Message> threads = draftMessages.get(did);
if (replyToMessage == null) {
SparseArray<TLRPC.Message> threads = draftMessages.get(did);
if (threads != null) {
threads.remove(threadId);
if (threads.size() == 0) {
@ -4781,7 +4886,6 @@ public class MediaDataController extends BaseController {
editor.remove("rt_" + did + "_" + threadId);
}
} else {
SparseArray<TLRPC.Message> threads = draftMessages.get(did);
if (threads == null) {
threads = new SparseArray<>();
draftMessages.put(did, threads);

View File

@ -119,6 +119,8 @@ public class MessageObject {
public boolean isRestrictedMessage;
public long loadedFileSize;
public boolean animateComments;
public boolean loadingCancelled;
public int stableId;
@ -167,6 +169,7 @@ public class MessageObject {
public CharSequence vCardData;
public ArrayList<String> highlightedWords;
public String messageTrimmedToHighlight;
static final String[] excludeWords = new String[] {
" vs. ",
@ -255,10 +258,7 @@ public class MessageObject {
if (nameEncoding != null && nameEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
byte[] bytes = AndroidUtilities.decodeQuotedPrintable(AndroidUtilities.getStringBytes(currentData.company));
if (bytes != null && bytes.length != 0) {
String decodedName = new String(bytes, nameCharset);
if (decodedName != null) {
currentData.company = decodedName;
}
currentData.company = new String(bytes, nameCharset);
}
}
currentData.company = currentData.company.replace(';', ' ');
@ -365,6 +365,7 @@ public class MessageObject {
public ArrayList<MessageObject> messages = new ArrayList<>();
public ArrayList<GroupedMessagePosition> posArray = new ArrayList<>();
public HashMap<MessageObject, GroupedMessagePosition> positions = new HashMap<>();
public boolean isDocuments;
private int maxSizeWidth = 800;
@ -418,6 +419,7 @@ public class MessageObject {
int maxX = 0;
boolean forceCalc = false;
boolean needShare = false;
boolean isMusic = false;
hasSibling = false;
hasCaption = false;
@ -431,6 +433,9 @@ public class MessageObject {
messageObject.messageOwner.from_id instanceof TLRPC.TL_peerUser && (messageObject.messageOwner.peer_id.channel_id != 0 || messageObject.messageOwner.peer_id.chat_id != 0 ||
messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGame || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaInvoice)
);
if (messageObject.isMusic() || messageObject.isDocument()) {
isDocuments = true;
}
}
TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize());
GroupedMessagePosition position = new GroupedMessagePosition();
@ -458,6 +463,28 @@ public class MessageObject {
hasCaption = true;
}
}
if (isDocuments) {
for (int a = 0; a < count; a++) {
GroupedMessagePosition pos = posArray.get(a);
pos.flags |= POSITION_FLAG_LEFT | POSITION_FLAG_RIGHT;
if (a == 0) {
pos.flags |= POSITION_FLAG_TOP;
} else if (a == count - 1) {
pos.flags |= POSITION_FLAG_BOTTOM;
pos.last = true;
}
pos.edge = true;
pos.aspectRatio = 1.0f;
pos.minX = 0;
pos.maxX = 0;
pos.minY = (byte) a;
pos.maxY = (byte) a;
pos.spanSize = 1000;
pos.pw = maxSizeWidth;
pos.ph = 100;
}
return;
}
if (needShare) {
maxSizeWidth -= 50;
@ -542,7 +569,7 @@ public class MessageObject {
position3.set(1, 1, 1, 1, width, secondHeight, POSITION_FLAG_RIGHT | POSITION_FLAG_BOTTOM);
maxX = 1;
}
} else if (count == 4) {
} else {
GroupedMessagePosition position1 = posArray.get(0);
GroupedMessagePosition position2 = posArray.get(1);
GroupedMessagePosition position3 = posArray.get(2);
@ -997,9 +1024,7 @@ public class MessageObject {
TLRPC.User fromUser = null;
if (event.user_id > 0) {
if (fromUser == null) {
fromUser = MessagesController.getInstance(currentAccount).getUser(event.user_id);
}
fromUser = MessagesController.getInstance(currentAccount).getUser(event.user_id);
}
Calendar rightNow = new GregorianCalendar();
@ -1168,10 +1193,8 @@ public class MessageObject {
n = new TLRPC.TL_chatBannedRights();
}
if (o.send_messages != n.send_messages) {
if (!added) {
rights.append('\n');
added = true;
}
rights.append('\n');
added = true;
rights.append('\n').append(!n.send_messages ? '+' : '-').append(' ');
rights.append(LocaleController.getString("EventLogRestrictedSendMessages", R.string.EventLogRestrictedSendMessages));
}
@ -1237,7 +1260,7 @@ public class MessageObject {
TLRPC.User whoUser = MessagesController.getInstance(currentAccount).getUser(event.action.prev_participant.user_id);
TLRPC.TL_chatBannedRights o = event.action.prev_participant.banned_rights;
TLRPC.TL_chatBannedRights n = event.action.new_participant.banned_rights;
if (chat.megagroup && (n == null || !n.view_messages || n != null && o != null && n.until_date != o.until_date)) {
if (chat.megagroup && (n == null || !n.view_messages || o != null && n.until_date != o.until_date)) {
StringBuilder rights;
StringBuilder bannedDuration;
if (n != null && !AndroidUtilities.isBannedForever(n)) {
@ -1291,10 +1314,8 @@ public class MessageObject {
n = new TLRPC.TL_chatBannedRights();
}
if (o.view_messages != n.view_messages) {
if (!added) {
rights.append('\n');
added = true;
}
rights.append('\n');
added = true;
rights.append('\n').append(!n.view_messages ? '+' : '-').append(' ');
rights.append(LocaleController.getString("EventLogRestrictedReadMessages", R.string.EventLogRestrictedReadMessages));
}
@ -1379,13 +1400,13 @@ public class MessageObject {
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionUpdatePinned) {
if (fromUser != null && fromUser.id == 136817688 && event.action.message.fwd_from != null && event.action.message.fwd_from.from_id instanceof TLRPC.TL_peerChannel) {
TLRPC.Chat channel = MessagesController.getInstance(currentAccount).getChat(event.action.message.fwd_from.from_id.channel_id);
if (event.action.message instanceof TLRPC.TL_messageEmpty) {
if (event.action.message instanceof TLRPC.TL_messageEmpty || !event.action.message.pinned) {
messageText = replaceWithLink(LocaleController.getString("EventLogUnpinnedMessages", R.string.EventLogUnpinnedMessages), "un1", channel);
} else {
messageText = replaceWithLink(LocaleController.getString("EventLogPinnedMessages", R.string.EventLogPinnedMessages), "un1", channel);
}
} else {
if (event.action.message instanceof TLRPC.TL_messageEmpty) {
if (event.action.message instanceof TLRPC.TL_messageEmpty || !event.action.message.pinned) {
messageText = replaceWithLink(LocaleController.getString("EventLogUnpinnedMessages", R.string.EventLogUnpinnedMessages), "un1", fromUser);
} else {
messageText = replaceWithLink(LocaleController.getString("EventLogPinnedMessages", R.string.EventLogPinnedMessages), "un1", fromUser);
@ -2110,6 +2131,9 @@ public class MessageObject {
}
public void measureInlineBotButtons() {
if (isRestrictedMessage) {
return;
}
wantedBotKeyboardWidth = 0;
if (messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup || messageOwner.reactions != null && !messageOwner.reactions.results.isEmpty()) {
Theme.createChatResources(null, true);
@ -2175,33 +2199,72 @@ public class MessageObject {
return localType != 0;
}
private TLRPC.User getUser(AbstractMap<Integer, TLRPC.User> users, SparseArray<TLRPC.User> sUsers, int uid) {
TLRPC.User user = null;
if (users != null) {
user = users.get(uid);
} else if (sUsers != null) {
user = sUsers.get(uid);
}
if (user == null) {
user = MessagesController.getInstance(currentAccount).getUser(uid);
}
return user;
}
private TLRPC.Chat getChat(AbstractMap<Integer, TLRPC.Chat> chats, SparseArray<TLRPC.Chat> sChats, int cid) {
TLRPC.Chat chat = null;
if (chats != null) {
chat = chats.get(cid);
} else if (sChats != null) {
chat = sChats.get(cid);
}
if (chat == null) {
chat = MessagesController.getInstance(currentAccount).getChat(cid);
}
return chat;
}
private void updateMessageText(AbstractMap<Integer, TLRPC.User> users, AbstractMap<Integer, TLRPC.Chat> chats, SparseArray<TLRPC.User> sUsers, SparseArray<TLRPC.Chat> sChats) {
TLRPC.User fromUser = null;
TLRPC.Chat fromChat = null;
if (messageOwner.from_id instanceof TLRPC.TL_peerUser) {
if (users != null) {
fromUser = users.get(messageOwner.from_id.user_id);
} else if (sUsers != null) {
fromUser = sUsers.get(messageOwner.from_id.user_id);
}
if (fromUser == null) {
fromUser = MessagesController.getInstance(currentAccount).getUser(messageOwner.from_id.user_id);
}
fromUser = getUser(users, sUsers, messageOwner.from_id.user_id);
} else if (messageOwner.from_id instanceof TLRPC.TL_peerChannel) {
if (chats != null) {
fromChat = chats.get(messageOwner.from_id.channel_id);
} else if (sChats != null) {
fromChat = sChats.get(messageOwner.from_id.channel_id);
}
if (fromChat == null) {
fromChat = MessagesController.getInstance(currentAccount).getChat(messageOwner.from_id.channel_id);
}
fromChat = getChat(chats, sChats, messageOwner.from_id.channel_id);
}
TLObject fromObject = fromUser != null ? fromUser : fromChat;
if (messageOwner instanceof TLRPC.TL_messageService) {
if (messageOwner.action != null) {
if (messageOwner.action instanceof TLRPC.TL_messageActionCustomAction) {
if (messageOwner.action instanceof TLRPC.TL_messageActionGeoProximityReached) {
TLRPC.TL_messageActionGeoProximityReached action = (TLRPC.TL_messageActionGeoProximityReached) messageOwner.action;
int fromId = getPeerId(action.from_id);
TLObject from;
if (fromId > 0) {
from = getUser(users, sUsers, fromId);
} else {
from = getChat(chats, sChats, -fromId);
}
int toId = getPeerId(action.to_id);
int selfUserId = UserConfig.getInstance(currentAccount).getClientUserId();
if (toId == selfUserId) {
messageText = replaceWithLink(LocaleController.formatString("ActionUserWithinRadius", R.string.ActionUserWithinRadius, LocaleController.formatDistance(action.distance, 2)), "un1", from);
} else {
TLObject to;
if (toId > 0) {
to = getUser(users, sUsers, toId);
} else {
to = getChat(chats, sChats, -toId);
}
if (fromId == selfUserId) {
messageText = replaceWithLink(LocaleController.formatString("ActionUserWithinYouRadius", R.string.ActionUserWithinYouRadius, LocaleController.formatDistance(action.distance, 2)), "un1", to);
} else {
messageText = replaceWithLink(LocaleController.formatString("ActionUserWithinOtherRadius", R.string.ActionUserWithinOtherRadius, LocaleController.formatDistance(action.distance, 2)), "un2", to);
messageText = replaceWithLink(messageText, "un1", from);
}
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionCustomAction) {
messageText = messageOwner.action.message;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionChatCreate) {
if (isOut()) {
@ -2625,7 +2688,7 @@ public class MessageObject {
messageText = LocaleController.getString("AttachGif", R.string.AttachGif);
} else {
String name = FileLoader.getDocumentFileName(getDocument());
if (name != null && name.length() > 0) {
if (!TextUtils.isEmpty(name)) {
messageText = name;
} else {
messageText = LocaleController.getString("AttachDocument", R.string.AttachDocument);
@ -2698,7 +2761,7 @@ public class MessageObject {
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
TLRPC.Document document = getDocument();
if (document != null && document.mime_type != null) {
if (isGifDocument(document)) {
if (isGifDocument(document, hasValidGroupId())) {
type = 8;
} else if (isSticker()) {
type = TYPE_STICKER;
@ -2808,7 +2871,11 @@ public class MessageObject {
}
public static boolean isGifDocument(TLRPC.Document document) {
return document != null /*&& !document.thumbs.isEmpty()*/ && document.mime_type != null && (document.mime_type.equals("image/gif") || isNewGifDocument(document));
return isGifDocument(document, false);
}
public static boolean isGifDocument(TLRPC.Document document, boolean hasGroup) {
return document != null && document.mime_type != null && (document.mime_type.equals("image/gif") && !hasGroup || isNewGifDocument(document));
}
public static boolean isDocumentHasThumb(TLRPC.Document document) {
@ -2856,7 +2923,7 @@ public class MessageObject {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
width = attribute.w;
height = attribute.w;
height = attribute.h;
round = attribute.round_message;
}
}
@ -2947,7 +3014,7 @@ public class MessageObject {
if (!update || photoThumbs == null) {
photoThumbs = new ArrayList<>();
photoThumbs.addAll(emojiAnimatedSticker.thumbs);
} else if (photoThumbs != null && !photoThumbs.isEmpty()) {
} else if (!photoThumbs.isEmpty()) {
updatePhotoSizeLocations(photoThumbs, emojiAnimatedSticker.thumbs);
}
photoThumbsObject = emojiAnimatedSticker;
@ -2982,7 +3049,7 @@ public class MessageObject {
if (!update || photoThumbs == null) {
photoThumbs = new ArrayList<>();
photoThumbs.addAll(document.thumbs);
} else if (photoThumbs != null && !photoThumbs.isEmpty()) {
} else if (!photoThumbs.isEmpty()) {
updatePhotoSizeLocations(photoThumbs, document.thumbs);
}
photoThumbsObject = document;
@ -3381,13 +3448,13 @@ public class MessageObject {
if (patternType == 1) {
if (ch == '@') {
url = new URLSpanNoUnderline("https://instagram.com/" + charSequence.subSequence(start + 1, end).toString());
} else if (ch == '#') {
} else {
url = new URLSpanNoUnderline("https://www.instagram.com/explore/tags/" + charSequence.subSequence(start + 1, end).toString());
}
} else if (patternType == 2) {
if (ch == '@') {
url = new URLSpanNoUnderline("https://twitter.com/" + charSequence.subSequence(start + 1, end).toString());
} else if (ch == '#') {
} else {
url = new URLSpanNoUnderline("https://twitter.com/hashtag/" + charSequence.subSequence(start + 1, end).toString());
}
} else {
@ -3465,7 +3532,7 @@ public class MessageObject {
}
public boolean hasValidGroupId() {
return getGroupId() != 0 && photoThumbs != null && !photoThumbs.isEmpty();
return getGroupId() != 0 && (photoThumbs != null && !photoThumbs.isEmpty() || isMusic() || isDocument());
}
public long getGroupIdForUse() {
@ -3481,16 +3548,20 @@ public class MessageObject {
}
public static void addLinks(boolean isOut, CharSequence messageText, boolean botCommands, boolean check) {
addLinks(isOut, messageText, botCommands, check, false);
}
public static void addLinks(boolean isOut, CharSequence messageText, boolean botCommands, boolean check, boolean internalOnly) {
if (messageText instanceof Spannable && containsUrls(messageText)) {
if (messageText.length() < 1000) {
try {
AndroidUtilities.addLinks((Spannable) messageText, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
AndroidUtilities.addLinks((Spannable) messageText, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS, internalOnly);
} catch (Exception e) {
FileLog.e(e);
}
} else {
try {
AndroidUtilities.addLinks((Spannable) messageText, Linkify.WEB_URLS);
AndroidUtilities.addLinks((Spannable) messageText, Linkify.WEB_URLS, internalOnly);
} catch (Exception e) {
FileLog.e(e);
}
@ -3648,7 +3719,7 @@ public class MessageObject {
b++;
N2++;
runs.add(b, r);
} else if (newRun.end >= run.end) {
} else {
TextStyleSpan.TextStyleRun r = new TextStyleSpan.TextStyleRun(newRun);
r.merge(run);
r.end = run.end;
@ -4608,7 +4679,7 @@ public class MessageObject {
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
return isGifDocument(message.media.webpage.document);
}
return message.media != null && isGifDocument(message.media.document);
return message.media != null && isGifDocument(message.media.document, message.grouped_id != 0);
}
public static boolean isRoundVideoMessage(TLRPC.Message message) {
@ -4903,6 +4974,10 @@ public class MessageObject {
return isMusicMessage(messageOwner);
}
public boolean isDocument() {
return getDocument() != null && !isVideo() && !isMusic() && !isVoice() && !isAnyKindOfSticker();
}
public boolean isVoice() {
return isVoiceMessage(messageOwner);
}
@ -4919,6 +4994,10 @@ public class MessageObject {
return isLiveLocationMessage(messageOwner);
}
public boolean isExpiredLiveLocation(int date) {
return messageOwner.date + messageOwner.media.period <= date;
}
public boolean isGame() {
return isGameMessage(messageOwner);
}
@ -5498,9 +5577,7 @@ public class MessageObject {
if (currentPhotoObject == null) {
return;
}
if (currentPhotoObject != null) {
mediaExists = FileLoader.getPathToAttach(currentPhotoObject, true).exists();
}
mediaExists = FileLoader.getPathToAttach(currentPhotoObject, true).exists();
} else if (type == 11) {
TLRPC.Photo photo = messageOwner.action.photo;
if (photo == null || photo.video_sizes.isEmpty()) {
@ -5530,15 +5607,12 @@ public class MessageObject {
searchForWords.addAll(Arrays.asList(words));
}
if (getDocument() != null) {
String fileName = FileLoader.getDocumentFileName(getDocument());
if (fileName != null) {
fileName = fileName.toLowerCase();
if (fileName.contains(query) && !foundWords.contains(query)) {
foundWords.add(query);
}
String[] words = fileName.split("\\P{L}+");
searchForWords.addAll(Arrays.asList(words));
String fileName = FileLoader.getDocumentFileName(getDocument()).toLowerCase();
if (fileName.contains(query) && !foundWords.contains(query)) {
foundWords.add(query);
}
String[] words = fileName.split("\\P{L}+");
searchForWords.addAll(Arrays.asList(words));
}
if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && messageOwner.media.webpage instanceof TLRPC.TL_webPage) {
@ -5600,7 +5674,22 @@ public class MessageObject {
}
if (!foundWords.isEmpty()) {
highlightedWords = foundWords;
if (messageOwner.message != null) {
String str = messageOwner.message.replace('\n', ' ').replaceAll(" +", " ").trim();
int lastIndex = str.length();
int startHighlightedIndex = str.toLowerCase().indexOf(foundWords.get(0));
int maxSymbols = 130;
if (startHighlightedIndex < 0) {
startHighlightedIndex = 0;
}
if (lastIndex > maxSymbols) {
int newStart = Math.max(0, startHighlightedIndex - maxSymbols / 2);
str = str.substring(newStart, Math.min(lastIndex, startHighlightedIndex - newStart + startHighlightedIndex + maxSymbols / 2));
}
messageTrimmedToHighlight = str;
}
}
}
public boolean hasHighlightedWords() {

View File

@ -86,7 +86,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 = 70;
private final static int LAST_DB_VERSION = 73;
public static MessagesStorage getInstance(int num) {
MessagesStorage localInstance = Instance[num];
@ -337,8 +337,8 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE user_settings(uid INTEGER PRIMARY KEY, info BLOB, pinned INTEGER)").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS user_settings_pinned_idx ON user_settings(uid, pinned) WHERE pinned != 0;").stepThis().dispose();
database.executeFast("CREATE TABLE chat_pinned(uid INTEGER PRIMARY KEY, pinned INTEGER, data BLOB)").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS chat_pinned_mid_idx ON chat_pinned(uid, pinned) WHERE pinned != 0;").stepThis().dispose();
database.executeFast("CREATE TABLE chat_pinned_v2(uid INTEGER, mid INTEGER, data BLOB, PRIMARY KEY (uid, mid));").stepThis().dispose();
database.executeFast("CREATE TABLE chat_pinned_count(uid INTEGER PRIMARY KEY, count INTEGER, end INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE chat_hints(did INTEGER, type INTEGER, rating REAL, date INTEGER, PRIMARY KEY(did, type))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS chat_hints_rating_idx ON chat_hints(rating);").stepThis().dispose();
@ -368,7 +368,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE bot_info(uid INTEGER PRIMARY KEY, info BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE pending_tasks(id INTEGER PRIMARY KEY, data BLOB);").stepThis().dispose();
database.executeFast("CREATE TABLE requested_holes(uid INTEGER, seq_out_start INTEGER, seq_out_end INTEGER, PRIMARY KEY (uid, seq_out_start, seq_out_end));").stepThis().dispose();
database.executeFast("CREATE TABLE sharing_locations(uid INTEGER PRIMARY KEY, mid INTEGER, date INTEGER, period INTEGER, message BLOB);").stepThis().dispose();
database.executeFast("CREATE TABLE sharing_locations(uid INTEGER PRIMARY KEY, mid INTEGER, date INTEGER, period INTEGER, message BLOB, proximity INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE emoji_keywords_v2(lang TEXT, keyword TEXT, emoji TEXT, PRIMARY KEY(lang, keyword, emoji));").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS emoji_keywords_v2_keyword ON emoji_keywords_v2(keyword);").stepThis().dispose();
@ -386,9 +386,6 @@ public class MessagesStorage extends BaseController {
//version
database.executeFast("PRAGMA user_version = " + LAST_DB_VERSION).stepThis().dispose();
//database.executeFast("CREATE TABLE secret_holes(uid INTEGER, seq_in INTEGER, seq_out INTEGER, data BLOB, PRIMARY KEY (uid, seq_in, seq_out));").stepThis().dispose();
//database.executeFast("CREATE TABLE attach_data(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
} else {
int version = database.executeInt("PRAGMA user_version");
if (BuildVars.LOGS_ENABLED) {
@ -685,8 +682,6 @@ public class MessagesStorage extends BaseController {
if (version == 30) {
database.executeFast("ALTER TABLE chat_settings_v2 ADD COLUMN pinned INTEGER default 0").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS chat_settings_pinned_idx ON chat_settings_v2(uid, pinned) WHERE pinned != 0;").stepThis().dispose();
database.executeFast("CREATE TABLE IF NOT EXISTS chat_pinned(uid INTEGER PRIMARY KEY, pinned INTEGER, data BLOB)").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS chat_pinned_mid_idx ON chat_pinned(uid, pinned) WHERE pinned != 0;").stepThis().dispose();
database.executeFast("CREATE TABLE IF NOT EXISTS users_data(uid INTEGER PRIMARY KEY, about TEXT)").stepThis().dispose();
database.executeFast("PRAGMA user_version = 31").stepThis().dispose();
version = 31;
@ -791,7 +786,6 @@ public class MessagesStorage extends BaseController {
version = 49;
}
if (version == 49) {
database.executeFast("DELETE FROM chat_pinned WHERE uid = 1").stepThis().dispose();
database.executeFast("CREATE TABLE IF NOT EXISTS user_settings(uid INTEGER PRIMARY KEY, info BLOB, pinned INTEGER)").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS user_settings_pinned_idx ON user_settings(uid, pinned) WHERE pinned != 0;").stepThis().dispose();
database.executeFast("PRAGMA user_version = 50").stepThis().dispose();
@ -910,6 +904,21 @@ public class MessagesStorage extends BaseController {
version = 70;
}
if (version == 70) {
database.executeFast("CREATE TABLE IF NOT EXISTS chat_pinned_v2(uid INTEGER, mid INTEGER, data BLOB, PRIMARY KEY (uid, mid));").stepThis().dispose();
database.executeFast("PRAGMA user_version = 71").stepThis().dispose();
version = 71;
}
if (version == 71) {
database.executeFast("ALTER TABLE sharing_locations ADD COLUMN proximity INTEGER default 0").stepThis().dispose();
database.executeFast("PRAGMA user_version = 72").stepThis().dispose();
version = 72;
}
if (version == 72) {
database.executeFast("CREATE TABLE IF NOT EXISTS chat_pinned_count(uid INTEGER PRIMARY KEY, count INTEGER, end INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 73").stepThis().dispose();
version = 73;
}
if (version == 73) {
}
} catch (Exception e) {
@ -2905,6 +2914,7 @@ public class MessagesStorage extends BaseController {
final ArrayList<Integer> mids = new ArrayList<>();
SQLiteCursor cursor = database.queryFinalized("SELECT data FROM messages WHERE uid = " + did);
ArrayList<File> filesToDelete = new ArrayList<>();
ArrayList<String> namesToDelete = new ArrayList<>();
ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
try {
while (cursor.next()) {
@ -2915,7 +2925,7 @@ public class MessagesStorage extends BaseController {
message.readAttachPath(data, getUserConfig().clientUserId);
if (UserObject.isReplyUser(did) && MessageObject.getPeerId(message.fwd_from.from_id) == fromId || MessageObject.getFromChatId(message) == fromId && message.id != 1) {
mids.add(message.id);
addFilesToDelete(message, filesToDelete, idsToDelete, false);
addFilesToDelete(message, filesToDelete, idsToDelete, namesToDelete, false);
}
}
data.reuse();
@ -2926,7 +2936,10 @@ public class MessagesStorage extends BaseController {
}
cursor.dispose();
deleteFromDownloadQueue(idsToDelete, true);
AndroidUtilities.runOnUIThread(() -> getMessagesController().markDialogMessageAsDeleted(mids, did));
AndroidUtilities.runOnUIThread(() -> {
getFileLoader().cancelLoadFiles(namesToDelete);
getMessagesController().markDialogMessageAsDeleted(mids, did);
});
markMessagesAsDeletedInternal(mids, channelId, false, false);
updateDialogsWithDeletedMessagesInternal(mids, null, channelId);
getFileLoader().deleteFiles(filesToDelete, 0);
@ -2939,7 +2952,7 @@ public class MessagesStorage extends BaseController {
});
}
private boolean addFilesToDelete(TLRPC.Message message, ArrayList<File> filesToDelete, ArrayList<Pair<Long, Integer>> ids, boolean forceCache) {
private boolean addFilesToDelete(TLRPC.Message message, ArrayList<File> filesToDelete, ArrayList<Pair<Long, Integer>> ids, ArrayList<String> namesToDelete, boolean forceCache) {
if (message == null) {
return false;
}
@ -2972,21 +2985,29 @@ public class MessagesStorage extends BaseController {
if (photo != null) {
for (int a = 0, N = photo.sizes.size(); a < N; a++) {
TLRPC.PhotoSize photoSize = photo.sizes.get(a);
String name = FileLoader.getAttachFileName(photoSize);
if (!TextUtils.isEmpty(name)) {
namesToDelete.add(name);
}
File file = FileLoader.getPathToAttach(photoSize);
if (file != null && file.toString().length() > 0) {
if (file.toString().length() > 0) {
filesToDelete.add(file);
}
}
return true;
} else if (document != null) {
String name = FileLoader.getAttachFileName(document);
if (!TextUtils.isEmpty(name)) {
namesToDelete.add(name);
}
File file = FileLoader.getPathToAttach(document, forceCache);
if (file != null && file.toString().length() > 0) {
if (file.toString().length() > 0) {
filesToDelete.add(file);
}
for (int a = 0, N = document.thumbs.size(); a < N; a++) {
TLRPC.PhotoSize photoSize = document.thumbs.get(a);
file = FileLoader.getPathToAttach(photoSize);
if (file != null && file.toString().length() > 0) {
if (file.toString().length() > 0) {
filesToDelete.add(file);
}
}
@ -3012,6 +3033,7 @@ public class MessagesStorage extends BaseController {
if ((int) did == 0 || messagesOnly == 2) {
SQLiteCursor cursor = database.queryFinalized("SELECT data FROM messages WHERE uid = " + did);
ArrayList<File> filesToDelete = new ArrayList<>();
ArrayList<String> namesToDelete = new ArrayList<>();
ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
try {
while (cursor.next()) {
@ -3020,7 +3042,7 @@ public class MessagesStorage extends BaseController {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.readAttachPath(data, getUserConfig().clientUserId);
data.reuse();
addFilesToDelete(message, filesToDelete, idsToDelete, false);
addFilesToDelete(message, filesToDelete, idsToDelete, namesToDelete, false);
}
}
} catch (Exception e) {
@ -3028,13 +3050,15 @@ public class MessagesStorage extends BaseController {
}
cursor.dispose();
deleteFromDownloadQueue(idsToDelete, true);
AndroidUtilities.runOnUIThread(() -> getFileLoader().cancelLoadFiles(namesToDelete));
getFileLoader().deleteFiles(filesToDelete, messagesOnly);
}
if (messagesOnly == 0 || messagesOnly == 3) {
database.executeFast("DELETE FROM dialogs WHERE did = " + did).stepThis().dispose();
database.executeFast("DELETE FROM chat_settings_v2 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM chat_pinned WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM chat_pinned_v2 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM chat_pinned_count WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM channel_users_v2 WHERE did = " + did).stepThis().dispose();
database.executeFast("DELETE FROM search_recent WHERE did = " + did).stepThis().dispose();
int lower_id = (int) did;
@ -3221,6 +3245,8 @@ public class MessagesStorage extends BaseController {
String ids = "(" + TextUtils.join(",", dids) + ")";
database.beginTransaction();
database.executeFast("DELETE FROM chat_pinned_count WHERE uid IN " + ids).stepThis().dispose();
database.executeFast("DELETE FROM chat_pinned_v2 WHERE uid IN " + ids).stepThis().dispose();
database.executeFast("DELETE FROM dialogs WHERE did IN " + ids).stepThis().dispose();
database.executeFast("DELETE FROM messages WHERE uid IN " + ids).stepThis().dispose();
database.executeFast("DELETE FROM polls WHERE 1").stepThis().dispose();
@ -3364,6 +3390,7 @@ public class MessagesStorage extends BaseController {
storageQueue.postRunnable(() -> {
try {
ArrayList<File> filesToDelete = new ArrayList<>();
ArrayList<String> namesToDelete = new ArrayList<>();
ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
final ArrayList<TLRPC.Message> messages = new ArrayList<>();
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid, date, uid FROM messages WHERE mid IN (%s)", TextUtils.join(",", mids)));
@ -3374,7 +3401,7 @@ public class MessagesStorage extends BaseController {
message.readAttachPath(data, getUserConfig().clientUserId);
data.reuse();
if (message.media != null) {
if (!addFilesToDelete(message, filesToDelete, idsToDelete, true)) {
if (!addFilesToDelete(message, filesToDelete, idsToDelete, namesToDelete, true)) {
continue;
} else {
if (message.media.document != null) {
@ -3451,6 +3478,7 @@ public class MessagesStorage extends BaseController {
}
});
}
AndroidUtilities.runOnUIThread(() -> getFileLoader().cancelLoadFiles(namesToDelete));
getFileLoader().deleteFiles(filesToDelete, 0);
} catch (Exception e) {
FileLog.e(e);
@ -4267,7 +4295,7 @@ public class MessagesStorage extends BaseController {
continue;
}
}
if (mutedDialogs.indexOfKey(did) >= 0 && filter.alwaysShow.indexOf(did) >= 0) {
if (mutedDialogs.indexOfKey(did) >= 0 && filter.alwaysShow.contains(did)) {
unreadCount--;
}
}
@ -4574,7 +4602,7 @@ public class MessagesStorage extends BaseController {
if (info instanceof TLRPC.TL_chatFull) {
info.participants = participants;
final TLRPC.ChatFull finalInfo = info;
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.chatInfoDidLoad, finalInfo, 0, false, null));
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.chatInfoDidLoad, finalInfo, 0, false));
SQLitePreparedStatement state = database.executeFast("REPLACE INTO chat_settings_v2 VALUES(?, ?, ?, ?)");
NativeByteBuffer data = new NativeByteBuffer(info.getObjectSize());
@ -4631,10 +4659,10 @@ public class MessagesStorage extends BaseController {
});
}
public void updateChannelUsers(final int channel_id, final ArrayList<TLRPC.ChannelParticipant> participants) {
public void updateChannelUsers(final int channelId, final ArrayList<TLRPC.ChannelParticipant> participants) {
storageQueue.postRunnable(() -> {
try {
long did = -channel_id;
long did = -channelId;
database.executeFast("DELETE FROM channel_users_v2 WHERE did = " + did).stepThis().dispose();
database.beginTransaction();
SQLitePreparedStatement state = database.executeFast("REPLACE INTO channel_users_v2 VALUES(?, ?, ?, ?)");
@ -4655,7 +4683,7 @@ public class MessagesStorage extends BaseController {
}
state.dispose();
database.commitTransaction();
loadChatInfo(channel_id, null, false, true);
loadChatInfo(channelId, true, null, false, true);
} catch (Exception e) {
FileLog.e(e);
}
@ -4724,12 +4752,16 @@ public class MessagesStorage extends BaseController {
});
}
public void loadUserInfo(TLRPC.User user, final boolean force, int classGuid) {
public void loadUserInfo(TLRPC.User user, final boolean force, int classGuid, int fromMessageId) {
if (user == null) {
return;
}
storageQueue.postRunnable(() -> {
MessageObject pinnedMessageObject = null;
HashMap<Integer, MessageObject> pinnedMessagesMap = new HashMap<>();
ArrayList<Integer> pinnedMessages = new ArrayList<>();
int totalPinnedCount = 0;
boolean pinnedEndReached = false;
TLRPC.UserFull info = null;
try {
SQLiteCursor cursor = database.queryFinalized("SELECT info, pinned FROM user_settings WHERE uid = " + user.id);
@ -4737,18 +4769,47 @@ public class MessagesStorage extends BaseController {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
info = TLRPC.UserFull.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
info.pinned_msg_id = cursor.intValue(1);
data.reuse();
}
}
cursor.dispose();
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT mid FROM chat_pinned_v2 WHERE uid = %d ORDER BY mid DESC", user.id));
while (cursor.next()) {
int id = cursor.intValue(0);
pinnedMessages.add(id);
pinnedMessagesMap.put(id, null);
}
cursor.dispose();
cursor = database.queryFinalized("SELECT count, end FROM chat_pinned_count WHERE uid = " + user.id);
if (cursor.next()) {
totalPinnedCount = cursor.intValue(0);
pinnedEndReached = cursor.intValue(1) != 0;
}
cursor.dispose();
if (info != null && info.pinned_msg_id != 0) {
pinnedMessageObject = getMediaDataController().loadPinnedMessage(user.id, 0, info.pinned_msg_id, false);
if (pinnedMessages.isEmpty() || info.pinned_msg_id > pinnedMessages.get(0)) {
pinnedMessages.clear();
pinnedMessages.add(info.pinned_msg_id);
pinnedMessagesMap.put(info.pinned_msg_id, null);
}
}
if (!pinnedMessages.isEmpty()) {
ArrayList<MessageObject> messageObjects = getMediaDataController().loadPinnedMessages(user.id, 0, pinnedMessages, false);
if (messageObjects != null) {
for (int a = 0, N = messageObjects.size(); a < N; a++) {
MessageObject messageObject = messageObjects.get(a);
pinnedMessagesMap.put(messageObject.getId(), messageObject);
}
}
}
} catch (Exception e) {
FileLog.e(e);
} finally {
getMessagesController().processUserInfo(user, info, true, force, pinnedMessageObject, classGuid);
getMessagesController().processUserInfo(user, info, true, force, classGuid, pinnedMessages, pinnedMessagesMap, totalPinnedCount, pinnedEndReached);
}
});
}
@ -4847,43 +4908,6 @@ public class MessagesStorage extends BaseController {
});
}
public void updateUserPinnedMessage(final int userId, final int messageId) {
storageQueue.postRunnable(() -> {
try {
SQLiteCursor cursor = database.queryFinalized("SELECT info, pinned FROM user_settings WHERE uid = " + userId);
TLRPC.UserFull info = null;
if (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
info = TLRPC.UserFull.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
info.pinned_msg_id = cursor.intValue(1);
}
}
cursor.dispose();
if (info instanceof TLRPC.UserFull) {
info.pinned_msg_id = messageId;
info.flags |= 64;
final TLRPC.UserFull finalInfo = info;
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.userInfoDidLoad, userId, finalInfo, null));
SQLitePreparedStatement state = database.executeFast("REPLACE INTO user_settings VALUES(?, ?, ?)");
NativeByteBuffer data = new NativeByteBuffer(info.getObjectSize());
info.serializeToStream(data);
state.bindInteger(1, userId);
state.bindByteBuffer(2, data);
state.bindInteger(3, info.pinned_msg_id);
state.step();
state.dispose();
data.reuse();
}
} catch (Exception e) {
FileLog.e(e);
}
});
}
public void updateChatOnlineCount(final int channelId, final int onlineCount) {
storageQueue.postRunnable(() -> {
try {
@ -4899,43 +4923,123 @@ public class MessagesStorage extends BaseController {
});
}
public void updateChatPinnedMessage(final int channelId, final int messageId) {
public void updatePinnedMessages(long dialogId, ArrayList<Integer> ids, boolean pin, int totalCount, int maxId, boolean end, HashMap<Integer, MessageObject> messages) {
storageQueue.postRunnable(() -> {
try {
SQLiteCursor cursor = database.queryFinalized("SELECT info, pinned, online FROM chat_settings_v2 WHERE uid = " + channelId);
TLRPC.ChatFull info = null;
if (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
info = TLRPC.ChatFull.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
info.pinned_msg_id = cursor.intValue(1);
info.online_count = cursor.intValue(2);
if (pin) {
database.beginTransaction();
int alreadyAdded = 0;
boolean endReached;
if (messages != null) {
if (maxId == 0) {
database.executeFast("DELETE FROM chat_pinned_v2 WHERE uid = " + dialogId).stepThis().dispose();
}
} else {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM chat_pinned_v2 WHERE uid = %d AND mid IN (%s)", dialogId, TextUtils.join(",", ids)));
alreadyAdded = cursor.next() ? cursor.intValue(0) : 0;
}
}
cursor.dispose();
if (info != null) {
if (info instanceof TLRPC.TL_channelFull) {
info.pinned_msg_id = messageId;
info.flags |= 32;
} else if (info instanceof TLRPC.TL_chatFull) {
info.pinned_msg_id = messageId;
info.flags |= 64;
SQLitePreparedStatement state = database.executeFast("REPLACE INTO chat_pinned_v2 VALUES(?, ?, ?)");
for (int a = 0, N = ids.size(); a < N; a++) {
Integer id = ids.get(a);
state.requery();
state.bindLong(1, dialogId);
state.bindInteger(2, id);
MessageObject message = null;
if (messages != null) {
message = messages.get(id);
}
NativeByteBuffer data = null;
if (message != null) {
data = new NativeByteBuffer(message.messageOwner.getObjectSize());
message.messageOwner.serializeToStream(data);
state.bindByteBuffer(3, data);
} else {
state.bindNull(3);
}
state.step();
if (data != null) {
data.reuse();
}
}
state.dispose();
database.commitTransaction();
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM chat_pinned_v2 WHERE uid = %d", dialogId));
int newCount1 = cursor.next() ? cursor.intValue(0) : 0;
cursor.dispose();
int newCount;
if (messages != null) {
newCount = Math.max(totalCount, newCount1);
endReached = end;
} else {
SQLiteCursor cursor2 = database.queryFinalized(String.format(Locale.US, "SELECT count, end FROM chat_pinned_count WHERE uid = %d", dialogId));
int newCount2;
if (cursor2.next()) {
newCount2 = cursor2.intValue(0);
endReached = cursor2.intValue(1) != 0;
} else {
newCount2 = 0;
endReached = false;
}
cursor2.dispose();
newCount = Math.max(newCount2 + (ids.size() - alreadyAdded), newCount1);
}
final TLRPC.ChatFull finalInfo = info;
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.chatInfoDidLoad, finalInfo, 0, false, null));
SQLitePreparedStatement state = database.executeFast("REPLACE INTO chat_settings_v2 VALUES(?, ?, ?, ?)");
NativeByteBuffer data = new NativeByteBuffer(info.getObjectSize());
info.serializeToStream(data);
state.bindInteger(1, channelId);
state.bindByteBuffer(2, data);
state.bindInteger(3, info.pinned_msg_id);
state.bindInteger(4, info.online_count);
state = database.executeFast("REPLACE INTO chat_pinned_count VALUES(?, ?, ?)");
state.requery();
state.bindLong(1, dialogId);
state.bindInteger(2, newCount);
state.bindInteger(3, endReached ? 1 : 0);
state.step();
state.dispose();
data.reuse();
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.didLoadPinnedMessages, dialogId, ids, true, null, messages, maxId, newCount, endReached));
} else {
int newCount;
boolean endReached;
if (ids == null) {
database.executeFast("DELETE FROM chat_pinned_v2 WHERE uid = " + dialogId).stepThis().dispose();
if (dialogId < 0) {
database.executeFast("UPDATE chat_settings_v2 SET pinned = " + 0 + " WHERE uid = " + dialogId).stepThis().dispose();
} else {
database.executeFast("UPDATE user_settings SET pinned = " + 0 + " WHERE uid = " + dialogId).stepThis().dispose();
}
newCount = 0;
endReached = true;
} else {
database.executeFast(String.format("DELETE FROM chat_pinned_v2 WHERE uid = " + dialogId + " AND mid IN(%s)", TextUtils.join(",", ids))).stepThis().dispose();
SQLiteCursor cursor = database.queryFinalized("SELECT changes()");
int updatedCount = cursor.next() ? cursor.intValue(0) : 0;
cursor.dispose();
cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM chat_pinned_v2 WHERE uid = %d", dialogId));
int newCount1 = cursor.next() ? cursor.intValue(0) : 0;
cursor.dispose();
cursor = database.queryFinalized(String.format(Locale.US, "SELECT count, end FROM chat_pinned_count WHERE uid = %d", dialogId));
int newCount2;
if (cursor.next()) {
newCount2 = Math.max(0, cursor.intValue(0) - updatedCount);
endReached = cursor.intValue(1) != 0;
} else {
newCount2 = 0;
endReached = false;
}
cursor.dispose();
newCount = Math.max(newCount1, newCount2);
}
SQLitePreparedStatement state = database.executeFast("REPLACE INTO chat_pinned_count VALUES(?, ?, ?)");
state.requery();
state.bindLong(1, dialogId);
state.bindInteger(2, newCount);
state.bindInteger(3, endReached ? 1 : 0);
state.step();
state.dispose();
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.didLoadPinnedMessages, dialogId, ids, false, null, messages, maxId, newCount, endReached));
}
} catch (Exception e) {
FileLog.e(e);
@ -5000,7 +5104,7 @@ public class MessagesStorage extends BaseController {
info.participants.version = version;
final TLRPC.ChatFull finalInfo = info;
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.chatInfoDidLoad, finalInfo, 0, false, null));
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.chatInfoDidLoad, finalInfo, 0, false));
SQLitePreparedStatement state = database.executeFast("REPLACE INTO chat_settings_v2 VALUES(?, ?, ?, ?)");
NativeByteBuffer data = new NativeByteBuffer(info.getObjectSize());
@ -5055,12 +5159,17 @@ public class MessagesStorage extends BaseController {
return result[0];
}
private TLRPC.ChatFull loadChatInfoInternal(final int chat_id, final boolean force, final boolean byChannelUsers) {
MessageObject pinnedMessageObject = null;
private TLRPC.ChatFull loadChatInfoInternal(final int chatId, boolean isChannel, final boolean force, final boolean byChannelUsers, int fromMessageId) {
TLRPC.ChatFull info = null;
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
HashMap<Integer, MessageObject> pinnedMessagesMap = new HashMap<>();
ArrayList<Integer> pinnedMessages = new ArrayList<>();
int totalPinnedCount = 0;
boolean pinnedEndReached = false;
try {
SQLiteCursor cursor = database.queryFinalized("SELECT info, pinned, online FROM chat_settings_v2 WHERE uid = " + chat_id);
SQLiteCursor cursor = database.queryFinalized("SELECT info, pinned, online FROM chat_settings_v2 WHERE uid = " + chatId);
if (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
@ -5085,7 +5194,7 @@ public class MessagesStorage extends BaseController {
getUsersInternal(usersToLoad.toString(), loadedUsers);
}
} else if (info instanceof TLRPC.TL_channelFull) {
cursor = database.queryFinalized("SELECT us.data, us.status, cu.data, cu.date FROM channel_users_v2 as cu LEFT JOIN users as us ON us.uid = cu.uid WHERE cu.did = " + (-chat_id) + " ORDER BY cu.date DESC");
cursor = database.queryFinalized("SELECT us.data, us.status, cu.data, cu.date FROM channel_users_v2 as cu LEFT JOIN users as us ON us.uid = cu.uid WHERE cu.did = " + (-chatId) + " ORDER BY cu.date DESC");
info.participants = new TLRPC.TL_chatParticipants();
while (cursor.next()) {
try {
@ -5131,21 +5240,54 @@ public class MessagesStorage extends BaseController {
getUsersInternal(usersToLoad.toString(), loadedUsers);
}
}
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT mid FROM chat_pinned_v2 WHERE uid = %d ORDER BY mid DESC", -chatId));
while (cursor.next()) {
int id = cursor.intValue(0);
pinnedMessages.add(id);
pinnedMessagesMap.put(id, null);
}
cursor.dispose();
cursor = database.queryFinalized("SELECT count, end FROM chat_pinned_count WHERE uid = " + (-chatId));
if (cursor.next()) {
totalPinnedCount = cursor.intValue(0);
pinnedEndReached = cursor.intValue(1) != 0;
}
cursor.dispose();
if (info != null && info.pinned_msg_id != 0) {
pinnedMessageObject = getMediaDataController().loadPinnedMessage(-chat_id, info instanceof TLRPC.TL_channelFull ? chat_id : 0, info.pinned_msg_id, false);
if (pinnedMessages.isEmpty() || info.pinned_msg_id > pinnedMessages.get(0)) {
pinnedMessages.clear();
pinnedMessages.add(info.pinned_msg_id);
pinnedMessagesMap.put(info.pinned_msg_id, null);
}
}
if (!pinnedMessages.isEmpty()) {
ArrayList<MessageObject> messageObjects = getMediaDataController().loadPinnedMessages(-chatId, isChannel ? chatId : 0, pinnedMessages, false);
if (messageObjects != null) {
for (int a = 0, N = messageObjects.size(); a < N; a++) {
MessageObject messageObject = messageObjects.get(a);
pinnedMessagesMap.put(messageObject.getId(), messageObject);
}
}
}
} catch (Exception e) {
FileLog.e(e);
} finally {
getMessagesController().processChatInfo(chat_id, info, loadedUsers, true, force, byChannelUsers, pinnedMessageObject);
getMessagesController().processChatInfo(chatId, info, loadedUsers, true, force, byChannelUsers, pinnedMessages, pinnedMessagesMap, totalPinnedCount, pinnedEndReached);
}
return info;
}
public TLRPC.ChatFull loadChatInfo(final int chat_id, final CountDownLatch countDownLatch, final boolean force, final boolean byChannelUsers) {
public TLRPC.ChatFull loadChatInfo(int chatId, boolean isChannel, CountDownLatch countDownLatch, boolean force, boolean byChannelUsers) {
return loadChatInfo(chatId, isChannel, countDownLatch, force, byChannelUsers, 0);
}
public TLRPC.ChatFull loadChatInfo(int chatId, boolean isChannel, CountDownLatch countDownLatch, boolean force, boolean byChannelUsers, int fromMessageId) {
TLRPC.ChatFull[] result = new TLRPC.ChatFull[1];
storageQueue.postRunnable(() -> {
result[0] = loadChatInfoInternal(chat_id, force, byChannelUsers);
result[0] = loadChatInfoInternal(chatId, isChannel, force, byChannelUsers, fromMessageId);
if (countDownLatch != null) {
countDownLatch.countDown();
}
@ -6515,7 +6657,7 @@ public class MessagesStorage extends BaseController {
runnable.run();
};
} else {*/
return () -> getMessagesController().processLoadedMessages(res, dialogId, mergeDialogId, countQueryFinal, maxIdOverrideFinal, offset_date, true, classGuid, minUnreadIdFinal, lastMessageIdFinal, countUnreadFinal, maxUnreadDateFinal, load_type, isChannel, isEndFinal, scheduled, replyMessageId, loadIndex, queryFromServerFinal, mentionsUnreadFinal);
return () -> getMessagesController().processLoadedMessages(res, dialogId, mergeDialogId, countQueryFinal, maxIdOverrideFinal, offset_date, true, classGuid, minUnreadIdFinal, lastMessageIdFinal, countUnreadFinal, maxUnreadDateFinal, load_type, isChannel, isEndFinal, scheduled ? 1 : 0, replyMessageId, loadIndex, queryFromServerFinal, mentionsUnreadFinal);
//}
}
@ -6523,14 +6665,14 @@ public class MessagesStorage extends BaseController {
storageQueue.postRunnable(() -> {
long mergeDialogIdFinal = mergeDialogId;
int lowerId = (int) dialogId;
if (loadInfo) {
/*if (loadInfo) {
if (lowerId < 0) {
TLRPC.ChatFull info = loadChatInfoInternal(-lowerId, true, false);
TLRPC.ChatFull info = loadChatInfoInternal(-lowerId, true, false, 0);
if (info != null) {
mergeDialogIdFinal = -info.migrated_from_chat_id;
}
}
}
}*/
Utilities.stageQueue.postRunnable(getMessagesInternal(dialogId, mergeDialogIdFinal, count, max_id, offset_date, minDate, classGuid, load_type, isChannel, scheduled, replyMessageId, loadIndex));
});
}
@ -7272,7 +7414,7 @@ public class MessagesStorage extends BaseController {
Pair<Long, Integer> pair = ids.get(a);
state.requery();
state.bindLong(1, pair.first);
state.bindInteger(1, pair.second);
state.bindInteger(2, pair.second);
state.step();
}
state.dispose();
@ -7448,7 +7590,8 @@ public class MessagesStorage extends BaseController {
}
cursor.dispose();
database.executeFast("DELETE FROM chat_pinned_count WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM chat_pinned_v2 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM messages WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose();
database.executeFast("UPDATE media_counts_v2 SET old = 1 WHERE uid = " + did).stepThis().dispose();
@ -7638,9 +7781,7 @@ public class MessagesStorage extends BaseController {
public void updateRepliesMaxReadId(int chatId, int mid, int readMaxId, boolean useQueue) {
if (useQueue) {
storageQueue.postRunnable(() -> {
updateRepliesMaxReadIdInternal(chatId, mid, readMaxId);
});
storageQueue.postRunnable(() -> updateRepliesMaxReadIdInternal(chatId, mid, readMaxId));
} else {
updateRepliesMaxReadIdInternal(chatId, mid, readMaxId);
}
@ -8748,6 +8889,7 @@ public class MessagesStorage extends BaseController {
String ids;
final ArrayList<Integer> temp = new ArrayList<>(messages);
LongSparseArray<Integer[]> dialogsToUpdate = new LongSparseArray<>();
LongSparseArray<ArrayList<Integer>> messagesByDialogs = new LongSparseArray<>();
if (channelId != 0) {
StringBuilder builder = new StringBuilder(messages.size());
for (int a = 0; a < messages.size(); a++) {
@ -8763,6 +8905,7 @@ public class MessagesStorage extends BaseController {
ids = TextUtils.join(",", messages);
}
ArrayList<File> filesToDelete = new ArrayList<>();
ArrayList<String> namesToDelete = new ArrayList<>();
ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
int currentUser = getUserConfig().getClientUserId();
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, data, read_state, out, mention, mid FROM messages WHERE mid IN(%s)", ids));
@ -8772,6 +8915,12 @@ public class MessagesStorage extends BaseController {
long did = cursor.longValue(0);
int mid = cursor.intValue(5);
temp.remove((Integer) mid);
ArrayList<Integer> mids = messagesByDialogs.get(did);
if (mids == null) {
mids = new ArrayList<>();
messagesByDialogs.put(did, mids);
}
mids.add(mid);
if (did != currentUser) {
int read_state = cursor.intValue(2);
if (cursor.intValue(3) == 0) {
@ -8796,7 +8945,7 @@ public class MessagesStorage extends BaseController {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.readAttachPath(data, getUserConfig().clientUserId);
data.reuse();
addFilesToDelete(message, filesToDelete, idsToDelete, false);
addFilesToDelete(message, filesToDelete, idsToDelete, namesToDelete, false);
}
}
} catch (Exception e) {
@ -8804,6 +8953,7 @@ public class MessagesStorage extends BaseController {
}
cursor.dispose();
deleteFromDownloadQueue(idsToDelete, true);
AndroidUtilities.runOnUIThread(() -> getFileLoader().cancelLoadFiles(namesToDelete));
getFileLoader().deleteFiles(filesToDelete, 0);
for (int a = 0; a < dialogsToUpdate.size(); a++) {
@ -8829,6 +8979,30 @@ public class MessagesStorage extends BaseController {
state.dispose();
}
for (int a = 0, N = messagesByDialogs.size(); a < N; a++) {
long did = messagesByDialogs.keyAt(a);
ArrayList<Integer> mids = messagesByDialogs.valueAt(a);
database.executeFast(String.format(Locale.US, "DELETE FROM chat_pinned_v2 WHERE uid = %d AND mid IN(%s)", did, TextUtils.join(",", mids))).stepThis().dispose();
int updatedCount = 0;
cursor = database.queryFinalized("SELECT changes()");
if (cursor.next()) {
updatedCount = cursor.intValue(0);
}
cursor.dispose();
if (updatedCount > 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT count FROM chat_pinned_count WHERE uid = %d", did));
if (cursor.next()) {
int count = cursor.intValue(0);
SQLitePreparedStatement state = database.executeFast("UPDATE chat_pinned_count SET count = ? WHERE uid = ?");
state.requery();
state.bindInteger(1, Math.max(0, count - updatedCount));
state.bindLong(2, did);
state.step();
state.dispose();
}
cursor.dispose();
}
}
database.executeFast(String.format(Locale.US, "DELETE FROM messages WHERE mid IN(%s)", ids)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "DELETE FROM polls WHERE mid IN(%s)", ids)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "DELETE FROM bot_keyboard WHERE mid IN(%s)", ids)).stepThis().dispose();
@ -8965,11 +9139,11 @@ public class MessagesStorage extends BaseController {
NativeByteBuffer data = cursor.byteBufferValue(16);
if (data != null) {
dialogFolder.folder = TLRPC.TL_folder.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
} else {
dialogFolder.folder = new TLRPC.TL_folder();
dialogFolder.folder.id = cursor.intValue(15);
}
data.reuse();
}
dialog = dialogFolder;
} else {
@ -9043,7 +9217,7 @@ public class MessagesStorage extends BaseController {
}
if (!dialogs.dialogs.isEmpty() || !encryptedChats.isEmpty()) {
getMessagesController().processDialogsUpdate(dialogs, encryptedChats);
getMessagesController().processDialogsUpdate(dialogs, encryptedChats, true);
}
} catch (Exception e) {
FileLog.e(e);
@ -9082,6 +9256,7 @@ public class MessagesStorage extends BaseController {
maxMessageId |= ((long) channelId) << 32;
ArrayList<File> filesToDelete = new ArrayList<>();
ArrayList<String> namesToDelete = new ArrayList<>();
ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
int currentUser = getUserConfig().getClientUserId();
@ -9114,7 +9289,7 @@ public class MessagesStorage extends BaseController {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.readAttachPath(data, getUserConfig().clientUserId);
data.reuse();
addFilesToDelete(message, filesToDelete, idsToDelete, false);
addFilesToDelete(message, filesToDelete, idsToDelete, namesToDelete, false);
}
}
} catch (Exception e) {
@ -9123,6 +9298,7 @@ public class MessagesStorage extends BaseController {
cursor.dispose();
deleteFromDownloadQueue(idsToDelete, true);
AndroidUtilities.runOnUIThread(() -> getFileLoader().cancelLoadFiles(namesToDelete));
getFileLoader().deleteFiles(filesToDelete, 0);
for (int a = 0; a < dialogsToUpdate.size(); a++) {
@ -9148,6 +9324,27 @@ public class MessagesStorage extends BaseController {
state.dispose();
}
database.executeFast(String.format(Locale.US, "DELETE FROM chat_pinned_v2 WHERE uid = %d AND mid <= %d", -channelId, maxMessageId)).stepThis().dispose();
int updatedCount = 0;
cursor = database.queryFinalized("SELECT changes()");
if (cursor.next()) {
updatedCount = cursor.intValue(0);
}
cursor.dispose();
if (updatedCount > 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT count FROM chat_pinned_count WHERE uid = %d", -channelId));
if (cursor.next()) {
int count = cursor.intValue(0);
SQLitePreparedStatement state = database.executeFast("UPDATE chat_pinned_count SET count = ? WHERE uid = ?");
state.requery();
state.bindInteger(1, Math.max(0, count - updatedCount));
state.bindLong(2, -channelId);
state.step();
state.dispose();
}
cursor.dispose();
}
database.executeFast(String.format(Locale.US, "DELETE FROM messages WHERE uid = %d AND mid <= %d", -channelId, maxMessageId)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "DELETE FROM media_v2 WHERE uid = %d AND mid <= %d", -channelId, maxMessageId)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "UPDATE media_counts_v2 SET old = 1 WHERE uid = %d", -channelId)).stepThis().dispose();
@ -9572,6 +9769,7 @@ public class MessagesStorage extends BaseController {
//load_type == 3 ? load around message
//load_type == 4 ? load around date
ArrayList<File> filesToDelete = new ArrayList<>();
ArrayList<String> namesToDelete = new ArrayList<>();
ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?)");
@ -9612,7 +9810,7 @@ public class MessagesStorage extends BaseController {
sameMedia = oldMessage.media.document.id == message.media.document.id;
}
if (!sameMedia) {
addFilesToDelete(oldMessage, filesToDelete, idsToDelete, false);
addFilesToDelete(oldMessage, filesToDelete, idsToDelete, namesToDelete, false);
}
}
boolean oldMention = cursor.intValue(3) != 0;
@ -9786,6 +9984,7 @@ public class MessagesStorage extends BaseController {
getMediaDataController().putBotKeyboard(dialog_id, botKeyboard);
}
deleteFromDownloadQueue(idsToDelete, false);
AndroidUtilities.runOnUIThread(() -> getFileLoader().cancelLoadFiles(namesToDelete));
getFileLoader().deleteFiles(filesToDelete, 0);
putUsersInternal(messages.users);
putChatsInternal(messages.chats);
@ -9833,6 +10032,25 @@ public class MessagesStorage extends BaseController {
if (message.action.chat_id != 0 && !chatsToLoad.contains(message.action.chat_id)) {
chatsToLoad.add(message.action.chat_id);
}
if (message.action instanceof TLRPC.TL_messageActionGeoProximityReached) {
TLRPC.TL_messageActionGeoProximityReached action = (TLRPC.TL_messageActionGeoProximityReached) message.action;
Integer id = MessageObject.getPeerId(action.from_id);
if (id > 0) {
if (!usersToLoad.contains(id)) {
usersToLoad.add(id);
}
} else if (!chatsToLoad.contains(-id)) {
chatsToLoad.add(-id);
}
id = MessageObject.getPeerId(action.to_id);
if (id > 0) {
if (!usersToLoad.contains(id)) {
usersToLoad.add(id);
}
} else if (!chatsToLoad.contains(-id)) {
chatsToLoad.add(-id);
}
}
if (!message.action.users.isEmpty()) {
for (int a = 0; a < message.action.users.size(); a++) {
Integer uid = message.action.users.get(a);
@ -10799,6 +11017,9 @@ public class MessagesStorage extends BaseController {
try {
String savedMessages = LocaleController.getString("SavedMessages", R.string.SavedMessages).toLowerCase();
String search1 = query.trim().toLowerCase();
if (TextUtils.isEmpty(search1)) {
return;
}
String search2 = LocaleController.getInstance().getTranslitString(search1);
if (search1.equals(search2) || search2.length() == 0) {
search2 = null;
@ -10815,7 +11036,7 @@ public class MessagesStorage extends BaseController {
int resultCount = 0;
LongSparseArray<DialogsSearchAdapter.DialogSearchResult> dialogsResult = new LongSparseArray<>();
SQLiteCursor cursor = null;
SQLiteCursor cursor;
if (folderId >= 0) {
cursor = getDatabase().queryFinalized("SELECT did, date FROM dialogs WHERE folder_id = ? ORDER BY date DESC LIMIT 600", folderId);
} else {

View File

@ -22,7 +22,7 @@ import java.util.zip.ZipFile;
public class NativeLoader {
private final static int LIB_VERSION = 33;
private final static int LIB_VERSION = 34;
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

@ -13,6 +13,7 @@ import android.util.SparseArray;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class NotificationCenter {
@ -63,7 +64,7 @@ public class NotificationCenter {
public static final int didSetOrRemoveTwoStepPassword = totalEvents++;
public static final int didRemoveTwoStepPassword = totalEvents++;
public static final int replyMessagesDidLoad = totalEvents++;
public static final int pinnedMessageDidLoad = totalEvents++;
public static final int didLoadPinnedMessages = totalEvents++;
public static final int newSessionReceived = totalEvents++;
public static final int didReceivedWebpages = totalEvents++;
public static final int didReceivedWebpagesInUpdates = totalEvents++;
@ -74,6 +75,7 @@ public class NotificationCenter {
public static final int messagesReadContent = totalEvents++;
public static final int botInfoDidLoad = totalEvents++;
public static final int userInfoDidLoad = totalEvents++;
public static final int pinnedInfoDidLoad = totalEvents++;
public static final int botKeyboardDidLoad = totalEvents++;
public static final int chatSearchResultsAvailable = totalEvents++;
public static final int chatSearchResultsLoading = totalEvents++;
@ -201,6 +203,8 @@ public class NotificationCenter {
private SparseArray<ArrayList<NotificationCenterDelegate>> removeAfterBroadcast = new SparseArray<>();
private SparseArray<ArrayList<NotificationCenterDelegate>> addAfterBroadcast = new SparseArray<>();
private ArrayList<DelayedPost> delayedPosts = new ArrayList<>(10);
private ArrayList<Runnable> delayedRunnables = new ArrayList<>(10);
private ArrayList<Runnable> delayedRunnablesTmp = new ArrayList<>(10);
private ArrayList<DelayedPost> delayedPostsTmp = new ArrayList<>(10);
private ArrayList<PostponeNotificationCallback> postponeCallbackList = new ArrayList<>(10);
@ -209,6 +213,8 @@ public class NotificationCenter {
private int animationInProgressCount;
private int animationInProgressPointer = 1;
HashSet<Integer> heavyOperationsCounter = new HashSet<>();
private final HashMap<Integer, int[]> allowedNotifications = new HashMap<>();
public interface NotificationCenterDelegate {
@ -264,14 +270,21 @@ public class NotificationCenter {
}
public int setAnimationInProgress(int oldIndex, int[] allowedNotifications) {
return setAnimationInProgress(oldIndex, allowedNotifications, true);
}
public int setAnimationInProgress(int oldIndex, int[] allowedNotifications, boolean stopHeavyOperations) {
onAnimationFinish(oldIndex);
if (animationInProgressCount == 0) {
if (heavyOperationsCounter.isEmpty() && stopHeavyOperations) {
NotificationCenter.getGlobalInstance().postNotificationName(stopAllHeavyOperations, 512);
}
animationInProgressCount++;
animationInProgressPointer++;
if (stopHeavyOperations) {
heavyOperationsCounter.add(animationInProgressPointer);
}
if (allowedNotifications == null) {
allowedNotifications = new int[0];
}
@ -294,8 +307,13 @@ public class NotificationCenter {
int[] notifications = allowedNotifications.remove(index);
if (notifications != null) {
animationInProgressCount--;
if (!heavyOperationsCounter.isEmpty()) {
heavyOperationsCounter.remove(index);
if (heavyOperationsCounter.isEmpty()) {
NotificationCenter.getGlobalInstance().postNotificationName(startAllHeavyOperations, 512);
}
}
if (animationInProgressCount == 0) {
NotificationCenter.getGlobalInstance().postNotificationName(startAllHeavyOperations, 512);
runDelayedNotifications();
}
}
@ -312,6 +330,16 @@ public class NotificationCenter {
}
delayedPostsTmp.clear();
}
if (!delayedRunnables.isEmpty()) {
delayedRunnablesTmp.clear();
delayedRunnablesTmp.addAll(delayedRunnables);
delayedRunnables.clear();
for (int a = 0; a < delayedRunnablesTmp.size(); a++) {
delayedRunnablesTmp.get(a).run();
}
delayedRunnablesTmp.clear();
}
}
public boolean isAnimationInProgress() {
@ -327,7 +355,7 @@ public class NotificationCenter {
if (!allowDuringAnimation && !allowedNotifications.isEmpty()) {
int size = allowedNotifications.size();
int allowedCount = 0;
for(Integer key : allowedNotifications.keySet()) {
for (Integer key : allowedNotifications.keySet()) {
int[] allowed = allowedNotifications.get(key);
if (allowed != null) {
for (int a = 0; a < allowed.length; a++) {
@ -344,7 +372,7 @@ public class NotificationCenter {
}
if (id == startAllHeavyOperations) {
Integer flags = (Integer) args[0];
currentHeavyOperationFlags &=~ flags;
currentHeavyOperationFlags &= ~flags;
} else if (id == stopAllHeavyOperations) {
Integer flags = (Integer) args[0];
currentHeavyOperationFlags |= flags;
@ -483,4 +511,12 @@ public class NotificationCenter {
public interface PostponeNotificationCallback {
boolean needPostpone(int id, int currentAccount, Object[] args);
}
public void doOnIdle(Runnable runnable) {
if (isAnimationInProgress()) {
delayedRunnables.add(runnable);
} else {
runnable.run();
}
}
}

View File

@ -1242,12 +1242,13 @@ public class NotificationsController extends BaseController {
}
return messageObject.messageOwner.message;
}
int selfUsedId = getUserConfig().getClientUserId();
if (fromId == 0) {
fromId = messageObject.getFromChatId();
if (fromId == 0) {
fromId = -chat_id;
}
} else if (fromId == getUserConfig().getClientUserId()) {
} else if (fromId == selfUsedId) {
fromId = messageObject.getFromChatId();
}
@ -1321,7 +1322,9 @@ public class NotificationsController extends BaseController {
if (dialogPreviewEnabled && (chat_id == 0 && fromId != 0 && preferences.getBoolean("EnablePreviewAll", true) || chat_id != 0 && (!isChannel && preferences.getBoolean("EnablePreviewGroup", true) || isChannel && preferences.getBoolean("EnablePreviewChannel", true)))) {
if (messageObject.messageOwner instanceof TLRPC.TL_messageService) {
userName[0] = null;
if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserJoined || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionContactSignUp) {
if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGeoProximityReached) {
return messageObject.messageText.toString();
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserJoined || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionContactSignUp) {
return LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, name);
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
return LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, name);
@ -1345,7 +1348,7 @@ public class NotificationsController extends BaseController {
if (messageObject.messageOwner.peer_id.channel_id != 0 && !chat.megagroup) {
return LocaleController.formatString("ChannelAddedByNotification", R.string.ChannelAddedByNotification, name, chat.title);
} else {
if (singleUserId == getUserConfig().getClientUserId()) {
if (singleUserId == selfUsedId) {
return LocaleController.formatString("NotificationInvitedToGroup", R.string.NotificationInvitedToGroup, name, chat.title);
} else {
TLRPC.User u2 = getMessagesController().getUser(singleUserId);
@ -1396,7 +1399,7 @@ public class NotificationsController extends BaseController {
}
}
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser) {
if (messageObject.messageOwner.action.user_id == getUserConfig().getClientUserId()) {
if (messageObject.messageOwner.action.user_id == selfUsedId) {
return LocaleController.formatString("NotificationGroupKickYou", R.string.NotificationGroupKickYou, name, chat.title);
} else if (messageObject.messageOwner.action.user_id == fromId) {
return LocaleController.formatString("NotificationGroupLeftMember", R.string.NotificationGroupLeftMember, name, chat.title);
@ -1490,7 +1493,7 @@ public class NotificationsController extends BaseController {
return LocaleController.formatString("NotificationActionPinnedNoText", R.string.NotificationActionPinnedNoText, name, chat.title);
}
}
} else {
} else if (chat != null) {
if (messageObject.replyMessageObject == null) {
return LocaleController.formatString("NotificationActionPinnedNoTextChannel", R.string.NotificationActionPinnedNoTextChannel, chat.title);
} else {
@ -1562,6 +1565,78 @@ public class NotificationsController extends BaseController {
return LocaleController.formatString("NotificationActionPinnedNoTextChannel", R.string.NotificationActionPinnedNoTextChannel, chat.title);
}
}
} else {
if (messageObject.replyMessageObject == null) {
return LocaleController.formatString("NotificationActionPinnedNoTextUser", R.string.NotificationActionPinnedNoTextUser, name);
} else {
MessageObject object = messageObject.replyMessageObject;
if (object.isMusic()) {
return LocaleController.formatString("NotificationActionPinnedMusicUser", R.string.NotificationActionPinnedMusicUser, name);
} else if (object.isVideo()) {
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
String message = "\uD83D\uDCF9 " + object.messageOwner.message;
return LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
} else {
return LocaleController.formatString("NotificationActionPinnedVideoUser", R.string.NotificationActionPinnedVideoUser, name);
}
} else if (object.isGif()) {
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
String message = "\uD83C\uDFAC " + object.messageOwner.message;
return LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
} else {
return LocaleController.formatString("NotificationActionPinnedGifUser", R.string.NotificationActionPinnedGifUser, name);
}
} else if (object.isVoice()) {
return LocaleController.formatString("NotificationActionPinnedVoiceUser", R.string.NotificationActionPinnedVoiceUser, name);
} else if (object.isRoundVideo()) {
return LocaleController.formatString("NotificationActionPinnedRoundUser", R.string.NotificationActionPinnedRoundUser, name);
} else if (object.isSticker() || object.isAnimatedSticker()) {
String emoji = object.getStickerEmoji();
if (emoji != null) {
return LocaleController.formatString("NotificationActionPinnedStickerEmojiUser", R.string.NotificationActionPinnedStickerEmojiUser, name, emoji);
} else {
return LocaleController.formatString("NotificationActionPinnedStickerUser", R.string.NotificationActionPinnedStickerUser, name);
}
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
String message = "\uD83D\uDCCE " + object.messageOwner.message;
return LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
} else {
return LocaleController.formatString("NotificationActionPinnedFileUser", R.string.NotificationActionPinnedFileUser, name);
}
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaGeo || object.messageOwner.media instanceof TLRPC.TL_messageMediaVenue) {
return LocaleController.formatString("NotificationActionPinnedGeoUser", R.string.NotificationActionPinnedGeoUser, name);
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaGeoLive) {
return LocaleController.formatString("NotificationActionPinnedGeoLiveUser", R.string.NotificationActionPinnedGeoLiveUser, name);
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaContact) {
TLRPC.TL_messageMediaContact mediaContact = (TLRPC.TL_messageMediaContact) object.messageOwner.media;
return LocaleController.formatString("NotificationActionPinnedContactUser", R.string.NotificationActionPinnedContactUser, name, ContactsController.formatName(mediaContact.first_name, mediaContact.last_name));
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaPoll) {
TLRPC.TL_messageMediaPoll mediaPoll = (TLRPC.TL_messageMediaPoll) object.messageOwner.media;
if (mediaPoll.poll.quiz) {
return LocaleController.formatString("NotificationActionPinnedQuizUser", R.string.NotificationActionPinnedQuizUser, name, mediaPoll.poll.question);
} else {
return LocaleController.formatString("NotificationActionPinnedPollUser", R.string.NotificationActionPinnedPollUser, name, mediaPoll.poll.question);
}
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
String message = "\uD83D\uDDBC " + object.messageOwner.message;
return LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
} else {
return LocaleController.formatString("NotificationActionPinnedPhotoUser", R.string.NotificationActionPinnedPhotoUser, name);
}
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaGame) {
return LocaleController.formatString("NotificationActionPinnedGameUser", R.string.NotificationActionPinnedGameUser, name);
} else if (object.messageText != null && object.messageText.length() > 0) {
CharSequence message = object.messageText;
if (message.length() > 20) {
message = message.subSequence(0, 20) + "...";
}
return LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
} else {
return LocaleController.formatString("NotificationActionPinnedNoTextUser", R.string.NotificationActionPinnedNoTextUser, name);
}
}
}
}
} else {
@ -1736,7 +1811,9 @@ public class NotificationsController extends BaseController {
if (chat_id == 0 && from_id != 0) {
if (dialogPreviewEnabled && preferences.getBoolean("EnablePreviewAll", true)) {
if (messageObject.messageOwner instanceof TLRPC.TL_messageService) {
if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserJoined || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionContactSignUp) {
if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGeoProximityReached) {
msg = messageObject.messageText.toString();
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserJoined || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionContactSignUp) {
msg = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, name);
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
msg = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, name);
@ -2004,7 +2081,7 @@ public class NotificationsController extends BaseController {
msg = LocaleController.formatString("NotificationActionPinnedNoText", R.string.NotificationActionPinnedNoText, name, chat.title);
}
}
} else {
} else if (chat != null) {
if (messageObject.replyMessageObject == null) {
msg = LocaleController.formatString("NotificationActionPinnedNoTextChannel", R.string.NotificationActionPinnedNoTextChannel, chat.title);
} else {
@ -2076,6 +2153,78 @@ public class NotificationsController extends BaseController {
msg = LocaleController.formatString("NotificationActionPinnedNoTextChannel", R.string.NotificationActionPinnedNoTextChannel, chat.title);
}
}
} else {
if (messageObject.replyMessageObject == null) {
msg = LocaleController.formatString("NotificationActionPinnedNoTextUser", R.string.NotificationActionPinnedNoTextUser, name);
} else {
MessageObject object = messageObject.replyMessageObject;
if (object.isMusic()) {
msg = LocaleController.formatString("NotificationActionPinnedMusicUser", R.string.NotificationActionPinnedMusicUser, name);
} else if (object.isVideo()) {
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
String message = "\uD83D\uDCF9 " + object.messageOwner.message;
msg = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
} else {
msg = LocaleController.formatString("NotificationActionPinnedVideoUser", R.string.NotificationActionPinnedVideoUser, name);
}
} else if (object.isGif()) {
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
String message = "\uD83C\uDFAC " + object.messageOwner.message;
msg = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
} else {
msg = LocaleController.formatString("NotificationActionPinnedGifUser", R.string.NotificationActionPinnedGifUser, name);
}
} else if (object.isVoice()) {
msg = LocaleController.formatString("NotificationActionPinnedVoiceUser", R.string.NotificationActionPinnedVoiceUser, name);
} else if (object.isRoundVideo()) {
msg = LocaleController.formatString("NotificationActionPinnedRoundUser", R.string.NotificationActionPinnedRoundUser, name);
} else if (object.isSticker() || object.isAnimatedSticker()) {
String emoji = object.getStickerEmoji();
if (emoji != null) {
msg = LocaleController.formatString("NotificationActionPinnedStickerEmojiUser", R.string.NotificationActionPinnedStickerEmojiUser, name, emoji);
} else {
msg = LocaleController.formatString("NotificationActionPinnedStickerUser", R.string.NotificationActionPinnedStickerUser, name);
}
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
String message = "\uD83D\uDCCE " + object.messageOwner.message;
msg = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
} else {
msg = LocaleController.formatString("NotificationActionPinnedFileUser", R.string.NotificationActionPinnedFileUser, name);
}
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaGeo || object.messageOwner.media instanceof TLRPC.TL_messageMediaVenue) {
msg = LocaleController.formatString("NotificationActionPinnedGeoUser", R.string.NotificationActionPinnedGeoUser, name);
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaGeoLive) {
msg = LocaleController.formatString("NotificationActionPinnedGeoLiveUser", R.string.NotificationActionPinnedGeoLiveUser, name);
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaContact) {
TLRPC.TL_messageMediaContact mediaContact = (TLRPC.TL_messageMediaContact) messageObject.messageOwner.media;
msg = LocaleController.formatString("NotificationActionPinnedContactUser", R.string.NotificationActionPinnedContactUser, name, ContactsController.formatName(mediaContact.first_name, mediaContact.last_name));
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaPoll) {
TLRPC.TL_messageMediaPoll mediaPoll = (TLRPC.TL_messageMediaPoll) object.messageOwner.media;
if (mediaPoll.poll.quiz) {
msg = LocaleController.formatString("NotificationActionPinnedQuizUser", R.string.NotificationActionPinnedQuizUser, name, mediaPoll.poll.question);
} else {
msg = LocaleController.formatString("NotificationActionPinnedPollUser", R.string.NotificationActionPinnedPollUser, name, mediaPoll.poll.question);
}
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
String message = "\uD83D\uDDBC " + object.messageOwner.message;
msg = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
} else {
msg = LocaleController.formatString("NotificationActionPinnedPhotoUser", R.string.NotificationActionPinnedPhotoUser, name);
}
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaGame) {
msg = LocaleController.formatString("NotificationActionPinnedGameUser", R.string.NotificationActionPinnedGameUser, name);
} else if (object.messageText != null && object.messageText.length() > 0) {
CharSequence message = object.messageText;
if (message.length() > 20) {
message = message.subSequence(0, 20) + "...";
}
msg = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
} else {
msg = LocaleController.formatString("NotificationActionPinnedNoTextUser", R.string.NotificationActionPinnedNoTextUser, name);
}
}
}
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGameScore) {
msg = messageObject.messageText.toString();
@ -3839,7 +3988,11 @@ public class NotificationsController extends BaseController {
}
}
if (!unsupportedNotificationShortcut()) {
ShortcutManagerCompat.removeDynamicShortcuts(ApplicationLoader.applicationContext, ids);
try {
ShortcutManagerCompat.removeDynamicShortcuts(ApplicationLoader.applicationContext, ids);
} catch (Exception e) {
FileLog.e(e);
}
}
for (int a = 0; a < oldIdsWear.size(); a++) {

View File

@ -299,6 +299,8 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
public TLRPC.EncryptedChat encryptedChat;
public VideoEditedInfo videoEditedInfo;
public boolean performMediaUpload;
public boolean retriedToSend;
public int topMessageId;
@ -377,7 +379,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
} else if (request.request instanceof TLRPC.TL_messages_sendMultiMedia) {
performSendMessageRequestMulti((TLRPC.TL_messages_sendMultiMedia) request.request, request.msgObjs, request.originalPaths, request.parentObjects, request.delayedMessage, request.scheduled);
} else {
performSendMessageRequest(request.request, request.msgObj, request.originalPath, request.delayedMessage, request.parentObject, request.scheduled);
performSendMessageRequest(request.request, request.msgObj, request.originalPath, request.delayedMessage, request.parentObject, null, request.scheduled);
}
}
requests = null;
@ -471,19 +473,19 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (file != null && media != null) {
if (message.type == 0) {
media.file = file;
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, message, true, null, message.parentObject, message.scheduled);
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, message, true, null, message.parentObject, null, message.scheduled);
} else if (message.type == 1) {
if (media.file == null) {
media.file = file;
if (media.thumb == null && message.photoSize != null && message.photoSize.location != null) {
performSendDelayedMessage(message);
} else {
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, null, message.parentObject, message.scheduled);
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, null, message.parentObject, null, message.scheduled);
}
} else {
media.thumb = file;
media.flags |= 4;
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, null, message.parentObject, message.scheduled);
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, null, message.parentObject, null, message.scheduled);
}
} else if (message.type == 2) {
if (media.file == null) {
@ -491,16 +493,16 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (media.thumb == null && message.photoSize != null && message.photoSize.location != null) {
performSendDelayedMessage(message);
} else {
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, null, message.parentObject, message.scheduled);
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, null, message.parentObject, null, message.scheduled);
}
} else {
media.thumb = file;
media.flags |= 4;
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, null, message.parentObject, message.scheduled);
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, null, message.parentObject, null, message.scheduled);
}
} else if (message.type == 3) {
media.file = file;
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, null, message.parentObject, message.scheduled);
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath, null, message.parentObject, null, message.scheduled);
} else if (message.type == 4) {
if (media instanceof TLRPC.TL_inputMediaUploadedDocument) {
if (media.file == null) {
@ -876,6 +878,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
message.messageObjects.remove(index);
message.messages.remove(index);
message.originalPaths.remove(index);
message.parentObjects.remove(index);
if (message.sendRequest != null) {
TLRPC.TL_messages_sendMultiMedia request = (TLRPC.TL_messages_sendMultiMedia) message.sendRequest;
request.multi_media.remove(index);
@ -1114,7 +1117,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
arr.add(message);
getMessagesStorage().putMessages(arr, false, true, false, 0, false);
performSendMessageRequest(req, newMsgObj, null, null, null, false);
performSendMessageRequest(req, newMsgObj, null, null, null, null, false);
}
public void sendSticker(TLRPC.Document document, long peer, MessageObject replyToMsg, MessageObject replyToTopMsg, Object parentObject, boolean notify, int scheduleDate) {
@ -1339,8 +1342,8 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
}
if (msgObj.messageOwner.post_author != null) {
newMsg.fwd_from.post_author = msgObj.messageOwner.post_author;
newMsg.fwd_from.flags |= 8;
/*newMsg.fwd_from.post_author = msgObj.messageOwner.post_author;
newMsg.fwd_from.flags |= 8;*/
} else if (!msgObj.isOutOwner() && fromId > 0 && msgObj.messageOwner.post) {
TLRPC.User signUser = getMessagesController().getUser(fromId);
if (signUser != null) {
@ -1998,32 +2001,32 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
reqSend = request;
if (type == 1) {
performSendMessageRequest(reqSend, messageObject, null, delayedMessage, parentObject, messageObject.scheduled);
performSendMessageRequest(reqSend, messageObject, null, delayedMessage, parentObject, params, messageObject.scheduled);
} else if (type == 2) {
if (performMediaUpload) {
performSendDelayedMessage(delayedMessage);
} else {
performSendMessageRequest(reqSend, messageObject, originalPath, null, true, delayedMessage, parentObject, messageObject.scheduled);
performSendMessageRequest(reqSend, messageObject, originalPath, null, true, delayedMessage, parentObject, params, messageObject.scheduled);
}
} else if (type == 3) {
if (performMediaUpload) {
performSendDelayedMessage(delayedMessage);
} else {
performSendMessageRequest(reqSend, messageObject, originalPath, delayedMessage, parentObject, messageObject.scheduled);
performSendMessageRequest(reqSend, messageObject, originalPath, delayedMessage, parentObject, params, messageObject.scheduled);
}
} else if (type == 6) {
performSendMessageRequest(reqSend, messageObject, originalPath, delayedMessage, parentObject, messageObject.scheduled);
performSendMessageRequest(reqSend, messageObject, originalPath, delayedMessage, parentObject, params, messageObject.scheduled);
} else if (type == 7) {
if (performMediaUpload) {
performSendDelayedMessage(delayedMessage);
} else {
performSendMessageRequest(reqSend, messageObject, originalPath, delayedMessage, parentObject, messageObject.scheduled);
performSendMessageRequest(reqSend, messageObject, originalPath, delayedMessage, parentObject, params, messageObject.scheduled);
}
} else if (type == 8) {
if (performMediaUpload) {
performSendDelayedMessage(delayedMessage);
} else {
performSendMessageRequest(reqSend, messageObject, originalPath, delayedMessage, parentObject, messageObject.scheduled);
performSendMessageRequest(reqSend, messageObject, originalPath, delayedMessage, parentObject, params, messageObject.scheduled);
}
}
}
@ -3033,15 +3036,6 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
newMsg.from_id = newMsg.peer_id;
}
newMsg.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
newMsgObj = new MessageObject(currentAccount, newMsg, replyToMsg, true, true);
newMsgObj.wasJustSent = true;
newMsgObj.scheduled = scheduleDate != 0;
if (!newMsgObj.isForwarded() && (newMsgObj.type == 3 || videoEditedInfo != null || newMsgObj.type == 2) && !TextUtils.isEmpty(newMsg.attachPath)) {
newMsgObj.attachPathExists = true;
}
if (newMsgObj.videoEditedInfo != null && videoEditedInfo == null) {
videoEditedInfo = newMsgObj.videoEditedInfo;
}
long groupId = 0;
boolean isFinalGroupMedia = false;
@ -3055,6 +3049,16 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
isFinalGroupMedia = params.get("final") != null;
}
newMsgObj = new MessageObject(currentAccount, newMsg, replyToMsg, true, true);
newMsgObj.wasJustSent = true;
newMsgObj.scheduled = scheduleDate != 0;
if (!newMsgObj.isForwarded() && (newMsgObj.type == 3 || videoEditedInfo != null || newMsgObj.type == 2) && !TextUtils.isEmpty(newMsg.attachPath)) {
newMsgObj.attachPathExists = true;
}
if (newMsgObj.videoEditedInfo != null && videoEditedInfo == null) {
videoEditedInfo = newMsgObj.videoEditedInfo;
}
if (groupId == 0) {
ArrayList<MessageObject> objArr = new ArrayList<>();
objArr.add(newMsgObj);
@ -3117,7 +3121,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
reqSend.schedule_date = scheduleDate;
reqSend.flags |= 1024;
}
performSendMessageRequest(reqSend, newMsgObj, null, null, parentObject, scheduleDate != 0);
performSendMessageRequest(reqSend, newMsgObj, null, null, parentObject, params, scheduleDate != 0);
if (retryMessageObject == null) {
getMediaDataController().cleanDraft(peer, replyToTopMsg != null ? replyToTopMsg.getId() : 0, false);
}
@ -3171,6 +3175,14 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
inputMedia = new TLRPC.TL_inputMediaGeoLive();
inputMedia.period = location.period;
inputMedia.flags |= 2;
if (location.heading != 0) {
inputMedia.heading = location.heading;
inputMedia.flags |= 4;
}
if (location.proximity_notification_radius != 0) {
inputMedia.proximity_notification_radius = location.proximity_notification_radius;
inputMedia.flags |= 8;
}
} else {
inputMedia = new TLRPC.TL_inputMediaGeoPoint();
}
@ -3301,6 +3313,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (forceNoSoundVideo || !TextUtils.isEmpty(path) && path.toLowerCase().endsWith("mp4") && (params == null || params.containsKey("forceDocument"))) {
uploadedMedia.nosound_video = true;
}
uploadedMedia.force_file = params != null && params.containsKey("forceDocument");
uploadedMedia.mime_type = document.mime_type;
uploadedMedia.attributes = document.attributes;
} else {
@ -3322,18 +3335,20 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
inputMedia = media;
}
if (!http && uploadedMedia != null) {
delayedMessage = new DelayedMessage(peer);
delayedMessage.originalPath = originalPath;
delayedMessage.type = 2;
delayedMessage.obj = newMsgObj;
if (delayedMessage == null) {
delayedMessage = new DelayedMessage(peer);
delayedMessage.type = 2;
delayedMessage.obj = newMsgObj;
delayedMessage.originalPath = originalPath;
delayedMessage.parentObject = parentObject;
delayedMessage.scheduled = scheduleDate != 0;
}
delayedMessage.inputUploadMedia = uploadedMedia;
delayedMessage.performMediaUpload = performMediaUpload;
if (!document.thumbs.isEmpty()) {
delayedMessage.photoSize = document.thumbs.get(0);
delayedMessage.locationParent = document;
}
delayedMessage.parentObject = parentObject;
delayedMessage.inputUploadMedia = uploadedMedia;
delayedMessage.performMediaUpload = performMediaUpload;
delayedMessage.scheduled = scheduleDate != 0;
}
} else if (type == 8) {
TLRPC.TL_inputMediaUploadedDocument uploadedDocument = new TLRPC.TL_inputMediaUploadedDocument();
@ -3455,35 +3470,35 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (groupId != 0) {
performSendDelayedMessage(delayedMessage);
} else if (type == 1) {
performSendMessageRequest(reqSend, newMsgObj, null, delayedMessage, parentObject, scheduleDate != 0);
performSendMessageRequest(reqSend, newMsgObj, null, delayedMessage, parentObject, params, scheduleDate != 0);
} else if (type == 2) {
if (performMediaUpload) {
performSendDelayedMessage(delayedMessage);
} else {
performSendMessageRequest(reqSend, newMsgObj, originalPath, null, true, delayedMessage, parentObject, scheduleDate != 0);
performSendMessageRequest(reqSend, newMsgObj, originalPath, null, true, delayedMessage, parentObject, params, scheduleDate != 0);
}
} else if (type == 3) {
if (performMediaUpload) {
performSendDelayedMessage(delayedMessage);
} else {
performSendMessageRequest(reqSend, newMsgObj, originalPath, delayedMessage, parentObject, scheduleDate != 0);
performSendMessageRequest(reqSend, newMsgObj, originalPath, delayedMessage, parentObject, params, scheduleDate != 0);
}
} else if (type == 6) {
performSendMessageRequest(reqSend, newMsgObj, originalPath, delayedMessage, parentObject, scheduleDate != 0);
performSendMessageRequest(reqSend, newMsgObj, originalPath, delayedMessage, parentObject, params, scheduleDate != 0);
} else if (type == 7) {
if (performMediaUpload && delayedMessage != null) {
performSendDelayedMessage(delayedMessage);
} else {
performSendMessageRequest(reqSend, newMsgObj, originalPath, delayedMessage, parentObject, scheduleDate != 0);
performSendMessageRequest(reqSend, newMsgObj, originalPath, delayedMessage, parentObject, params, scheduleDate != 0);
}
} else if (type == 8) {
if (performMediaUpload) {
performSendDelayedMessage(delayedMessage);
} else {
performSendMessageRequest(reqSend, newMsgObj, originalPath, delayedMessage, parentObject, scheduleDate != 0);
performSendMessageRequest(reqSend, newMsgObj, originalPath, delayedMessage, parentObject, params, scheduleDate != 0);
}
} else if (type == 10 || type == 11) {
performSendMessageRequest(reqSend, newMsgObj, originalPath, delayedMessage, parentObject, scheduleDate != 0);
performSendMessageRequest(reqSend, newMsgObj, originalPath, delayedMessage, parentObject, params, scheduleDate != 0);
}
} else {
TLRPC.TL_decryptedMessage reqSend;
@ -3685,24 +3700,28 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
reqSend.media.size = document.size;
reqSend.media.mime_type = document.mime_type;
if (document.key == null) {
delayedMessage = new DelayedMessage(peer);
delayedMessage.originalPath = originalPath;
delayedMessage.sendEncryptedRequest = reqSend;
delayedMessage.type = 2;
delayedMessage.obj = newMsgObj;
if (params != null && params.containsKey("parentObject")) {
delayedMessage.parentObject = params.get("parentObject");
} else {
delayedMessage.parentObject = parentObject;
if (document.key == null || groupId != 0) {
if (delayedMessage == null) {
delayedMessage = new DelayedMessage(peer);
delayedMessage.encryptedChat = encryptedChat;
delayedMessage.type = 2;
delayedMessage.sendEncryptedRequest = reqSend;
delayedMessage.originalPath = originalPath;
delayedMessage.obj = newMsgObj;
if (params != null && params.containsKey("parentObject")) {
delayedMessage.parentObject = params.get("parentObject");
} else {
delayedMessage.parentObject = parentObject;
}
delayedMessage.performMediaUpload = true;
delayedMessage.scheduled = scheduleDate != 0;
}
delayedMessage.encryptedChat = encryptedChat;
delayedMessage.performMediaUpload = true;
if (path != null && path.length() > 0 && path.startsWith("http")) {
delayedMessage.httpLocation = path;
}
delayedMessage.scheduled = scheduleDate != 0;
performSendDelayedMessage(delayedMessage);
if (groupId == 0) {
performSendDelayedMessage(delayedMessage);
}
} else {
TLRPC.TL_inputEncryptedFile encryptedFile = new TLRPC.TL_inputEncryptedFile();
encryptedFile.id = document.id;
@ -3755,7 +3774,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
delayedMessage.performMediaUpload = true;
request.messages.add(reqSend);
TLRPC.TL_inputEncryptedFile encryptedFile = new TLRPC.TL_inputEncryptedFile();
encryptedFile.id = type == 3 ? 1 : 0;
encryptedFile.id = type == 3 || type == 7 ? 1 : 0;
request.files.add(encryptedFile);
performSendDelayedMessage(delayedMessage);
}
@ -3792,7 +3811,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
reqSend.id.add(retryMessageObject.messageOwner.fwd_from.channel_post);
}
}
performSendMessageRequest(reqSend, newMsgObj, null, null, parentObject, scheduleDate != 0);
performSendMessageRequest(reqSend, newMsgObj, null, null, parentObject, params, scheduleDate != 0);
} else if (type == 9) {
TLRPC.TL_messages_sendInlineBotResult reqSend = new TLRPC.TL_messages_sendInlineBotResult();
reqSend.peer = sendToPeer;
@ -3813,7 +3832,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
reqSend.clear_draft = true;
getMediaDataController().cleanDraft(peer, replyToTopMsg != null ? replyToTopMsg.getId() : 0, false);
}
performSendMessageRequest(reqSend, newMsgObj, null, null, parentObject, scheduleDate != 0);
performSendMessageRequest(reqSend, newMsgObj, null, null, parentObject, params, scheduleDate != 0);
}
} catch (Exception e) {
FileLog.e(e);
@ -4058,7 +4077,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
getFileLoader().uploadFile(documentLocation, false, false, ConnectionsManager.FileTypeVideo);
}
putToUploadingMessages(messageObject);
} else {
} else if (message.photoSize != null) {
String location = FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.photoSize.location.volume_id + "_" + message.photoSize.location.local_id + ".jpg";
putToDelayedMessages(location, message);
message.extraHashMap.put(location + "_o", documentLocation);
@ -4399,8 +4418,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
ArrayList<Object> arrayList = new ArrayList<>(parentObjects);
getFileRefController().requestReference(arrayList, req, msgObjs, originalPaths, arrayList, delayedMessage, scheduled);
return;
} else if (delayedMessage != null) {
} else if (delayedMessage != null && !delayedMessage.retriedToSend) {
delayedMessage.retriedToSend = true;
AndroidUtilities.runOnUIThread(() -> {
boolean hasEmptyFile = false;
for (int a = 0, size = req.multi_media.size(); a < size; a++) {
if (delayedMessage.parentObjects.get(a) == null) {
continue;
@ -4416,8 +4437,21 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
delayedMessage.httpLocation = delayedMessage.httpLocations.get(a);
delayedMessage.photoSize = delayedMessage.locations.get(a);
delayedMessage.performMediaUpload = true;
if (request.media.file == null || delayedMessage.photoSize != null) {
hasEmptyFile = true;
}
performSendDelayedMessage(delayedMessage, a);
}
if (!hasEmptyFile) {
for (int i = 0; i < msgObjs.size(); i++) {
TLRPC.Message newMsgObj = msgObjs.get(i).messageOwner;
getMessagesStorage().markMessageAsSendError(newMsgObj, scheduled);
newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
getNotificationCenter().postNotificationName(NotificationCenter.messageSendError, newMsgObj.id);
processSentMessage(newMsgObj.id);
removeFromSendingMessages(newMsgObj.id, scheduled);
}
}
});
return;
}
@ -4561,8 +4595,8 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}, null, ConnectionsManager.RequestFlagCanCompress | ConnectionsManager.RequestFlagInvokeAfter);
}
private void performSendMessageRequest(final TLObject req, final MessageObject msgObj, final String originalPath, DelayedMessage delayedMessage, Object parentObject, boolean scheduled) {
performSendMessageRequest(req, msgObj, originalPath, null, false, delayedMessage, parentObject, scheduled);
private void performSendMessageRequest(final TLObject req, final MessageObject msgObj, final String originalPath, DelayedMessage delayedMessage, Object parentObject, HashMap<String, String> params, boolean scheduled) {
performSendMessageRequest(req, msgObj, originalPath, null, false, delayedMessage, parentObject, params, scheduled);
}
private DelayedMessage findMaxDelayedMessageForMessageId(int messageId, long dialogId) {
@ -4592,7 +4626,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
return maxDelayedMessage;
}
protected void performSendMessageRequest(final TLObject req, final MessageObject msgObj, final String originalPath, DelayedMessage parentMessage, boolean check, DelayedMessage delayedMessage, Object parentObject, boolean scheduled) {
protected void performSendMessageRequest(final TLObject req, final MessageObject msgObj, final String originalPath, DelayedMessage parentMessage, boolean check, DelayedMessage delayedMessage, Object parentObject, HashMap<String, String> params, boolean scheduled) {
if (!(req instanceof TLRPC.TL_messages_editMessage)) {
if (check) {
DelayedMessage maxDelayedMessage = findMaxDelayedMessageForMessageId(msgObj.getId(), msgObj.getDialogId());
@ -4811,8 +4845,8 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
existFlags = 0;
}
if (MessageObject.isLiveLocationMessage(newMsgObj)) {
getLocationController().addSharingLocation(newMsgObj.dialog_id, newMsgObj.id, newMsgObj.media.period, newMsgObj);
if (MessageObject.isLiveLocationMessage(newMsgObj) && newMsgObj.via_bot_id == 0 && TextUtils.isEmpty(newMsgObj.via_bot_name)) {
getLocationController().addSharingLocation(newMsgObj.dialog_id, newMsgObj.id, newMsgObj.media.period, newMsgObj.media.proximity_notification_radius, newMsgObj);
}
if (!isSentError) {
@ -5184,7 +5218,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
}
private static boolean prepareSendingDocumentInternal(AccountInstance accountInstance, String path, String originalPath, Uri uri, String mime, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, CharSequence caption, final ArrayList<TLRPC.MessageEntity> entities, final MessageObject editingMessageObject, boolean forceDocument, boolean notify, int scheduleDate) {
private static boolean prepareSendingDocumentInternal(AccountInstance accountInstance, String path, String originalPath, Uri uri, String mime, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, CharSequence caption, final ArrayList<TLRPC.MessageEntity> entities, final MessageObject editingMessageObject, long[] groupId, boolean isGroupFinal, boolean forceDocument, boolean notify, int scheduleDate, Boolean[] withThumb) {
if ((path == null || path.length() == 0) && uri == null) {
return false;
}
@ -5363,7 +5397,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
} else {
document.mime_type = "application/octet-stream";
}
if (document.mime_type.equals("image/gif") && (editingMessageObject == null || editingMessageObject.getGroupIdForUse() == 0)) {
if (!forceDocument && document.mime_type.equals("image/gif") && (editingMessageObject == null || editingMessageObject.getGroupIdForUse() == 0)) {
try {
Bitmap bitmap = ImageLoader.loadBitmap(f.getAbsolutePath(), null, 90, 90, true);
if (bitmap != null) {
@ -5418,6 +5452,22 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (parentFinal != null) {
params.put("parentObject", parentFinal);
}
Boolean prevWithThumb = false;
if (withThumb != null) {
prevWithThumb = withThumb[0];
withThumb[0] = document.mime_type != null && (document.mime_type.toLowerCase().startsWith("image/") || document.mime_type.toLowerCase().startsWith("video/mp4")) || MessageObject.canPreviewDocument(document);
}
if (groupId != null) {
if (withThumb != null && prevWithThumb != null && prevWithThumb != withThumb[0]) {
finishGroup(accountInstance, groupId[0], scheduleDate);
groupId[0] = Utilities.random.nextLong();
}
params.put("groupId", "" + groupId[0]);
if (isGroupFinal) {
params.put("final", "1");
}
}
AndroidUtilities.runOnUIThread(() -> {
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessageMedia(editingMessageObject, null, null, documentFinal, pathFinal, params, false, parentFinal);
@ -5450,13 +5500,27 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
@UiThread
public static void prepareSendingAudioDocuments(AccountInstance accountInstance, ArrayList<MessageObject> messageObjects, String caption, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, MessageObject editingMessageObject, boolean notify, int scheduleDate) {
new Thread(() -> {
int size = messageObjects.size();
for (int a = 0; a < size; a++) {
int count = messageObjects.size();
long groupId = 0;
int mediaCount = 0;
for (int a = 0; a < count; a++) {
final MessageObject messageObject = messageObjects.get(a);
String originalPath = messageObject.messageOwner.attachPath;
final File f = new File(originalPath);
boolean isEncrypted = (int) dialogId == 0;
int enryptedLayer = 0;
if (isEncrypted) {
int high_id = (int) (dialogId >> 32);
TLRPC.EncryptedChat encryptedChat = accountInstance.getMessagesController().getEncryptedChat(high_id);
if (encryptedChat != null) {
enryptedLayer = AndroidUtilities.getPeerLayerVersion(encryptedChat.layer);
}
}
if ((!isEncrypted || enryptedLayer >= 73) && count > 1 && mediaCount % 10 == 0) {
groupId = Utilities.random.nextLong();
mediaCount = 0;
}
if (originalPath != null) {
originalPath += "audio" + f.length();
@ -5494,6 +5558,11 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (parentFinal != null) {
params.put("parentObject", parentFinal);
}
mediaCount++;
params.put("groupId", "" + groupId);
if (mediaCount == 10 || a == count - 1) {
params.put("final", "1");
}
AndroidUtilities.runOnUIThread(() -> {
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessageMedia(editingMessageObject, null, null, documentFinal, messageObject.messageOwner.attachPath, params, false, parentFinal);
@ -5505,6 +5574,26 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}).start();
}
private static void finishGroup(AccountInstance accountInstance, long groupId, int scheduleDate) {
AndroidUtilities.runOnUIThread(() -> {
SendMessagesHelper instance = accountInstance.getSendMessagesHelper();
ArrayList<DelayedMessage> arrayList = instance.delayedMessages.get("group_" + groupId);
if (arrayList != null && !arrayList.isEmpty()) {
DelayedMessage message = arrayList.get(0);
MessageObject prevMessage = message.messageObjects.get(message.messageObjects.size() - 1);
message.finalGroupMessage = prevMessage.getId();
prevMessage.messageOwner.params.put("final", "1");
TLRPC.TL_messages_messages messagesRes = new TLRPC.TL_messages_messages();
messagesRes.messages.add(prevMessage.messageOwner);
accountInstance.getMessagesStorage().putMessages(messagesRes, message.peer, -2, 0, false, scheduleDate != 0);
instance.sendReadyToSendGroup(message, true, true);
}
});
}
@UiThread
public static void prepareSendingDocuments(AccountInstance accountInstance, ArrayList<String> paths, ArrayList<String> originalPaths, ArrayList<Uri> uris, String caption, String mime, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, InputContentInfoCompat inputContent, MessageObject editingMessageObject, boolean notify, int scheduleDate) {
if (paths == null && originalPaths == null && uris == null || paths != null && originalPaths != null && paths.size() != originalPaths.size()) {
@ -5512,20 +5601,62 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
new Thread(() -> {
boolean error = false;
long[] groupId = new long[1];
int mediaCount = 0;
Boolean[] withThumb = new Boolean[1];
boolean isEncrypted = (int) dialogId == 0;
int enryptedLayer = 0;
if (isEncrypted) {
int high_id = (int) (dialogId >> 32);
TLRPC.EncryptedChat encryptedChat = accountInstance.getMessagesController().getEncryptedChat(high_id);
if (encryptedChat != null) {
enryptedLayer = AndroidUtilities.getPeerLayerVersion(encryptedChat.layer);
}
}
if (paths != null) {
for (int a = 0; a < paths.size(); a++) {
int count = paths.size();
for (int a = 0; a < count; a++) {
final String captionFinal = a == 0 ? caption : null;
if (!prepareSendingDocumentInternal(accountInstance, paths.get(a), originalPaths.get(a), null, mime, dialogId, replyToMsg, replyToTopMsg, captionFinal, null, editingMessageObject, false, notify, scheduleDate)) {
if (!isEncrypted && count > 1 && mediaCount % 10 == 0) {
if (groupId[0] != 0) {
finishGroup(accountInstance, groupId[0], scheduleDate);
}
groupId[0] = Utilities.random.nextLong();
mediaCount = 0;
}
mediaCount++;
long prevGroupId = groupId[0];
if (!prepareSendingDocumentInternal(accountInstance, paths.get(a), originalPaths.get(a), null, mime, dialogId, replyToMsg, replyToTopMsg, captionFinal, null, editingMessageObject, groupId, mediaCount == 10 || a == count - 1, true, notify, scheduleDate, withThumb)) {
error = true;
}
if (prevGroupId != groupId[0]) {
mediaCount = 1;
}
}
}
if (uris != null) {
groupId[0] = 0;
mediaCount = 0;
int count = uris.size();
for (int a = 0; a < uris.size(); a++) {
final String captionFinal = a == 0 && (paths == null || paths.size() == 0) ? caption : null;
if (!prepareSendingDocumentInternal(accountInstance, null, null, uris.get(a), mime, dialogId, replyToMsg, replyToTopMsg, captionFinal, null, editingMessageObject, false, notify, scheduleDate)) {
if (!isEncrypted && count > 1 && mediaCount % 10 == 0) {
if (groupId[0] != 0) {
finishGroup(accountInstance, groupId[0], scheduleDate);
}
groupId[0] = Utilities.random.nextLong();
mediaCount = 0;
}
mediaCount++;
long prevGroupId = groupId[0];
if (!prepareSendingDocumentInternal(accountInstance, null, null, uris.get(a), mime, dialogId, replyToMsg, replyToTopMsg, captionFinal, null, editingMessageObject, groupId, mediaCount == 10 || a == count - 1, true, notify, scheduleDate, withThumb)) {
error = true;
}
if (prevGroupId != groupId[0]) {
mediaCount = 1;
}
}
}
if (inputContent != null) {
@ -5546,8 +5677,14 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
@UiThread
public static void prepareSendingPhoto(AccountInstance accountInstance, String imageFilePath, Uri imageUri, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, CharSequence caption, ArrayList<TLRPC.MessageEntity> entities, ArrayList<TLRPC.InputDocument> stickers, InputContentInfoCompat inputContent, int ttl, MessageObject editingMessageObject, boolean notify, int scheduleDate) {
prepareSendingPhoto(accountInstance, imageFilePath, null, imageUri, dialogId, replyToMsg, replyToTopMsg, caption, entities, stickers, inputContent, ttl, editingMessageObject, null, notify, scheduleDate);
}
@UiThread
public static void prepareSendingPhoto(AccountInstance accountInstance, String imageFilePath, String thumbFilePath, Uri imageUri, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, CharSequence caption, ArrayList<TLRPC.MessageEntity> entities, ArrayList<TLRPC.InputDocument> stickers, InputContentInfoCompat inputContent, int ttl, MessageObject editingMessageObject, VideoEditedInfo videoEditedInfo, boolean notify, int scheduleDate) {
SendingMediaInfo info = new SendingMediaInfo();
info.path = imageFilePath;
info.thumbPath = thumbFilePath;
info.uri = imageUri;
if (caption != null) {
info.caption = caption.toString();
@ -5557,6 +5694,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (stickers != null) {
info.masks = new ArrayList<>(stickers);
}
info.videoEditedInfo = videoEditedInfo;
ArrayList<SendingMediaInfo> infos = new ArrayList<>();
infos.add(info);
prepareSendingMedia(accountInstance, infos, dialogId, replyToMsg, replyToTopMsg, inputContent, false, false, editingMessageObject, notify, scheduleDate);
@ -5858,14 +5996,17 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
accountInstance.getSendMessagesHelper().sendMessage(venue, dialogId, replyToMsg, replyToTopMsg, result.send_message.reply_markup, params, notify, scheduleDate);
} else if (result.send_message instanceof TLRPC.TL_botInlineMessageMediaGeo) {
if (result.send_message.period != 0) {
if (result.send_message.period != 0 || result.send_message.proximity_notification_radius != 0) {
TLRPC.TL_messageMediaGeoLive location = new TLRPC.TL_messageMediaGeoLive();
location.period = result.send_message.period;
location.period = result.send_message.period != 0 ? result.send_message.period : 900;
location.geo = result.send_message.geo;
location.heading = result.send_message.heading;
location.proximity_notification_radius = result.send_message.proximity_notification_radius;
accountInstance.getSendMessagesHelper().sendMessage(location, dialogId, replyToMsg, replyToTopMsg, result.send_message.reply_markup, params, notify, scheduleDate);
} else {
TLRPC.TL_messageMediaGeo location = new TLRPC.TL_messageMediaGeo();
location.geo = result.send_message.geo;
location.heading = result.send_message.heading;
accountInstance.getSendMessagesHelper().sendMessage(location, dialogId, replyToMsg, replyToTopMsg, result.send_message.reply_markup, params, notify, scheduleDate);
}
} else if (result.send_message instanceof TLRPC.TL_botInlineMessageMediaContact) {
@ -6015,17 +6156,17 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
@UiThread
public static void prepareSendingMedia(AccountInstance accountInstance, ArrayList<SendingMediaInfo> media, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, InputContentInfoCompat inputContent, boolean forceDocument, boolean groupPhotos, MessageObject editingMessageObject, boolean notify, int scheduleDate) {
public static void prepareSendingMedia(AccountInstance accountInstance, ArrayList<SendingMediaInfo> media, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, InputContentInfoCompat inputContent, boolean forceDocument, boolean groupMedia, MessageObject editingMessageObject, boolean notify, int scheduleDate) {
if (media.isEmpty()) {
return;
}
for (int a = 0, N = media.size(); a < N; a++) {
if (media.get(a).ttl > 0) {
groupPhotos = false;
groupMedia = false;
break;
}
}
final boolean groupPhotosFinal = groupPhotos;
final boolean groupMediaFinal = groupMedia;
mediaSendQueue.postRunnable(() -> {
long beginTime = System.currentTimeMillis();
HashMap<SendingMediaInfo, MediaSendPrepareWorker> workers;
@ -6039,7 +6180,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
enryptedLayer = AndroidUtilities.getPeerLayerVersion(encryptedChat.layer);
}
}
if ((!isEncrypted || enryptedLayer >= 73) && !forceDocument && groupPhotosFinal) {
if ((!isEncrypted || enryptedLayer >= 73) && !forceDocument && groupMediaFinal) {
workers = new HashMap<>();
for (int a = 0; a < count; a++) {
final SendingMediaInfo info = media.get(a);
@ -6115,12 +6256,12 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
ArrayList<ArrayList<TLRPC.MessageEntity>> sendAsDocumentsEntities = null;
String extension = null;
int photosCount = 0;
int mediaCount = 0;
for (int a = 0; a < count; a++) {
final SendingMediaInfo info = media.get(a);
if (groupPhotosFinal && (!isEncrypted || enryptedLayer >= 73) && count > 1 && photosCount % 10 == 0) {
if (groupMediaFinal && (!isEncrypted || enryptedLayer >= 73) && count > 1 && mediaCount % 10 == 0) {
lastGroupId = groupId = Utilities.random.nextLong();
photosCount = 0;
mediaCount = 0;
}
if (info.searchImage != null && info.videoEditedInfo == null) {
if (info.searchImage.type == 1) {
@ -6153,7 +6294,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
document.attributes.add(fileName);
document.size = info.searchImage.size;
document.dc_id = 0;
if (cacheFile.toString().endsWith("mp4")) {
if (!forceDocument && cacheFile.toString().endsWith("mp4")) {
document.mime_type = "video/mp4";
document.attributes.add(new TLRPC.TL_documentAttributeAnimated());
} else {
@ -6276,10 +6417,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (parentFinal != null) {
params.put("parentObject", parentFinal);
}
if (groupPhotosFinal) {
photosCount++;
if (groupMediaFinal) {
mediaCount++;
params.put("groupId", "" + groupId);
if (photosCount == 10 || a == count -1) {
if (mediaCount == 10 || a == count -1) {
params.put("final", "1");
lastGroupId = 0;
}
@ -6439,10 +6580,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (parentFinal != null) {
params.put("parentObject", parentFinal);
}
if (!muted && groupPhotosFinal) {
photosCount++;
if (!muted && groupMediaFinal) {
mediaCount++;
params.put("groupId", "" + groupId);
if (photosCount == 10 || a == count -1) {
if (mediaCount == 10 || a == count -1) {
params.put("final", "1");
lastGroupId = 0;
}
@ -6468,7 +6609,19 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
});
} else {
prepareSendingDocumentInternal(accountInstance, info.path, info.path, null, null, dialogId, replyToMsg, replyToTopMsg, info.caption, info.entities, editingMessageObject, forceDocument, notify, scheduleDate);
if (sendAsDocuments == null) {
sendAsDocuments = new ArrayList<>();
sendAsDocumentsOriginal = new ArrayList<>();
sendAsDocumentsCaptions = new ArrayList<>();
sendAsDocumentsEntities = new ArrayList<>();
sendAsDocumentsUri = new ArrayList<>();
}
sendAsDocuments.add(info.path);
sendAsDocumentsOriginal.add(info.path);
sendAsDocumentsUri.add(info.uri);
sendAsDocumentsCaptions.add(info.caption);
sendAsDocumentsEntities.add(info.entities);
//prepareSendingDocumentInternal(accountInstance, info.path, info.path, null, null, dialogId, replyToMsg, replyToTopMsg, info.caption, info.entities, editingMessageObject, null, false, forceDocument, notify, scheduleDate, null);
}
} else {
String originalPath = info.path;
@ -6620,7 +6773,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
try {
if (!groupPhotosFinal || media.size() == 1) {
if (!groupMediaFinal || media.size() == 1) {
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photoFinal.sizes, AndroidUtilities.getPhotoSize());
if (currentPhotoObject != null) {
keyFinal[0] = getKeyForPhotoSize(currentPhotoObject, bitmapFinal, false, false);
@ -6630,10 +6783,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
FileLog.e(e);
}
if (groupPhotosFinal) {
photosCount++;
if (groupMediaFinal) {
mediaCount++;
params.put("groupId", "" + groupId);
if (photosCount == 10 || a == count - 1) {
if (mediaCount == 10 || a == count - 1) {
params.put("final", "1");
lastGroupId = 0;
}
@ -6667,31 +6820,21 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
}
if (lastGroupId != 0) {
final long lastGroupIdFinal = lastGroupId;
AndroidUtilities.runOnUIThread(() -> {
SendMessagesHelper instance = accountInstance.getSendMessagesHelper();
ArrayList<DelayedMessage> arrayList = instance.delayedMessages.get("group_" + lastGroupIdFinal);
if (arrayList != null && !arrayList.isEmpty()) {
DelayedMessage message = arrayList.get(0);
MessageObject prevMessage = message.messageObjects.get(message.messageObjects.size() - 1);
message.finalGroupMessage = prevMessage.getId();
prevMessage.messageOwner.params.put("final", "1");
TLRPC.TL_messages_messages messagesRes = new TLRPC.TL_messages_messages();
messagesRes.messages.add(prevMessage.messageOwner);
accountInstance.getMessagesStorage().putMessages(messagesRes, message.peer, -2, 0, false, scheduleDate != 0);
instance.sendReadyToSendGroup(message, true, true);
}
});
finishGroup(accountInstance, lastGroupId, scheduleDate);
}
if (inputContent != null) {
inputContent.releasePermission();
}
if (sendAsDocuments != null && !sendAsDocuments.isEmpty()) {
for (int a = 0; a < sendAsDocuments.size(); a++) {
prepareSendingDocumentInternal(accountInstance, sendAsDocuments.get(a), sendAsDocumentsOriginal.get(a), sendAsDocumentsUri.get(a), extension, dialogId, replyToMsg, replyToTopMsg, sendAsDocumentsCaptions.get(a), sendAsDocumentsEntities.get(a), editingMessageObject, forceDocument, notify, scheduleDate);
long[] groupId2 = new long[1];
int documentsCount = sendAsDocuments.size();
for (int a = 0; a < documentsCount; a++) {
if (forceDocument && !isEncrypted && count > 1 && mediaCount % 10 == 0) {
groupId2[0] = Utilities.random.nextLong();
mediaCount = 0;
}
mediaCount++;
prepareSendingDocumentInternal(accountInstance, sendAsDocuments.get(a), sendAsDocumentsOriginal.get(a), sendAsDocumentsUri.get(a), extension, dialogId, replyToMsg, replyToTopMsg, sendAsDocumentsCaptions.get(a), sendAsDocumentsEntities.get(a), editingMessageObject, groupId2, mediaCount == 10 || a == documentsCount - 1, forceDocument, notify, scheduleDate, null);
}
}
if (BuildVars.LOGS_ENABLED) {
@ -7100,7 +7243,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
});
} else {
prepareSendingDocumentInternal(accountInstance, videoPath, videoPath, null, null, dialogId, replyToMsg, replyToTopMsg, caption, entities, editingMessageObject, false, notify, scheduleDate);
prepareSendingDocumentInternal(accountInstance, videoPath, videoPath, null, null, dialogId, replyToMsg, replyToTopMsg, caption, entities, editingMessageObject, null, false, false, notify, scheduleDate, null);
}
}).start();
}

View File

@ -388,7 +388,7 @@ public class TextureRenderer {
for (int a = 0, N = mediaEntities.size(); a < N; a++) {
VideoEditedInfo.MediaEntity entity = mediaEntities.get(a);
if (entity.ptr != 0) {
RLottieDrawable.getFrame(entity.ptr, (int) entity.currentFrame, stickerBitmap, 512, 512, stickerBitmap.getRowBytes());
RLottieDrawable.getFrame(entity.ptr, (int) entity.currentFrame, stickerBitmap, 512, 512, stickerBitmap.getRowBytes(), true);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, stickerBitmap, 0);
entity.currentFrame += entity.framesPerDraw;

View File

@ -227,6 +227,10 @@ public class ConnectionsManager extends BaseController {
return native_getCurrentTime(currentAccount);
}
public int getCurrentDatacenterId() {
return native_getCurrentDatacenterId(currentAccount);
}
public int getTimeDifference() {
return native_getTimeDifference(currentAccount);
}
@ -513,6 +517,9 @@ public class ConnectionsManager extends BaseController {
int flags = 0;
EmuDetector detector = EmuDetector.with(ApplicationLoader.applicationContext);
if (detector.detect()) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("detected emu");
}
flags |= 1024;
}
return flags;
@ -657,6 +664,7 @@ public class ConnectionsManager extends BaseController {
public static native void native_resumeNetwork(int currentAccount, boolean partial);
public static native long native_getCurrentTimeMillis(int currentAccount);
public static native int native_getCurrentTime(int currentAccount);
public static native int native_getCurrentDatacenterId(int currentAccount);
public static native int native_getTimeDifference(int currentAccount);
public static native void native_sendRequest(int currentAccount, long object, RequestDelegateInternal onComplete, QuickAckDelegate onQuickAck, WriteToSocketDelegate onWriteToSocket, int flags, int datacenterId, int connetionType, boolean immediate, int requestToken);
public static native void native_cancelRequest(int currentAccount, int token, boolean notifyServer);

View File

@ -61,7 +61,7 @@ public class TLRPC {
public static final int MESSAGE_FLAG_EDITED = 0x00008000;
public static final int MESSAGE_FLAG_MEGAGROUP = 0x80000000;
public static final int LAYER = 119;
public static final int LAYER = 120;
public static class TL_stats_megagroupStats extends TLObject {
public static int constructor = 0xef7ff916;
@ -2427,19 +2427,20 @@ public class TLRPC {
public int pts;
public int count;
public int next_rate;
public int offset_id_offset;
public static messages_Messages TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
messages_Messages result = null;
switch (constructor) {
case 0x3a54685e:
result = new TL_messages_messagesSlice();
break;
case 0x8c718e87:
result = new TL_messages_messages();
break;
case 0x99262e37:
case 0x64479808:
result = new TL_messages_channelMessages();
break;
case 0xc8edce1e:
result = new TL_messages_messagesSlice();
break;
case 0x74535f21:
result = new TL_messages_messagesNotModified();
break;
@ -2454,6 +2455,99 @@ public class TLRPC {
}
}
public static class TL_messages_messagesSlice extends messages_Messages {
public static int constructor = 0x3a54685e;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
inexact = (flags & 2) != 0;
count = stream.readInt32(exception);
if ((flags & 1) != 0) {
next_rate = stream.readInt32(exception);
}
if ((flags & 4) != 0) {
offset_id_offset = stream.readInt32(exception);
}
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++) {
Message object = Message.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
messages.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++) {
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) {
return;
}
users.add(object);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = inexact ? (flags | 2) : (flags &~ 2);
stream.writeInt32(flags);
stream.writeInt32(count);
if ((flags & 1) != 0) {
stream.writeInt32(next_rate);
}
if ((flags & 4) != 0) {
stream.writeInt32(offset_id_offset);
}
stream.writeInt32(0x1cb5c415);
int count = messages.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
messages.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++) {
users.get(a).serializeToStream(stream);
}
}
}
public static class TL_messages_messages extends messages_Messages {
public static int constructor = 0x8c718e87;
@ -2530,7 +2624,7 @@ public class TLRPC {
}
public static class TL_messages_channelMessages extends messages_Messages {
public static int constructor = 0x99262e37;
public static int constructor = 0x64479808;
public void readParams(AbstractSerializedData stream, boolean exception) {
@ -2538,6 +2632,9 @@ public class TLRPC {
inexact = (flags & 2) != 0;
pts = stream.readInt32(exception);
count = stream.readInt32(exception);
if ((flags & 4) != 0) {
offset_id_offset = stream.readInt32(exception);
}
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
@ -2591,92 +2688,8 @@ public class TLRPC {
stream.writeInt32(flags);
stream.writeInt32(pts);
stream.writeInt32(count);
stream.writeInt32(0x1cb5c415);
int count = messages.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
messages.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++) {
users.get(a).serializeToStream(stream);
}
}
}
public static class TL_messages_messagesSlice extends messages_Messages {
public static int constructor = 0xc8edce1e;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
inexact = (flags & 2) != 0;
count = stream.readInt32(exception);
if ((flags & 1) != 0) {
next_rate = stream.readInt32(exception);
}
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++) {
Message object = Message.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
messages.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++) {
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) {
return;
}
users.add(object);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = inexact ? (flags | 2) : (flags &~ 2);
stream.writeInt32(flags);
stream.writeInt32(count);
if ((flags & 1) != 0) {
stream.writeInt32(next_rate);
if ((flags & 4) != 0) {
stream.writeInt32(offset_id_offset);
}
stream.writeInt32(0x1cb5c415);
int count = messages.size();
@ -4350,15 +4363,17 @@ public class TLRPC {
}
public static abstract class GeoPoint extends TLObject {
public double _long;
public double lat;
public int flags;
public double _long;
public double lat;
public int accuracy_radius;
public long access_hash;
public static GeoPoint TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
GeoPoint result = null;
switch (constructor) {
case 0x296f104:
result = new TL_geoPoint();
result = new TL_geoPoint_layer119();
break;
case 0x2049d70c:
result = new TL_geoPoint_layer81();
@ -4366,6 +4381,9 @@ public class TLRPC {
case 0x1117dd5f:
result = new TL_geoPointEmpty();
break;
case 0xb2a2f663:
result = new TL_geoPoint();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in GeoPoint", constructor));
@ -4377,7 +4395,7 @@ public class TLRPC {
}
}
public static class TL_geoPoint extends GeoPoint {
public static class TL_geoPoint_layer119 extends TL_geoPoint {
public static int constructor = 0x296f104;
@ -4420,6 +4438,32 @@ public class TLRPC {
}
}
public static class TL_geoPoint extends GeoPoint {
public static int constructor = 0xb2a2f663;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
_long = stream.readDouble(exception);
lat = stream.readDouble(exception);
access_hash = stream.readInt64(exception);
if ((flags & 1) != 0) {
accuracy_radius = stream.readInt32(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
stream.writeDouble(_long);
stream.writeDouble(lat);
stream.writeInt64(access_hash);
if ((flags & 1) != 0) {
stream.writeInt32(accuracy_radius);
}
}
}
public static class TL_account_privacyRules extends TLObject {
public static int constructor = 0x50a04e45;
@ -6350,7 +6394,37 @@ public class TLRPC {
}
}
public static class TL_messageMediaGeoLive extends MessageMedia {
public static class TL_messageMediaGeoLive extends MessageMedia {
public static int constructor = 0xb940c666;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
geo = GeoPoint.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 1) != 0) {
heading = stream.readInt32(exception);
}
period = stream.readInt32(exception);
if ((flags & 2) != 0) {
proximity_notification_radius = stream.readInt32(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
geo.serializeToStream(stream);
if ((flags & 1) != 0) {
stream.writeInt32(heading);
}
stream.writeInt32(period);
if ((flags & 2) != 0) {
stream.writeInt32(proximity_notification_radius);
}
}
}
public static class TL_messageMediaGeoLive_layer119 extends TL_messageMediaGeoLive {
public static int constructor = 0x7c3c2609;
@ -7571,15 +7645,18 @@ public class TLRPC {
}
public static abstract class InputGeoPoint extends TLObject {
public double lat;
public double _long;
public int flags;
public double lat;
public double _long;
public int accuracy_radius;
public static InputGeoPoint TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
InputGeoPoint result = null;
switch (constructor) {
case 0xf3b7acc9:
result = new TL_inputGeoPoint();
break;
case 0x48222faf:
result = new TL_inputGeoPoint();
break;
case 0xe4c123d6:
result = new TL_inputGeoPointEmpty();
break;
@ -7594,21 +7671,29 @@ public class TLRPC {
}
}
public static class TL_inputGeoPoint extends InputGeoPoint {
public static int constructor = 0xf3b7acc9;
public static class TL_inputGeoPoint extends InputGeoPoint {
public static int constructor = 0x48222faf;
public void readParams(AbstractSerializedData stream, boolean exception) {
lat = stream.readDouble(exception);
_long = stream.readDouble(exception);
}
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
lat = stream.readDouble(exception);
_long = stream.readDouble(exception);
if ((flags & 1) != 0) {
accuracy_radius = stream.readInt32(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeDouble(lat);
stream.writeDouble(_long);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
stream.writeDouble(lat);
stream.writeDouble(_long);
if ((flags & 1) != 0) {
stream.writeInt32(accuracy_radius);
}
}
}
public static class TL_inputGeoPointEmpty extends InputGeoPoint {
public static int constructor = 0xe4c123d6;
@ -12201,6 +12286,8 @@ public class TLRPC {
public String vcard;
public boolean no_webpage;
public int period;
public int heading;
public int proximity_notification_radius;
public static BotInlineMessage TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
BotInlineMessage result = null;
@ -12230,8 +12317,11 @@ public class TLRPC {
result = new TL_botInlineMessageText();
break;
case 0xb722de65:
result = new TL_botInlineMessageMediaGeo();
result = new TL_botInlineMessageMediaGeo_layer119();
break;
case 0x51846fd:
result = new TL_botInlineMessageMediaGeo();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in BotInlineMessage", constructor));
@ -12497,7 +12587,47 @@ public class TLRPC {
}
}
public static class TL_botInlineMessageMediaGeo extends BotInlineMessage {
public static class TL_botInlineMessageMediaGeo extends BotInlineMessage {
public static int constructor = 0x51846fd;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
geo = GeoPoint.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 1) != 0) {
heading = stream.readInt32(exception);
}
if ((flags & 2) != 0) {
period = stream.readInt32(exception);
}
if ((flags & 8) != 0) {
proximity_notification_radius = stream.readInt32(exception);
}
if ((flags & 4) != 0) {
reply_markup = ReplyMarkup.TLdeserialize(stream, stream.readInt32(exception), exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
geo.serializeToStream(stream);
if ((flags & 1) != 0) {
stream.writeInt32(heading);
}
if ((flags & 2) != 0) {
stream.writeInt32(period);
}
if ((flags & 8) != 0) {
stream.writeInt32(proximity_notification_radius);
}
if ((flags & 4) != 0) {
reply_markup.serializeToStream(stream);
}
}
}
public static class TL_botInlineMessageMediaGeo_layer119 extends TL_botInlineMessageMediaGeo {
public static int constructor = 0xb722de65;
@ -16173,6 +16303,9 @@ public class TLRPC {
public static ChannelParticipantsFilter TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
ChannelParticipantsFilter result = null;
switch (constructor) {
case 0xe04b5ceb:
result = new TL_channelParticipantsMentions();
break;
case 0xbb6ae88d:
result = new TL_channelParticipantsContacts();
break;
@ -16205,6 +16338,34 @@ public class TLRPC {
}
}
public static class TL_channelParticipantsMentions extends ChannelParticipantsFilter {
public static int constructor = 0xe04b5ceb;
public int flags;
public int top_msg_id;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
if ((flags & 1) != 0) {
q = stream.readString(exception);
}
if ((flags & 2) != 0) {
top_msg_id = stream.readInt32(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
if ((flags & 1) != 0) {
stream.writeString(q);
}
if ((flags & 2) != 0) {
stream.writeInt32(top_msg_id);
}
}
}
public static class TL_channelParticipantsContacts extends ChannelParticipantsFilter {
public static int constructor = 0xbb6ae88d;
@ -16381,6 +16542,9 @@ public class TLRPC {
case 0x94bd38ed:
result = new TL_messageActionPinMessage();
break;
case 0x98e0d697:
result = new TL_messageActionGeoProximityReached();
break;
case 0x95e3fbef:
result = new TL_messageActionChatDeletePhoto();
break;
@ -16755,6 +16919,27 @@ public class TLRPC {
}
}
public static class TL_messageActionGeoProximityReached extends MessageAction {
public static int constructor = 0x98e0d697;
public Peer from_id;
public Peer to_id;
public int distance;
public void readParams(AbstractSerializedData stream, boolean exception) {
from_id = Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
to_id = Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
distance = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
from_id.serializeToStream(stream);
to_id.serializeToStream(stream);
stream.writeInt32(distance);
}
}
public static class TL_messageActionChatDeletePhoto extends MessageAction {
public static int constructor = 0x95e3fbef;
@ -20531,6 +20716,7 @@ public class TLRPC {
public String provider;
public String venue_id;
public String venue_type;
public int heading;
public int period;
public boolean nosound_video;
public boolean force_file;
@ -20538,6 +20724,7 @@ public class TLRPC {
public InputFile thumb;
public String mime_type;
public ArrayList<DocumentAttribute> attributes = new ArrayList<>();
public int proximity_notification_radius;
public static InputMedia TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
InputMedia result = null;
@ -20572,7 +20759,7 @@ public class TLRPC {
case 0xc13d1c11:
result = new TL_inputMediaVenue();
break;
case 0xce4e82fd:
case 0x971fa843:
result = new TL_inputMediaGeoLive();
break;
case 0x5b38c6c1:
@ -20857,16 +21044,22 @@ public class TLRPC {
}
public static class TL_inputMediaGeoLive extends InputMedia {
public static int constructor = 0xce4e82fd;
public static int constructor = 0x971fa843;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
stopped = (flags & 1) != 0;
geo_point = InputGeoPoint.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 4) != 0) {
heading = stream.readInt32(exception);
}
if ((flags & 2) != 0) {
period = stream.readInt32(exception);
}
if ((flags & 8) != 0) {
proximity_notification_radius = stream.readInt32(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
@ -20874,9 +21067,15 @@ public class TLRPC {
flags = stopped ? (flags | 1) : (flags &~ 1);
stream.writeInt32(flags);
geo_point.serializeToStream(stream);
if ((flags & 4) != 0) {
stream.writeInt32(heading);
}
if ((flags & 2) != 0) {
stream.writeInt32(period);
}
if ((flags & 8) != 0) {
stream.writeInt32(proximity_notification_radius);
}
}
}
@ -21725,12 +21924,12 @@ public class TLRPC {
case 0xaca1657b:
result = new TL_updateMessagePoll();
break;
case 0x4c43da18:
result = new TL_updateUserPinnedMessage();
break;
case 0xa20db0e5:
result = new TL_updateDeleteMessages();
break;
case 0x8588878b:
result = new TL_updatePinnedChannelMessages();
break;
case 0x571d2742:
result = new TL_updateReadFeaturedStickers();
break;
@ -21794,9 +21993,6 @@ public class TLRPC {
case 0x6e5f8c22:
result = new TL_updateChatParticipantDelete();
break;
case 0xe10db349:
result = new TL_updateChatPinnedMessage();
break;
case 0xe40370a3:
result = new TL_updateEditMessage();
break;
@ -21833,9 +22029,6 @@ public class TLRPC {
case 0xebe46819:
result = new TL_updateServiceNotification();
break;
case 0x98592475:
result = new TL_updateChannelPinnedMessage();
break;
case 0x56022f4d:
result = new TL_updateLangPack();
break;
@ -21926,6 +22119,9 @@ public class TLRPC {
case 0x246a4b22:
result = new TL_updatePeerBlocked();
break;
case 0xed85eab5:
result = new TL_updatePinnedMessages();
break;
case 0x8e5e9873:
result = new TL_updateDcOptions();
break;
@ -21970,24 +22166,6 @@ public class TLRPC {
}
}
public static class TL_updateUserPinnedMessage extends Update {
public static int constructor = 0x4c43da18;
public int user_id;
public int id;
public void readParams(AbstractSerializedData stream, boolean exception) {
user_id = stream.readInt32(exception);
id = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(user_id);
stream.writeInt32(id);
}
}
public static class TL_updateDeleteMessages extends Update {
public static int constructor = 0xa20db0e5;
@ -22024,6 +22202,51 @@ public class TLRPC {
}
}
public static class TL_updatePinnedChannelMessages extends Update {
public static int constructor = 0x8588878b;
public int flags;
public boolean pinned;
public int channel_id;
public ArrayList<Integer> messages = new ArrayList<>();
public int pts;
public int pts_count;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
pinned = (flags & 1) != 0;
channel_id = stream.readInt32(exception);
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++) {
messages.add(stream.readInt32(exception));
}
pts = stream.readInt32(exception);
pts_count = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = pinned ? (flags | 1) : (flags &~ 1);
stream.writeInt32(flags);
stream.writeInt32(channel_id);
stream.writeInt32(0x1cb5c415);
int count = messages.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
stream.writeInt32(messages.get(a));
}
stream.writeInt32(pts);
stream.writeInt32(pts_count);
}
}
public static class TL_updateReadFeaturedStickers extends Update {
public static int constructor = 0x571d2742;
@ -22451,27 +22674,6 @@ public class TLRPC {
}
}
public static class TL_updateChatPinnedMessage extends Update {
public static int constructor = 0xe10db349;
public int chat_id;
public int id;
public int version;
public void readParams(AbstractSerializedData stream, boolean exception) {
chat_id = stream.readInt32(exception);
id = stream.readInt32(exception);
version = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(chat_id);
stream.writeInt32(id);
stream.writeInt32(version);
}
}
public static class TL_updateEditMessage extends Update {
public static int constructor = 0xe40370a3;
@ -22774,24 +22976,6 @@ public class TLRPC {
}
}
public static class TL_updateChannelPinnedMessage extends Update {
public static int constructor = 0x98592475;
public int channel_id;
public int id;
public void readParams(AbstractSerializedData stream, boolean exception) {
channel_id = stream.readInt32(exception);
id = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(channel_id);
stream.writeInt32(id);
}
}
public static class TL_updateLangPack extends Update {
public static int constructor = 0x56022f4d;
@ -23485,6 +23669,51 @@ public class TLRPC {
}
}
public static class TL_updatePinnedMessages extends Update {
public static int constructor = 0xed85eab5;
public int flags;
public boolean pinned;
public Peer peer;
public ArrayList<Integer> messages = new ArrayList<>();
public int pts;
public int pts_count;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
pinned = (flags & 1) != 0;
peer = Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
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++) {
messages.add(stream.readInt32(exception));
}
pts = stream.readInt32(exception);
pts_count = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = pinned ? (flags | 1) : (flags &~ 1);
stream.writeInt32(flags);
peer.serializeToStream(stream);
stream.writeInt32(0x1cb5c415);
int count = messages.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
stream.writeInt32(messages.get(a));
}
stream.writeInt32(pts);
stream.writeInt32(pts_count);
}
}
public static class TL_updateDcOptions extends Update {
public static int constructor = 0x8e5e9873;
@ -28237,6 +28466,9 @@ public class TLRPC {
switch (constructor) {
case 0x1c0facaf:
result = new TL_channelParticipantBanned();
break;
case 0xc3c6796b:
result = new TL_channelParticipantLeft();
break;
case 0x222c1886:
result = new TL_channelParticipantBanned_layer92();
@ -28309,6 +28541,20 @@ public class TLRPC {
}
}
public static class TL_channelParticipantLeft extends ChannelParticipant {
public static int constructor = 0xc3c6796b;
public void readParams(AbstractSerializedData stream, boolean exception) {
user_id = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(user_id);
}
}
public static class TL_channelParticipantCreator_layer103 extends TL_channelParticipantCreator {
public static int constructor = 0xe3e2e1f9;
@ -32266,6 +32512,9 @@ public class TLRPC {
case 0xe7026d0d:
result = new TL_inputMessagesFilterGeo();
break;
case 0x1bb00451:
result = new TL_inputMessagesFilterPinned();
break;
case 0xc1f8e69a:
result = new TL_inputMessagesFilterMyMentions();
break;
@ -32382,6 +32631,15 @@ public class TLRPC {
}
}
public static class TL_inputMessagesFilterPinned extends MessagesFilter {
public static int constructor = 0x1bb00451;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_inputMessagesFilterMyMentions extends MessagesFilter {
public static int constructor = 0xc1f8e69a;
@ -36865,12 +37123,12 @@ public class TLRPC {
}
public static class TL_messages_search extends TLObject {
public static int constructor = 0x4e17810b;
public static int constructor = 0xc352eec;
public int flags;
public InputPeer peer;
public String q;
public InputUser from_id;
public InputPeer from_id;
public int top_msg_id;
public MessagesFilter filter;
public int min_date;
@ -40262,6 +40520,8 @@ public class TLRPC {
public int flags;
public boolean silent;
public boolean unpin;
public boolean pm_oneside;
public InputPeer peer;
public int id;
@ -40272,6 +40532,8 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = silent ? (flags | 1) : (flags &~ 1);
flags = unpin ? (flags | 2) : (flags &~ 2);
flags = pm_oneside ? (flags | 4) : (flags &~ 4);
stream.writeInt32(flags);
peer.serializeToStream(stream);
stream.writeInt32(id);
@ -40938,6 +41200,21 @@ public class TLRPC {
}
}
public static class TL_messages_unpinAllMessages extends TLObject {
public static int constructor = 0xf025bc8b;
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_help_getAppChangelog extends TLObject {
public static int constructor = 0x9010ef6f;
@ -42736,6 +43013,7 @@ public class TLRPC {
public boolean shipping_address_requested;
public Photo photo;
public GeoPoint geo;
public int heading;
public String currency;
public String description;
public int receipt_msg_id;
@ -42759,6 +43037,7 @@ public class TLRPC {
public boolean test;
public int period;
public int ttl_seconds;
public int proximity_notification_radius;
public static MessageMedia TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
MessageMedia result = null;
@ -42784,8 +43063,11 @@ public class TLRPC {
case 0x7912b71f:
result = new TL_messageMediaVenue_layer71();
break;
case 0xb940c666:
result = new TL_messageMediaGeoLive();
break;
case 0x7c3c2609:
result = new TL_messageMediaGeoLive();
result = new TL_messageMediaGeoLive_layer119();
break;
case 0x2ec0533f:
result = new TL_messageMediaVenue();
@ -43259,6 +43541,7 @@ public class TLRPC {
public boolean from_scheduled;
public boolean legacy;
public boolean edit_hide;
public boolean pinned;
public MessageFwdHeader fwd_from;
public int via_bot_id;
public TL_messageReplyHeader reply_to;
@ -44039,6 +44322,7 @@ public class TLRPC {
from_scheduled = (flags & 262144) != 0;
legacy = (flags & 524288) != 0;
edit_hide = (flags & 2097152) != 0;
pinned = (flags & 16777216) != 0;
id = stream.readInt32(exception);
if ((flags & 256) != 0) {
from_id = Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
@ -44131,6 +44415,7 @@ public class TLRPC {
flags = from_scheduled ? (flags | 262144) : (flags &~ 262144);
flags = legacy ? (flags | 524288) : (flags &~ 524288);
flags = edit_hide ? (flags | 2097152) : (flags &~ 2097152);
flags = pinned ? (flags | 16777216) : (flags &~ 16777216);
stream.writeInt32(flags);
stream.writeInt32(id);
if ((flags & 256) != 0) {

View File

@ -948,9 +948,16 @@ public class ActionBarLayout extends FrameLayout {
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
if (preview) {
int height = fragment.getPreviewHeight();
int statusBarHeight = (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0);
if (height > 0 && height < getMeasuredHeight() - statusBarHeight) {
layoutParams.height = height;
layoutParams.topMargin = statusBarHeight + (getMeasuredHeight() - statusBarHeight - height) / 2;
} else {
layoutParams.topMargin = layoutParams.bottomMargin = AndroidUtilities.dp(46);
layoutParams.topMargin += AndroidUtilities.statusBarHeight;
}
layoutParams.rightMargin = layoutParams.leftMargin = AndroidUtilities.dp(8);
layoutParams.topMargin = layoutParams.bottomMargin = AndroidUtilities.dp(46);
layoutParams.topMargin += AndroidUtilities.statusBarHeight;
} else {
layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = layoutParams.leftMargin = 0;
}
@ -1183,6 +1190,7 @@ public class ActionBarLayout extends FrameLayout {
fragment.setParentLayout(null);
fragmentsStack.remove(fragment);
containerViewBack.setVisibility(View.INVISIBLE);
containerViewBack.setTranslationY(0);
bringChildToFront(containerView);
}
@ -1208,6 +1216,7 @@ public class ActionBarLayout extends FrameLayout {
}
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fragment.fragmentView.getLayoutParams();
layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = layoutParams.leftMargin = 0;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragment.fragmentView.setLayoutParams(layoutParams);
presentFragmentInternalRemoveOld(false, prevFragment);

View File

@ -704,20 +704,21 @@ public class ActionBarMenuItem extends FrameLayout {
}.setDuration(150)).addTransition(changeBounds);
transition.setOrdering(TransitionSet.ORDERING_TOGETHER);
transition.setInterpolator(CubicBezierInterpolator.EASE_OUT);
int selectedAccount = UserConfig.selectedAccount;
transition.addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
notificationIndex = NotificationCenter.getInstance(UserConfig.selectedAccount).setAnimationInProgress(notificationIndex,null);
notificationIndex = NotificationCenter.getInstance(selectedAccount).setAnimationInProgress(notificationIndex,null);
}
@Override
public void onTransitionEnd(Transition transition) {
NotificationCenter.getInstance(UserConfig.selectedAccount).onAnimationFinish(notificationIndex);
NotificationCenter.getInstance(selectedAccount).onAnimationFinish(notificationIndex);
}
@Override
public void onTransitionCancel(Transition transition) {
NotificationCenter.getInstance(UserConfig.selectedAccount).onAnimationFinish(notificationIndex);
NotificationCenter.getInstance(selectedAccount).onAnimationFinish(notificationIndex);
}
@Override

View File

@ -34,7 +34,9 @@ import android.widget.ScrollView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.LayoutHelper;
import java.lang.reflect.Field;
@ -51,6 +53,10 @@ public class ActionBarPopupWindow extends PopupWindow {
private AnimatorSet windowAnimatorSet;
private boolean animationEnabled = allowAnimation;
private int dismissAnimationDuration = 150;
private boolean isClosingAnimated;
private int currentAccount = UserConfig.selectedAccount;
private boolean pauseNotifications;
static {
Field f = null;
try {
@ -68,6 +74,7 @@ public class ActionBarPopupWindow extends PopupWindow {
private ViewTreeObserver.OnScrollChangedListener mSuperScrollListener;
private ViewTreeObserver mViewTreeObserver;
private int popupAnimationIndex = -1;
public interface OnDispatchKeyEventListener {
void onDispatchKeyEvent(KeyEvent keyEvent);
@ -426,12 +433,7 @@ public class ActionBarPopupWindow extends PopupWindow {
ObjectAnimator.ofFloat(content, "backScaleY", 0.0f, 1.0f),
ObjectAnimator.ofInt(content, "backAlpha", 0, 255));
windowAnimatorSet.setDuration(150 + 16 * visibleCount);
windowAnimatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
windowAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
windowAnimatorSet = null;
@ -442,16 +444,6 @@ public class ActionBarPopupWindow extends PopupWindow {
child.setAlpha(1.0f);
}
}
@Override
public void onAnimationCancel(Animator animation) {
onAnimationEnd(animation);
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
windowAnimatorSet.start();
}
@ -480,12 +472,22 @@ public class ActionBarPopupWindow extends PopupWindow {
dismiss(true);
}
public void setPauseNotifications(boolean value) {
pauseNotifications = value;
}
public void dismiss(boolean animated) {
setFocusable(false);
if (animationEnabled && animated) {
if (windowAnimatorSet != null) {
windowAnimatorSet.cancel();
if (windowAnimatorSet != null) {
if (animated && isClosingAnimated) {
return;
}
windowAnimatorSet.cancel();
windowAnimatorSet = null;
}
isClosingAnimated = false;
if (animationEnabled && animated) {
isClosingAnimated = true;
ActionBarPopupWindowLayout content = (ActionBarPopupWindowLayout) getContentView();
if (content.itemAnimators != null && !content.itemAnimators.isEmpty()) {
for (int a = 0, N = content.itemAnimators.size(); a < N; a++) {
@ -500,15 +502,11 @@ public class ActionBarPopupWindow extends PopupWindow {
ObjectAnimator.ofFloat(content, View.TRANSLATION_Y, AndroidUtilities.dp(content.showedFromBotton ? 5 : -5)),
ObjectAnimator.ofFloat(content, View.ALPHA, 0.0f));
windowAnimatorSet.setDuration(dismissAnimationDuration);
windowAnimatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
windowAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
windowAnimatorSet = null;
isClosingAnimated = false;
setFocusable(false);
try {
ActionBarPopupWindow.super.dismiss();
@ -516,18 +514,14 @@ public class ActionBarPopupWindow extends PopupWindow {
}
unregisterListener();
}
@Override
public void onAnimationCancel(Animator animation) {
onAnimationEnd(animation);
}
@Override
public void onAnimationRepeat(Animator animation) {
if (pauseNotifications) {
NotificationCenter.getInstance(currentAccount).onAnimationFinish(popupAnimationIndex);
}
}
});
if (pauseNotifications) {
popupAnimationIndex = NotificationCenter.getInstance(currentAccount).setAnimationInProgress(popupAnimationIndex, null);
}
windowAnimatorSet.start();
} else {
try {

View File

@ -13,8 +13,6 @@ import android.view.Window;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.SharedConfig;
@ -127,11 +125,12 @@ public class AdjustPanLayoutHelper {
onPanTranslationUpdate(-y, v, isKeyboardVisible);
});
animationInProgress = true;
int selectedAccount = UserConfig.selectedAccount;
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
animationInProgress = false;
NotificationCenter.getInstance(UserConfig.selectedAccount).onAnimationFinish(notificationsIndex);
NotificationCenter.getInstance(selectedAccount).onAnimationFinish(notificationsIndex);
animator = null;
setViewHeight(ViewGroup.LayoutParams.MATCH_PARENT);
viewsToHeightSet.clear();
@ -144,7 +143,7 @@ public class AdjustPanLayoutHelper {
animator.setDuration(220);
animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
notificationsIndex = NotificationCenter.getInstance(UserConfig.selectedAccount).setAnimationInProgress(notificationsIndex, null);
notificationsIndex = NotificationCenter.getInstance(selectedAccount).setAnimationInProgress(notificationsIndex, null);
animator.start();
}

View File

@ -83,6 +83,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
private CharSequence subtitle;
private CharSequence message;
private int topResId;
private View topView;
private int topAnimationId;
private int topHeight = 132;
private Drawable topDrawable;
@ -270,6 +271,14 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
topImageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(topHeight), MeasureSpec.EXACTLY));
availableHeight -= topImageView.getMeasuredHeight() - AndroidUtilities.dp(8);
}
if (topView != null) {
int w = width - AndroidUtilities.dp(16);
float scale = w / 936.0f;
int h = (int) (354 * scale);
topView.measure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY));
topView.getLayoutParams().height = h;
availableHeight -= topView.getMeasuredHeight();
}
if (progressViewStyle == 0) {
layoutParams = (LayoutParams) contentScrollView.getLayoutParams();
@ -398,6 +407,9 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
topImageView.getBackground().setColorFilter(new PorterDuffColorFilter(topBackgroundColor, PorterDuff.Mode.MULTIPLY));
topImageView.setPadding(0, 0, 0, 0);
containerView.addView(topImageView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, topHeight, Gravity.LEFT | Gravity.TOP, -8, -8, 0, 0));
} else if (topView != null) {
topView.setPadding(0, 0, 0, 0);
containerView.addView(topView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, topHeight, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
}
if (title != null) {
@ -1102,6 +1114,11 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
return this;
}
public Builder setTopView(View view) {
alertDialog.topView = view;
return this;
}
public Builder setTopAnimation(int resId, int backgroundColor) {
alertDialog.topAnimationId = resId;
alertDialog.topBackgroundColor = backgroundColor;

View File

@ -42,6 +42,7 @@ import org.telegram.messenger.SecretChatHelper;
import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList;
@ -429,6 +430,10 @@ public class BaseFragment {
}
}
protected int getPreviewHeight() {
return LayoutHelper.MATCH_PARENT;
}
protected void onBecomeFullyHidden() {
}

View File

@ -52,7 +52,6 @@ import org.telegram.messenger.LocaleController;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.CubicBezierInterpolator;
@ -521,9 +520,6 @@ public class BottomSheet extends Dialog {
float translation = 0;
if (Build.VERSION.SDK_INT >= 29 && getAdditionalMandatoryOffsets() > 0) {
float dist = containerView.getMeasuredHeight() - containerView.getTranslationY();
if (currentSheetAnimationType == 1) {
dist *= 0.1f;
}
translation = Math.max(0, bottomInset - dist);
}
int navBarHeight = drawNavigationBar ? bottomInset : 0;
@ -678,11 +674,6 @@ public class BottomSheet extends Dialog {
}
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
}
public void setAllowNestedScroll(boolean value) {
allowNestedScroll = value;
if (!allowNestedScroll) {
@ -1247,6 +1238,10 @@ public class BottomSheet extends Dialog {
return this;
}
public View getCustomView() {
return bottomSheet.customView;
}
public Builder setTitle(CharSequence title) {
return setTitle(title, false);
}

View File

@ -164,7 +164,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
}
}
private boolean createLayout(int width) {
protected boolean createLayout(int width) {
if (text != null) {
try {
if (leftDrawable != null) {

View File

@ -83,11 +83,18 @@ import org.telegram.ui.Cells.ThemesHorizontalListCell;
import org.telegram.ui.Components.AudioVisualizerDrawable;
import org.telegram.ui.Components.BackgroundGradientDrawable;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.MsgClockDrawable;
import org.telegram.ui.Components.PathAnimator;
import org.telegram.ui.Components.PlayingGameDrawable;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RecordStatusDrawable;
import org.telegram.ui.Components.RoundStatusDrawable;
import org.telegram.ui.Components.ScamDrawable;
import org.telegram.ui.Components.SendingFileDrawable;
import org.telegram.ui.Components.StatusDrawable;
import org.telegram.ui.Components.SvgHelper;
import org.telegram.ui.Components.ThemeEditorView;
import org.telegram.ui.Components.TypingDotsDrawable;
import java.io.File;
import java.io.FileInputStream;
@ -106,6 +113,7 @@ import java.util.HashSet;
import java.util.Locale;
import androidx.annotation.UiThread;
import androidx.core.graphics.ColorUtils;
public class Theme {
@ -220,6 +228,10 @@ public class Theme {
isBottomNear = bottomNear;
}
public int getTopY() {
return topY;
}
private int dp(float value) {
if (currentType == TYPE_PREVIEW) {
return (int) Math.ceil(3 * value);
@ -479,7 +491,7 @@ public class Theme {
}
}
if (currentType == TYPE_MEDIA) {
if (currentType == TYPE_PREVIEW || paintToUse != null || topY + bounds.bottom - rad < currentBackgroundHeight) {
if (paintToUse != null || topY + bounds.bottom - rad < currentBackgroundHeight) {
int radToUse = isBottomNear ? nearRad : rad;
path.lineTo(bounds.right - padding, bounds.bottom - padding - radToUse);
@ -534,7 +546,7 @@ public class Theme {
}
}
if (currentType == TYPE_MEDIA) {
if (currentType == TYPE_PREVIEW || paintToUse != null || topY + bounds.bottom - rad < currentBackgroundHeight) {
if (paintToUse != null || topY + bounds.bottom - rad < currentBackgroundHeight) {
int radToUse = isBottomNear ? nearRad : rad;
path.lineTo(bounds.left + padding, bounds.bottom - padding - radToUse);
@ -556,8 +568,9 @@ public class Theme {
path.close();
canvas.drawPath(path, p);
if (gradientShader != null && isSelected) {
selectedPaint.setColor(getColor(key_chat_outBubbleGradientSelectedOverlay));
if (gradientShader != null && isSelected && paintToUse == null) {
int color = getColor(key_chat_outBubbleGradientSelectedOverlay);
selectedPaint.setColor(ColorUtils.setAlphaComponent(color, (int) (Color.alpha(color) * alpha / 255f)));
canvas.drawPath(path, selectedPaint);
}
}
@ -975,7 +988,7 @@ public class Theme {
int subTextColor;
int seekbarColor;
if (useBlackText(myMessagesAccentColor, myMessagesGradientAccentColor)) {
textColor = 0xff000000;
textColor = 0xff212121;
subTextColor = 0xff555555;
seekbarColor = 0x4d000000;
} else {
@ -1010,6 +1023,7 @@ public class Theme {
currentColors.put(key_chat_outPreviewInstantSelectedText, textColor);
currentColors.put(key_chat_outViews, textColor);
currentColors.put(key_chat_outViewsSelected, textColor);
currentColors.put(key_chat_outAudioTitleText, textColor);
currentColors.put(key_chat_outFileNameText, textColor);
@ -1976,6 +1990,7 @@ public class Theme {
public static Paint dialogs_countPaint;
public static Paint dialogs_errorPaint;
public static Paint dialogs_countGrayPaint;
public static Paint dialogs_actionMessagePaint;
public static TextPaint[] dialogs_namePaint;
public static TextPaint[] dialogs_nameEncryptedPaint;
public static TextPaint dialogs_searchNamePaint;
@ -2083,6 +2098,7 @@ public class Theme {
public static MessageDrawable chat_msgInMediaSelectedDrawable;
public static MessageDrawable chat_msgOutMediaDrawable;
public static MessageDrawable chat_msgOutMediaSelectedDrawable;
private static StatusDrawable[] chat_status_drawables = new StatusDrawable[5];
public static PathAnimator playPauseAnimator;
public static Drawable chat_msgOutCheckDrawable;
@ -2111,6 +2127,12 @@ public class Theme {
public static Drawable chat_msgInRepliesSelectedDrawable;
public static Drawable chat_msgOutRepliesDrawable;
public static Drawable chat_msgOutRepliesSelectedDrawable;
public static Drawable chat_msgInPinnedDrawable;
public static Drawable chat_msgInPinnedSelectedDrawable;
public static Drawable chat_msgOutPinnedDrawable;
public static Drawable chat_msgOutPinnedSelectedDrawable;
public static Drawable chat_msgStickerPinnedDrawable;
public static Drawable chat_msgMediaPinnedDrawable;
public static Drawable chat_msgMediaViewsDrawable;
public static Drawable chat_msgMediaRepliesDrawable;
public static Drawable chat_msgInMenuDrawable;
@ -3425,10 +3447,10 @@ public class Theme {
defaultColors.put(key_chat_messagePanelVoiceDuration, 0xffffffff);
defaultColors.put(key_chat_inlineResultIcon, 0xff5795cc);
defaultColors.put(key_chat_topPanelBackground, 0xffffffff);
defaultColors.put(key_chat_topPanelClose, 0xff8c959a);
defaultColors.put(key_chat_topPanelClose, 0xff8b969b);
defaultColors.put(key_chat_topPanelLine, 0xff6c9fd2);
defaultColors.put(key_chat_topPanelTitle, 0xff3a8ccf);
defaultColors.put(key_chat_topPanelMessage, 0xff999999);
defaultColors.put(key_chat_topPanelMessage, 0xff878e91);
defaultColors.put(key_chat_reportSpam, 0xffcf5957);
defaultColors.put(key_chat_addContact, 0xff4a82b5);
defaultColors.put(key_chat_inLoader, 0xff72b5e8);
@ -3522,7 +3544,7 @@ public class Theme {
defaultColors.put(key_inappPlayerTitle, 0xff2f3438);
defaultColors.put(key_inappPlayerBackground, 0xffffffff);
defaultColors.put(key_inappPlayerPlayPause, 0xff62b0eb);
defaultColors.put(key_inappPlayerClose, 0xffa8a8a8);
defaultColors.put(key_inappPlayerClose, 0xff8b969b);
defaultColors.put(key_returnToCallBackground, 0xff44a1e3);
defaultColors.put(key_returnToCallText, 0xffffffff);
@ -4373,6 +4395,8 @@ public class Theme {
eventType = 0;
} else if (monthOfYear == 1 && dayOfMonth == 14) {
eventType = 1;
} else if (monthOfYear == 9 && dayOfMonth >= 30 || monthOfYear == 10 && dayOfMonth == 1 && hour < 12) {
eventType = 2;
}
return eventType;
}
@ -6621,13 +6645,14 @@ public class Theme {
dialogs_countPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dialogs_countGrayPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dialogs_errorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dialogs_actionMessagePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dialogs_lockDrawable = resources.getDrawable(R.drawable.list_secret);
dialogs_checkDrawable = resources.getDrawable(R.drawable.list_check).mutate();
dialogs_playDrawable = resources.getDrawable(R.drawable.minithumb_play).mutate();
dialogs_checkReadDrawable = resources.getDrawable(R.drawable.list_check).mutate();
dialogs_halfCheckDrawable = resources.getDrawable(R.drawable.list_halfcheck);
dialogs_clockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
dialogs_clockDrawable = new MsgClockDrawable();
dialogs_errorDrawable = resources.getDrawable(R.drawable.list_warning_sign);
dialogs_reorderDrawable = resources.getDrawable(R.drawable.list_reorder).mutate();
dialogs_groupDrawable = resources.getDrawable(R.drawable.list_group);
@ -6674,6 +6699,7 @@ public class Theme {
dialogs_archiveTextPaint.setColor(getColor(key_chats_archiveText));
dialogs_countPaint.setColor(getColor(key_chats_unreadCounter));
dialogs_countGrayPaint.setColor(getColor(key_chats_unreadCounterMuted));
dialogs_actionMessagePaint.setColor(getColor(key_chats_actionMessage));
dialogs_errorPaint.setColor(getColor(key_chats_sentError));
dialogs_onlinePaint.setColor(getColor(key_windowBackgroundWhiteBlueText3));
dialogs_offlinePaint.setColor(getColor(key_windowBackgroundWhiteGrayText3));
@ -6833,12 +6859,12 @@ public class Theme {
chat_msgOutHalfCheckSelectedDrawable = resources.getDrawable(R.drawable.msg_halfcheck).mutate();
chat_msgMediaHalfCheckDrawable = resources.getDrawable(R.drawable.msg_halfcheck_s).mutate();
chat_msgStickerHalfCheckDrawable = resources.getDrawable(R.drawable.msg_halfcheck_s).mutate();
chat_msgOutClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgOutSelectedClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgInClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgInSelectedClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgMediaClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgStickerClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgOutClockDrawable = new MsgClockDrawable();
chat_msgOutSelectedClockDrawable = new MsgClockDrawable();
chat_msgInClockDrawable = new MsgClockDrawable();
chat_msgInSelectedClockDrawable = new MsgClockDrawable();
chat_msgMediaClockDrawable = new MsgClockDrawable();
chat_msgStickerClockDrawable = new MsgClockDrawable();
chat_msgInViewsDrawable = resources.getDrawable(R.drawable.msg_views).mutate();
chat_msgInViewsSelectedDrawable = resources.getDrawable(R.drawable.msg_views).mutate();
chat_msgOutViewsDrawable = resources.getDrawable(R.drawable.msg_views).mutate();
@ -6847,6 +6873,12 @@ public class Theme {
chat_msgInRepliesSelectedDrawable = resources.getDrawable(R.drawable.msg_reply_small).mutate();
chat_msgOutRepliesDrawable = resources.getDrawable(R.drawable.msg_reply_small).mutate();
chat_msgOutRepliesSelectedDrawable = resources.getDrawable(R.drawable.msg_reply_small).mutate();
chat_msgInPinnedDrawable = resources.getDrawable(R.drawable.msg_pin_mini).mutate();
chat_msgInPinnedSelectedDrawable = resources.getDrawable(R.drawable.msg_pin_mini).mutate();
chat_msgOutPinnedDrawable = resources.getDrawable(R.drawable.msg_pin_mini).mutate();
chat_msgOutPinnedSelectedDrawable = resources.getDrawable(R.drawable.msg_pin_mini).mutate();
chat_msgMediaPinnedDrawable = resources.getDrawable(R.drawable.msg_pin_mini).mutate();
chat_msgStickerPinnedDrawable = resources.getDrawable(R.drawable.msg_pin_mini).mutate();
chat_msgMediaViewsDrawable = resources.getDrawable(R.drawable.msg_views).mutate();
chat_msgMediaRepliesDrawable = resources.getDrawable(R.drawable.msg_reply_small).mutate();
chat_msgStickerViewsDrawable = resources.getDrawable(R.drawable.msg_views).mutate();
@ -7180,6 +7212,12 @@ public class Theme {
setDrawableColorByKey(chat_msgInRepliesSelectedDrawable, key_chat_inViewsSelected);
setDrawableColorByKey(chat_msgOutRepliesDrawable, key_chat_outViews);
setDrawableColorByKey(chat_msgOutRepliesSelectedDrawable, key_chat_outViewsSelected);
setDrawableColorByKey(chat_msgInPinnedDrawable, key_chat_inViews);
setDrawableColorByKey(chat_msgInPinnedSelectedDrawable, key_chat_inViewsSelected);
setDrawableColorByKey(chat_msgOutPinnedDrawable, key_chat_outViews);
setDrawableColorByKey(chat_msgOutPinnedSelectedDrawable, key_chat_outViewsSelected);
setDrawableColorByKey(chat_msgMediaPinnedDrawable, key_chat_mediaViews);
setDrawableColorByKey(chat_msgStickerPinnedDrawable, key_chat_serviceText);
setDrawableColorByKey(chat_msgMediaViewsDrawable, key_chat_mediaViews);
setDrawableColorByKey(chat_msgMediaRepliesDrawable, key_chat_mediaViews);
setDrawableColorByKey(chat_msgInMenuDrawable, key_chat_inMenu);
@ -7217,6 +7255,10 @@ public class Theme {
setDrawableColorByKey(calllog_msgCallDownRedDrawable, key_calls_callReceivedRedIcon);
setDrawableColorByKey(calllog_msgCallDownGreenDrawable, key_calls_callReceivedGreenIcon);
for (int i = 0; i < chat_status_drawables.length; i++) {
setDrawableColorByKey(chat_status_drawables[i], key_chats_actionMessage);
}
for (int a = 0; a < 2; a++) {
setCombinedDrawableColor(chat_fileMiniStatesDrawable[a][0], getColor(key_chat_outLoader), false);
setCombinedDrawableColor(chat_fileMiniStatesDrawable[a][0], getColor(key_chat_outMediaIcon), true);
@ -7595,7 +7637,9 @@ public class Theme {
if (drawable == null) {
return;
}
if (drawable instanceof ShapeDrawable) {
if (drawable instanceof MsgClockDrawable) {
((MsgClockDrawable) drawable).setColor(color);
} else if (drawable instanceof ShapeDrawable) {
((ShapeDrawable) drawable).getPaint().setColor(color);
} else if (drawable instanceof ScamDrawable) {
((ScamDrawable) drawable).setColor(color);
@ -7614,20 +7658,16 @@ public class Theme {
public static void setEmojiDrawableColor(Drawable drawable, int color, boolean selected) {
if (drawable instanceof StateListDrawable) {
try {
Drawable state;
if (selected) {
Drawable state = getStateDrawable(drawable, 0);
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
}
state = getStateDrawable(drawable, 0);
} else {
Drawable state = getStateDrawable(drawable, 1);
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
}
state = getStateDrawable(drawable, 1);
}
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
}
} catch (Throwable ignore) {
@ -7652,26 +7692,22 @@ public class Theme {
public static void setSelectorDrawableColor(Drawable drawable, int color, boolean selected) {
if (drawable instanceof StateListDrawable) {
try {
Drawable state;
if (selected) {
Drawable state = getStateDrawable(drawable, 0);
state = getStateDrawable(drawable, 0);
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
}
state = getStateDrawable(drawable, 1);
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
}
} else {
Drawable state = getStateDrawable(drawable, 2);
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
}
state = getStateDrawable(drawable, 2);
}
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
}
} catch (Throwable ignore) {
@ -8108,4 +8144,35 @@ public class Theme {
}
return animatedOutVisualizerDrawables.get(messageObject);
}
public static StatusDrawable getChatStatusDrawable(int type) {
if (type < 0 || type > 4) {
return null;
}
StatusDrawable statusDrawable = chat_status_drawables[type];
if (statusDrawable != null) {
return statusDrawable;
}
switch (type) {
case 0:
chat_status_drawables[0] = new TypingDotsDrawable(true);
break;
case 1:
chat_status_drawables[1] = new RecordStatusDrawable(true);
break;
case 2:
chat_status_drawables[2] = new SendingFileDrawable(true);
break;
case 3:
chat_status_drawables[3] = new PlayingGameDrawable(true);
break;
case 4:
chat_status_drawables[4] = new RoundStatusDrawable(true);
break;
}
statusDrawable = chat_status_drawables[type];
statusDrawable.start();
statusDrawable.setColor(getColor(key_chats_actionMessage));
return statusDrawable;
}
}

View File

@ -353,6 +353,10 @@ public class ThemeDescription {
}
} else if (viewToInvalidate instanceof ContextProgressView) {
((ContextProgressView) viewToInvalidate).updateColors();
} else if (viewToInvalidate instanceof SeekBarView) {
if ((changeFlags & FLAG_PROGRESSBAR) != 0) {
((SeekBarView) viewToInvalidate).setOuterColor(color);
}
}
if ((changeFlags & FLAG_TEXTCOLOR) != 0) {
if ((changeFlags & FLAG_CHECKTAG) == 0 || checkTag(currentKey, viewToInvalidate)) {

View File

@ -45,6 +45,8 @@ import org.telegram.ui.Cells.HintDialogCell;
import org.telegram.ui.Cells.LoadingCell;
import org.telegram.ui.Cells.ProfileSearchCell;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.ForegroundColorSpanThemable;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.FilteredSearchView;
@ -56,8 +58,6 @@ import java.util.concurrent.ConcurrentHashMap;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.exoplayer2.util.Log;
public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private Context mContext;
@ -179,7 +179,6 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
@Override
public void onDataSetChanged(int searchId) {
waitingResponseCount--;
Log.d("kek", "data set change " + waitingResponseCount);
lastGlobalSearchId = searchId;
if (lastLocalSearchId != searchId) {
searchResult.clear();
@ -340,7 +339,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
}
notifyDataSetChanged();
if (delegate != null && req.offset_id == 0) {
if (delegate != null) {
delegate.searchStateChanged(waitingResponseCount > 0, true);
delegate.runResultsEnterAnimation();
}
@ -567,7 +566,6 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private void updateSearchResults(final ArrayList<TLObject> result, final ArrayList<CharSequence> names, final ArrayList<TLRPC.User> encUsers, final int searchId) {
AndroidUtilities.runOnUIThread(() -> {
waitingResponseCount--;
Log.d("kek", "update local search " + waitingResponseCount);
if (searchId != lastSearchId) {
return;
}
@ -862,7 +860,10 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
view = new DialogCell(mContext, false, true);
break;
case 3:
view = new LoadingCell(mContext);
FlickerLoadingView flickerLoadingView = new FlickerLoadingView(mContext);
flickerLoadingView.setViewType(FlickerLoadingView.DIALOG_TYPE);
flickerLoadingView.setIsSingleCell(true);
view = flickerLoadingView;
break;
case 4:
view = new HashtagSearchCell(mContext);
@ -872,7 +873,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
if (getParent() != null && getParent().getParent() != null) {
getParent().getParent().requestDisallowInterceptTouchEvent(canScrollHorizontally(-1));
getParent().getParent().requestDisallowInterceptTouchEvent(canScrollHorizontally(-1) || canScrollHorizontally(1));
}
return super.onInterceptTouchEvent(e);
}
@ -981,7 +982,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
if (nameSearch != null && (index = AndroidUtilities.indexOfIgnoreCase(nameSearch, foundUserName)) != -1) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(nameSearch);
spannableStringBuilder.setSpan(new ForegroundColorSpan(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4)), index, index + foundUserName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableStringBuilder.setSpan(new ForegroundColorSpanThemable(Theme.key_windowBackgroundWhiteBlueText4), index, index + foundUserName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
name = spannableStringBuilder;
} else if (un != null) {
if (foundUserName.startsWith("@")) {
@ -998,7 +999,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
} else {
index++;
}
spannableStringBuilder.setSpan(new ForegroundColorSpan(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4)), index, index + len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableStringBuilder.setSpan(new ForegroundColorSpanThemable(Theme.key_windowBackgroundWhiteBlueText4), index, index + len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
username = spannableStringBuilder;
} catch (Exception e) {

View File

@ -258,6 +258,16 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
settingsIcon = R.drawable.menu_settings_14;
inviteIcon = R.drawable.menu_secret_ny;
helpIcon = R.drawable.menu_help;
} else if (eventType == 2) {
newGroupIcon = R.drawable.menu_groups_hw;
newSecretIcon = R.drawable.menu_secret_hw;
newChannelIcon = R.drawable.menu_broadcast_hw;
contactsIcon = R.drawable.menu_contacts_hw;
callsIcon = R.drawable.menu_calls_hw;
savedIcon = R.drawable.menu_bookmarks_hw;
settingsIcon = R.drawable.menu_settings_hw;
inviteIcon = R.drawable.menu_invite_hw;
helpIcon = R.drawable.menu_help_hw;
} else {
newGroupIcon = R.drawable.menu_groups;
newSecretIcon = R.drawable.menu_secret;

View File

@ -18,6 +18,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -84,6 +85,14 @@ public class FiltersView extends RecyclerListView {
public boolean supportsPredictiveItemAnimations() {
return false;
}
@Override
public void onInitializeAccessibilityNodeInfo(@NonNull Recycler recycler, @NonNull State state, @NonNull AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(recycler, state, info);
if (!isEnabled()) {
info.setVisibleToUser(false);
}
}
};
layoutManager.setOrientation(HORIZONTAL);
setLayoutManager(layoutManager);

View File

@ -99,6 +99,12 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
}
}
public void updateLiveLocationCell() {
if (shareLiveLocationPotistion > 0) {
notifyItemChanged(shareLiveLocationPotistion);
}
}
public void updateLiveLocations() {
if (!currentLiveLocations.isEmpty()) {
notifyItemRangeChanged(2, currentLiveLocations.size(), new Object());
@ -212,7 +218,9 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
@Override
public int getItemCount() {
if (locationType == LocationActivity.LOCATION_TYPE_GROUP_VIEW) {
if (locationType == LocationActivity.LOCATION_TYPE_LIVE_VIEW) {
return 2;
} else if (locationType == LocationActivity.LOCATION_TYPE_GROUP_VIEW) {
return 2;
} else if (locationType == LocationActivity.LOCATION_TYPE_GROUP) {
return 2;
@ -221,13 +229,13 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
} else if (locationType == 2) {
return 2 + currentLiveLocations.size();
} else {
if (searching || !searching && places.isEmpty()) {
if (searching || places.isEmpty()) {
return (locationType != 0 ? 6 : 5) + (needEmptyView ? 1 : 0);
}
if (locationType == 1) {
return 5 + places.size() + (places.isEmpty() ? 0 : 1) + (needEmptyView ? 1 : 0);
return 6 + places.size() + (needEmptyView ? 1 : 0);
} else {
return 4 + places.size() + (places.isEmpty() ? 0 : 1) + (needEmptyView ? 1 : 0);
return 5 + places.size() + (needEmptyView ? 1 : 0);
}
}
}
@ -336,7 +344,9 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
break;
case 7:
SharingLiveLocationCell locationCell = (SharingLiveLocationCell) holder.itemView;
if (chatLocation != null) {
if (locationType == LocationActivity.LOCATION_TYPE_LIVE_VIEW) {
locationCell.setDialog(currentMessageObject, gpsLocation);
} else if (chatLocation != null) {
locationCell.setDialog(dialogId, chatLocation);
} else if (currentMessageObject != null && position == 1) {
locationCell.setDialog(currentMessageObject, gpsLocation);
@ -392,6 +402,9 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
if (position == 0) {
return 0;
}
if (locationType == LocationActivity.LOCATION_TYPE_LIVE_VIEW) {
return 7;
}
if (needEmptyView && position == getItemCount() - 1) {
return 10;
}
@ -436,7 +449,7 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
return 9;
} else if (position == 4) {
return 2;
} else if (searching || !searching && places.isEmpty()) {
} else if (searching || places.isEmpty()) {
return 4;
} else if (position == places.size() + 5) {
return 5;
@ -448,7 +461,7 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
return 9;
} else if (position == 3) {
return 2;
} else if (searching || !searching && places.isEmpty()) {
} else if (searching || places.isEmpty()) {
return 4;
} else if (position == places.size() + 4) {
return 5;

View File

@ -48,6 +48,7 @@ import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import androidx.recyclerview.widget.RecyclerView;
@ -65,8 +66,8 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter {
private long dialog_id;
private TLRPC.ChatFull info;
private SearchAdapterHelper searchAdapterHelper;
private ArrayList<TLRPC.User> searchResultUsernames;
private SparseArray<TLRPC.User> searchResultUsernamesMap;
private ArrayList<TLObject> searchResultUsernames;
private SparseArray<TLObject> searchResultUsernamesMap;
private Runnable searchGlobalRunnable;
private ArrayList<String> searchResultHashtags;
private ArrayList<String> searchResultCommands;
@ -683,9 +684,9 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter {
}
final String usernameString = result.toString().toLowerCase();
boolean hasSpace = usernameString.indexOf(' ') >= 0;
ArrayList<TLRPC.User> newResult = new ArrayList<>();
ArrayList<TLObject> newResult = new ArrayList<>();
final SparseArray<TLRPC.User> newResultsHashMap = new SparseArray<>();
final SparseArray<TLRPC.User> newMap = new SparseArray<>();
final SparseArray<TLObject> newMap = new SparseArray<>();
ArrayList<TLRPC.TL_topPeer> inlineBots = MediaDataController.getInstance(currentAccount).inlineBots;
if (!usernameOnly && needBotContext && dogPostion == 0 && !inlineBots.isEmpty()) {
int count = 0;
@ -706,61 +707,96 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter {
}
}
final TLRPC.Chat chat;
int threadId;
if (parentFragment != null) {
chat = parentFragment.getCurrentChat();
threadId = parentFragment.getThreadId();
} else if (info != null) {
chat = messagesController.getChat(info.id);
threadId = 0;
} else {
chat = null;
threadId = 0;
}
if (chat != null && info != null && info.participants != null && (!ChatObject.isChannel(chat) || chat.megagroup)) {
for (int a = 0; a < info.participants.participants.size(); a++) {
TLRPC.ChatParticipant chatParticipant = info.participants.participants.get(a);
TLRPC.User user = messagesController.getUser(chatParticipant.user_id);
if (user == null || !usernameOnly && UserObject.isUserSelf(user) || newResultsHashMap.indexOfKey(user.id) >= 0) {
continue;
}
if (usernameString.length() == 0) {
if (!user.deleted) {
newResult.add(user);
for (int a = -1; a < info.participants.participants.size(); a++) {
String username;
String firstName;
String lastName;
TLObject object;
int id;
if (a == -1) {
if (chat == null) {
continue;
}
if (usernameString.length() == 0) {
newResult.add(chat);
continue;
}
firstName = chat.title;
lastName = null;
username = chat.username;
object = chat;
id = -chat.id;
} else {
if (user.username != null && user.username.length() > 0 && user.username.toLowerCase().startsWith(usernameString)) {
newResult.add(user);
newMap.put(user.id, user);
} else {
if (user.first_name != null && user.first_name.length() > 0 && user.first_name.toLowerCase().startsWith(usernameString)) {
TLRPC.ChatParticipant chatParticipant = info.participants.participants.get(a);
TLRPC.User user = messagesController.getUser(chatParticipant.user_id);
if (user == null || !usernameOnly && UserObject.isUserSelf(user) || newResultsHashMap.indexOfKey(user.id) >= 0) {
continue;
}
if (usernameString.length() == 0) {
if (!user.deleted) {
newResult.add(user);
newMap.put(user.id, user);
} else if (user.last_name != null && user.last_name.length() > 0 && user.last_name.toLowerCase().startsWith(usernameString)) {
newResult.add(user);
newMap.put(user.id, user);
} else if (hasSpace && ContactsController.formatName(user.first_name, user.last_name).toLowerCase().startsWith(usernameString)) {
newResult.add(user);
newMap.put(user.id, user);
continue;
}
}
firstName = user.first_name;
lastName = user.last_name;
username = user.username;
object = user;
id = user.id;
}
if (!TextUtils.isEmpty(username) && username.toLowerCase().startsWith(usernameString) ||
!TextUtils.isEmpty(firstName) && firstName.toLowerCase().startsWith(usernameString) ||
!TextUtils.isEmpty(lastName) && lastName.toLowerCase().startsWith(usernameString) ||
hasSpace && ContactsController.formatName(firstName, lastName).toLowerCase().startsWith(usernameString)) {
newResult.add(object);
newMap.put(id, object);
}
}
}
Collections.sort(newResult, (lhs, rhs) -> {
if (newMap.indexOfKey(lhs.id) >= 0 && newMap.indexOfKey(rhs.id) >= 0) {
Collections.sort(newResult, new Comparator<TLObject>() {
private int getId(TLObject object) {
if (object instanceof TLRPC.User) {
return ((TLRPC.User) object).id;
} else {
return -((TLRPC.Chat) object).id;
}
}
@Override
public int compare(TLObject lhs, TLObject rhs) {
int id1 = getId(lhs);
int id2 = getId(rhs);
if (newMap.indexOfKey(id1) >= 0 && newMap.indexOfKey(id2) >= 0) {
return 0;
} else if (newMap.indexOfKey(id1) >= 0) {
return -1;
} else if (newMap.indexOfKey(id2) >= 0) {
return 1;
}
int lhsNum = users.indexOf(id1);
int rhsNum = users.indexOf(id2);
if (lhsNum != -1 && rhsNum != -1) {
return lhsNum < rhsNum ? -1 : (lhsNum == rhsNum ? 0 : 1);
} else if (lhsNum != -1 && rhsNum == -1) {
return -1;
} else if (lhsNum == -1 && rhsNum != -1) {
return 1;
}
return 0;
} else if (newMap.indexOfKey(lhs.id) >= 0) {
return -1;
} else if (newMap.indexOfKey(rhs.id) >= 0) {
return 1;
}
int lhsNum = users.indexOf(lhs.id);
int rhsNum = users.indexOf(rhs.id);
if (lhsNum != -1 && rhsNum != -1) {
return lhsNum < rhsNum ? -1 : (lhsNum == rhsNum ? 0 : 1);
} else if (lhsNum != -1 && rhsNum == -1) {
return -1;
} else if (lhsNum == -1 && rhsNum != -1) {
return 1;
}
return 0;
});
searchResultHashtags = null;
searchResultCommands = null;
@ -787,9 +823,14 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter {
req.channel = MessagesController.getInputChannel(chat);
req.limit = 20;
req.offset = 0;
TLRPC.TL_channelParticipantsSearch channelParticipantsSearch = new TLRPC.TL_channelParticipantsSearch();
channelParticipantsSearch.q = usernameString;
req.filter = channelParticipantsSearch;
TLRPC.TL_channelParticipantsMentions channelParticipantsMentions = new TLRPC.TL_channelParticipantsMentions();
channelParticipantsMentions.flags |= 1;
channelParticipantsMentions.q = usernameString;
if (threadId != 0) {
channelParticipantsMentions.flags |= 2;
channelParticipantsMentions.top_msg_id = threadId;
}
req.filter = channelParticipantsMentions;
final int currentReqId = ++channelLastReqId;
channelReqId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (channelReqId != 0 && currentReqId == channelLastReqId && searchResultUsernamesMap != null && searchResultUsernames != null) {
@ -887,7 +928,7 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter {
}
}
private void showUsersResult(ArrayList<TLRPC.User> newResult, SparseArray<TLRPC.User> newMap, boolean notify) {
private void showUsersResult(ArrayList<TLObject> newResult, SparseArray<TLObject> newMap, boolean notify) {
searchResultUsernames = newResult;
searchResultUsernamesMap = newMap;
if (cancelDelayRunnable != null) {
@ -1080,7 +1121,12 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter {
}
} else {
if (searchResultUsernames != null) {
((MentionCell) holder.itemView).setUser(searchResultUsernames.get(position));
TLObject object = searchResultUsernames.get(position);
if (object instanceof TLRPC.User) {
((MentionCell) holder.itemView).setUser((TLRPC.User) object);
} else if (object instanceof TLRPC.Chat) {
((MentionCell) holder.itemView).setChat((TLRPC.Chat) object);
}
} else if (searchResultHashtags != null) {
((MentionCell) holder.itemView).setText(searchResultHashtags.get(position));
} else if (searchResultSuggestions != null) {

View File

@ -33,6 +33,7 @@ import org.telegram.ui.Cells.GraySectionCell;
import org.telegram.ui.Cells.ProfileSearchCell;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Cells.UserCell;
import org.telegram.ui.Components.ForegroundColorSpanThemable;
import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList;
@ -330,7 +331,7 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
} else {
index++;
}
spannableStringBuilder.setSpan(new ForegroundColorSpan(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4)), index, index + len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableStringBuilder.setSpan(new ForegroundColorSpanThemable(Theme.key_windowBackgroundWhiteBlueText4), index, index + len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
username = spannableStringBuilder;
} catch (Exception e) {

View File

@ -463,14 +463,16 @@ public class SearchAdapterHelper {
state.step();
}
state.dispose();
MessagesStorage.getInstance(currentAccount).getDatabase().commitTransaction();
if (arrayList.size() >= 100) {
MessagesStorage.getInstance(currentAccount).getDatabase().beginTransaction();
if (arrayList.size() > 100) {
state = MessagesStorage.getInstance(currentAccount).getDatabase().executeFast("DELETE FROM hashtag_recent_v2 WHERE id = ?");
for (int a = 100; a < arrayList.size(); a++) {
MessagesStorage.getInstance(currentAccount).getDatabase().executeFast("DELETE FROM hashtag_recent_v2 WHERE id = '" + arrayList.get(a).hashtag + "'").stepThis().dispose();
state.requery();
state.bindString(1, arrayList.get(a).hashtag);
state.step();
}
MessagesStorage.getInstance(currentAccount).getDatabase().commitTransaction();
state.dispose();
}
MessagesStorage.getInstance(currentAccount).getDatabase().commitTransaction();
} catch (Exception e) {
FileLog.e(e);
}

View File

@ -1,6 +1,7 @@
package org.telegram.ui.Adapters;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.text.TextUtils;
@ -339,11 +340,13 @@ public class StickersSearchAdapter extends RecyclerListView.SelectionAdapter {
View view = null;
switch (viewType) {
case 0:
view = new StickerEmojiCell(context) {
StickerEmojiCell stickerEmojiCell = new StickerEmojiCell(context) {
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(82), MeasureSpec.EXACTLY));
}
};
view = stickerEmojiCell;
stickerEmojiCell.getImageView().setLayerNum(3);
break;
case 1:
view = new EmptyCell(context);

View File

@ -859,7 +859,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
}
public boolean handleTouchEvent(MotionEvent event) {
if (!closeAnimationInProgress && fullscreenVideoContainer.getVisibility() != VISIBLE && !textSelectionHelper.isSelectionMode()) {
if (pageSwitchAnimation == null && !closeAnimationInProgress && fullscreenVideoContainer.getVisibility() != VISIBLE && !textSelectionHelper.isSelectionMode()) {
if (event != null && event.getAction() == MotionEvent.ACTION_DOWN && !startedTracking && !maybeStartTracking) {
startedTrackingPointerId = event.getPointerId(0);
maybeStartTracking = true;
@ -3621,7 +3621,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
windowLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
windowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
windowLayoutParams.type = WindowManager.LayoutParams.LAST_APPLICATION_WINDOW - 1;
windowLayoutParams.softInputMode = SharedConfig.smoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
if (Build.VERSION.SDK_INT >= 21) {
windowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
@ -4010,10 +4010,6 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
return false;
}
if (messageObject != null) {
webpage = messageObject.messageOwner.media.webpage;
}
String anchor = null;
if (messageObject != null) {
webpage = messageObject.messageOwner.media.webpage;
@ -4084,7 +4080,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
return;
}
if (!pagesStack.isEmpty() && pagesStack.get(0) == webPageFinal && webPage.cached_page != null) {
if (!pagesStack.isEmpty() && pagesStack.get(0) == webPageFinal) {
if (messageObject != null) {
messageObject.messageOwner.media.webpage = webPage;
TLRPC.TL_messages_messages messagesRes = new TLRPC.TL_messages_messages();

View File

@ -95,9 +95,7 @@ public class AboutLinkCell extends FrameLayout {
}
oldText = text;
stringBuilder = new SpannableStringBuilder(oldText);
if (parseLinks) {
MessageObject.addLinks(false, stringBuilder, false, false);
}
MessageObject.addLinks(false, stringBuilder, false, false, !parseLinks);
Emoji.replaceEmoji(stringBuilder, Theme.profile_aboutTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
if (TextUtils.isEmpty(value)) {
valueTextView.setVisibility(GONE);

View File

@ -8,6 +8,9 @@
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;
@ -23,7 +26,6 @@ import android.text.Spanned;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.ReplacementSpan;
import android.view.HapticFeedbackConstants;
import android.view.accessibility.AccessibilityEvent;
@ -52,13 +54,17 @@ import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.ImageReceiver;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.EmptyStubSpan;
import org.telegram.ui.Components.ForegroundColorSpanThemable;
import org.telegram.ui.Components.PullForegroundDrawable;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.StaticLayoutEx;
import org.telegram.ui.Components.StatusDrawable;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.TypingDotsDrawable;
import org.telegram.ui.DialogsActivity;
import java.util.ArrayList;
@ -162,6 +168,7 @@ public class DialogCell extends BaseCell {
private TLRPC.Chat chat;
private TLRPC.EncryptedChat encryptedChat;
private CharSequence lastPrintString;
private int printingStringType;
private TLRPC.DraftMessage draftMessage;
private CheckBox2 checkBox;
@ -193,6 +200,8 @@ public class DialogCell extends BaseCell {
private boolean drawCheck2;
private boolean drawClock;
private int checkDrawLeft;
private int checkDrawLeft1;
private int clockDrawLeft;
private int checkDrawTop;
private int halfCheckDrawLeft;
@ -236,6 +245,13 @@ public class DialogCell extends BaseCell {
private RectF rect = new RectF();
private int animateToStatusDrawableParams;
private int animateFromStatusDrawableParams;
private int lastStatusDrawableParams = -1;
private float statusDrawableProgress;
private boolean statusDrawableAnimationInProgress;
private ValueAnimator statusDrawableAnimator;
public static class BounceInterpolator implements Interpolator {
public float getInterpolation(float t) {
@ -276,6 +292,14 @@ public class DialogCell extends BaseCell {
}
public void setDialog(TLRPC.Dialog dialog, int type, int folder) {
if (currentDialogId != dialog.id) {
if (statusDrawableAnimator != null) {
statusDrawableAnimator.removeAllListeners();
statusDrawableAnimator.cancel();
}
statusDrawableAnimationInProgress = false;
lastStatusDrawableParams = -1;
}
currentDialogId = dialog.id;
isDialogCell = true;
if (dialog instanceof TLRPC.TL_dialogFolder) {
@ -311,6 +335,9 @@ public class DialogCell extends BaseCell {
}
public void setDialog(long dialog_id, MessageObject messageObject, int date, boolean useMe) {
if (currentDialogId != dialog_id) {
lastStatusDrawableParams = -1;
}
currentDialogId = dialog_id;
message = messageObject;
useMeForMyMessages = useMe;
@ -462,6 +489,7 @@ public class DialogCell extends BaseCell {
return Emoji.replaceEmoji(builder, Theme.dialogs_messagePaint[paintIndex].getFontMetricsInt(), AndroidUtilities.dp(17), false);
}
public void buildLayout() {
int thumbSize;
if (useForceThreeLines || SharedConfig.useThreeLinesLayout) {
@ -493,7 +521,7 @@ public class DialogCell extends BaseCell {
CharSequence messageNameString = null;
CharSequence printingString = null;
if (isDialogCell) {
printingString = MessagesController.getInstance(currentAccount).getPrintingString(currentDialogId, 0);
printingString = MessagesController.getInstance(currentAccount).getPrintingString(currentDialogId, 0, true);
}
TextPaint currentMessagePaint = Theme.dialogs_messagePaint[paintIndex];
boolean checkMessage = true;
@ -509,6 +537,7 @@ public class DialogCell extends BaseCell {
int offsetName = 0;
boolean showChecks = !UserObject.isUserSelf(user) && !useMeForMyMessages;
boolean drawTime = true;
printingStringType = -1;
String messageFormat;
boolean hasNameInMessage;
@ -601,7 +630,7 @@ public class DialogCell extends BaseCell {
if (customDialog.isMedia) {
currentMessagePaint = Theme.dialogs_messagePrintingPaint[paintIndex];
stringBuilder = SpannableStringBuilder.valueOf(String.format(messageFormat, message.messageText));
stringBuilder.setSpan(new ForegroundColorSpan(Theme.getColor(Theme.key_chats_attachMessage)), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new ForegroundColorSpanThemable(Theme.key_chats_attachMessage), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
String mess = customDialog.message;
if (mess.length() > 150) {
@ -772,8 +801,18 @@ public class DialogCell extends BaseCell {
}
if (printingString != null) {
lastPrintString = messageString = printingString;
lastPrintString = printingString;
printingStringType = MessagesController.getInstance(currentAccount).getPrintingStringType(currentDialogId, 0);
StatusDrawable statusDrawable = Theme.getChatStatusDrawable(printingStringType);
int startPadding = 0;
if (statusDrawable != null) {
startPadding = statusDrawable.getIntrinsicWidth() + AndroidUtilities.dp(3);
}
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append(" ").append(TextUtils.replace(printingString, new String[]{"..."}, new String[]{""})).setSpan(new FixedWidthSpan(startPadding), 0, 1, 0);
messageString = spannableStringBuilder;
currentMessagePaint = Theme.dialogs_messagePrintingPaint[paintIndex];
checkMessage = false;
} else {
lastPrintString = null;
if (draftMessage != null) {
@ -784,7 +823,7 @@ public class DialogCell extends BaseCell {
messageString = "";
} else {
SpannableStringBuilder stringBuilder = SpannableStringBuilder.valueOf(messageNameString);
stringBuilder.setSpan(new ForegroundColorSpan(Theme.getColor(Theme.key_chats_draft)), 0, messageNameString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new ForegroundColorSpanThemable(Theme.key_chats_draft), 0, messageNameString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
messageString = stringBuilder;
}
} else {
@ -794,7 +833,7 @@ public class DialogCell extends BaseCell {
}
SpannableStringBuilder stringBuilder = SpannableStringBuilder.valueOf(String.format(messageFormat, mess.replace('\n', ' '), messageNameString));
if (!useForceThreeLines && !SharedConfig.useThreeLinesLayout) {
stringBuilder.setSpan(new ForegroundColorSpan(Theme.getColor(Theme.key_chats_draft)), 0, messageNameString.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new ForegroundColorSpanThemable(Theme.key_chats_draft), 0, messageNameString.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
messageString = Emoji.replaceEmoji(stringBuilder, Theme.dialogs_messagePaint[paintIndex].getFontMetricsInt(), AndroidUtilities.dp(20), false);
}
@ -819,7 +858,13 @@ public class DialogCell extends BaseCell {
}
}
} else {
messageString = "";
if (dialogsType == 3 && UserObject.isUserSelf(user)) {
messageString = LocaleController.getString("SavedMessagesInfo", R.string.SavedMessagesInfo);
showChecks = false;
drawTime = false;
} else {
messageString = "";
}
}
} else {
TLRPC.User fromUser = null;
@ -875,7 +920,7 @@ public class DialogCell extends BaseCell {
}
}
}
if (chat != null && chat.id > 0 && fromChat == null) {
if (chat != null && chat.id > 0 && fromChat == null && (!ChatObject.isChannel(chat) || ChatObject.isMegagroup(chat))) {
if (message.isOutOwner()) {
messageNameString = LocaleController.getString("FromYou", R.string.FromYou);
} else if (fromUser != null) {
@ -943,14 +988,16 @@ public class DialogCell extends BaseCell {
innerMessage = innerMessage.replace('\n', ' ');
stringBuilder = SpannableStringBuilder.valueOf(String.format(messageFormat, innerMessage, messageNameString));
try {
stringBuilder.setSpan(new ForegroundColorSpan(Theme.getColor(Theme.key_chats_attachMessage)), hasNameInMessage ? messageNameString.length() + 2 : 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new ForegroundColorSpanThemable(Theme.key_chats_attachMessage), hasNameInMessage ? messageNameString.length() + 2 : 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} catch (Exception e) {
FileLog.e(e);
}
} else if (message.messageOwner.message != null) {
String mess = message.messageOwner.message;
if (message.hasHighlightedWords()) {
mess = mess.replace('\n', ' ').replaceAll(" +", " ").trim();
if (message.messageTrimmedToHighlight != null) {
mess = message.messageTrimmedToHighlight;
}
int w = getMeasuredWidth() - AndroidUtilities.dp(72 + 23 + 10);
if (hasNameInMessage) {
if (!TextUtils.isEmpty(messageNameString)) {
@ -959,7 +1006,7 @@ public class DialogCell extends BaseCell {
w -= currentMessagePaint.measureText(": ");
}
if (w > 0) {
mess = AndroidUtilities.ellipsizeCenterEnd(mess, message.highlightedWords.get(0), w, currentMessagePaint).toString();
mess = AndroidUtilities.ellipsizeCenterEnd(mess, message.highlightedWords.get(0), w, currentMessagePaint, 130).toString();
}
} else {
if (mess.length() > 150) {
@ -974,7 +1021,7 @@ public class DialogCell extends BaseCell {
int thumbInsertIndex = 0;
if (!useForceThreeLines && !SharedConfig.useThreeLinesLayout || currentDialogFolderId != 0 && stringBuilder.length() > 0) {
try {
stringBuilder.setSpan(new ForegroundColorSpan(Theme.getColor(Theme.key_chats_nameMessage)), 0, thumbInsertIndex = messageNameString.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new ForegroundColorSpanThemable(Theme.key_chats_nameMessage), 0, thumbInsertIndex = messageNameString.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
offsetName = thumbInsertIndex;
} catch (Exception e) {
FileLog.e(e);
@ -1017,7 +1064,10 @@ public class DialogCell extends BaseCell {
emoji = "\uD83D\uDCCE ";
}
if (message.hasHighlightedWords() && !TextUtils.isEmpty(message.messageOwner.message)) {
String str = message.messageOwner.message.replace('\n', ' ').replaceAll(" +", " ").trim();
String str = message.messageTrimmedToHighlight;
if (message.messageTrimmedToHighlight != null) {
str = message.messageTrimmedToHighlight;
}
int w = getMeasuredWidth() - AndroidUtilities.dp(72 + 23 + 24);
if (hasNameInMessage) {
if (!TextUtils.isEmpty(messageNameString)) {
@ -1026,7 +1076,7 @@ public class DialogCell extends BaseCell {
w -= currentMessagePaint.measureText(": ");
}
if (w > 0) {
str = AndroidUtilities.ellipsizeCenterEnd(str, message.highlightedWords.get(0), w, currentMessagePaint).toString();
str = AndroidUtilities.ellipsizeCenterEnd(str, message.highlightedWords.get(0), w, currentMessagePaint, 130).toString();
}
messageString = emoji + str;
} else {
@ -1042,9 +1092,12 @@ public class DialogCell extends BaseCell {
messageString = String.format("\uD83C\uDFA7 %s - %s", message.getMusicAuthor(), message.getMusicTitle());
} else {
if (message.hasHighlightedWords() && !TextUtils.isEmpty(message.messageOwner.message)){
messageString = message.messageOwner.message.replace('\n', ' ').trim();
messageString = message.messageTrimmedToHighlight;
if (message.messageTrimmedToHighlight != null) {
messageString = message.messageTrimmedToHighlight;
}
int w = getMeasuredWidth() - AndroidUtilities.dp(72 + 23 );
messageString = AndroidUtilities.ellipsizeCenterEnd(messageString, message.highlightedWords.get(0), w, currentMessagePaint).toString();
messageString = AndroidUtilities.ellipsizeCenterEnd(messageString, message.highlightedWords.get(0), w, currentMessagePaint, 130).toString();
} else {
messageString = message.messageText;
}
@ -1056,9 +1109,12 @@ public class DialogCell extends BaseCell {
}
if (hasMessageThumb) {
if (message.hasHighlightedWords() && !TextUtils.isEmpty(message.messageOwner.message)) {
messageString = message.messageOwner.message.replace('\n', ' ').replaceAll(" +", " ").trim();
messageString = message.messageTrimmedToHighlight;
if (message.messageTrimmedToHighlight != null) {
messageString = message.messageTrimmedToHighlight;
}
int w = getMeasuredWidth() - AndroidUtilities.dp(72 + 23 + thumbSize + 6);
messageString = AndroidUtilities.ellipsizeCenterEnd(messageString, message.highlightedWords.get(0), w, currentMessagePaint).toString();
messageString = AndroidUtilities.ellipsizeCenterEnd(messageString, message.highlightedWords.get(0), w, currentMessagePaint, 130).toString();
} else {
if (messageString.length() > 150) {
messageString = messageString.subSequence(0, 150);
@ -1250,9 +1306,9 @@ public class DialogCell extends BaseCell {
int w = Theme.dialogs_clockDrawable.getIntrinsicWidth() + AndroidUtilities.dp(5);
nameWidth -= w;
if (!LocaleController.isRTL) {
checkDrawLeft = timeLeft - w;
clockDrawLeft = timeLeft - w;
} else {
checkDrawLeft = timeLeft + timeWidth + AndroidUtilities.dp(5);
clockDrawLeft = timeLeft + timeWidth + AndroidUtilities.dp(5);
nameLeft += w;
}
} else if (drawCheck2) {
@ -1270,9 +1326,9 @@ public class DialogCell extends BaseCell {
}
} else {
if (!LocaleController.isRTL) {
checkDrawLeft = timeLeft - w;
checkDrawLeft1 = timeLeft - w;
} else {
checkDrawLeft = timeLeft + timeWidth + AndroidUtilities.dp(5);
checkDrawLeft1 = timeLeft + timeWidth + AndroidUtilities.dp(5);
nameLeft += w;
}
}
@ -1592,6 +1648,71 @@ public class DialogCell extends BaseCell {
}
}
private void drawCheckStatus(Canvas canvas, boolean drawClock, boolean drawCheck1, boolean drawCheck2, boolean moveCheck, float alpha) {
float scale = 0.5f + 0.5f * alpha;
if (drawClock) {
setDrawableBounds(Theme.dialogs_clockDrawable, clockDrawLeft, checkDrawTop);
if (alpha != 1f) {
canvas.save();
canvas.scale(scale, scale, Theme.dialogs_clockDrawable.getBounds().centerX(), Theme.dialogs_halfCheckDrawable.getBounds().centerY());
Theme.dialogs_clockDrawable.setAlpha((int) (255 * alpha));
}
Theme.dialogs_clockDrawable.draw(canvas);
if (alpha != 1f) {
canvas.restore();
Theme.dialogs_clockDrawable.setAlpha(255);
}
invalidate();
} else if (drawCheck2) {
if (drawCheck1) {
setDrawableBounds(Theme.dialogs_halfCheckDrawable, halfCheckDrawLeft, checkDrawTop);
if (moveCheck) {
canvas.save();
canvas.scale(scale, scale, Theme.dialogs_halfCheckDrawable.getBounds().centerX(), Theme.dialogs_halfCheckDrawable.getBounds().centerY());
Theme.dialogs_halfCheckDrawable.setAlpha((int) (255 * alpha));
}
if (!moveCheck && alpha != 0) {
canvas.save();
canvas.scale(scale, scale, Theme.dialogs_halfCheckDrawable.getBounds().centerX(), Theme.dialogs_halfCheckDrawable.getBounds().centerY());
Theme.dialogs_halfCheckDrawable.setAlpha((int) (255 * alpha));
Theme.dialogs_checkReadDrawable.setAlpha((int) (255 * alpha));
}
Theme.dialogs_halfCheckDrawable.draw(canvas);
if (moveCheck) {
canvas.restore();
canvas.save();
canvas.translate(AndroidUtilities.dp(4) * (1f - alpha), 0);
}
setDrawableBounds(Theme.dialogs_checkReadDrawable, checkDrawLeft, checkDrawTop);
Theme.dialogs_checkReadDrawable.draw(canvas);
if (moveCheck) {
canvas.restore();
Theme.dialogs_halfCheckDrawable.setAlpha(255);
}
if (!moveCheck && alpha != 0) {
canvas.restore();
Theme.dialogs_halfCheckDrawable.setAlpha(255);
Theme.dialogs_checkReadDrawable.setAlpha(255);
}
} else {
setDrawableBounds(Theme.dialogs_checkDrawable, checkDrawLeft1, checkDrawTop);
if (alpha != 1f) {
canvas.save();
canvas.scale(scale, scale, Theme.dialogs_checkDrawable.getBounds().centerX(), Theme.dialogs_halfCheckDrawable.getBounds().centerY());
Theme.dialogs_checkDrawable.setAlpha((int) (255 * alpha));
}
Theme.dialogs_checkDrawable.draw(canvas);
if (alpha != 1f) {
canvas.restore();
Theme.dialogs_checkDrawable.setAlpha(255);
}
}
}
}
public boolean isPointInsideAvatar(float x, float y) {
if (!LocaleController.isRTL) {
return x >= 0 && x < AndroidUtilities.dp(60);
@ -1749,7 +1870,7 @@ public class DialogCell extends BaseCell {
}
if (isDialogCell) {
if ((mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) {
CharSequence printString = MessagesController.getInstance(currentAccount).getPrintingString(currentDialogId, 0);
CharSequence printString = MessagesController.getInstance(currentAccount).getPrintingString(currentDialogId, 0, true);
if (lastPrintString != null && printString == null || lastPrintString == null && printString != null || lastPrintString != null && printString != null && !lastPrintString.equals(printString)) {
continueUpdate = true;
}
@ -2186,25 +2307,54 @@ public class DialogCell extends BaseCell {
FileLog.e(e);
}
canvas.restore();
}
if (currentDialogFolderId == 0) {
if (drawClock) {
setDrawableBounds(Theme.dialogs_clockDrawable, checkDrawLeft, checkDrawTop);
Theme.dialogs_clockDrawable.draw(canvas);
} else if (drawCheck2) {
if (drawCheck1) {
setDrawableBounds(Theme.dialogs_halfCheckDrawable, halfCheckDrawLeft, checkDrawTop);
Theme.dialogs_halfCheckDrawable.draw(canvas);
setDrawableBounds(Theme.dialogs_checkReadDrawable, checkDrawLeft, checkDrawTop);
Theme.dialogs_checkReadDrawable.draw(canvas);
} else {
setDrawableBounds(Theme.dialogs_checkDrawable, checkDrawLeft, checkDrawTop);
Theme.dialogs_checkDrawable.draw(canvas);
if (printingStringType >= 0) {
StatusDrawable statusDrawable = Theme.getChatStatusDrawable(printingStringType);
if (statusDrawable != null) {
canvas.save();
int left = LocaleController.isRTL ? messageLeft + messageLayout.getWidth() - statusDrawable.getIntrinsicWidth() : messageLeft;
if (printingStringType == 1 || printingStringType == 4) {
canvas.translate(left, messageTop + (printingStringType == 1 ? AndroidUtilities.dp(1) : 0));
} else {
canvas.translate(left, messageTop + (AndroidUtilities.dp(18) - statusDrawable.getIntrinsicHeight()) / 2f);
}
statusDrawable.draw(canvas);
invalidate(left, messageTop, left + statusDrawable.getIntrinsicWidth(), messageTop + statusDrawable.getIntrinsicHeight());
canvas.restore();
}
}
}
if (currentDialogFolderId == 0) {
int currentStatus = (drawClock ? 1 : 0) + (drawCheck1 ? 2 : 0) + (drawCheck2 ? 4 : 0);
if (lastStatusDrawableParams >= 0 && lastStatusDrawableParams != currentStatus && !statusDrawableAnimationInProgress) {
createStatusDrawableAnimator(lastStatusDrawableParams, currentStatus);
}
if (statusDrawableAnimationInProgress) {
currentStatus = animateToStatusDrawableParams;
}
boolean drawClock = (currentStatus & 1) != 0;
boolean drawCheck1 = (currentStatus & 2) != 0;
boolean drawCheck2 = (currentStatus & 4) != 0;
if (statusDrawableAnimationInProgress) {
boolean outDrawClock = (animateFromStatusDrawableParams & 1) != 0;
boolean outDrawCheck1 = (animateFromStatusDrawableParams & 2) != 0;
boolean outDrawCheck2 = (animateFromStatusDrawableParams & 4) != 0;
if (!drawClock && !outDrawClock && outDrawCheck2 && !outDrawCheck1 && drawCheck1 && drawCheck2) {
drawCheckStatus(canvas, drawClock, drawCheck1, drawCheck2, true, statusDrawableProgress);
} else {
drawCheckStatus(canvas, outDrawClock, outDrawCheck1, outDrawCheck2, false, 1f - statusDrawableProgress);
drawCheckStatus(canvas, drawClock, drawCheck1, drawCheck2, false, statusDrawableProgress);
}
} else {
drawCheckStatus(canvas, drawClock, drawCheck1, drawCheck2, false,1f);
}
lastStatusDrawableParams = (this.drawClock ? 1 : 0) + (this.drawCheck1 ? 2 : 0) + (this.drawCheck2 ? 4 : 0);
}
if (dialogMuted && !drawVerified && !drawScam) {
setDrawableBounds(Theme.dialogs_muteDrawable, nameMuteLeft - AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 0 : 1), AndroidUtilities.dp(SharedConfig.useThreeLinesLayout ? 13.5f : 17.5f));
Theme.dialogs_muteDrawable.draw(canvas);
@ -2447,6 +2597,35 @@ public class DialogCell extends BaseCell {
}
}
private void createStatusDrawableAnimator(int lastStatusDrawableParams, int currentStatus) {
statusDrawableProgress = 0f;
statusDrawableAnimator = ValueAnimator.ofFloat(0,1f);
statusDrawableAnimator.setDuration(220);
statusDrawableAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
animateFromStatusDrawableParams = lastStatusDrawableParams;
animateToStatusDrawableParams = currentStatus;
statusDrawableAnimator.addUpdateListener(valueAnimator -> {
statusDrawableProgress = (float) valueAnimator.getAnimatedValue();
invalidate();
});
statusDrawableAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
int currentStatus = (DialogCell.this.drawClock ? 1 : 0) + (DialogCell.this.drawCheck1 ? 2 : 0) + (DialogCell.this.drawCheck2 ? 4 : 0);
if (animateToStatusDrawableParams != currentStatus) {
createStatusDrawableAnimator(animateToStatusDrawableParams, currentStatus);
} else {
statusDrawableAnimationInProgress = false;
DialogCell.this.lastStatusDrawableParams = animateToStatusDrawableParams;
}
invalidate();
}
});
statusDrawableAnimationInProgress = true;
statusDrawableAnimator.start();
}
public void startOutAnimation() {
if (archivedChatsDrawable != null) {
archivedChatsDrawable.outCy = avatarImage.getCenterY();

View File

@ -146,7 +146,7 @@ public class DrawerProfileCell extends FrameLayout {
}
Theme.ThemeInfo themeInfo = Theme.getActiveTheme();
if (dayThemeName.equals(nightThemeName)) {
if (themeInfo.isDark()) {
if (themeInfo.isDark() || dayThemeName.equals("Dark Blue") || dayThemeName.equals("Night")) {
dayThemeName = "Blue";
} else {
nightThemeName = "Dark Blue";

View File

@ -90,6 +90,29 @@ public class MentionCell extends LinearLayout {
usernameTextView.setVisibility(VISIBLE);
}
public void setChat(TLRPC.Chat chat) {
if (chat == null) {
nameTextView.setText("");
usernameTextView.setText("");
imageView.setImageDrawable(null);
return;
}
avatarDrawable.setInfo(chat);
if (chat.photo != null && chat.photo.photo_small != null) {
imageView.setImage(ImageLocation.getForChat(chat, false), "50_50", avatarDrawable, chat);
} else {
imageView.setImageDrawable(avatarDrawable);
}
nameTextView.setText(chat.title);
if (chat.username != null) {
usernameTextView.setText("@" + chat.username);
} else {
usernameTextView.setText("");
}
imageView.setVisibility(VISIBLE);
usernameTextView.setVisibility(VISIBLE);
}
public void setText(String text) {
imageView.setVisibility(INVISIBLE);
usernameTextView.setVisibility(INVISIBLE);

View File

@ -100,6 +100,7 @@ public class SendLocationCell extends FrameLayout {
accurateTextView.setAlpha(value ? 1.0f : 0.5f);
imageView.setAlpha(value ? 1.0f : 0.5f);
}
checkText();
}
@Override

View File

@ -175,7 +175,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
CharSequence caption = Emoji.replaceEmoji(currentMessageObject.messageOwner.message.replace("\n", " ").replaceAll(" +", " ").trim(), Theme.chat_msgTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
CharSequence sequence = AndroidUtilities.highlightText(caption, currentMessageObject.highlightedWords);
if (sequence != null) {
sequence = TextUtils.ellipsize(AndroidUtilities.ellipsizeCenterEnd(sequence, currentMessageObject.highlightedWords.get(0), maxWidth, captionTextPaint), captionTextPaint, maxWidth, TextUtils.TruncateAt.END);
sequence = TextUtils.ellipsize(AndroidUtilities.ellipsizeCenterEnd(sequence, currentMessageObject.highlightedWords.get(0), maxWidth, captionTextPaint, 130), captionTextPaint, maxWidth, TextUtils.TruncateAt.END);
captionLayout = new StaticLayout(sequence, captionTextPaint, maxWidth + AndroidUtilities.dp(4), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
}

View File

@ -530,7 +530,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
int h = AndroidUtilities.dp(5 + 29) + nameTextView.getMeasuredHeight() + (needDivider ? 1 : 0);
if (caption != null && captionTextView != null && message.hasHighlightedWords()) {
ignoreRequestLayout = true;
captionTextView.setText(AndroidUtilities.ellipsizeCenterEnd(caption, message.highlightedWords.get(0), captionTextView.getMeasuredWidth(), captionTextView.getPaint()));
captionTextView.setText(AndroidUtilities.ellipsizeCenterEnd(caption, message.highlightedWords.get(0), captionTextView.getMeasuredWidth(), captionTextView.getPaint(), 130));
ignoreRequestLayout = false;
h += captionTextView.getMeasuredHeight() + AndroidUtilities.dp(3);

View File

@ -352,7 +352,7 @@ public class SharedLinkCell extends FrameLayout {
CharSequence caption = Emoji.replaceEmoji(message.messageOwner.message.replace("\n", " ").replaceAll(" +", " ").trim(), Theme.chat_msgTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
CharSequence sequence = AndroidUtilities.highlightText(caption, message.highlightedWords);
if (sequence != null) {
sequence = TextUtils.ellipsize(AndroidUtilities.ellipsizeCenterEnd(sequence, message.highlightedWords.get(0), maxWidth, captionTextPaint), captionTextPaint, maxWidth, TextUtils.TruncateAt.END);
sequence = TextUtils.ellipsize(AndroidUtilities.ellipsizeCenterEnd(sequence, message.highlightedWords.get(0), maxWidth, captionTextPaint, 130), captionTextPaint, maxWidth, TextUtils.TruncateAt.END);
captionLayout = new StaticLayout(sequence, captionTextPaint, maxWidth + AndroidUtilities.dp(4), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
}

View File

@ -1491,7 +1491,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
textArea.set(maybeTextX, maybeTextY,
maybeTextX + chatMessageCell.getCaptionLayout().getWidth(),
maybeTextY + chatMessageCell.getCaptionLayout().getHeight());
} else if (messageObject != null && messageObject.textLayoutBlocks.size() > 0) {
} else if (messageObject != null && messageObject.textLayoutBlocks != null && messageObject.textLayoutBlocks.size() > 0) {
MessageObject.TextLayoutBlock block = messageObject.textLayoutBlocks.get(messageObject.textLayoutBlocks.size() - 1);
textArea.set(
maybeTextX, maybeTextY,

View File

@ -211,7 +211,7 @@ public class ChangeBioActivity extends BaseFragment {
FileLog.e(e);
}
userFull.about = newName;
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, user.id, userFull, null);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, user.id, userFull);
finishFragment();
});
} else {

View File

@ -2475,13 +2475,13 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInClockDrawable}, null, Theme.key_chat_inSentClock));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInSelectedClockDrawable}, null, Theme.key_chat_inSentClockSelected));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgMediaCheckDrawable, Theme.chat_msgMediaHalfCheckDrawable}, null, Theme.key_chat_mediaSentCheck));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgStickerHalfCheckDrawable, Theme.chat_msgStickerCheckDrawable, Theme.chat_msgStickerClockDrawable, Theme.chat_msgStickerViewsDrawable, Theme.chat_msgStickerRepliesDrawable}, null, Theme.key_chat_serviceText));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgStickerHalfCheckDrawable, Theme.chat_msgStickerCheckDrawable, Theme.chat_msgStickerClockDrawable, Theme.chat_msgStickerViewsDrawable, Theme.chat_msgStickerRepliesDrawable, Theme.chat_msgStickerPinnedDrawable}, null, Theme.key_chat_serviceText));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgMediaClockDrawable}, null, Theme.key_chat_mediaSentClock));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutViewsDrawable, Theme.chat_msgOutRepliesDrawable}, null, Theme.key_chat_outViews));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutViewsSelectedDrawable, Theme.chat_msgOutRepliesSelectedDrawable}, null, Theme.key_chat_outViewsSelected));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInViewsDrawable, Theme.chat_msgInRepliesDrawable}, null, Theme.key_chat_inViews));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInViewsSelectedDrawable, Theme.chat_msgInRepliesSelectedDrawable}, null, Theme.key_chat_inViewsSelected));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgMediaViewsDrawable, Theme.chat_msgMediaRepliesDrawable}, null, Theme.key_chat_mediaViews));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutViewsDrawable, Theme.chat_msgOutRepliesDrawable, Theme.chat_msgOutPinnedDrawable}, null, Theme.key_chat_outViews));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutViewsSelectedDrawable, Theme.chat_msgOutRepliesSelectedDrawable, Theme.chat_msgOutPinnedSelectedDrawable}, null, Theme.key_chat_outViewsSelected));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInViewsDrawable, Theme.chat_msgInRepliesDrawable, Theme.chat_msgInPinnedDrawable}, null, Theme.key_chat_inViews));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInViewsSelectedDrawable, Theme.chat_msgInRepliesSelectedDrawable, Theme.chat_msgInPinnedSelectedDrawable}, null, Theme.key_chat_inViewsSelected));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgMediaViewsDrawable, Theme.chat_msgMediaRepliesDrawable, Theme.chat_msgMediaPinnedDrawable}, null, Theme.key_chat_mediaViews));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutMenuDrawable}, null, Theme.key_chat_outMenu));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutMenuSelectedDrawable}, null, Theme.key_chat_outMenuSelected));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInMenuDrawable}, null, Theme.key_chat_inMenu));

View File

@ -17,6 +17,7 @@ import android.graphics.RectF;
import android.os.Build;
import android.os.Bundle;
import android.text.TextPaint;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@ -1465,6 +1466,7 @@ public abstract class BaseChartView<T extends ChartData, L extends LineViewData>
legendSignatureView.setVisibility(VISIBLE);
selectionA = 1f;
moveLegend(chartFullWidth * (pickerDelegate.pickerStart) - HORIZONTAL_PADDING);
performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
}
public long getStartDate() {

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,6 @@ import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
@ -196,7 +195,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
return false;
}
if (info == null) {
info = MessagesStorage.getInstance(currentAccount).loadChatInfo(chatId, new CountDownLatch(1), false, false);
info = MessagesStorage.getInstance(currentAccount).loadChatInfo(chatId, ChatObject.isChannel(currentChat), new CountDownLatch(1), false, false);
if (info == null) {
return false;
}
@ -1143,7 +1142,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
}
if (nameTextView != null) {
String text = nameTextView.getText().toString();
if (text != null && text.length() != 0) {
if (text.length() != 0) {
args.putString("nameTextView", text);
}
}
@ -1265,7 +1264,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
}
if (stickersCell != null) {
if (info.stickerset != null) {
if (info != null && info.stickerset != null) {
stickersCell.setTextAndValue(LocaleController.getString("GroupStickers", R.string.GroupStickers), info.stickerset.title, false);
} else {
stickersCell.setText(LocaleController.getString("GroupStickers", R.string.GroupStickers), false);

View File

@ -123,7 +123,7 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
return false;
}
if (info == null) {
info = getMessagesStorage().loadChatInfo(chatId, new CountDownLatch(1), false, false);
info = getMessagesStorage().loadChatInfo(chatId, ChatObject.isChannel(currentChat), new CountDownLatch(1), false, false);
if (info == null) {
return false;
}

View File

@ -407,7 +407,7 @@ public class ChatLinkActivity extends BaseFragment implements NotificationCenter
}
progressDialog[0] = null;
info.linked_chat_id = 0;
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.chatInfoDidLoad, info, 0, false, null);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.chatInfoDidLoad, info, 0, false);
AndroidUtilities.runOnUIThread(() -> getMessagesController().loadFullChat(currentChatId, 0, true), 1000);
if (!isChannel) {
finishFragment();
@ -537,7 +537,7 @@ public class ChatLinkActivity extends BaseFragment implements NotificationCenter
progressDialog[0] = null;
}
info.linked_chat_id = chat.id;
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.chatInfoDidLoad, info, 0, false, null);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.chatInfoDidLoad, info, 0, false);
AndroidUtilities.runOnUIThread(() -> getMessagesController().loadFullChat(currentChatId, 0, true), 1000);
if (createFragment != null) {
removeSelfFromStack();

View File

@ -61,6 +61,7 @@ import org.telegram.ui.Cells.TextCheckCell2;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.Cells.ManageChatUserCell;
import org.telegram.ui.Cells.TextSettingsCell;
import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.EmptyTextProgressView;
import org.telegram.ui.Components.IntSeekBarAccessibilityDelegate;
import org.telegram.ui.Components.LayoutHelper;
@ -1114,7 +1115,19 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
private void openRightsEdit2(int userId, int date, TLObject participant, TLRPC.TL_chatAdminRights adminRights, TLRPC.TL_chatBannedRights bannedRights, String rank, boolean canEditAdmin, int type, boolean removeFragment) {
ChatRightsEditActivity fragment = new ChatRightsEditActivity(userId, chatId, adminRights, defaultBannedRights, bannedRights, rank, type, true, false);
boolean[] needShowBulletin = new boolean[1];
final boolean isAdmin = participant instanceof TLRPC.TL_channelParticipantAdmin || participant instanceof TLRPC.TL_chatParticipantAdmin;
ChatRightsEditActivity fragment = new ChatRightsEditActivity(userId, chatId, adminRights, defaultBannedRights, bannedRights, rank, type, true, false) {
@Override
protected void onTransitionAnimationEnd(boolean isOpen, boolean backward) {
if (!isOpen && backward && needShowBulletin[0] && BulletinFactory.canShowBulletin(ChatUsersActivity.this)) {
final TLRPC.User user = getMessagesController().getUser(userId);
if (user != null) {
BulletinFactory.createPromoteToAdminBulletin(ChatUsersActivity.this, user.first_name).show();
}
}
}
};
fragment.setDelegate(new ChatRightsEditActivity.ChatRightsEditActivityDelegate() {
@Override
public void didSetRights(int rights, TLRPC.TL_chatAdminRights rightsAdmin, TLRPC.TL_chatBannedRights rightsBanned, String rank) {
@ -1158,6 +1171,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
loadChatParticipants(0, 200);
}
}
if (rights == 1 && !isAdmin) {
needShowBulletin[0] = true;
}
} else if (type == 1) {
if (rights == 0) {
removeParticipants(userId);

View File

@ -8,16 +8,20 @@
package org.telegram.ui.Components;
import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Vibrator;
import android.text.Html;
@ -33,6 +37,7 @@ import android.util.TypedValue;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.FrameLayout;
@ -95,6 +100,8 @@ import java.util.List;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import androidx.annotation.RequiresApi;
public class AlertsCreator {
public static Dialog processError(int currentAccount, TLRPC.TL_error error, BaseFragment fragment, TLObject request, Object... args) {
@ -157,7 +164,7 @@ public class AlertsCreator {
if (fragment != null) {
showSimpleAlert(fragment, LocaleController.getString("EditMessageError", R.string.EditMessageError));
} else {
showSimpleToast(fragment, LocaleController.getString("EditMessageError", R.string.EditMessageError));
showSimpleToast(null, LocaleController.getString("EditMessageError", R.string.EditMessageError));
}
}
} else if (request instanceof TLRPC.TL_messages_sendMessage ||
@ -216,7 +223,7 @@ public class AlertsCreator {
} else if (request instanceof TLRPC.TL_account_sendConfirmPhoneCode) {
if (error.code == 400) {
return showSimpleAlert(fragment, LocaleController.getString("CancelLinkExpired", R.string.CancelLinkExpired));
} else if (error.text != null) {
} else {
if (error.text.startsWith("FLOOD_WAIT")) {
return showSimpleAlert(fragment, LocaleController.getString("FloodWait", R.string.FloodWait));
} else {
@ -262,7 +269,7 @@ public class AlertsCreator {
break;
}
} else if (request instanceof TLRPC.TL_contacts_importContacts) {
if (error == null || error.text.startsWith("FLOOD_WAIT")) {
if (error.text.startsWith("FLOOD_WAIT")) {
showSimpleAlert(fragment, LocaleController.getString("FloodWait", R.string.FloodWait));
} else {
showSimpleAlert(fragment, LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred) + "\n" + error.text);
@ -395,7 +402,7 @@ public class AlertsCreator {
int end;
if (start != -1) {
end = TextUtils.indexOf(spanned, ']', start + 1);
if (start != -1 && end != -1) {
if (end != -1) {
spanned.delete(end, end + 1);
spanned.delete(start, start + 1);
}
@ -434,7 +441,7 @@ public class AlertsCreator {
if (!few) {
TLRPC.ChatFull chatFull = MessagesController.getInstance(currentAccount).getChatFull(chat.id);
if (chatFull == null) {
chatFull = MessagesStorage.getInstance(currentAccount).loadChatInfo(chat.id, new CountDownLatch(1), false, false);
chatFull = MessagesStorage.getInstance(currentAccount).loadChatInfo(chat.id, ChatObject.isChannel(chat), new CountDownLatch(1), false, false);
}
if (chatFull != null && chatFull.slowmode_next_send_date >= ConnectionsManager.getInstance(currentAccount).getCurrentTime()) {
few = true;
@ -575,7 +582,7 @@ public class AlertsCreator {
cells[a].setTag(a);
if (a == 0) {
cells[a].setText(LocaleController.getString("DeleteReportSpam", R.string.DeleteReportSpam), "", true, false);
} else if (a == 1) {
} else {
cells[a].setText(LocaleController.formatString("DeleteThisChat", R.string.DeleteThisChat), "", true, false);
}
cells[a].setPadding(LocaleController.isRTL ? AndroidUtilities.dp(16) : AndroidUtilities.dp(8), 0, LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(16), 0);
@ -1158,7 +1165,7 @@ public class AlertsCreator {
avatarDrawable.setInfo(user);
imageView.setImage(ImageLocation.getForUser(user, false), "50_50", avatarDrawable, user);
}
} else if (chat != null) {
} else {
avatarDrawable.setInfo(chat);
imageView.setImage(ImageLocation.getForChat(chat, false), "50_50", avatarDrawable, chat);
}
@ -1181,7 +1188,7 @@ public class AlertsCreator {
messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("AreYouSureClearHistoryWithUser", R.string.AreYouSureClearHistoryWithUser, UserObject.getUserName(user))));
}
}
} else if (chat != null) {
} else {
if (!ChatObject.isChannel(chat) || chat.megagroup && TextUtils.isEmpty(chat.username)) {
messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("AreYouSureClearHistoryWithChat", R.string.AreYouSureClearHistoryWithChat, chat.title)));
} else if (chat.megagroup) {
@ -2506,7 +2513,48 @@ public class AlertsCreator {
return builder.create();
}
public static AlertDialog.Builder createContactsPermissionDialog(final Activity parentActivity, final MessagesStorage.IntCallback callback) {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static AlertDialog.Builder createBackgroundLocationPermissionDialog(Activity activity, TLRPC.User selfUser, Runnable cancelRunnable) {
if (activity == null || Build.VERSION.SDK_INT < 29) {
return null;
}
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
String svg = RLottieDrawable.readRes(null, Theme.getCurrentTheme().isDark() ? R.raw.permission_map_dark : R.raw.permission_map);
String pinSvg = RLottieDrawable.readRes(null, Theme.getCurrentTheme().isDark() ? R.raw.permission_pin_dark : R.raw.permission_pin);
FrameLayout frameLayout = new FrameLayout(activity);
frameLayout.setClipToOutline(true);
frameLayout.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight() + AndroidUtilities.dp(6), AndroidUtilities.dp(6));
}
});
View background = new View(activity);
background.setBackground(SvgHelper.getDrawable(svg));
frameLayout.addView(background, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
View pin = new View(activity);
pin.setBackground(SvgHelper.getDrawable(pinSvg));
frameLayout.addView(pin, LayoutHelper.createFrame(60, 82, Gravity.CENTER, 0, 0, 0, 0));
BackupImageView imageView = new BackupImageView(activity);
imageView.setRoundRadius(AndroidUtilities.dp(26));
imageView.setImage(ImageLocation.getForUser(selfUser, false), "50_50", (Drawable) null, selfUser);
frameLayout.addView(imageView, LayoutHelper.createFrame(52, 52, Gravity.CENTER, 0, 0, 0, 11));
builder.setTopView(frameLayout);
builder.setMessage(AndroidUtilities.replaceTags(LocaleController.getString("PermissionBackgroundLocation", R.string.PermissionBackgroundLocation)));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialog, which) -> {
if (activity.checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 30);
}
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), ((dialog, which) -> cancelRunnable.run()));
return builder;
}
public static AlertDialog.Builder createContactsPermissionDialog(Activity parentActivity, MessagesStorage.IntCallback callback) {
AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity);
builder.setTopImage(R.drawable.permissions_contacts, Theme.getColor(Theme.key_dialogTopBackground));
builder.setMessage(AndroidUtilities.replaceTags(LocaleController.getString("ContactsPermissionAlert", R.string.ContactsPermissionAlert)));
@ -2607,14 +2655,12 @@ public class AlertsCreator {
LocaleController.getString("NotificationsPriorityUrgent", R.string.NotificationsPriorityUrgent)
};
} else {
if (dialog_id == 0) {
if (globalType == NotificationsController.TYPE_PRIVATE) {
selected[0] = preferences.getInt("priority_messages", 1);
} else if (globalType == NotificationsController.TYPE_GROUP) {
selected[0] = preferences.getInt("priority_group", 1);
} else if (globalType == NotificationsController.TYPE_CHANNEL) {
selected[0] = preferences.getInt("priority_channel", 1);
}
if (globalType == NotificationsController.TYPE_PRIVATE) {
selected[0] = preferences.getInt("priority_messages", 1);
} else if (globalType == NotificationsController.TYPE_GROUP) {
selected[0] = preferences.getInt("priority_group", 1);
} else if (globalType == NotificationsController.TYPE_CHANNEL) {
selected[0] = preferences.getInt("priority_channel", 1);
}
if (selected[0] == 4) {
selected[0] = 0;
@ -3072,7 +3118,7 @@ public class AlertsCreator {
cell.setText(LocaleController.getString("DeleteBanUser", R.string.DeleteBanUser), "", false, false);
} else if (a == 1) {
cell.setText(LocaleController.getString("DeleteReportSpam", R.string.DeleteReportSpam), "", false, false);
} else if (a == 2) {
} else {
cell.setText(LocaleController.formatString("DeleteAllFrom", R.string.DeleteAllFrom, ContactsController.formatName(actionUser.first_name, actionUser.last_name)), "", false, false);
}
cell.setPadding(LocaleController.isRTL ? AndroidUtilities.dp(16) : AndroidUtilities.dp(8), 0, LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(16), 0);
@ -3114,7 +3160,12 @@ public class AlertsCreator {
} else if (!scheduled && !ChatObject.isChannel(chat) && encryptedChat == null) {
if (user != null && user.id != UserConfig.getInstance(currentAccount).getClientUserId() && (!user.bot || user.support) || chat != null) {
if (selectedMessage != null) {
boolean hasOutgoing = !selectedMessage.isSendError() && (selectedMessage.messageOwner.action == null || selectedMessage.messageOwner.action instanceof TLRPC.TL_messageActionEmpty || selectedMessage.messageOwner.action instanceof TLRPC.TL_messageActionPhoneCall) && (selectedMessage.isOut() || canRevokeInbox || ChatObject.hasAdminRights(chat)) && (currentDate - selectedMessage.messageOwner.date) <= revokeTimeLimit;
boolean hasOutgoing = !selectedMessage.isSendError() && (
selectedMessage.messageOwner.action == null ||
selectedMessage.messageOwner.action instanceof TLRPC.TL_messageActionEmpty ||
selectedMessage.messageOwner.action instanceof TLRPC.TL_messageActionPhoneCall ||
selectedMessage.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage ||
selectedMessage.messageOwner.action instanceof TLRPC.TL_messageActionGeoProximityReached) && (selectedMessage.isOut() || canRevokeInbox || ChatObject.hasAdminRights(chat)) && (currentDate - selectedMessage.messageOwner.date) <= revokeTimeLimit;
if (hasOutgoing) {
myMessagesCount++;
}
@ -3123,7 +3174,11 @@ public class AlertsCreator {
for (int a = 1; a >= 0; a--) {
for (int b = 0; b < selectedMessages[a].size(); b++) {
MessageObject msg = selectedMessages[a].valueAt(b);
if (!(msg.messageOwner.action == null || msg.messageOwner.action instanceof TLRPC.TL_messageActionEmpty || msg.messageOwner.action instanceof TLRPC.TL_messageActionPhoneCall)) {
if (!(msg.messageOwner.action == null ||
msg.messageOwner.action instanceof TLRPC.TL_messageActionEmpty ||
msg.messageOwner.action instanceof TLRPC.TL_messageActionPhoneCall ||
msg.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage ||
msg.messageOwner.action instanceof TLRPC.TL_messageActionGeoProximityReached)) {
continue;
}
if ((msg.isOut() || canRevokeInbox) || chat != null && ChatObject.canBlockUsers(chat)) {
@ -3196,7 +3251,7 @@ public class AlertsCreator {
int channelId = 0;
if (!ids.isEmpty()) {
MessageObject msg = selectedMessages[a].get(ids.get(0));
if (channelId == 0 && msg.messageOwner.peer_id.channel_id != 0) {
if (msg.messageOwner.peer_id.channel_id != 0) {
channelId = msg.messageOwner.peer_id.channel_id;
}
}
@ -3230,9 +3285,6 @@ public class AlertsCreator {
MessagesController.getInstance(currentAccount).deleteUserChannelHistory(chat, userFinal, 0);
}
}
if (BulletinFactory.canShowBulletin(fragment)) {
BulletinFactory.createDeleteMessagesBulletin(fragment, count).show();
}
if (onDelete != null) {
onDelete.run();
}

View File

@ -0,0 +1,161 @@
package org.telegram.ui.Components;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.graphics.Canvas;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.Property;
import android.view.View;
import org.telegram.messenger.AndroidUtilities;
import java.util.ArrayList;
import java.util.Locale;
public class AnimatedNumberLayout {
private ArrayList<StaticLayout> letters = new ArrayList<>();
private ArrayList<StaticLayout> oldLetters = new ArrayList<>();
private final TextPaint textPaint;
private ObjectAnimator animator;
private float progress = 0.0f;
private int currentNumber = 1;
private final View parentView;
public static final Property<AnimatedNumberLayout, Float> PROGRESS = new AnimationProperties.FloatProperty<AnimatedNumberLayout>("progress") {
@Override
public void setValue(AnimatedNumberLayout object, float value) {
object.setProgress(value);
}
@Override
public Float get(AnimatedNumberLayout object) {
return object.progress;
}
};
public AnimatedNumberLayout(View parent, TextPaint paint) {
textPaint = paint;
parentView = parent;
}
private void setProgress(float value) {
if (progress == value) {
return;
}
progress = value;
parentView.invalidate();
}
private float getProgress() {
return progress;
}
public int getWidth() {
float width = 0;
int count = letters.size();
for (int a = 0; a < count; a++) {
width += letters.get(a).getLineWidth(0);
}
return (int) Math.ceil(width);
}
public void setNumber(int number, boolean animated) {
if (currentNumber == number && !letters.isEmpty()) {
return;
}
if (animator != null) {
animator.cancel();
animator = null;
}
oldLetters.clear();
oldLetters.addAll(letters);
letters.clear();
String oldText = String.format(Locale.US, "%d", currentNumber);
String text = String.format(Locale.US, "%d", number);
boolean forwardAnimation = number > currentNumber;
currentNumber = number;
progress = 0;
for (int a = 0; a < text.length(); a++) {
String ch = text.substring(a, a + 1);
String oldCh = !oldLetters.isEmpty() && a < oldText.length() ? oldText.substring(a, a + 1) : null;
if (oldCh != null && oldCh.equals(ch)) {
letters.add(oldLetters.get(a));
oldLetters.set(a, null);
} else {
StaticLayout layout = new StaticLayout(ch, textPaint, (int) Math.ceil(textPaint.measureText(ch)), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
letters.add(layout);
}
}
if (animated && !oldLetters.isEmpty()) {
animator = ObjectAnimator.ofFloat(this, PROGRESS, forwardAnimation ? -1 : 1, 0);
animator.setDuration(150);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
animator = null;
oldLetters.clear();
}
});
animator.start();
}
parentView.invalidate();
}
public void draw(Canvas canvas) {
if (letters.isEmpty()) {
return;
}
float height = letters.get(0).getHeight();
int count = Math.max(letters.size(), oldLetters.size());
canvas.save();
int currentAlpha = textPaint.getAlpha();
for (int a = 0; a < count; a++) {
canvas.save();
StaticLayout old = a < oldLetters.size() ? oldLetters.get(a) : null;
StaticLayout layout = a < letters.size() ? letters.get(a) : null;
if (progress > 0) {
if (old != null) {
textPaint.setAlpha((int) (currentAlpha * progress));
canvas.save();
canvas.translate(0, (progress - 1.0f) * height);
old.draw(canvas);
canvas.restore();
if (layout != null) {
textPaint.setAlpha((int) (currentAlpha * (1.0f - progress)));
canvas.translate(0, progress * height);
}
} else {
textPaint.setAlpha(currentAlpha);
}
} else if (progress < 0) {
if (old != null) {
textPaint.setAlpha((int) (currentAlpha * -progress));
canvas.save();
canvas.translate(0, (1.0f + progress) * height);
old.draw(canvas);
canvas.restore();
}
if (layout != null) {
if (a == count - 1 || old != null) {
textPaint.setAlpha((int) (currentAlpha * (1.0f + progress)));
canvas.translate(0, progress * height);
} else {
textPaint.setAlpha(currentAlpha);
}
}
} else if (layout != null) {
textPaint.setAlpha(currentAlpha);
}
if (layout != null) {
layout.draw(canvas);
}
canvas.restore();
canvas.translate((layout != null ? layout.getLineWidth(0) : old.getLineWidth(0)), 0);
}
canvas.restore();
}
}

View File

@ -13,20 +13,28 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -53,6 +61,7 @@ import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.MessageObject;
@ -82,6 +91,7 @@ import org.telegram.ui.LaunchActivity;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.NotificationCenterDelegate, DownloadController.FileDownloadProgressListener {
@ -100,11 +110,11 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
private TextView emptySubtitleTextView;
private FrameLayout playerLayout;
private BackupImageView placeholderImageView;
private TextView titleTextView;
private ImageView prevButton;
private ImageView nextButton;
private TextView authorTextView;
private CoverContainer coverContainer;
private ClippingTextViewSwitcher titleTextView;
private RLottieImageView prevButton;
private RLottieImageView nextButton;
private ClippingTextViewSwitcher authorTextView;
private ActionBarMenuItem optionsButton;
private LineProgressView progressView;
private SeekBarView seekBarView;
@ -117,6 +127,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
private ActionBarMenuSubItem shuffleListItem;
private ActionBarMenuSubItem reverseOrderItem;
private ImageView playButton;
private PlayPauseDrawable playPauseDrawable;
private FrameLayout blurredView;
private BackupImageView bigAlbumConver;
private ActionBarMenuItem searchItem;
@ -134,6 +145,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
private int searchOpenOffset;
private ArrayList<MessageObject> playlist;
private MessageObject lastMessageObject;
private int scrollOffsetY = Integer.MAX_VALUE;
private int topBeforeSwitch;
@ -328,6 +340,23 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
canvas.drawRect(backgroundPaddingLeft, 0, getMeasuredWidth() - backgroundPaddingLeft, AndroidUtilities.statusBarHeight, Theme.dialogs_onlineCirclePaint);
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Bulletin.addDelegate(this, new Bulletin.Delegate() {
@Override
public int getBottomOffset() {
return playerLayout.getHeight();
}
});
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Bulletin.removeDelegate(this);
}
};
containerView.setWillNotDraw(false);
containerView.setPadding(backgroundPaddingLeft, 0, backgroundPaddingLeft, 0);
@ -444,7 +473,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
}
};
placeholderImageView = new BackupImageView(context) {
coverContainer = new CoverContainer(context) {
private long pressTime;
@ -452,7 +481,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
if (imageReceiver.hasBitmapImage()) {
if (getImageReceiver().hasBitmapImage()) {
showAlbumCover(true, true);
pressTime = SystemClock.elapsedRealtime();
}
@ -463,28 +492,41 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
}
return true;
}
};
placeholderImageView.getImageReceiver().setDelegate((imageReceiver, set, thumb, memCache) -> {
if (blurredView.getTag() != null) {
bigAlbumConver.setImageBitmap(placeholderImageView.imageReceiver.getBitmap());
}
});
placeholderImageView.setRoundRadius(AndroidUtilities.dp(4));
playerLayout.addView(placeholderImageView, LayoutHelper.createFrame(44, 44, Gravity.TOP | Gravity.RIGHT, 0, 20, 20, 0));
titleTextView = new TextView(context);
titleTextView.setTextColor(Theme.getColor(Theme.key_player_actionBarTitle));
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17);
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleTextView.setEllipsize(TextUtils.TruncateAt.END);
titleTextView.setSingleLine(true);
@Override
protected void onImageUpdated(ImageReceiver imageReceiver) {
if (blurredView.getTag() != null) {
bigAlbumConver.setImageBitmap(imageReceiver.getBitmap());
}
}
};
playerLayout.addView(coverContainer, LayoutHelper.createFrame(44, 44, Gravity.TOP | Gravity.RIGHT, 0, 20, 20, 0));
titleTextView = new ClippingTextViewSwitcher(context) {
@Override
protected TextView createTextView() {
final TextView textView = new TextView(context);
textView.setTextColor(Theme.getColor(Theme.key_player_actionBarTitle));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setSingleLine(true);
return textView;
}
};
playerLayout.addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 20, 20, 72, 0));
authorTextView = new TextView(context);
authorTextView.setTextColor(Theme.getColor(Theme.key_player_time));
authorTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
authorTextView.setEllipsize(TextUtils.TruncateAt.END);
authorTextView.setSingleLine(true);
authorTextView = new ClippingTextViewSwitcher(context) {
@Override
protected TextView createTextView() {
final TextView textView = new TextView(context);
textView.setTextColor(Theme.getColor(Theme.key_player_time));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setSingleLine(true);
return textView;
}
};
playerLayout.addView(authorTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 20, 47, 72, 0));
seekBarView = new SeekBarView(context);
@ -616,20 +658,29 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
updateRepeatButton();
});
buttons[1] = prevButton = new ImageView(context);
final int iconColor = Theme.getColor(Theme.key_player_button);
buttons[1] = prevButton = new RLottieImageView(context);
prevButton.setScaleType(ImageView.ScaleType.CENTER);
prevButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_player_button), PorterDuff.Mode.MULTIPLY));
prevButton.setImageResource(R.drawable.player_new_previous);
prevButton.setAnimation(R.raw.player_prev, 20, 20);
prevButton.setLayerColor("Triangle 3.**", iconColor);
prevButton.setLayerColor("Triangle 4.**", iconColor);
prevButton.setLayerColor("Rectangle 4.**", iconColor);
if (Build.VERSION.SDK_INT >= 21) {
prevButton.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), 1, AndroidUtilities.dp(22)));
}
bottomView.addView(prevButton, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
prevButton.setOnClickListener(v -> MediaController.getInstance().playPreviousMessage());
prevButton.setOnClickListener(v -> {
MediaController.getInstance().playPreviousMessage();
prevButton.setProgress(0f);
prevButton.playAnimation();
});
prevButton.setContentDescription(LocaleController.getString("AccDescrPrevious", R.string.AccDescrPrevious));
buttons[2] = playButton = new ImageView(context);
playButton.setScaleType(ImageView.ScaleType.CENTER);
playButton.setImageResource(R.drawable.player_new_play);
playButton.setImageDrawable(playPauseDrawable = new PlayPauseDrawable(28));
playPauseDrawable.setPause(!MediaController.getInstance().isMessagePaused(), false);
playButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_player_button), PorterDuff.Mode.MULTIPLY));
if (Build.VERSION.SDK_INT >= 21) {
playButton.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), 1, AndroidUtilities.dp(24)));
@ -646,18 +697,25 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
}
});
buttons[3] = nextButton = new ImageView(context);
buttons[3] = nextButton = new RLottieImageView(context);
nextButton.setScaleType(ImageView.ScaleType.CENTER);
nextButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_player_button), PorterDuff.Mode.MULTIPLY));
nextButton.setImageResource(R.drawable.player_new_next);
nextButton.setAnimation(R.raw.player_prev, 20, 20);
nextButton.setLayerColor("Triangle 3.**", iconColor);
nextButton.setLayerColor("Triangle 4.**", iconColor);
nextButton.setLayerColor("Rectangle 4.**", iconColor);
nextButton.setRotation(180f);
if (Build.VERSION.SDK_INT >= 21) {
nextButton.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), 1, AndroidUtilities.dp(22)));
}
bottomView.addView(nextButton, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
nextButton.setOnClickListener(v -> MediaController.getInstance().playNextMessage());
nextButton.setOnClickListener(v -> {
MediaController.getInstance().playNextMessage();
nextButton.setProgress(0f);
nextButton.playAnimation();
});
nextButton.setContentDescription(LocaleController.getString("Next", R.string.Next));
buttons[4] = optionsButton = new ActionBarMenuItem(context, null, 0, Theme.getColor(Theme.key_player_button));
buttons[4] = optionsButton = new ActionBarMenuItem(context, null, 0, iconColor);
optionsButton.setLongClickEnabled(false);
optionsButton.setShowSubmenuByMove(false);
optionsButton.setIcon(R.drawable.ic_ab_other);
@ -821,6 +879,8 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
bigAlbumConver = new BackupImageView(context);
bigAlbumConver.setAspectFit(true);
bigAlbumConver.setRoundRadius(AndroidUtilities.dp(8));
bigAlbumConver.setScaleX(0.9f);
bigAlbumConver.setScaleY(0.9f);
blurredView.addView(bigAlbumConver, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 30, 30, 30, 30));
updateTitle(false);
@ -1065,7 +1125,9 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
if (path == null || path.length() == 0) {
path = FileLoader.getPathToMessage(messageObject.messageOwner).toString();
}
MediaController.saveFile(path, parentActivity, 3, fileName, messageObject.getDocument() != null ? messageObject.getDocument().mime_type : "");
MediaController.saveFile(path, parentActivity, 3, fileName, messageObject.getDocument() != null ? messageObject.getDocument().mime_type : "", () -> {
BulletinFactory.of((FrameLayout) containerView).createDownloadBulletin(BulletinFactory.FileType.AUDIO).show();
});
}
}
@ -1075,7 +1137,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
return;
}
blurredView.setTag(1);
bigAlbumConver.setImageBitmap(placeholderImageView.imageReceiver.getBitmap());
bigAlbumConver.setImageBitmap(coverContainer.getImageReceiver().getBitmap());
blurredAnimationInProgress = true;
BaseFragment fragment = parentActivity.getActionBarLayout().fragmentsStack.get(parentActivity.getActionBarLayout().fragmentsStack.size() - 1);
View fragmentView = fragment.getFragmentView();
@ -1096,6 +1158,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
blurredAnimationInProgress = false;
}
}).start();
bigAlbumConver.animate().scaleX(1f).scaleY(1f).setDuration(180).start();
} else {
if (blurredView.getVisibility() != View.VISIBLE) {
return;
@ -1111,10 +1174,13 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
blurredAnimationInProgress = false;
}
}).start();
bigAlbumConver.animate().scaleX(0.9f).scaleY(0.9f).setDuration(180).start();
} else {
blurredView.setAlpha(0.0f);
blurredView.setVisibility(View.INVISIBLE);
bigAlbumConver.setImageBitmap(null);
bigAlbumConver.setScaleX(0.9f);
bigAlbumConver.setScaleY(0.9f);
}
}
}
@ -1358,12 +1424,16 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
}
private void updateProgress(MessageObject messageObject) {
updateProgress(messageObject, false);
}
private void updateProgress(MessageObject messageObject, boolean animated) {
if (seekBarView != null) {
int newTime;
if (seekBarView.isDragging()) {
newTime = (int) (messageObject.getDuration() * seekBarView.getProgress());
} else {
seekBarView.setProgress(messageObject.audioProgress);
seekBarView.setProgress(messageObject.audioProgress, animated);
float bufferedProgress;
if (currentAudioFinishedLoading) {
@ -1423,21 +1493,25 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
dismiss();
} else {
if (messageObject == null) {
lastMessageObject = null;
return;
}
final boolean sameMessageObject = messageObject == lastMessageObject;
lastMessageObject = messageObject;
if (messageObject.eventId != 0 || messageObject.getId() <= -2000000000) {
optionsButton.setVisibility(View.INVISIBLE);
} else {
optionsButton.setVisibility(View.VISIBLE);
}
checkIfMusicDownloaded(messageObject);
updateProgress(messageObject);
updateProgress(messageObject, !sameMessageObject);
updateCover(messageObject, !sameMessageObject);
if (MediaController.getInstance().isMessagePaused()) {
playButton.setImageResource(R.drawable.player_new_play);
playPauseDrawable.setPause(false);
playButton.setContentDescription(LocaleController.getString("AccActionPlay", R.string.AccActionPlay));
} else {
playButton.setImageResource(R.drawable.player_new_pause);
playPauseDrawable.setPause(true);
playButton.setContentDescription(LocaleController.getString("AccActionPause", R.string.AccActionPause));
}
String title = messageObject.getMusicTitle();
@ -1445,35 +1519,6 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
titleTextView.setText(title);
authorTextView.setText(author);
String loadTitle = author + " " + title;
AudioInfo audioInfo = MediaController.getInstance().getAudioInfo();
if (audioInfo != null && audioInfo.getCover() != null) {
placeholderImageView.setImageBitmap(audioInfo.getCover());
currentFile = null;
currentAudioFinishedLoading = true;
} else {
TLRPC.Document document = messageObject.getDocument();
currentFile = FileLoader.getAttachFileName(document);
currentAudioFinishedLoading = false;
TLRPC.PhotoSize thumb = document != null ? FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 240) : null;
if (!(thumb instanceof TLRPC.TL_photoSize) && !(thumb instanceof TLRPC.TL_photoSizeProgressive)) {
thumb = null;
}
String artworkUrl = messageObject.getArtworkUrl(false);
if (!TextUtils.isEmpty(artworkUrl)) {
if (thumb != null) {
placeholderImageView.setImage(ImageLocation.getForPath(artworkUrl), null, ImageLocation.getForDocument(thumb, document), null, null, 0, 1, messageObject);
} else {
placeholderImageView.setImage(artworkUrl, null, null);
}
} else if (thumb != null) {
placeholderImageView.setImage(null, null, ImageLocation.getForDocument(thumb, document), null, null, 0, 1, messageObject);
} else {
placeholderImageView.setImageDrawable(null);
}
placeholderImageView.invalidate();
}
int duration = lastDuration = messageObject.getDuration();
if (durationTextView != null) {
@ -1485,6 +1530,91 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
} else {
playbackSpeedButton.setVisibility(View.GONE);
}
if (!sameMessageObject) {
preloadNeighboringThumbs();
}
}
}
private void updateCover(MessageObject messageObject, boolean animated) {
final BackupImageView imageView = animated ? coverContainer.getNextImageView() : coverContainer.getImageView();
final AudioInfo audioInfo = MediaController.getInstance().getAudioInfo();
if (audioInfo != null && audioInfo.getCover() != null) {
imageView.setImageBitmap(audioInfo.getCover());
currentFile = null;
currentAudioFinishedLoading = true;
} else {
TLRPC.Document document = messageObject.getDocument();
currentFile = FileLoader.getAttachFileName(document);
currentAudioFinishedLoading = false;
String artworkUrl = messageObject.getArtworkUrl(false);
final ImageLocation thumbImageLocation = getArtworkThumbImageLocation(messageObject);
if (!TextUtils.isEmpty(artworkUrl)) {
imageView.setImage(ImageLocation.getForPath(artworkUrl), null, thumbImageLocation, null, null, 0, 1, messageObject);
} else if (thumbImageLocation != null) {
imageView.setImage(null, null, thumbImageLocation, null, null, 0, 1, messageObject);
} else {
imageView.setImageDrawable(null);
}
imageView.invalidate();
}
if (animated) {
coverContainer.switchImageViews();
}
}
private ImageLocation getArtworkThumbImageLocation(MessageObject messageObject) {
final TLRPC.Document document = messageObject.getDocument();
TLRPC.PhotoSize thumb = document != null ? FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 240) : null;
if (!(thumb instanceof TLRPC.TL_photoSize) && !(thumb instanceof TLRPC.TL_photoSizeProgressive)) {
thumb = null;
}
if (thumb != null) {
return ImageLocation.getForDocument(thumb, document);
} else {
final String smallArtworkUrl = messageObject.getArtworkUrl(true);
if (smallArtworkUrl != null) {
return ImageLocation.getForPath(smallArtworkUrl);
}
}
return null;
}
private void preloadNeighboringThumbs() {
final MediaController mediaController = MediaController.getInstance();
final List<MessageObject> playlist = mediaController.getPlaylist();
if (playlist.size() <= 1) {
return;
}
final List<MessageObject> neighboringItems = new ArrayList<>();
final int playingIndex = mediaController.getPlayingMessageObjectNum();
int nextIndex = playingIndex + 1;
int prevIndex = playingIndex - 1;
if (nextIndex >= playlist.size()) {
nextIndex = 0;
}
if (prevIndex <= -1) {
prevIndex = playlist.size() - 1;
}
neighboringItems.add(playlist.get(nextIndex));
if (nextIndex != prevIndex) {
neighboringItems.add(playlist.get(prevIndex));
}
for (int i = 0, N = neighboringItems.size(); i < N; i++) {
final MessageObject messageObject = neighboringItems.get(i);
final ImageLocation thumbImageLocation = getArtworkThumbImageLocation(messageObject);
if (thumbImageLocation != null) {
if (thumbImageLocation.path != null) {
ImageLoader.getInstance().preloadArtwork(thumbImageLocation.path);
} else {
FileLoader.getInstance(currentAccount).loadFile(thumbImageLocation, messageObject, null, 0, 1);
}
}
}
}
@ -1693,8 +1823,8 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
themeDescriptions.add(new ThemeDescription(progressView, 0, null, null, null, null, Theme.key_player_progressBackground));
themeDescriptions.add(new ThemeDescription(progressView, 0, null, null, null, null, Theme.key_player_progress));
themeDescriptions.add(new ThemeDescription(seekBarView, 0, null, null, null, null, Theme.key_player_progressBackground));
themeDescriptions.add(new ThemeDescription(seekBarView, 0, null, null, null, null, Theme.key_player_progress));
themeDescriptions.add(new ThemeDescription(seekBarView, 0, null, null, null, null, Theme.key_player_progressCachedBackground));
themeDescriptions.add(new ThemeDescription(seekBarView, ThemeDescription.FLAG_PROGRESSBAR, null, null, null, null, Theme.key_player_progress));
themeDescriptions.add(new ThemeDescription(playbackSpeedButton, ThemeDescription.FLAG_CHECKTAG | ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_inappPlayerPlayPause));
themeDescriptions.add(new ThemeDescription(playbackSpeedButton, ThemeDescription.FLAG_CHECKTAG | ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_inappPlayerClose));
@ -1709,13 +1839,17 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
themeDescriptions.add(new ThemeDescription(optionsButton, 0, null, null, null, delegate, Theme.key_actionBarDefaultSubmenuItem));
themeDescriptions.add(new ThemeDescription(optionsButton, 0, null, null, null, delegate, Theme.key_actionBarDefaultSubmenuBackground));
themeDescriptions.add(new ThemeDescription(prevButton, ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_player_button));
themeDescriptions.add(new ThemeDescription(prevButton, 0, null, new RLottieDrawable[]{prevButton.getAnimatedDrawable()}, "Triangle 3", Theme.key_player_button));
themeDescriptions.add(new ThemeDescription(prevButton, 0, null, new RLottieDrawable[]{prevButton.getAnimatedDrawable()}, "Triangle 4", Theme.key_player_button));
themeDescriptions.add(new ThemeDescription(prevButton, 0, null, new RLottieDrawable[]{prevButton.getAnimatedDrawable()}, "Rectangle 4", Theme.key_player_button));
themeDescriptions.add(new ThemeDescription(prevButton, ThemeDescription.FLAG_IMAGECOLOR | ThemeDescription.FLAG_USEBACKGROUNDDRAWABLE, null, null, null, null, Theme.key_listSelector));
themeDescriptions.add(new ThemeDescription(playButton, ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_player_button));
themeDescriptions.add(new ThemeDescription(playButton, ThemeDescription.FLAG_IMAGECOLOR | ThemeDescription.FLAG_USEBACKGROUNDDRAWABLE, null, null, null, null, Theme.key_listSelector));
themeDescriptions.add(new ThemeDescription(nextButton, ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_player_button));
themeDescriptions.add(new ThemeDescription(nextButton, 0, null, new RLottieDrawable[]{nextButton.getAnimatedDrawable()}, "Triangle 3", Theme.key_player_button));
themeDescriptions.add(new ThemeDescription(nextButton, 0, null, new RLottieDrawable[]{nextButton.getAnimatedDrawable()}, "Triangle 4", Theme.key_player_button));
themeDescriptions.add(new ThemeDescription(nextButton, 0, null, new RLottieDrawable[]{nextButton.getAnimatedDrawable()}, "Rectangle 4", Theme.key_player_button));
themeDescriptions.add(new ThemeDescription(nextButton, ThemeDescription.FLAG_IMAGECOLOR | ThemeDescription.FLAG_USEBACKGROUNDDRAWABLE, null, null, null, null, Theme.key_listSelector));
themeDescriptions.add(new ThemeDescription(playerLayout, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_player_background));
@ -1736,11 +1870,250 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
themeDescriptions.add(new ThemeDescription(durationTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_player_time));
themeDescriptions.add(new ThemeDescription(timeTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_player_time));
themeDescriptions.add(new ThemeDescription(titleTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_player_actionBarTitle));
themeDescriptions.add(new ThemeDescription(authorTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_player_time));
themeDescriptions.add(new ThemeDescription(titleTextView.getTextView(), ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_player_actionBarTitle));
themeDescriptions.add(new ThemeDescription(titleTextView.getNextTextView(), ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_player_actionBarTitle));
themeDescriptions.add(new ThemeDescription(authorTextView.getTextView(), ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_player_time));
themeDescriptions.add(new ThemeDescription(authorTextView.getNextTextView(), ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_player_time));
themeDescriptions.add(new ThemeDescription(containerView, 0, null, null, null, null, Theme.key_sheet_scrollUp));
return themeDescriptions;
}
private static abstract class CoverContainer extends FrameLayout {
private final BackupImageView[] imageViews = new BackupImageView[2];
private int activeIndex;
private AnimatorSet animatorSet;
public CoverContainer(@NonNull Context context) {
super(context);
for (int i = 0; i < 2; i++) {
imageViews[i] = new BackupImageView(context);
final int index = i;
imageViews[i].getImageReceiver().setDelegate((imageReceiver, set, thumb, memCache) -> {
if (index == activeIndex) {
onImageUpdated(imageReceiver);
}
});
imageViews[i].setRoundRadius(AndroidUtilities.dp(4));
if (i == 1) {
imageViews[i].setVisibility(GONE);
}
addView(imageViews[i], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
}
public final void switchImageViews() {
if (animatorSet != null) {
animatorSet.cancel();
}
animatorSet = new AnimatorSet();
activeIndex = activeIndex == 0 ? 1 : 0;
final BackupImageView prevImageView = imageViews[activeIndex == 0 ? 1 : 0];
final BackupImageView currImageView = imageViews[activeIndex];
final boolean hasBitmapImage = prevImageView.getImageReceiver().hasBitmapImage();
currImageView.setAlpha(hasBitmapImage ? 1f : 0f);
currImageView.setScaleX(0.8f);
currImageView.setScaleY(0.8f);
currImageView.setVisibility(VISIBLE);
if (hasBitmapImage) {
prevImageView.bringToFront();
} else {
prevImageView.setVisibility(GONE);
prevImageView.setImageDrawable(null);
}
final ValueAnimator expandAnimator = ValueAnimator.ofFloat(0.8f, 1f);
expandAnimator.setDuration(125);
expandAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT);
expandAnimator.addUpdateListener(a -> {
float animatedValue = (float) a.getAnimatedValue();
currImageView.setScaleX(animatedValue);
currImageView.setScaleY(animatedValue);
if (!hasBitmapImage) {
currImageView.setAlpha(a.getAnimatedFraction());
}
});
if (hasBitmapImage) {
final ValueAnimator collapseAnimator = ValueAnimator.ofFloat(prevImageView.getScaleX(), 0.8f);
collapseAnimator.setDuration(125);
collapseAnimator.setInterpolator(CubicBezierInterpolator.EASE_IN);
collapseAnimator.addUpdateListener(a -> {
float animatedValue = (float) a.getAnimatedValue();
prevImageView.setScaleX(animatedValue);
prevImageView.setScaleY(animatedValue);
final float fraction = a.getAnimatedFraction();
if (fraction > 0.25f && !currImageView.getImageReceiver().hasBitmapImage()) {
prevImageView.setAlpha(1f - (fraction - 0.25f) * (1f / 0.75f));
}
});
collapseAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
prevImageView.setVisibility(GONE);
prevImageView.setImageDrawable(null);
prevImageView.setAlpha(1f);
}
});
animatorSet.playSequentially(collapseAnimator, expandAnimator);
} else {
animatorSet.play(expandAnimator);
}
animatorSet.start();
}
public final BackupImageView getImageView() {
return imageViews[activeIndex];
}
public final BackupImageView getNextImageView() {
return imageViews[activeIndex == 0 ? 1 : 0];
}
public final ImageReceiver getImageReceiver() {
return getImageView().getImageReceiver();
}
protected abstract void onImageUpdated(ImageReceiver imageReceiver);
}
private abstract static class ClippingTextViewSwitcher extends FrameLayout {
private final TextView[] textViews = new TextView[2];
private final float[] clipProgress = new float[]{0f, 0.75f};
private final int gradientSize = AndroidUtilities.dp(24);
private final Matrix gradientMatrix;
private final Paint gradientPaint;
private final Paint erasePaint;
private int activeIndex;
private AnimatorSet animatorSet;
private LinearGradient gradientShader;
public ClippingTextViewSwitcher(@NonNull Context context) {
super(context);
for (int i = 0; i < 2; i++) {
textViews[i] = createTextView();
if (i == 1) {
textViews[i].setAlpha(0f);
textViews[i].setVisibility(GONE);
}
addView(textViews[i], LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT));
}
gradientMatrix = new Matrix();
gradientPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
gradientPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
erasePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
erasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
gradientShader = new LinearGradient(gradientSize, 0, 0, 0, 0, 0xFF000000, Shader.TileMode.CLAMP);
gradientPaint.setShader(gradientShader);
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
final int index = child == textViews[0] ? 0 : 1;
final boolean result;
if (clipProgress[index] > 0f) {
final int width = child.getWidth();
final int height = child.getHeight();
final int saveCount = canvas.saveLayer(0, 0, width, height, null, Canvas.ALL_SAVE_FLAG);
result = super.drawChild(canvas, child, drawingTime);
final float gradientStart = width * (1f - clipProgress[index]);
final float gradientEnd = gradientStart + gradientSize;
gradientMatrix.setTranslate(gradientStart, 0);
gradientShader.setLocalMatrix(gradientMatrix);
canvas.drawRect(gradientStart, 0, gradientEnd, height, gradientPaint);
if (width > gradientEnd) {
canvas.drawRect(gradientEnd, 0, width, height, erasePaint);
}
canvas.restoreToCount(saveCount);
} else {
result = super.drawChild(canvas, child, drawingTime);
}
return result;
}
public void setText(CharSequence text) {
final CharSequence currentText = textViews[activeIndex].getText();
if (TextUtils.isEmpty(currentText)) {
textViews[activeIndex].setText(text);
return;
} else if (TextUtils.equals(text, currentText)) {
return;
}
final int index = activeIndex == 0 ? 1 : 0;
final int prevIndex = activeIndex;
activeIndex = index;
if (animatorSet != null) {
animatorSet.cancel();
}
animatorSet = new AnimatorSet();
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
textViews[prevIndex].setVisibility(GONE);
}
});
textViews[index].setText(text);
textViews[index].bringToFront();
textViews[index].setVisibility(VISIBLE);
final int duration = 300;
final ValueAnimator collapseAnimator = ValueAnimator.ofFloat(clipProgress[prevIndex], 0.75f);
collapseAnimator.setDuration(duration / 3 * 2); // 0.66
collapseAnimator.addUpdateListener(a -> {
clipProgress[prevIndex] = (float) a.getAnimatedValue();
invalidate();
});
final ValueAnimator expandAnimator = ValueAnimator.ofFloat(clipProgress[index], 0f);
expandAnimator.setStartDelay(duration / 3); // 0.33
expandAnimator.setDuration(duration / 3 * 2); // 0.66
expandAnimator.addUpdateListener(a -> {
clipProgress[index] = (float) a.getAnimatedValue();
invalidate();
});
final ObjectAnimator fadeOutAnimator = ObjectAnimator.ofFloat(textViews[prevIndex], View.ALPHA, 0f);
fadeOutAnimator.setStartDelay(duration / 4); // 0.25
fadeOutAnimator.setDuration(duration / 2); // 0.5
final ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat(textViews[index], View.ALPHA, 1f);
fadeInAnimator.setStartDelay(duration / 4); // 0.25
fadeInAnimator.setDuration(duration / 2); // 0.5
animatorSet.playTogether(collapseAnimator, expandAnimator, fadeOutAnimator, fadeInAnimator);
animatorSet.start();
}
public TextView getTextView() {
return textViews[activeIndex];
}
public TextView getNextTextView() {
return textViews[activeIndex == 0 ? 1 : 0];
}
protected abstract TextView createTextView();
}
}

View File

@ -13,6 +13,7 @@ import android.graphics.Typeface;
import android.graphics.drawable.InsetDrawable;
import android.os.Build;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
@ -30,8 +31,10 @@ import androidx.core.util.Preconditions;
import androidx.core.view.ViewCompat;
import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.BaseFragment;
@ -81,25 +84,33 @@ public final class Bulletin {
private static Bulletin visibleBulletin;
private final Layout layout;
private final FrameLayout parentLayout;
private final ParentLayout parentLayout;
private final FrameLayout containerLayout;
private final Runnable hideRunnable = this::hide;
private final int duration;
private boolean showing;
private Runnable exitRunnable;
private boolean canHide;
private int currentBottomOffset;
private Delegate currentDelegate;
private Layout.Transition layoutTransition;
private Bulletin(@NonNull FrameLayout containerLayout, @NonNull Layout layout, int duration) {
this.layout = layout;
this.parentLayout = new FrameLayout(layout.getContext());
this.parentLayout.addView(layout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
this.parentLayout = new ParentLayout(layout) {
@Override
protected void onPressedStateChanged(boolean pressed) {
setCanHide(!pressed);
if (containerLayout.getParent() != null) {
containerLayout.getParent().requestDisallowInterceptTouchEvent(pressed);
}
}
};
this.containerLayout = containerLayout;
this.duration = duration;
}
public void show() {
public Bulletin show() {
if (!showing) {
showing = true;
@ -128,7 +139,7 @@ public final class Bulletin {
ensureLayoutTransitionCreated();
layoutTransition.animateEnter(layout, layout::onEnterTransitionStart, () -> {
layout.onEnterTransitionEnd();
layout.postDelayed(exitRunnable = Bulletin.this::hide, duration);
setCanHide(true);
}, offset -> {
if (currentDelegate != null) {
currentDelegate.onOffsetChange(layout.getHeight() - offset);
@ -141,7 +152,7 @@ public final class Bulletin {
layout.setTranslationY(-currentBottomOffset);
layout.onEnterTransitionStart();
layout.onEnterTransitionEnd();
layout.postDelayed(exitRunnable = Bulletin.this::hide, duration);
setCanHide(true);
}
}
}
@ -160,6 +171,18 @@ public final class Bulletin {
containerLayout.addView(parentLayout);
}
return this;
}
private void setCanHide(boolean canHide) {
if (this.canHide != canHide) {
this.canHide = canHide;
if (canHide) {
layout.postDelayed(hideRunnable, duration);
} else {
layout.removeCallbacks(hideRunnable);
}
}
}
private void ensureLayoutTransitionCreated() {
@ -172,8 +195,8 @@ public final class Bulletin {
hide(isTransitionsEnabled());
}
private void hide(boolean animated) {
if (showing) {
public void hide(boolean animated) {
if (showing && canHide) {
showing = false;
if (visibleBulletin == this) {
@ -184,10 +207,7 @@ public final class Bulletin {
currentBottomOffset = 0;
if (ViewCompat.isLaidOut(layout)) {
if (exitRunnable != null) {
layout.removeCallbacks(exitRunnable);
exitRunnable = null;
}
layout.removeCallbacks(hideRunnable);
if (animated) {
ensureLayoutTransitionCreated();
layoutTransition.animateExit(layout, layout::onExitTransitionStart, () -> {
@ -232,6 +252,85 @@ public final class Bulletin {
return MessagesController.getGlobalMainSettings().getBoolean("view_animations", true) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
}
private static abstract class ParentLayout extends FrameLayout {
private final Layout layout;
private final Rect rect = new Rect();
private final GestureDetector gestureDetector;
private boolean pressed;
private float translationX;
private SpringAnimation springAnimation;
public ParentLayout(Layout layout) {
super(layout.getContext());
this.layout = layout;
gestureDetector = new GestureDetector(layout.getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return springAnimation == null;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
layout.setTranslationX(translationX -= distanceX);
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (Math.abs(velocityX) > 2000f) {
springAnimation = new SpringAnimation(layout, DynamicAnimation.TRANSLATION_X, Math.signum(velocityX) * layout.getWidth() * 2f);
springAnimation.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY);
springAnimation.getSpring().setStiffness(100f);
springAnimation.setStartVelocity(velocityX);
springAnimation.start();
return true;
}
return false;
}
});
gestureDetector.setIsLongpressEnabled(false);
addView(layout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (pressed || inLayoutHitRect(event.getX(), event.getY())) {
gestureDetector.onTouchEvent(event);
final int actionMasked = event.getActionMasked();
if (actionMasked == MotionEvent.ACTION_DOWN) {
if (!pressed && springAnimation == null) {
layout.animate().cancel();
translationX = layout.getTranslationX();
onPressedStateChanged(pressed = true);
}
} else if (actionMasked == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_CANCEL) {
if (pressed) {
if (springAnimation == null) {
if (Math.abs(translationX) > layout.getWidth() / 2) {
layout.animate().translationX(Math.signum(translationX) * layout.getWidth()).setDuration(200).setInterpolator(AndroidUtilities.accelerateInterpolator).start();
} else {
layout.animate().translationX(0).setDuration(200).start();
}
}
onPressedStateChanged(pressed = false);
}
}
return true;
}
return false;
}
private boolean inLayoutHitRect(float x, float y) {
layout.getHitRect(rect);
return rect.contains((int) x, (int) y);
}
protected abstract void onPressedStateChanged(boolean pressed);
}
//region Offset Providers
public static void addDelegate(@NonNull BaseFragment fragment, @NonNull Delegate delegate) {
final FrameLayout containerLayout = fragment.getLayoutContainer();
@ -297,12 +396,6 @@ public final class Bulletin {
setLayoutParams(LayoutHelper.createFrame(matchParentWidth ? LayoutHelper.MATCH_PARENT : LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
return true;
}
public Bulletin getBulletin() {
return bulletin;
}
@ -481,22 +574,14 @@ public final class Bulletin {
springAnimation.getSpring().setDampingRatio(DAMPING_RATIO);
springAnimation.getSpring().setStiffness(STIFFNESS);
if (endAction != null) {
springAnimation.addEndListener(new DynamicAnimation.OnAnimationEndListener() {
@Override
public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value, float velocity) {
if (!canceled) {
endAction.run();
}
springAnimation.addEndListener((animation, canceled, value, velocity) -> {
if (!canceled) {
endAction.run();
}
});
}
if (onUpdate != null) {
springAnimation.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
@Override
public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
onUpdate.accept(value);
}
});
springAnimation.addUpdateListener((animation, value, velocity) -> onUpdate.accept(value));
}
springAnimation.start();
if (startAction != null) {
@ -510,22 +595,14 @@ public final class Bulletin {
springAnimation.getSpring().setDampingRatio(DAMPING_RATIO);
springAnimation.getSpring().setStiffness(STIFFNESS);
if (endAction != null) {
springAnimation.addEndListener(new DynamicAnimation.OnAnimationEndListener() {
@Override
public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value, float velocity) {
if (!canceled) {
endAction.run();
}
springAnimation.addEndListener((animation, canceled, value, velocity) -> {
if (!canceled) {
endAction.run();
}
});
}
if (onUpdate != null) {
springAnimation.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
@Override
public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
onUpdate.accept(value);
}
});
springAnimation.addUpdateListener((animation, value, velocity) -> onUpdate.accept(value));
}
springAnimation.start();
if (startAction != null) {
@ -644,6 +721,61 @@ public final class Bulletin {
subtitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
linearLayout.addView(subtitleTextView);
}
}
public static class TwoLineLottieLayout extends ButtonLayout {
public final RLottieImageView imageView;
public final TextView titleTextView;
public final TextView subtitleTextView;
private final int textColor;
public TwoLineLottieLayout(@NonNull Context context) {
this(context, Theme.getColor(Theme.key_undo_background), Theme.getColor(Theme.key_undo_infoColor));
}
public TwoLineLottieLayout(@NonNull Context context, @ColorInt int backgroundColor, @ColorInt int textColor) {
super(context, backgroundColor);
this.textColor = textColor;
imageView = new RLottieImageView(context);
addView(imageView, LayoutHelper.createFrameRelatively(28, 28, Gravity.START | Gravity.CENTER_VERTICAL, 14, 10, 14, 10));
final int undoInfoColor = Theme.getColor(Theme.key_undo_infoColor);
final LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
addView(linearLayout, LayoutHelper.createFrameRelatively(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL, 54, 8, 12, 8));
titleTextView = new TextView(context);
titleTextView.setSingleLine();
titleTextView.setTextColor(undoInfoColor);
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
linearLayout.addView(titleTextView);
subtitleTextView = new TextView(context);
subtitleTextView.setMaxLines(2);
subtitleTextView.setTextColor(undoInfoColor);
subtitleTextView.setTypeface(Typeface.SANS_SERIF);
subtitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
linearLayout.addView(subtitleTextView);
}
@Override
protected void onShow() {
super.onShow();
imageView.playAnimation();
}
public void setAnimation(int resId, String... layers) {
imageView.setAnimation(resId, 28, 28);
for (int i = 0; i < layers.length; i++) {
imageView.setLayerColor(layers[i] + ".**", textColor);
}
}
}
public static class LottieLayout extends ButtonLayout {
@ -736,18 +868,31 @@ public final class Bulletin {
private Bulletin bulletin;
private boolean isUndone;
public UndoButton(@NonNull Context context) {
public UndoButton(@NonNull Context context, boolean text) {
super(context);
final int undoCancelColor = Theme.getColor(Theme.key_undo_cancelColor);
final ImageView undoImageView = new ImageView(getContext());
undoImageView.setOnClickListener(v -> undo());
undoImageView.setImageResource(R.drawable.chats_undo);
undoImageView.setColorFilter(new PorterDuffColorFilter(undoCancelColor, PorterDuff.Mode.MULTIPLY));
undoImageView.setBackground(Theme.createSelectorDrawable((undoCancelColor & 0x00ffffff) | 0x19000000));
ViewHelper.setPaddingRelative(undoImageView, 0, 12, 0, 12);
addView(undoImageView, LayoutHelper.createFrameRelatively(56, 48, Gravity.CENTER_VERTICAL));
if (text) {
TextView undoTextView = new TextView(context);
undoTextView.setOnClickListener(v -> undo());
undoTextView.setBackground(Theme.createSelectorDrawable((undoCancelColor & 0x00ffffff) | 0x19000000, 7));
undoTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
undoTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
undoTextView.setTextColor(undoCancelColor);
undoTextView.setText(LocaleController.getString("Undo", R.string.Undo));
undoTextView.setGravity(Gravity.CENTER_VERTICAL);
ViewHelper.setPaddingRelative(undoTextView, 16, 0, 16, 0);
addView(undoTextView, LayoutHelper.createFrameRelatively(LayoutHelper.WRAP_CONTENT, 48, Gravity.CENTER_VERTICAL, 0, 0, 0, 0));
} else {
final ImageView undoImageView = new ImageView(getContext());
undoImageView.setOnClickListener(v -> undo());
undoImageView.setImageResource(R.drawable.chats_undo);
undoImageView.setColorFilter(new PorterDuffColorFilter(undoCancelColor, PorterDuff.Mode.MULTIPLY));
undoImageView.setBackground(Theme.createSelectorDrawable((undoCancelColor & 0x00ffffff) | 0x19000000));
ViewHelper.setPaddingRelative(undoImageView, 0, 12, 0, 12);
addView(undoImageView, LayoutHelper.createFrameRelatively(56, 48, Gravity.CENTER_VERTICAL));
}
}
public void undo() {

View File

@ -1,9 +1,11 @@
package org.telegram.ui.Components;
import android.content.Context;
import android.widget.FrameLayout;
import androidx.core.util.Preconditions;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationsController;
import org.telegram.messenger.R;
@ -11,13 +13,112 @@ import org.telegram.ui.ActionBar.BaseFragment;
public final class BulletinFactory {
private BulletinFactory() {
public static BulletinFactory of(BaseFragment fragment) {
Preconditions.checkNotNull(fragment);
return new BulletinFactory(fragment);
}
public static BulletinFactory of(FrameLayout containerLayout) {
Preconditions.checkNotNull(containerLayout);
return new BulletinFactory(containerLayout);
}
public static boolean canShowBulletin(BaseFragment fragment) {
return fragment != null && fragment.getParentActivity() != null;
return fragment != null && fragment.getParentActivity() != null && fragment.getLayoutContainer() != null;
}
public enum FileType {
PHOTO("PhotoSavedHint", R.string.PhotoSavedHint),
PHOTO_TO_DOWNLOADS("PhotoSavedToDownloadsHint", R.string.PhotoSavedToDownloadsHint),
PHOTOS("PhotosSavedHint"),
VIDEO("VideoSavedHint", R.string.VideoSavedHint),
VIDEO_TO_DOWNLOADS("VideoSavedToDownloadsHint", R.string.VideoSavedToDownloadsHint),
VIDEOS("VideosSavedHint"),
AUDIO("AudioSavedHint", R.string.AudioSavedHint),
AUDIOS("AudiosSavedHint"),
GIF("GifSavedToDownloadsHint", R.string.GifSavedToDownloadsHint),
MEDIA("MediaSavedHint"),
UNKNOWN("FileSavedHint", R.string.FileSavedHint),
UNKNOWNS("FilesSavedHint");
private final String localeKey;
private final int localeRes;
private final boolean plural;
FileType(String localeKey, int localeRes) {
this.localeKey = localeKey;
this.localeRes = localeRes;
this.plural = false;
}
FileType(String localeKey) {
this.localeKey = localeKey;
this.localeRes = 0;
this.plural = true;
}
private String getText() {
return getText(1);
}
private String getText(int amount) {
if (plural) {
return LocaleController.formatPluralString(localeKey, amount);
} else {
return LocaleController.getString(localeKey, localeRes);
}
}
}
private final BaseFragment fragment;
private final FrameLayout containerLayout;
private BulletinFactory(BaseFragment fragment) {
this.fragment = fragment;
this.containerLayout = null;
}
private BulletinFactory(FrameLayout containerLayout) {
this.containerLayout = containerLayout;
this.fragment = null;
}
public Bulletin createDownloadBulletin(FileType fileType) {
return createDownloadBulletin(fileType, 1);
}
public Bulletin createDownloadBulletin(FileType fileType, int filesAmount) {
return createDownloadBulletin(fileType, filesAmount, 0, 0);
}
public Bulletin createDownloadBulletin(FileType fileType, int filesAmount, int backgroundColor, int textColor) {
final Bulletin.LottieLayout layout;
if (backgroundColor != 0 && textColor != 0) {
layout = new Bulletin.LottieLayout(getContext(), backgroundColor, textColor);
} else {
layout = new Bulletin.LottieLayout(getContext());
}
layout.setAnimation(R.raw.ic_download, "Box", "Arrow", "Mask", "Arrow 2", "Splash");
layout.textView.setText(fileType.getText(filesAmount));
return create(layout, Bulletin.DURATION_SHORT);
}
private Bulletin create(Bulletin.Layout layout, int duration) {
if (fragment != null) {
return Bulletin.make(fragment, layout, duration);
} else {
return Bulletin.make(containerLayout, layout, duration);
}
}
private Context getContext() {
return fragment != null ? fragment.getParentActivity() : containerLayout.getContext();
}
//region Static Factory
public static Bulletin createMuteBulletin(BaseFragment fragment, int setting) {
Preconditions.checkArgument(canShowBulletin(fragment));
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(fragment.getParentActivity());
@ -72,16 +173,58 @@ public final class BulletinFactory {
return Bulletin.make(fragment, layout, Bulletin.DURATION_SHORT);
}
public static Bulletin createSaveToGalleryBulletin(FrameLayout containerLayout, boolean video, int backgroundColor, int textColor) {
Preconditions.checkNotNull(containerLayout);
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(containerLayout.getContext(), backgroundColor, textColor);
layout.imageView.setAnimation(R.raw.ic_download, 28, 28);
layout.setAnimation(R.raw.ic_download, "Box", "Arrow", "Mask", "Arrow 2", "Splash");
if (video) {
layout.textView.setText(LocaleController.getString("VideoSavedHint", R.string.VideoSavedHint));
public static Bulletin createUnpinAllMessagesBulletin(BaseFragment fragment, int count, boolean hide, Runnable undoAction, Runnable delayedAction) {
Preconditions.checkArgument(canShowBulletin(fragment));
Bulletin.ButtonLayout buttonLayout;
if (hide) {
final Bulletin.TwoLineLottieLayout layout = new Bulletin.TwoLineLottieLayout(fragment.getParentActivity());
layout.setAnimation(R.raw.ic_unpin, "Pin", "Line");
layout.titleTextView.setText(LocaleController.getString("PinnedMessagesHidden", R.string.PinnedMessagesHidden));
layout.subtitleTextView.setText(LocaleController.getString("PinnedMessagesHiddenInfo", R.string.PinnedMessagesHiddenInfo));
buttonLayout = layout;
} else {
layout.textView.setText(LocaleController.getString("PhotoSavedHint", R.string.PhotoSavedHint));
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(fragment.getParentActivity());
layout.setAnimation(R.raw.ic_unpin, "Pin", "Line");
layout.textView.setText(LocaleController.formatPluralString("MessagesUnpinned", count));
buttonLayout = layout;
}
return Bulletin.make(containerLayout, layout, Bulletin.DURATION_SHORT);
buttonLayout.setButton(new Bulletin.UndoButton(fragment.getParentActivity(), true).setUndoAction(undoAction).setDelayedAction(delayedAction));
return Bulletin.make(fragment, buttonLayout, 5000);
}
public static Bulletin createSaveToGalleryBulletin(BaseFragment fragment, boolean video) {
return of(fragment).createDownloadBulletin(video ? FileType.VIDEO : FileType.PHOTO);
}
public static Bulletin createSaveToGalleryBulletin(FrameLayout containerLayout, boolean video, int backgroundColor, int textColor) {
return of(containerLayout).createDownloadBulletin(video ? FileType.VIDEO : FileType.PHOTO, 1, backgroundColor, textColor);
}
public static Bulletin createPromoteToAdminBulletin(BaseFragment fragment, String userFirstName) {
Preconditions.checkArgument(canShowBulletin(fragment));
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(fragment.getParentActivity());
layout.setAnimation(R.raw.ic_admin, "Shield");
layout.textView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("UserSetAsAdminHint", R.string.UserSetAsAdminHint, userFirstName)));
return Bulletin.make(fragment, layout, Bulletin.DURATION_SHORT);
}
public static Bulletin createPinMessageBulletin(BaseFragment fragment) {
return createPinMessageBulletin(fragment, true, null, null);
}
public static Bulletin createUnpinMessageBulletin(BaseFragment fragment, Runnable undoAction, Runnable delayedAction) {
return createPinMessageBulletin(fragment, false, undoAction, delayedAction);
}
private static Bulletin createPinMessageBulletin(BaseFragment fragment, boolean pinned, Runnable undoAction, Runnable delayedAction) {
Preconditions.checkArgument(canShowBulletin(fragment));
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(fragment.getParentActivity());
layout.setAnimation(pinned ? R.raw.ic_pin : R.raw.ic_unpin, "Pin", "Line");
layout.textView.setText(LocaleController.getString(pinned ? "MessagePinnedHint" : "MessageUnpinnedHint", pinned ? R.string.MessagePinnedHint : R.string.MessageUnpinnedHint));
if (!pinned) {
layout.setButton(new Bulletin.UndoButton(fragment.getParentActivity(), true).setUndoAction(undoAction).setDelayedAction(delayedAction));
}
return Bulletin.make(fragment, layout, pinned ? Bulletin.DURATION_SHORT : 5000);
}
//endregion
}

View File

@ -46,6 +46,7 @@ import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.ImageSpan;
import android.util.Property;
@ -133,6 +134,14 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
private boolean clearBotButtonsOnKeyboardOpen;
private boolean expandStickersWithKeyboard;
public int getHeightWithTopView() {
int h = getMeasuredHeight();
if (topView != null && topView.getVisibility() == View.VISIBLE) {
h -= (1f - topViewEnterProgress) * topView.getLayoutParams().height;
}
return h;
}
public interface ChatActivityEnterViewDelegate {
void onMessageSend(CharSequence message, boolean notify, int scheduleDate);
@ -195,6 +204,10 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
default void prepareMessageSending() {
}
default void onTrendingStickersShowed(boolean show) {
}
}
private final static int RECORD_STATE_ENTER = 0;
@ -459,16 +472,11 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
boolean prevOpen2 = emojiTabOpen;
emojiTabOpen = curPage == 0;
if (stickersExpanded) {
if (!stickersTabOpen && searchingType == 0) {
if (searchingType != 0) {
searchingType = 0;
emojiView.closeSearch(true);
emojiView.hideSearchKeyboard();
}
setStickersExpanded(false, true, false);
} else if (searchingType != 0) {
if (searchingType != 0) {
searchingType = curPage == 0 ? 2 : 1;
checkStickresExpandHeight();
} else if (!stickersTabOpen) {
setStickersExpanded(false, true, false);
}
}
if (prevOpen != stickersTabOpen || prevOpen2 != emojiTabOpen) {
@ -2019,6 +2027,9 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
@Override
public boolean onTouchEvent(MotionEvent event) {
if (stickersDragging || stickersExpansionAnim != null) {
return false;
}
if (isPopupShowing() && event.getAction() == MotionEvent.ACTION_DOWN) {
if (searchingType != 0) {
searchingType = 0;
@ -2154,9 +2165,6 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
if ((ctrlPressed || sendByEnter) && keyEvent.getAction() == KeyEvent.ACTION_DOWN && editingMessageObject == null) {
sendMessage();
return true;
} else if (i == KeyEvent.KEYCODE_CTRL_LEFT || i == KeyEvent.KEYCODE_CTRL_RIGHT) {
ctrlPressed = keyEvent.getAction() == KeyEvent.ACTION_DOWN;
return true;
}
}
return false;
@ -2191,7 +2199,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
CharSequence message = AndroidUtilities.getTrimmedString(charSequence.toString());
if (delegate != null) {
if (!ignoreTextChange) {
if (count > 2 || charSequence == null || charSequence.length() == 0) {
if (count > 2 || TextUtils.isEmpty(charSequence)) {
messageWebPageSearch = true;
}
delegate.onTextChanged(charSequence, before > count + 1 || (count - before) > 2);
@ -2201,14 +2209,6 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
processChange = true;
}
if (editingMessageObject == null && !canWriteToChannel && message.length() != 0 && lastTypingTimeSend < System.currentTimeMillis() - 5000 && !ignoreTextChange) {
int currentTime = ConnectionsManager.getInstance(currentAccount).getCurrentTime();
TLRPC.User currentUser = null;
if ((int) dialog_id > 0) {
currentUser = accountInstance.getMessagesController().getUser((int) dialog_id);
}
if (currentUser != null && (currentUser.id == UserConfig.getInstance(currentAccount).getClientUserId() || currentUser.status != null && currentUser.status.expires < currentTime && !accountInstance.getMessagesController().onlinePrivacy.containsKey(currentUser.id))) {
return;
}
lastTypingTimeSend = System.currentTimeMillis();
if (delegate != null) {
delegate.needSendTyping();
@ -2289,7 +2289,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
SharedPreferences preferences1 = MessagesController.getMainSettings(currentAccount);
preferences1.edit().remove("hidekeyboard_" + dialog_id).commit();
} else {
if (currentPopupContentType == 1 && botButtonsMessageObject != null) {
if (botButtonsMessageObject != null) {
SharedPreferences preferences1 = MessagesController.getMainSettings(currentAccount);
preferences1.edit().putInt("hidekeyboard_" + dialog_id, botButtonsMessageObject.getId()).commit();
}
@ -2874,7 +2874,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
sendButtonContainer.addView(expandStickersButton, LayoutHelper.createFrame(48, 48));
expandStickersButton.setOnClickListener(v -> {
if (expandStickersButton.getVisibility() != VISIBLE || expandStickersButton.getAlpha() != 1.0f) {
if (expandStickersButton.getVisibility() != VISIBLE || expandStickersButton.getAlpha() != 1.0f || waitingForKeyboardOpen || (keyboardVisible && messageEditText.isFocused())) {
return;
}
if (stickersExpanded) {
@ -3050,7 +3050,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
} else {
cell.setTextAndIcon(LocaleController.getString("ScheduleMessage", R.string.ScheduleMessage), R.drawable.msg_schedule);
}
} else if (num == 1) {
} else {
cell.setTextAndIcon(LocaleController.getString("SendWithoutSound", R.string.SendWithoutSound), R.drawable.input_notify_off);
}
cell.setMinimumWidth(AndroidUtilities.dp(196));
@ -3061,7 +3061,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
if (num == 0) {
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), this::sendMessageInternal);
} else if (num == 1) {
} else {
sendMessageInternal(false, 0);
}
});
@ -3795,12 +3795,12 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
replyingMessageObject = messageObject;
setButtons(replyingMessageObject, true);
} else if (messageObject == null && replyingMessageObject == botButtonsMessageObject) {
} else if (replyingMessageObject == botButtonsMessageObject) {
replyingMessageObject = null;
setButtons(botMessageObject, false);
botMessageObject = null;
} else {
replyingMessageObject = messageObject;
replyingMessageObject = null;
}
MediaController.getInstance().setReplyingMessage(messageObject, getThreadMessage());
}
@ -4463,7 +4463,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
runningAnimation2 = null;
}
if (attachLayout != null || recordInterfaceState == 0) {
if (attachLayout != null && recordInterfaceState == 0) {
attachLayout.setVisibility(VISIBLE);
runningAnimation2 = new AnimatorSet();
ArrayList<Animator> animators = new ArrayList<>();
@ -5802,12 +5802,8 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
if (AndroidUtilities.isTablet()) {
if (parentActivity instanceof LaunchActivity) {
LaunchActivity launchActivity = (LaunchActivity) parentActivity;
if (launchActivity != null) {
View layout = launchActivity.getLayersActionBarLayout();
allowFocus = layout == null || layout.getVisibility() != View.VISIBLE;
} else {
allowFocus = true;
}
View layout = launchActivity.getLayersActionBarLayout();
allowFocus = layout == null || layout.getVisibility() != View.VISIBLE;
} else {
allowFocus = true;
}
@ -5886,11 +5882,11 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
scheduledButton.setAlpha(visible ? 1.0f : 0.0f);
scheduledButton.setScaleX(visible ? 1.0f : 0.1f);
scheduledButton.setScaleY(visible ? 1.0f : 0.1f);
if (notifyButton != null) {
notifyButton.setVisibility(notifyVisible && scheduledButton.getVisibility() != VISIBLE ? VISIBLE : GONE);
}
}
if (notifyButton != null) {
notifyButton.setVisibility(notifyVisible && scheduledButton.getVisibility() != VISIBLE ? VISIBLE : GONE);
}
} else {
} else if (scheduledButton != null) {
if (visible) {
scheduledButton.setVisibility(VISIBLE);
}
@ -6103,7 +6099,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
Bundle args1 = new Bundle();
if (lower_part > 0) {
args1.putInt("user_id", lower_part);
} else if (lower_part < 0) {
} else {
args1.putInt("chat_id", -lower_part);
}
if (!accountInstance.getMessagesController().checkCanOpenChat(args1, fragment1)) {
@ -6378,8 +6374,14 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
if (trendingStickersAlert == this) {
trendingStickersAlert = null;
}
if (delegate != null) {
delegate.onTrendingStickersShowed(false);
}
}
};
if (delegate != null) {
delegate.onTrendingStickersShowed(true);
}
trendingStickersAlert.show();
}
}
@ -6452,7 +6454,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
private boolean allowDragging() {
return stickersTabOpen && !(!stickersExpanded && messageEditText.length() > 0) && emojiView.areThereAnyStickers();
return stickersTabOpen && !(!stickersExpanded && messageEditText.length() > 0) && emojiView.areThereAnyStickers() && !waitingForKeyboardOpen;
}
});
sizeNotifierLayout.addView(emojiView, sizeNotifierLayout.getChildCount() - 1);
@ -6850,6 +6852,9 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
showKeyboardOnResume = true;
} else if (!AndroidUtilities.usingHardwareInput && !keyboardVisible && !AndroidUtilities.isInMultiwindow && (parentFragment == null || !parentFragment.isInBubbleMode())) {
waitingForKeyboardOpen = true;
if (emojiView != null) {
emojiView.onTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0));
}
AndroidUtilities.cancelRunOnUIThread(openKeyboardRunnable);
AndroidUtilities.runOnUIThread(openKeyboardRunnable, 100);
}
@ -7448,6 +7453,10 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
this.adjustPanLayoutHelper = adjustPanLayoutHelper;
}
public AdjustPanLayoutHelper getAdjustPanLayoutHelper() {
return adjustPanLayoutHelper;
}
public boolean pannelAniamationInProgress() {
return panelAnimation != null;
}
@ -7463,6 +7472,10 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
return animatedTop;
}
public void checkAnimation() {
}
private class ScrimDrawable extends Drawable {
private Paint paint;

View File

@ -318,6 +318,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
protected int avatarPicker;
protected boolean avatarSearch;
protected boolean typeButtonsAvailable;
private int selectedId;
@ -334,6 +335,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
private float baseSelectedTextViewTranslationY;
private boolean menuShowed;
protected SizeNotifierFrameLayout sizeNotifierFrameLayout;
private boolean openTransitionFinished;
private Object viewChangeAnimator;
@ -609,7 +611,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
@Override
protected boolean heightAnimationEnabled() {
if (isDismissed()) {
if (isDismissed() || !openTransitionFinished) {
return false;
}
return !commentTextView.isPopupVisible();
@ -1200,13 +1202,13 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
baseFragment.getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 4);
return;
}
openAudioLayout();
openAudioLayout(true);
} else if (num == 4) {
if (Build.VERSION.SDK_INT >= 23 && baseFragment.getParentActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
baseFragment.getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 4);
return;
}
openDocumentsLayout();
openDocumentsLayout(true);
} else if (num == 5) {
if (Build.VERSION.SDK_INT >= 23) {
if (baseFragment.getParentActivity().checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
@ -1609,6 +1611,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
ChatActivity chatActivity = (ChatActivity) baseFragment;
calcMandatoryInsets = chatActivity.isKeyboardVisible();
}
openTransitionFinished = false;
}
public void setEditingMessageObject(MessageObject messageObject) {
@ -1749,6 +1752,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
public void onRequestPermissionsResultFragment(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 5 && grantResults != null && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openContactsLayout();
} else if (requestCode == 30 && locationLayout != null && currentAttachLayout == locationLayout && isShowing()) {
locationLayout.openShareLiveLocation();
}
}
@ -1760,7 +1765,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
showLayout(contactsLayout);
}
private void openAudioLayout() {
private void openAudioLayout(boolean show) {
if (audioLayout == null) {
layouts[3] = audioLayout = new ChatAttachAlertAudioLayout(this, getContext());
audioLayout.setDelegate((audios, caption, notify, scheduleDate) -> ((ChatActivity) baseFragment).sendAudio(audios, caption, notify, scheduleDate));
@ -1770,10 +1775,12 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
TLRPC.Chat currentChat = chatActivity.getCurrentChat();
audioLayout.setMaxSelectedFiles(currentChat != null && !ChatObject.hasAdminRights(currentChat) && currentChat.slowmode_enabled || editingMessageObject != null ? 1 : -1);
}
showLayout(audioLayout);
if (show) {
showLayout(audioLayout);
}
}
private void openDocumentsLayout() {
private void openDocumentsLayout(boolean show) {
if (documentLayout == null) {
layouts[4] = documentLayout = new ChatAttachAlertDocumentLayout(this, getContext(), false);
documentLayout.setDelegate(new ChatAttachAlertDocumentLayout.DocumentSelectActivityDelegate() {
@ -1806,7 +1813,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
@Override
public void startMusicSelectActivity() {
openAudioLayout();
openAudioLayout(true);
}
});
}
@ -1818,7 +1825,9 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
documentLayout.setMaxSelectedFiles(maxSelectedPhotos);
documentLayout.setCanSelectOnlyImageFiles(true);
}
showLayout(documentLayout);
if (show) {
showLayout(documentLayout);
}
}
private boolean showCommentTextView(boolean show, boolean animated) {
@ -1836,7 +1845,10 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (show) {
frameLayout2.setVisibility(View.VISIBLE);
writeButtonContainer.setVisibility(View.VISIBLE);
} else {
if (!typeButtonsAvailable) {
shadow.setVisibility(View.VISIBLE);
}
} else if (typeButtonsAvailable) {
buttonsRecyclerView.setVisibility(View.VISIBLE);
}
if (animated) {
@ -1853,9 +1865,12 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
animators.add(ObjectAnimator.ofFloat(frameLayout2, View.TRANSLATION_Y, show ? 0.0f : AndroidUtilities.dp(48)));
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 {
} else if (typeButtonsAvailable) {
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));
animators.add(ObjectAnimator.ofFloat(shadow, View.ALPHA, show ? 1.0f : 0.0f));
}
commentsAnimator.playTogether(animators);
@ -1868,7 +1883,10 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (!show) {
frameLayout2.setVisibility(View.INVISIBLE);
writeButtonContainer.setVisibility(View.INVISIBLE);
} else {
if (!typeButtonsAvailable) {
shadow.setVisibility(View.INVISIBLE);
}
} else if (typeButtonsAvailable) {
buttonsRecyclerView.setVisibility(View.INVISIBLE);
}
commentsAnimator = null;
@ -1895,13 +1913,19 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
frameLayout2.setTranslationY(show ? 0.0f : AndroidUtilities.dp(48));
shadow.setTranslationY(show ? AndroidUtilities.dp(36) : AndroidUtilities.dp(48 + 36));
shadow.setAlpha(show ? 1.0f : 0.0f);
} else {
} else if (typeButtonsAvailable) {
buttonsRecyclerView.setTranslationY(show ? AndroidUtilities.dp(36) : 0);
shadow.setTranslationY(show ? AndroidUtilities.dp(36) : 0);
} else {
shadow.setTranslationY(AndroidUtilities.dp(36));
shadow.setAlpha(show ? 1.0f : 0.0f);
}
if (!show) {
frameLayout2.setVisibility(View.INVISIBLE);
writeButtonContainer.setVisibility(View.INVISIBLE);
if (!typeButtonsAvailable) {
shadow.setVisibility(View.INVISIBLE);
}
}
}
return true;
@ -1980,9 +2004,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
setFocusable(true);
editText.requestFocus();
if (showKeyboard) {
AndroidUtilities.runOnUIThread(() -> {
AndroidUtilities.showKeyboard(editText);
});
AndroidUtilities.runOnUIThread(() -> AndroidUtilities.showKeyboard(editText));
}
}, keyboardVisible ? 200 : 0);
}
@ -2197,14 +2219,15 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
actionBarAnimation = null;
}
boolean needsSearchItem = avatarSearch || currentAttachLayout == photoLayout && !menuShowed && baseFragment instanceof ChatActivity && ((ChatActivity) baseFragment).allowSendGifs();
boolean needMoreItem = avatarPicker != 0 || !menuShowed && currentAttachLayout == photoLayout && mediaEnabled;
if (show) {
if (needsSearchItem) {
searchItem.setVisibility(View.VISIBLE);
}
if (avatarPicker != 0 || !menuShowed && currentAttachLayout == photoLayout) {
if (needMoreItem) {
selectedMenuItem.setVisibility(View.VISIBLE);
}
} else if (avatarPicker == 0) {
} else if (typeButtonsAvailable) {
buttonsRecyclerView.setVisibility(View.VISIBLE);
}
if (animated) {
@ -2216,7 +2239,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (needsSearchItem) {
animators.add(ObjectAnimator.ofFloat(searchItem, View.ALPHA, show ? 1.0f : 0.0f));
}
if (avatarPicker != 0 || !menuShowed && currentAttachLayout == photoLayout) {
if (needMoreItem) {
animators.add(ObjectAnimator.ofFloat(selectedMenuItem, View.ALPHA, show ? 1.0f : 0.0f));
}
actionBarAnimation.playTogether(animators);
@ -2225,7 +2248,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
public void onAnimationEnd(Animator animation) {
if (actionBarAnimation != null) {
if (show) {
if (avatarPicker == 0) {
if (typeButtonsAvailable) {
buttonsRecyclerView.setVisibility(View.INVISIBLE);
}
} else {
@ -2245,7 +2268,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
actionBarAnimation.start();
} else {
if (show) {
if (avatarPicker == 0) {
if (typeButtonsAvailable) {
buttonsRecyclerView.setVisibility(View.INVISIBLE);
}
}
@ -2254,7 +2277,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (needsSearchItem) {
searchItem.setAlpha(show ? 1.0f : 0.0f);
}
if (avatarPicker != 0 || !menuShowed && currentAttachLayout == photoLayout) {
if (needMoreItem) {
selectedMenuItem.setAlpha(show ? 1.0f : 0.0f);
}
if (!show) {
@ -2395,7 +2418,30 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
commentTextView.hidePopup(true);
enterCommentEventSent = false;
setFocusable(false);
if (currentAttachLayout != photoLayout) {
ChatAttachAlert.AttachAlertLayout layoutToSet;
if (editingMessageObject != null && editingMessageObject.hasValidGroupId() && (editingMessageObject.isMusic() || editingMessageObject.isDocument())) {
if (editingMessageObject.isMusic()) {
openAudioLayout(false);
layoutToSet = audioLayout;
selectedId = 3;
} else {
openDocumentsLayout(false);
layoutToSet = documentLayout;
selectedId = 4;
}
typeButtonsAvailable = false;
buttonsRecyclerView.setVisibility(View.GONE);
shadow.setVisibility(View.INVISIBLE);
} else {
layoutToSet = photoLayout;
typeButtonsAvailable = avatarPicker == 0;
selectedId = 1;
if (typeButtonsAvailable) {
buttonsRecyclerView.setVisibility(View.VISIBLE);
shadow.setVisibility(View.VISIBLE);
}
}
if (currentAttachLayout != layoutToSet) {
if (actionBar.isSearchFieldVisible()) {
actionBar.closeSearchField();
}
@ -2403,18 +2449,17 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
currentAttachLayout.onHide();
currentAttachLayout.setVisibility(View.GONE);
currentAttachLayout.onHidden();
currentAttachLayout = photoLayout;
currentAttachLayout = layoutToSet;
setAllowNestedScroll(true);
if (currentAttachLayout.getParent() == null) {
containerView.addView(currentAttachLayout, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
selectedId = 1;
photoLayout.setAlpha(1.0f);
photoLayout.setVisibility(View.VISIBLE);
photoLayout.onShow();
photoLayout.onShown();
actionBar.setVisibility(View.VISIBLE);
actionBarShadow.setVisibility(View.VISIBLE);
layoutToSet.setAlpha(1.0f);
layoutToSet.setVisibility(View.VISIBLE);
layoutToSet.onShow();
layoutToSet.onShown();
actionBar.setVisibility(layoutToSet.needsActionBar() != 0 ? View.VISIBLE : View.INVISIBLE);
actionBarShadow.setVisibility(actionBar.getVisibility());
}
updateCountButton(0);
@ -2449,6 +2494,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
}
currentAttachLayout.onOpenAnimationEnd();
AndroidUtilities.makeAccessibilityAnnouncement(LocaleController.getString("AccDescrAttachButton", R.string.AccDescrAttachButton));
openTransitionFinished = true;
}
@Override
@ -2471,6 +2517,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
avatarPicker = type;
avatarSearch = search;
if (avatarPicker != 0) {
typeButtonsAvailable = false;
buttonsRecyclerView.setVisibility(View.GONE);
shadow.setVisibility(View.GONE);
if (avatarPicker == 2) {
@ -2478,6 +2525,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
} else {
selectedTextView.setText(LocaleController.getString("ChoosePhoto", R.string.ChoosePhoto));
}
} else {
typeButtonsAvailable = true;
}
}
@ -2593,9 +2642,17 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
galleryButton = buttonsCount++;
documentButton = buttonsCount++;
} else if (editingMessageObject != null) {
galleryButton = buttonsCount++;
documentButton = buttonsCount++;
musicButton = buttonsCount++;
if ((editingMessageObject.isMusic() || editingMessageObject.isDocument()) && editingMessageObject.hasValidGroupId()) {
if (editingMessageObject.isMusic()) {
musicButton = buttonsCount++;
} else {
documentButton = buttonsCount++;
}
} else {
galleryButton = buttonsCount++;
documentButton = buttonsCount++;
musicButton = buttonsCount++;
}
} else {
if (mediaEnabled) {
galleryButton = buttonsCount++;
@ -2714,4 +2771,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
public void setAllowNestedScroll(boolean allowNestedScroll) {
this.allowNestedScroll = allowNestedScroll;
}
public BaseFragment getBaseFragment() {
return baseFragment;
}
}

View File

@ -81,6 +81,7 @@ public class ChatAttachAlertAudioLayout extends ChatAttachAlert.AttachAlertLayou
private boolean ignoreLayout;
private ArrayList<MediaController.AudioEntry> audioEntries = new ArrayList<>();
private ArrayList<MediaController.AudioEntry> selectedAudiosOrder = new ArrayList<>();
private LongSparseArray<MediaController.AudioEntry> selectedAudios = new LongSparseArray<>();
private AudioSelectDelegate delegate;
@ -371,6 +372,7 @@ public class ChatAttachAlertAudioLayout extends ChatAttachAlert.AttachAlertLayou
@Override
void onHidden() {
selectedAudios.clear();
selectedAudiosOrder.clear();
}
@Override
@ -463,6 +465,7 @@ public class ChatAttachAlertAudioLayout extends ChatAttachAlert.AttachAlertLayou
boolean add;
if (selectedAudios.indexOfKey(audioEntry.id) >= 0) {
selectedAudios.remove(audioEntry.id);
selectedAudiosOrder.remove(audioEntry);
audioCell.setChecked(false, true);
add = false;
} else {
@ -471,6 +474,7 @@ public class ChatAttachAlertAudioLayout extends ChatAttachAlert.AttachAlertLayou
return;
}
selectedAudios.put(audioEntry.id, audioEntry);
selectedAudiosOrder.add(audioEntry);
audioCell.setChecked(true, true);
add = true;
}
@ -489,8 +493,8 @@ public class ChatAttachAlertAudioLayout extends ChatAttachAlert.AttachAlertLayou
}
sendPressed = true;
ArrayList<MessageObject> audios = new ArrayList<>();
for (int a = 0; a < selectedAudios.size(); a++) {
audios.add(selectedAudios.valueAt(a).messageObject);
for (int a = 0; a < selectedAudiosOrder.size(); a++) {
audios.add(selectedAudiosOrder.get(a).messageObject);
}
delegate.didSelectAudio(audios, parentAlert.commentTextView.getText().toString(), notify, scheduleDate);
}

View File

@ -101,6 +101,7 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
private ArrayList<HistoryEntry> history = new ArrayList<>();
private DocumentSelectActivityDelegate delegate;
private HashMap<String, ListItem> selectedFiles = new HashMap<>();
private ArrayList<String> selectedFilesOrder = new ArrayList<>();
private boolean scrolling;
private ArrayList<ListItem> recentItems = new ArrayList<>();
private int maxSelectedFiles = -1;
@ -511,7 +512,7 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
return;
}
sendPressed = true;
ArrayList<String> files = new ArrayList<>(selectedFiles.keySet());
ArrayList<String> files = new ArrayList<>(selectedFilesOrder);
delegate.didSelectFiles(files, parentAlert.commentTextView.getText().toString(), notify, scheduleDate);
parentAlert.dismiss();
}
@ -524,6 +525,7 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
boolean add;
if (selectedFiles.containsKey(path)) {
selectedFiles.remove(path);
selectedFilesOrder.remove(path);
add = false;
} else {
if (!item.file.canRead()) {
@ -546,6 +548,7 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
return false;
}
selectedFiles.put(path, item);
selectedFilesOrder.add(path);
add = true;
}
scrolling = false;
@ -686,6 +689,7 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
@Override
void onShow() {
selectedFiles.clear();
selectedFilesOrder.clear();
history.clear();
listRoots();
updateSearchButton();

View File

@ -17,6 +17,7 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@ -148,6 +149,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
private FrameLayout lastPressedMarkerView;
private boolean checkPermission = true;
private boolean checkBackgroundPermission = true;
private boolean searching;
private boolean searchWas;
@ -1118,10 +1120,23 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
animatorSet.start();
}
private void openShareLiveLocation() {
public void openShareLiveLocation() {
if (delegate == null || getParentActivity() == null || myLocation == null) {
return;
}
if (checkBackgroundPermission && Build.VERSION.SDK_INT >= 29) {
Activity activity = getParentActivity();
if (activity != null) {
checkBackgroundPermission = false;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
int lastTime = preferences.getInt("backgroundloc", 0);
if (Math.abs(System.currentTimeMillis() / 1000 - lastTime) > 24 * 60 * 60 && activity.checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
preferences.edit().putInt("backgroundloc", (int) (System.currentTimeMillis() / 1000)).commit();
AlertsCreator.createBackgroundLocationPermissionDialog(activity, getMessagesController().getUser(getUserConfig().getClientUserId()), this::openShareLiveLocation).show();
return;
}
}
}
TLRPC.User user = null;
if ((int) dialogId > 0) {
user = parentAlert.baseFragment.getMessagesController().getUser((int) dialogId);

View File

@ -2062,8 +2062,11 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
}
float topLocal = child.getY() + gridView.getY() + getY();
float top = topLocal + parentAlert.getSheetContainer().getY();
float top = topLocal + parentAlert.getSheetContainer().getY();
float left = child.getX() + gridView.getX() + getX() + parentAlert.getSheetContainer().getX();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
left -= getRootWindowInsets().getSystemWindowInsetLeft();
}
float maxY = (Build.VERSION.SDK_INT >= 21 && !parentAlert.inBubbleMode ? AndroidUtilities.statusBarHeight : 0) + ActionBar.getCurrentActionBarHeight();
if (topLocal < maxY) {

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