update to 10.0.1 (3793)

This commit is contained in:
xaxtix 2023-08-15 02:42:46 +04:00
parent 0bcf4fe556
commit 702d37ce69
330 changed files with 15366 additions and 3288 deletions

View file

@ -82,7 +82,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 31 targetSdkVersion 33
versionName "8.9.0" versionName "8.9.0"
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi'] vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']

View file

@ -13,6 +13,7 @@
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<permission android:name="${applicationId}.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> <permission android:name="${applicationId}.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>

View file

@ -13,6 +13,7 @@
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.READ_CALL_LOG" />

View file

@ -13,6 +13,7 @@
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<permission android:name="${applicationId}.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> <permission android:name="${applicationId}.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>

View file

@ -13,6 +13,7 @@
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.READ_CALL_LOG" />

View file

@ -13,6 +13,7 @@
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.READ_CALL_LOG" />

View file

@ -122,7 +122,7 @@ typedef struct VideoInfo {
} else { } else {
attached = false; attached = false;
} }
DEBUG_DELREF("gifvideocpp stream"); DEBUG_DELREF("gifvideo.cpp stream");
jniEnv->DeleteGlobalRef(stream); jniEnv->DeleteGlobalRef(stream);
if (attached) { if (attached) {
javaVm->DetachCurrentThread(); javaVm->DetachCurrentThread();

View file

@ -3057,7 +3057,7 @@ void ConnectionsManager::updateDcSettings(uint32_t dcNum, bool workaround, bool
if ((!workaround && !updatingDcSettings) || (workaround && !updatingDcSettingsWorkaround)) { if ((!workaround && !updatingDcSettings) || (workaround && !updatingDcSettingsWorkaround)) {
return; return;
} }
if (!workaround && updatingDcSettingsAgain) { if (!workaround && updatingDcSettingsAgain && updatingDcSettingsAgainDcNum == dcNum) {
updatingDcSettingsAgain = false; updatingDcSettingsAgain = false;
for (auto & datacenter : datacenters) { for (auto & datacenter : datacenters) {
datacenter.second->resetInitVersion(); datacenter.second->resetInitVersion();

View file

@ -924,7 +924,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_onStreamP
return; return;
} }
auto context = (AndroidContext *) instance->_platformContext.get(); auto context = (AndroidContext *) instance->_platformContext.get();
std::shared_ptr<BroadcastPartTask> task; std::shared_ptr<BroadcastPartTask> task = nullptr;
auto q = (VideoChannelDescription::Quality) quality; auto q = (VideoChannelDescription::Quality) quality;
if (videoChannel != 0) { if (videoChannel != 0) {
for (auto videoTaskIter = context->videoStreamTasks.begin(); videoTaskIter != context->videoStreamTasks.end(); videoTaskIter++) { for (auto videoTaskIter = context->videoStreamTasks.begin(); videoTaskIter != context->videoStreamTasks.end(); videoTaskIter++) {

View file

@ -30,6 +30,9 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" />
@ -53,6 +56,7 @@
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/> <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" /> <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="com.sec.android.provider.badge.permission.READ"/> <uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/> <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>

View file

@ -97,6 +97,7 @@ import java.math.BigDecimal;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
@ -2844,13 +2845,31 @@ public final class Util {
@RequiresApi(api = Build.VERSION_CODES.M) @RequiresApi(api = Build.VERSION_CODES.M)
private static boolean requestExternalStoragePermission(Activity activity) { private static boolean requestExternalStoragePermission(Activity activity) {
if (activity.checkSelfPermission(permission.READ_EXTERNAL_STORAGE) if (Build.VERSION.SDK_INT >= 33) {
!= PackageManager.PERMISSION_GRANTED) { ArrayList<String> permissions = new ArrayList<>();
activity.requestPermissions( if (activity.checkSelfPermission(permission.READ_MEDIA_VIDEO) != PackageManager.PERMISSION_GRANTED) {
new String[] {permission.READ_EXTERNAL_STORAGE}, /* requestCode= */ 0); permissions.add(permission.READ_MEDIA_VIDEO);
return true; }
if (activity.checkSelfPermission(permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
permissions.add(permission.READ_MEDIA_IMAGES);
}
if (activity.checkSelfPermission(permission.READ_MEDIA_AUDIO) != PackageManager.PERMISSION_GRANTED) {
permissions.add(permission.READ_MEDIA_AUDIO);
}
if (!permissions.isEmpty()) {
activity.requestPermissions(permissions.toArray(new String[0]), /* requestCode= */ 0);
return true;
}
return false;
} else {
if (activity.checkSelfPermission(permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(
new String[]{permission.READ_EXTERNAL_STORAGE}, /* requestCode= */ 0);
return true;
}
return false;
} }
return false;
} }
@RequiresApi(api = Build.VERSION_CODES.N) @RequiresApi(api = Build.VERSION_CODES.N)

View file

@ -8,6 +8,7 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.Manifest;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
@ -112,6 +113,7 @@ import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils; import androidx.core.math.MathUtils;
import androidx.core.widget.NestedScrollView;
import androidx.dynamicanimation.animation.DynamicAnimation; import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.dynamicanimation.animation.SpringAnimation; import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce; import androidx.dynamicanimation.animation.SpringForce;
@ -157,6 +159,8 @@ import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.URLSpanReplacement; import org.telegram.ui.Components.URLSpanReplacement;
import org.telegram.ui.Components.UndoView; import org.telegram.ui.Components.UndoView;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import org.telegram.ui.Stories.PeerStoriesView;
import org.telegram.ui.Stories.StoryMediaAreasView;
import org.telegram.ui.ThemePreviewActivity; import org.telegram.ui.ThemePreviewActivity;
import org.telegram.ui.WallpapersListActivity; import org.telegram.ui.WallpapersListActivity;
@ -454,6 +458,10 @@ public class AndroidUtilities {
} }
public static SpannableStringBuilder replaceSingleTag(String str, int colorKey, int type, Runnable runnable) { public static SpannableStringBuilder replaceSingleTag(String str, int colorKey, int type, Runnable runnable) {
return replaceSingleTag(str, colorKey, type, runnable, null);
}
public static SpannableStringBuilder replaceSingleTag(String str, int colorKey, int type, Runnable runnable, Theme.ResourcesProvider resourcesProvider) {
int startIndex = str.indexOf("**"); int startIndex = str.indexOf("**");
int endIndex = str.indexOf("**", startIndex + 1); int endIndex = str.indexOf("**", startIndex + 1);
str = str.replace("**", ""); str = str.replace("**", "");
@ -473,7 +481,7 @@ public class AndroidUtilities {
super.updateDrawState(ds); super.updateDrawState(ds);
ds.setUnderlineText(false); ds.setUnderlineText(false);
if (colorKey >= 0) { if (colorKey >= 0) {
ds.setColor(Theme.getColor(colorKey)); ds.setColor(Theme.getColor(colorKey, resourcesProvider));
} }
} }
@ -490,7 +498,7 @@ public class AndroidUtilities {
public void updateDrawState(TextPaint textPaint) { public void updateDrawState(TextPaint textPaint) {
textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
int wasAlpha = textPaint.getAlpha(); int wasAlpha = textPaint.getAlpha();
textPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText)); textPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText, resourcesProvider));
textPaint.setAlpha(wasAlpha); textPaint.setAlpha(wasAlpha);
} }
}, index, index + len, 0); }, index, index + len, 0);
@ -573,18 +581,25 @@ public class AndroidUtilities {
} }
public static boolean findClickableView(ViewGroup container, float x, float y) { public static boolean findClickableView(ViewGroup container, float x, float y) {
return findClickableView(container, x, y, null);
}
public static boolean findClickableView(ViewGroup container, float x, float y, View onlyThisView) {
if (container == null) { if (container == null) {
return false; return false;
} }
for (int i = 0; i < container.getChildCount(); i++) { for (int i = 0; i < container.getChildCount(); i++) {
View child = container.getChildAt(i); View child = container.getChildAt(i);
if (child.getVisibility() != View.VISIBLE) { if (child.getVisibility() != View.VISIBLE || child instanceof PeerStoriesView && child != onlyThisView) {
continue;
}
if (child instanceof StoryMediaAreasView.AreaView && !((StoryMediaAreasView) container).hasSelected() && (x < dp(60) || x > container.getWidth() - dp(60))) {
continue; continue;
} }
child.getHitRect(AndroidUtilities.rectTmp2); child.getHitRect(AndroidUtilities.rectTmp2);
if (AndroidUtilities.rectTmp2.contains((int) x, (int) y) && child.isClickable()) { if (AndroidUtilities.rectTmp2.contains((int) x, (int) y) && child.isClickable()) {
return true; return true;
} else if (child instanceof ViewGroup && findClickableView((ViewGroup) child, x - child.getX(), y - child.getY())) { } else if (child instanceof ViewGroup && findClickableView((ViewGroup) child, x - child.getX(), y - child.getY(), onlyThisView)) {
return true; return true;
} }
} }
@ -721,6 +736,36 @@ public class AndroidUtilities {
} }
} }
public static float[] getCoordinateInParent(ViewGroup parentView, View view) {
float x = 0, y = 0;
View child = view;
float yOffset = 0;
float xOffset = 0;
if (child != null && parentView != null) {
while (child != parentView) {
if (child == null) {
xOffset = 0;
yOffset = 0;
break;
}
yOffset += child.getY();
xOffset += child.getX();
if (child instanceof NestedScrollView) {
yOffset -= child.getScrollY();
xOffset -= child.getScrollX();
}
if (child.getParent() instanceof View) {
child = (View) child.getParent();
} else {
xOffset = 0;
yOffset = 0;
break;
}
}
}
return new float[] {xOffset, yOffset};
}
private static class LinkSpec { private static class LinkSpec {
String url; String url;
int start; int start;
@ -2982,7 +3027,17 @@ public class AndroidUtilities {
} }
private static File getAlbumDir(boolean secretChat) { private static File getAlbumDir(boolean secretChat) {
if (secretChat || !BuildVars.NO_SCOPED_STORAGE || (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) { if (
secretChat ||
!BuildVars.NO_SCOPED_STORAGE ||
(
Build.VERSION.SDK_INT >= 33 &&
ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED
) || (
Build.VERSION.SDK_INT >= 23 && Build.VERSION.SDK_INT <= 33 &&
ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
)
) {
return FileLoader.getDirectory(FileLoader.MEDIA_DIR_IMAGE); return FileLoader.getDirectory(FileLoader.MEDIA_DIR_IMAGE);
} }
File storageDir = null; File storageDir = null;
@ -5197,7 +5252,7 @@ public class AndroidUtilities {
} }
public static boolean intersect1d(int x1, int x2, int y1, int y2) { public static boolean intersect1d(int x1, int x2, int y1, int y2) {
return Math.max(x1, x2) >= Math.min(y1, y2) && Math.max(y1, y2) >= Math.min(x1, x2); return Math.max(x1, x2) > Math.min(y1, y2) && Math.max(y1, y2) > Math.min(x1, x2);
} }
public static String getSysInfoString(String path) { public static String getSysInfoString(String path) {

View file

@ -24,8 +24,8 @@ public class BuildVars {
public static boolean USE_CLOUD_STRINGS = true; public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true; public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29; public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 3721; public static int BUILD_VERSION = 3793;
public static String BUILD_VERSION_STRING = "9.7.6"; public static String BUILD_VERSION_STRING = "10.0.1";
public static int APP_ID = 4; public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";

View file

@ -177,11 +177,11 @@ public class ChatMessagesMetadataController {
public void onFragmentDestroy() { public void onFragmentDestroy() {
for (int i = 0; i < reactionsRequests.size(); i++) { for (int i = 0; i < reactionsRequests.size(); i++) {
chatActivity.getConnectionsManager().cancelRequest(reactionsRequests.remove(i), false); chatActivity.getConnectionsManager().cancelRequest(reactionsRequests.get(i), false);
} }
reactionsRequests.clear(); reactionsRequests.clear();
for (int i = 0; i < extendedMediaRequests.size(); i++) { for (int i = 0; i < extendedMediaRequests.size(); i++) {
chatActivity.getConnectionsManager().cancelRequest(extendedMediaRequests.remove(i), false); chatActivity.getConnectionsManager().cancelRequest(extendedMediaRequests.get(i), false);
} }
extendedMediaRequests.clear(); extendedMediaRequests.clear();
} }

View file

@ -2878,6 +2878,11 @@ public class ContactsController extends BaseController {
if (firstName != null) { if (firstName != null) {
firstName = firstName.trim(); firstName = firstName.trim();
} }
if (firstName != null && lastName == null && maxLength > 0 && firstName.contains(" ") ) {
int i = firstName.indexOf(" ");
lastName = firstName.substring(i + 1);
firstName = firstName.substring(0, i);
}
if (lastName != null) { if (lastName != null) {
lastName = lastName.trim(); lastName = lastName.trim();
} }
@ -2885,7 +2890,7 @@ public class ContactsController extends BaseController {
if (LocaleController.nameDisplayOrder == 1) { if (LocaleController.nameDisplayOrder == 1) {
if (firstName != null && firstName.length() > 0) { if (firstName != null && firstName.length() > 0) {
if (maxLength > 0 && firstName.length() > maxLength + 2) { if (maxLength > 0 && firstName.length() > maxLength + 2) {
return firstName.substring(0, maxLength); return firstName.substring(0, maxLength) + "";
} }
result.append(firstName); result.append(firstName);
if (lastName != null && lastName.length() > 0) { if (lastName != null && lastName.length() > 0) {
@ -2898,14 +2903,14 @@ public class ContactsController extends BaseController {
} }
} else if (lastName != null && lastName.length() > 0) { } else if (lastName != null && lastName.length() > 0) {
if (maxLength > 0 && lastName.length() > maxLength + 2) { if (maxLength > 0 && lastName.length() > maxLength + 2) {
return lastName.substring(0, maxLength); return lastName.substring(0, maxLength) + "";
} }
result.append(lastName); result.append(lastName);
} }
} else { } else {
if (lastName != null && lastName.length() > 0) { if (lastName != null && lastName.length() > 0) {
if (maxLength > 0 && lastName.length() > maxLength + 2) { if (maxLength > 0 && lastName.length() > maxLength + 2) {
return lastName.substring(0, maxLength); return lastName.substring(0, maxLength) + "";
} }
result.append(lastName); result.append(lastName);
if (firstName != null && firstName.length() > 0) { if (firstName != null && firstName.length() > 0) {
@ -2918,7 +2923,7 @@ public class ContactsController extends BaseController {
} }
} else if (firstName != null && firstName.length() > 0) { } else if (firstName != null && firstName.length() > 0) {
if (maxLength > 0 && firstName.length() > maxLength + 2) { if (maxLength > 0 && firstName.length() > maxLength + 2) {
return firstName.substring(0, maxLength); return firstName.substring(0, maxLength) + "";
} }
result.append(firstName); result.append(firstName);
} }

View file

@ -1326,6 +1326,13 @@ public class DatabaseMigrationHelper {
version = 127; version = 127;
} }
if (version == 127) {
database.executeFast("ALTER TABLE stories ADD COLUMN custom_params BLOB default NULL").stepThis().dispose();
database.executeFast("PRAGMA user_version = 128").stepThis().dispose();
version = 128;
}
return version; return version;
} }

View file

@ -84,6 +84,15 @@ public class DispatchQueue extends Thread {
return postRunnable(runnable, 0); return postRunnable(runnable, 0);
} }
public boolean postToFrontRunnable(Runnable runnable) {
try {
syncLatch.await();
} catch (Exception e) {
FileLog.e(e, false);
}
return handler.postAtFrontOfQueue(runnable);
}
public boolean postRunnable(Runnable runnable, long delay) { public boolean postRunnable(Runnable runnable, long delay) {
try { try {
syncLatch.await(); syncLatch.await();

View file

@ -280,18 +280,22 @@ public class FilePathDatabase {
CountDownLatch syncLatch = new CountDownLatch(1); CountDownLatch syncLatch = new CountDownLatch(1);
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
postRunnable(() -> { long[] threadTime = new long[1];
postToFrontRunnable(() -> {
long threadTimeLocal = System.currentTimeMillis();
ensureDatabaseCreated(); ensureDatabaseCreated();
try { try {
for (int i = 0; i < arrayListFinal.size(); i++) { for (int i = 0; i < arrayListFinal.size(); i++) {
MessageObject messageObject = arrayListFinal.get(i); MessageObject messageObject = arrayListFinal.get(i);
messageObject.checkMediaExistance(false); messageObject.checkMediaExistance(false);
} }
threadTime[0] = System.currentTimeMillis() - threadTimeLocal;
} catch (Throwable e) { } catch (Throwable e) {
FileLog.e(e); FileLog.e(e);
} finally { } finally {
syncLatch.countDown(); syncLatch.countDown();
} }
}); });
try { try {
@ -300,7 +304,7 @@ public class FilePathDatabase {
FileLog.e(e); FileLog.e(e);
} }
FileLog.d("checkMediaExistance size=" + messageObjects.size() + " time=" + (System.currentTimeMillis() - time)); FileLog.d("checkMediaExistance size=" + messageObjects.size() + " time=" + (System.currentTimeMillis() - time) + " thread_time=" + threadTime[0]);
if (BuildVars.DEBUG_VERSION) { if (BuildVars.DEBUG_VERSION) {
if (Thread.currentThread() == Looper.getMainLooper().getThread()) { if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
@ -465,6 +469,11 @@ public class FilePathDatabase {
dispatchQueue.postRunnable(runnable); dispatchQueue.postRunnable(runnable);
} }
private void postToFrontRunnable(Runnable runnable) {
ensureQueueExist();
dispatchQueue.postToFrontRunnable(runnable);
}
private void ensureQueueExist() { private void ensureQueueExist() {
if (dispatchQueue == null) { if (dispatchQueue == null) {
synchronized (this) { synchronized (this) {

View file

@ -146,6 +146,9 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
} }
File currentFileFast = loadOperation.getCurrentFileFast(); File currentFileFast = loadOperation.getCurrentFileFast();
if (file == null || !Objects.equals(currentFile, currentFileFast)) { if (file == null || !Objects.equals(currentFile, currentFileFast)) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("check stream file " + currentFileFast);
}
if (file != null) { if (file != null) {
try { try {
file.close(); file.close();

View file

@ -284,12 +284,25 @@ public class FilesMigrationService extends Service {
public void migrateOldFolder() { public void migrateOldFolder() {
Activity activity = fragment.getParentActivity(); Activity activity = fragment.getParentActivity();
boolean canWrite = activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; boolean canWrite = activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
boolean canRead = activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; boolean canRead = (
Build.VERSION.SDK_INT >= 33 && (
activity.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED &&
activity.checkSelfPermission(Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED &&
activity.checkSelfPermission(Manifest.permission.READ_MEDIA_AUDIO) == PackageManager.PERMISSION_GRANTED
) ||
Build.VERSION.SDK_INT < 33 && activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
);
if (!canRead || !canWrite) { if (!canRead || !canWrite) {
ArrayList<String> permissions = new ArrayList<>(); ArrayList<String> permissions = new ArrayList<>();
if (!canRead) { if (!canRead) {
permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); if (Build.VERSION.SDK_INT >= 33) {
permissions.add(Manifest.permission.READ_MEDIA_IMAGES);
permissions.add(Manifest.permission.READ_MEDIA_VIDEO);
permissions.add(Manifest.permission.READ_MEDIA_AUDIO);
} else {
permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
} }
if (!canWrite) { if (!canWrite) {
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);

View file

@ -120,6 +120,11 @@ public class GoogleMapsProvider implements IMapsProvider {
return googleMap.getMaxZoomLevel(); return googleMap.getMaxZoomLevel();
} }
@Override
public float getMinZoomLevel() {
return googleMap.getMinZoomLevel();
}
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
@Override @Override
public void setMyLocationEnabled(boolean enabled) { public void setMyLocationEnabled(boolean enabled) {
@ -151,6 +156,11 @@ public class GoogleMapsProvider implements IMapsProvider {
}); });
} }
@Override
public void setOnCameraIdleListener(Runnable callback) {
googleMap.setOnCameraIdleListener(callback::run);
}
@Override @Override
public CameraPosition getCameraPosition() { public CameraPosition getCameraPosition() {
com.google.android.gms.maps.model.CameraPosition pos = googleMap.getCameraPosition(); com.google.android.gms.maps.model.CameraPosition pos = googleMap.getCameraPosition();

View file

@ -37,8 +37,10 @@ public interface IMapsProvider {
void animateCamera(ICameraUpdate update, int duration, ICancelableCallback callback); void animateCamera(ICameraUpdate update, int duration, ICancelableCallback callback);
void moveCamera(ICameraUpdate update); void moveCamera(ICameraUpdate update);
float getMaxZoomLevel(); float getMaxZoomLevel();
float getMinZoomLevel();
void setMyLocationEnabled(boolean enabled); void setMyLocationEnabled(boolean enabled);
IUISettings getUiSettings(); IUISettings getUiSettings();
void setOnCameraIdleListener(Runnable callback);
void setOnCameraMoveStartedListener(OnCameraMoveStartedListener onCameraMoveStartedListener); void setOnCameraMoveStartedListener(OnCameraMoveStartedListener onCameraMoveStartedListener);
CameraPosition getCameraPosition(); CameraPosition getCameraPosition();
void setOnMapLoadedCallback(Runnable callback); void setOnMapLoadedCallback(Runnable callback);

View file

@ -31,6 +31,8 @@ import android.view.View;
import androidx.annotation.Keep; import androidx.annotation.Keep;
import com.google.android.exoplayer2.util.Log;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AnimatedFileDrawable; import org.telegram.ui.Components.AnimatedFileDrawable;
@ -76,6 +78,12 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return currentMediaDrawable; return currentMediaDrawable;
} }
public void updateStaticDrawableThump(Bitmap bitmap) {
staticThumbShader = null;
roundPaint.setShader(null);
setStaticDrawable(new BitmapDrawable(bitmap));
}
public interface ImageReceiverDelegate { public interface ImageReceiverDelegate {
void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb, boolean memCache); void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb, boolean memCache);

View file

@ -139,6 +139,25 @@ public class LinkifyPort {
"\uDB00\uDC00-\uDB3F\uDFFD" + "\uDB00\uDC00-\uDB3F\uDFFD" +
"\uDB44\uDC00-\uDB7F\uDFFD" + "\uDB44\uDC00-\uDB7F\uDFFD" +
"&&[^\u00A0[\u2000-\u200A]\u2028\u2029\u202F\u3000]]"; "&&[^\u00A0[\u2000-\u200A]\u2028\u2029\u202F\u3000]]";
private static final String UCS_CHAR_FIXED = "[" +
"\u00A0-\uD7FF" +
"\uF900-\uFDCF" +
"\uFDF0-\uFFEF" +
// "\uD800\uDC00-\uD83F\uDFFD" +
"\uD840\uDC00-\uD87F\uDFFD" +
"\uD880\uDC00-\uD8BF\uDFFD" +
"\uD8C0\uDC00-\uD8FF\uDFFD" +
"\uD900\uDC00-\uD93F\uDFFD" +
"\uD940\uDC00-\uD97F\uDFFD" +
"\uD980\uDC00-\uD9BF\uDFFD" +
"\uD9C0\uDC00-\uD9FF\uDFFD" +
"\uDA00\uDC00-\uDA3F\uDFFD" +
"\uDA40\uDC00-\uDA7F\uDFFD" +
"\uDA80\uDC00-\uDABF\uDFFD" +
"\uDAC0\uDC00-\uDAFF\uDFFD" +
"\uDB00\uDC00-\uDB3F\uDFFD" +
"\uDB44\uDC00-\uDB7F\uDFFD" +
"&&[^\u00A0[\u2000-\u200A]\u2028\u2029\u202F\u3000]]";
private static final String IP_ADDRESS_STRING = private static final String IP_ADDRESS_STRING =
"((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]" "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]" + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
@ -146,7 +165,7 @@ public class LinkifyPort {
+ "|[1-9][0-9]|[0-9]))"; + "|[1-9][0-9]|[0-9]))";
private static final String TLD_CHAR = "a-zA-Z" + UCS_CHAR; private static final String TLD_CHAR = "a-zA-Z" + UCS_CHAR;
private static final String PUNYCODE_TLD = "xn\\-\\-[\\w\\-]{0,58}\\w"; private static final String PUNYCODE_TLD = "xn\\-\\-[\\w\\-]{0,58}\\w";
private static final String LABEL_CHAR = "a-zA-Z0-9" + UCS_CHAR; private static final String LABEL_CHAR = "a-zA-Z0-9" + UCS_CHAR_FIXED;
private static final String IRI_LABEL = "[" + LABEL_CHAR + "](?:[" + LABEL_CHAR + "_\\-]{0,61}[" + LABEL_CHAR + "]){0,1}"; private static final String IRI_LABEL = "[" + LABEL_CHAR + "](?:[" + LABEL_CHAR + "_\\-]{0,61}[" + LABEL_CHAR + "]){0,1}";
private static String STRICT_TLD = "(?:" + IANA_TOP_LEVEL_DOMAINS + "|" + PUNYCODE_TLD + ")"; private static String STRICT_TLD = "(?:" + IANA_TOP_LEVEL_DOMAINS + "|" + PUNYCODE_TLD + ")";
private static final String STRICT_HOST_NAME = "(?:(?:" + IRI_LABEL + "\\.)+" + STRICT_TLD + ")"; private static final String STRICT_HOST_NAME = "(?:(?:" + IRI_LABEL + "\\.)+" + STRICT_TLD + ")";

View file

@ -20,6 +20,7 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.SystemClock; import android.os.SystemClock;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import androidx.collection.LongSparseArray; import androidx.collection.LongSparseArray;
@ -997,7 +998,7 @@ public class LocationController extends BaseController implements NotificationCe
} }
public interface LocationFetchCallback { public interface LocationFetchCallback {
void onLocationAddressAvailable(String address, String displayAddress, Location location); void onLocationAddressAvailable(String address, String displayAddress, TLRPC.TL_messageMediaVenue city, TLRPC.TL_messageMediaVenue street, Location location);
} }
private static HashMap<LocationFetchCallback, Runnable> callbacks = new HashMap<>(); private static HashMap<LocationFetchCallback, Runnable> callbacks = new HashMap<>();
@ -1011,15 +1012,24 @@ public class LocationController extends BaseController implements NotificationCe
callbacks.remove(callback); callbacks.remove(callback);
} }
if (location == null) { if (location == null) {
callback.onLocationAddressAvailable(null, null, null); callback.onLocationAddressAvailable(null, null, null, null, null);
return; return;
} }
Locale locale;
try {
locale = LocaleController.getInstance().getCurrentLocale();
} catch (Exception ignore) {
locale = LocaleController.getInstance().getSystemDefaultLocale();
}
final Locale finalLocale = locale;
Utilities.globalQueue.postRunnable(fetchLocationRunnable = () -> { Utilities.globalQueue.postRunnable(fetchLocationRunnable = () -> {
String name; String name, displayName, city, street, countryCode = null;
String displayName; boolean onlyCountry = true;
TLRPC.TL_messageMediaVenue cityLocation = null;
TLRPC.TL_messageMediaVenue streetLocation = null;
try { try {
Geocoder gcd = new Geocoder(ApplicationLoader.applicationContext, LocaleController.getInstance().getSystemDefaultLocale()); Geocoder gcd = new Geocoder(ApplicationLoader.applicationContext, finalLocale);
List<Address> addresses = gcd.getFromLocation(location.getLatitude(), location.getLongitude(), 1); List<Address> addresses = gcd.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if (addresses.size() > 0) { if (addresses.size() > 0) {
Address address = addresses.get(0); Address address = addresses.get(0);
@ -1028,6 +1038,74 @@ public class LocationController extends BaseController implements NotificationCe
StringBuilder nameBuilder = new StringBuilder(); StringBuilder nameBuilder = new StringBuilder();
StringBuilder displayNameBuilder = new StringBuilder(); StringBuilder displayNameBuilder = new StringBuilder();
StringBuilder cityBuilder = new StringBuilder();
StringBuilder streetBuilder = new StringBuilder();
String locality = null;
String feature = null;
// String addressLine = null;
// try {
// addressLine = address.getAddressLine(0);
// } catch (Exception ignore) {}
// if (addressLine != null) {
// String postalCode = address.getPostalCode();
// if (postalCode != null) {
// addressLine = addressLine.replace(" " + postalCode, "");
// addressLine = addressLine.replace(postalCode, "");
// }
// String[] parts = addressLine.split(", ");
// if (parts.length > 2) {
// String _country = parts[parts.length - 1].replace(",", "").trim();
// String _city = parts[parts.length - 2].replace(",", "").trim();
//// if (_city.length() > 3) {
//// locality = _city;
//// }
//// feature = parts[0].replace(",", "").trim();
// }
// }
if (TextUtils.isEmpty(locality)) {
locality = address.getLocality();
}
if (TextUtils.isEmpty(locality)) {
locality = address.getSubAdminArea();
}
if (TextUtils.isEmpty(locality)) {
locality = address.getAdminArea();
}
// if (TextUtils.isEmpty(feature) && !TextUtils.equals(address.getFeatureName(), locality) && !TextUtils.equals(address.getFeatureName(), address.getCountryName())) {
// feature = address.getFeatureName();
// }
if (TextUtils.isEmpty(feature) && !TextUtils.equals(address.getThoroughfare(), locality) && !TextUtils.equals(address.getThoroughfare(), address.getCountryName())) {
feature = address.getThoroughfare();
}
if (TextUtils.isEmpty(feature) && !TextUtils.equals(address.getSubLocality(), locality) && !TextUtils.equals(address.getSubLocality(), address.getCountryName())) {
feature = address.getSubLocality();
}
if (TextUtils.isEmpty(feature) && !TextUtils.equals(address.getLocality(), locality) && !TextUtils.equals(address.getLocality(), address.getCountryName())) {
feature = address.getLocality();
}
if (!TextUtils.isEmpty(feature) && !TextUtils.equals(feature, locality) && !TextUtils.equals(feature, address.getCountryName())) {
if (streetBuilder.length() > 0) {
streetBuilder.append(", ");
}
streetBuilder.append(feature);
} else {
streetBuilder = null;
}
if (!TextUtils.isEmpty(locality)) {
if (cityBuilder.length() > 0) {
cityBuilder.append(", ");
}
cityBuilder.append(locality);
onlyCountry = false;
if (streetBuilder != null) {
if (streetBuilder.length() > 0) {
streetBuilder.append(", ");
}
streetBuilder.append(locality);
}
}
arg = address.getSubThoroughfare(); arg = address.getSubThoroughfare();
if (!TextUtils.isEmpty(arg)) { if (!TextUtils.isEmpty(arg)) {
@ -1065,12 +1143,29 @@ public class LocationController extends BaseController implements NotificationCe
} }
nameBuilder.append(arg); nameBuilder.append(arg);
} }
countryCode = address.getCountryCode();
arg = address.getCountryName(); arg = address.getCountryName();
if (!TextUtils.isEmpty(arg)) { if (!TextUtils.isEmpty(arg)) {
if (nameBuilder.length() > 0) { if (nameBuilder.length() > 0) {
nameBuilder.append(", "); nameBuilder.append(", ");
} }
nameBuilder.append(arg); nameBuilder.append(arg);
String shortCountry = arg;
final String lng = finalLocale.getLanguage();
if (("US".equals(address.getCountryCode()) || "AE".equals(address.getCountryCode())) && ("en".equals(lng) || "uk".equals(lng) || "ru".equals(lng)) || "GB".equals(address.getCountryCode()) && "en".equals(lng)) {
shortCountry = "";
String[] words = arg.split(" ");
for (String word : words) {
if (word.length() > 0)
shortCountry += word.charAt(0);
}
} else if ("US".equals(address.getCountryCode())) {
shortCountry = "USA";
}
if (cityBuilder.length() > 0) {
cityBuilder.append(", ");
}
cityBuilder.append(shortCountry);
} }
arg = address.getCountryName(); arg = address.getCountryName();
@ -1106,19 +1201,94 @@ public class LocationController extends BaseController implements NotificationCe
name = nameBuilder.toString(); name = nameBuilder.toString();
displayName = displayNameBuilder.toString(); displayName = displayNameBuilder.toString();
city = cityBuilder.toString();
street = streetBuilder == null ? null : streetBuilder.toString();
} else { } else {
name = displayName = String.format(Locale.US, "Unknown address (%f,%f)", location.getLatitude(), location.getLongitude()); name = displayName = String.format(Locale.US, "Unknown address (%f,%f)", location.getLatitude(), location.getLongitude());
city = null;
street = null;
}
if (!TextUtils.isEmpty(city)) {
cityLocation = new TLRPC.TL_messageMediaVenue();
cityLocation.geo = new TLRPC.TL_geoPoint();
cityLocation.geo.lat = location.getLatitude();
cityLocation.geo._long = location.getLongitude();
cityLocation.query_id = -1;
cityLocation.title = city;
cityLocation.icon = onlyCountry ? "https://ss3.4sqi.net/img/categories_v2/building/government_capitolbuilding_64.png" : "https://ss3.4sqi.net/img/categories_v2/travel/hotel_64.png";
cityLocation.emoji = countryCodeToEmoji(countryCode);
cityLocation.address = onlyCountry ? LocaleController.getString("Country", R.string.Country) : LocaleController.getString("PassportCity", R.string.PassportCity);
}
if (!TextUtils.isEmpty(street)) {
streetLocation = new TLRPC.TL_messageMediaVenue();
streetLocation.geo = new TLRPC.TL_geoPoint();
streetLocation.geo.lat = location.getLatitude();
streetLocation.geo._long = location.getLongitude();
streetLocation.query_id = -1;
streetLocation.title = street;
streetLocation.icon = "pin";
streetLocation.address = LocaleController.getString("PassportStreet1", R.string.PassportStreet1);
}
if (cityLocation == null && streetLocation == null && location != null) {
String ocean = detectOcean(location.getLongitude(), location.getLatitude());
if (ocean != null) {
cityLocation = new TLRPC.TL_messageMediaVenue();
cityLocation.geo = new TLRPC.TL_geoPoint();
cityLocation.geo.lat = location.getLatitude();
cityLocation.geo._long = location.getLongitude();
cityLocation.query_id = -1;
cityLocation.title = ocean;
cityLocation.icon = "pin";
cityLocation.emoji = "🌊";
cityLocation.address = "Ocean";
}
} }
} catch (Exception ignore) { } catch (Exception ignore) {
name = displayName = String.format(Locale.US, "Unknown address (%f,%f)", location.getLatitude(), location.getLongitude()); name = displayName = String.format(Locale.US, "Unknown address (%f,%f)", location.getLatitude(), location.getLongitude());
city = null;
street = null;
} }
final String nameFinal = name; final String nameFinal = name;
final String displayNameFinal = displayName; final String displayNameFinal = displayName;
final TLRPC.TL_messageMediaVenue finalCityLocation = cityLocation;
final TLRPC.TL_messageMediaVenue finalStreetLocation = streetLocation;
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
callbacks.remove(callback); callbacks.remove(callback);
callback.onLocationAddressAvailable(nameFinal, displayNameFinal, location); callback.onLocationAddressAvailable(nameFinal, displayNameFinal, finalCityLocation, finalStreetLocation, location);
}); });
}, 300); }, 300);
callbacks.put(callback, fetchLocationRunnable); callbacks.put(callback, fetchLocationRunnable);
} }
public static String countryCodeToEmoji(String code) {
if (code == null) {
return null;
}
code = code.toUpperCase();
final int count = code.codePointCount(0, code.length());
if (count > 2) {
return null;
}
StringBuilder flag = new StringBuilder();
for (int j = 0; j < count; ++j) {
flag.append(Character.toChars(Character.codePointAt(code, j) - 0x41 + 0x1F1E6));
}
return flag.toString();
}
public static String detectOcean(double x, double y) {
if (y > 65) {
return "Arctic Ocean";
}
if (x > -88 && x < 40 && y > 0 || x > -60 && x < 20 && y <= 0) {
return "Atlantic Ocean";
}
if (y <= 30 && x >= 20 && x < 150) {
return "Indian Ocean";
}
if ((x > 106 || x < -60) && y > 0 || (x > 150 || x < -60) && y <= 0) {
return "Pacific Ocean";
}
return null;
}
} }

View file

@ -918,8 +918,16 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
int count = 0; int count = 0;
Cursor cursor = null; Cursor cursor = null;
try { try {
if (ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { final Context context = ApplicationLoader.applicationContext;
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{"COUNT(_id)"}, null, null, null); if (
Build.VERSION.SDK_INT >= 33 && (
context.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED ||
context.checkSelfPermission(Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED ||
context.checkSelfPermission(Manifest.permission.READ_MEDIA_AUDIO) == PackageManager.PERMISSION_GRANTED
) ||
context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
) {
cursor = MediaStore.Images.Media.query(context.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{"COUNT(_id)"}, null, null, null);
if (cursor != null) { if (cursor != null) {
if (cursor.moveToNext()) { if (cursor.moveToNext()) {
count += cursor.getInt(0); count += cursor.getInt(0);
@ -934,8 +942,16 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
} }
} }
try { try {
if (ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { final Context context = ApplicationLoader.applicationContext;
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, new String[]{"COUNT(_id)"}, null, null, null); if (
Build.VERSION.SDK_INT >= 33 && (
context.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED ||
context.checkSelfPermission(Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED ||
context.checkSelfPermission(Manifest.permission.READ_MEDIA_AUDIO) == PackageManager.PERMISSION_GRANTED
) ||
context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
) {
cursor = MediaStore.Images.Media.query(context.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, new String[]{"COUNT(_id)"}, null, null, null);
if (cursor != null) { if (cursor != null) {
if (cursor.moveToNext()) { if (cursor.moveToNext()) {
count += cursor.getInt(0); count += cursor.getInt(0);
@ -1773,8 +1789,32 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (raisedToBack == minCount || accelerometerVertical) { if (raisedToBack == minCount || accelerometerVertical) {
lastAccelerometerDetected = System.currentTimeMillis(); lastAccelerometerDetected = System.currentTimeMillis();
} }
if (proximityTouched && (raisedToBack == minCount || accelerometerVertical || System.currentTimeMillis() - lastAccelerometerDetected < 60) && !VoIPService.isAnyKindOfCallActive() && !manualRecording && !forbidRaiseToListen()) { final boolean allowRecording = !manualRecording && playingMessageObject == null && SharedConfig.enabledRaiseTo(true) && ApplicationLoader.isScreenOn && !inputFieldHasText && allowStartRecord && raiseChat != null && !callInProgress;
if (SharedConfig.enabledRaiseTo(true) && playingMessageObject == null && recordStartRunnable == null && recordingAudio == null && !PhotoViewer.getInstance().isVisible() && ApplicationLoader.isScreenOn && !inputFieldHasText && allowStartRecord && raiseChat != null && !callInProgress) { final boolean allowListening = SharedConfig.enabledRaiseTo(false) && playingMessageObject != null && (playingMessageObject.isVoice() || playingMessageObject.isRoundVideo());
final boolean proximityDetected = proximityTouched;
final boolean accelerometerDetected = raisedToBack == minCount || accelerometerVertical || System.currentTimeMillis() - lastAccelerometerDetected < 60;
final boolean alreadyPlaying = useFrontSpeaker || raiseToEarRecord;
final boolean wakelockAllowed = (
// proximityDetected ||
accelerometerDetected ||
alreadyPlaying
) && !forbidRaiseToListen() && !VoIPService.isAnyKindOfCallActive() && (allowRecording || allowListening) && !PhotoViewer.getInstance().isVisible();
if (proximityWakeLock != null) {
final boolean held = proximityWakeLock.isHeld();
if (held && !wakelockAllowed) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("wake lock releasing (proximityDetected=" + proximityDetected + ", accelerometerDetected=" + accelerometerDetected + ", alreadyPlaying=" + alreadyPlaying + ")");
}
proximityWakeLock.release();
} else if (!held && wakelockAllowed) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("wake lock acquiring (proximityDetected=" + proximityDetected + ", accelerometerDetected=" + accelerometerDetected + ", alreadyPlaying=" + alreadyPlaying + ")");
}
proximityWakeLock.acquire();
}
}
if (proximityTouched && wakelockAllowed) {
if (allowRecording && recordStartRunnable == null && recordingAudio == null) {
if (!raiseToEarRecord) { if (!raiseToEarRecord) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("start record"); FileLog.d("start record");
@ -1788,40 +1828,40 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (useFrontSpeaker) { if (useFrontSpeaker) {
setUseFrontSpeaker(true); setUseFrontSpeaker(true);
} }
ignoreOnPause = true; // ignoreOnPause = true;
if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) { // if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
proximityWakeLock.acquire(); // proximityWakeLock.acquire();
} // }
} }
} else if (SharedConfig.enabledRaiseTo(false) && playingMessageObject != null && (playingMessageObject.isVoice() || playingMessageObject.isRoundVideo())) { } else if (allowListening) {
if (!useFrontSpeaker) { if (!useFrontSpeaker) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("start listen"); FileLog.d("start listen");
} }
if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) { // if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
proximityWakeLock.acquire(); // proximityWakeLock.acquire();
} // }
setUseFrontSpeaker(true); setUseFrontSpeaker(true);
startAudioAgain(false); startAudioAgain(false);
ignoreOnPause = true; // ignoreOnPause = true;
} }
} }
raisedToBack = 0; raisedToBack = 0;
raisedToTop = 0; raisedToTop = 0;
raisedToTopSign = 0; raisedToTopSign = 0;
countLess = 0; countLess = 0;
} else if (proximityTouched && ((accelerometerSensor == null || linearSensor == null) && gravitySensor == null || ignoreAccelerometerGestures()) && !VoIPService.isAnyKindOfCallActive()) { } else if (proximityTouched && ((accelerometerSensor == null || linearSensor == null) && gravitySensor == null) && !VoIPService.isAnyKindOfCallActive()) {
if (playingMessageObject != null && !ApplicationLoader.mainInterfacePaused && (playingMessageObject.isVoice() || playingMessageObject.isRoundVideo()) && SharedConfig.enabledRaiseTo(false)) { if (playingMessageObject != null && !ApplicationLoader.mainInterfacePaused && allowListening) {
if (!useFrontSpeaker && !manualRecording && !forbidRaiseToListen()) { if (!useFrontSpeaker && !manualRecording && !forbidRaiseToListen()) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("start listen by proximity only"); FileLog.d("start listen by proximity only");
} }
if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) { // if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
proximityWakeLock.acquire(); // proximityWakeLock.acquire();
} // }
setUseFrontSpeaker(true); setUseFrontSpeaker(true);
startAudioAgain(false); startAudioAgain(false);
ignoreOnPause = true; // ignoreOnPause = true;
} }
} }
} else if (!proximityTouched && !manualRecording) { } else if (!proximityTouched && !manualRecording) {
@ -1832,9 +1872,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
stopRecording(2, false, 0); stopRecording(2, false, 0);
raiseToEarRecord = false; raiseToEarRecord = false;
ignoreOnPause = false; ignoreOnPause = false;
if (proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) { // if (!ignoreAccelerometerGestures() && proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release(); // proximityWakeLock.release();
} // }
} else if (useFrontSpeaker) { } else if (useFrontSpeaker) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("stop listen"); FileLog.d("stop listen");
@ -1842,9 +1882,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
useFrontSpeaker = false; useFrontSpeaker = false;
startAudioAgain(true); startAudioAgain(true);
ignoreOnPause = false; ignoreOnPause = false;
if (proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) { // if (!ignoreAccelerometerGestures() && proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release(); // proximityWakeLock.release();
} // }
} }
} }
if (timeSinceRaise != 0 && raisedToBack == minCount && Math.abs(System.currentTimeMillis() - timeSinceRaise) > 1000) { if (timeSinceRaise != 0 && raisedToBack == minCount && Math.abs(System.currentTimeMillis() - timeSinceRaise) > 1000) {
@ -1990,7 +2030,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
} }
sensorManager.unregisterListener(MediaController.this, proximitySensor); sensorManager.unregisterListener(MediaController.this, proximitySensor);
}); });
if (proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) { if (proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release(); proximityWakeLock.release();
} }
} }
@ -2072,14 +2112,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
stopProgressTimer(); stopProgressTimer();
lastProgress = 0; lastProgress = 0;
isPaused = false; isPaused = false;
if (!useFrontSpeaker && !SharedConfig.enabledRaiseTo(true)) { boolean playingNext = false;
ChatActivity chat = raiseChat;
stopRaiseToEarSensors(raiseChat, false, false);
raiseChat = chat;
}
if (proximityWakeLock != null && proximityWakeLock.isHeld() && !proximityTouched) {
proximityWakeLock.release();
}
if (playingMessageObject != null) { if (playingMessageObject != null) {
if (downloadingCurrentMessage) { if (downloadingCurrentMessage) {
FileLoader.getInstance(playingMessageObject.currentAccount).cancelLoadFile(playingMessageObject.getDocument()); FileLoader.getInstance(playingMessageObject.currentAccount).cancelLoadFile(playingMessageObject.getDocument());
@ -2108,10 +2141,10 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
voiceMessagesPlaylistMap = null; voiceMessagesPlaylistMap = null;
} }
} }
boolean next = false;
if (voiceMessagesPlaylist != null && index < voiceMessagesPlaylist.size()) { if (voiceMessagesPlaylist != null && index < voiceMessagesPlaylist.size()) {
MessageObject nextVoiceMessage = voiceMessagesPlaylist.get(index); MessageObject nextVoiceMessage = voiceMessagesPlaylist.get(index);
playMessage(nextVoiceMessage); playMessage(nextVoiceMessage);
playingNext = true;
if (!nextVoiceMessage.isRoundVideo() && pipRoundVideoView != null) { if (!nextVoiceMessage.isRoundVideo() && pipRoundVideoView != null) {
pipRoundVideoView.close(true); pipRoundVideoView.close(true);
pipRoundVideoView = null; pipRoundVideoView = null;
@ -2133,6 +2166,11 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
ApplicationLoader.applicationContext.stopService(intent); ApplicationLoader.applicationContext.stopService(intent);
} }
} }
if (!playingNext && byVoiceEnd && !SharedConfig.enabledRaiseTo(true)) {
ChatActivity chat = raiseChat;
stopRaiseToEarSensors(raiseChat, false, false);
raiseChat = chat;
}
} }
public boolean isGoingToShowMessageObject(MessageObject messageObject) { public boolean isGoingToShowMessageObject(MessageObject messageObject) {
@ -3483,9 +3521,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
startRaiseToEarSensors(raiseChat); startRaiseToEarSensors(raiseChat);
} }
if (!ApplicationLoader.mainInterfacePaused && proximityWakeLock != null && !proximityWakeLock.isHeld() && (playingMessageObject.isVoice() || playingMessageObject.isRoundVideo()) && SharedConfig.enabledRaiseTo(false)) { if (!ApplicationLoader.mainInterfacePaused && proximityWakeLock != null && !proximityWakeLock.isHeld() && (playingMessageObject.isVoice() || playingMessageObject.isRoundVideo()) && SharedConfig.enabledRaiseTo(false)) {
if (ignoreAccelerometerGestures()) { // proximityWakeLock.acquire();
proximityWakeLock.acquire();
}
} }
startProgressTimer(playingMessageObject); startProgressTimer(playingMessageObject);
NotificationCenter.getInstance(messageObject.currentAccount).postNotificationName(NotificationCenter.messagePlayingDidStart, messageObject, oldMessageObject); NotificationCenter.getInstance(messageObject.currentAccount).postNotificationName(NotificationCenter.messagePlayingDidStart, messageObject, oldMessageObject);
@ -3547,10 +3583,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return true; return true;
} }
public static boolean ignoreAccelerometerGestures() {
return Build.MANUFACTURER.equalsIgnoreCase("samsung");
}
public void updateSilent(boolean value) { public void updateSilent(boolean value) {
isSilent = value; isSilent = value;
if (videoPlayer != null) { if (videoPlayer != null) {
@ -4738,8 +4770,17 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
Cursor cursor = null; Cursor cursor = null;
try { try {
if (Build.VERSION.SDK_INT < 23 || ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { final Context context = ApplicationLoader.applicationContext;
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projectionPhotos, null, null, (Build.VERSION.SDK_INT > 28 ? MediaStore.Images.Media.DATE_MODIFIED : MediaStore.Images.Media.DATE_TAKEN) + " DESC"); if (
Build.VERSION.SDK_INT < 23 ||
Build.VERSION.SDK_INT < 33 && context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED ||
Build.VERSION.SDK_INT >= 33 && (
context.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED ||
context.checkSelfPermission(Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED ||
context.checkSelfPermission(Manifest.permission.READ_MEDIA_AUDIO) == PackageManager.PERMISSION_GRANTED
)
) {
cursor = MediaStore.Images.Media.query(context.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projectionPhotos, null, null, (Build.VERSION.SDK_INT > 28 ? MediaStore.Images.Media.DATE_MODIFIED : MediaStore.Images.Media.DATE_TAKEN) + " DESC");
if (cursor != null) { if (cursor != null) {
int imageIdColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID); int imageIdColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID);
int bucketIdColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID); int bucketIdColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID);
@ -4820,7 +4861,17 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
} }
try { try {
if (Build.VERSION.SDK_INT < 23 || ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
final Context context = ApplicationLoader.applicationContext;
if (
Build.VERSION.SDK_INT < 23 ||
Build.VERSION.SDK_INT < 33 && context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED ||
Build.VERSION.SDK_INT >= 33 && (
context.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED ||
context.checkSelfPermission(Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED ||
context.checkSelfPermission(Manifest.permission.READ_MEDIA_AUDIO) == PackageManager.PERMISSION_GRANTED
)
) {
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projectionVideo, null, null, (Build.VERSION.SDK_INT > 28 ? MediaStore.Video.Media.DATE_MODIFIED : MediaStore.Video.Media.DATE_TAKEN) + " DESC"); cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projectionVideo, null, null, (Build.VERSION.SDK_INT > 28 ? MediaStore.Video.Media.DATE_MODIFIED : MediaStore.Video.Media.DATE_TAKEN) + " DESC");
if (cursor != null) { if (cursor != null) {
int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID); int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID);

View file

@ -5330,7 +5330,7 @@ public class MediaDataController extends BaseController {
} }
} }
public void loadReplyMessagesForMessages(ArrayList<MessageObject> messages, long dialogId, boolean scheduled, int threadMessageId, Runnable callback) { public void loadReplyMessagesForMessages(ArrayList<MessageObject> messages, long dialogId, boolean scheduled, int threadMessageId, Runnable callback, int classGuid) {
if (DialogObject.isEncryptedDialog(dialogId)) { if (DialogObject.isEncryptedDialog(dialogId)) {
ArrayList<Long> replyMessages = new ArrayList<>(); ArrayList<Long> replyMessages = new ArrayList<>();
LongSparseArray<ArrayList<MessageObject>> replyMessageRandomOwners = new LongSparseArray<>(); LongSparseArray<ArrayList<MessageObject>> replyMessageRandomOwners = new LongSparseArray<>();
@ -5542,7 +5542,7 @@ public class MediaDataController extends BaseController {
AndroidUtilities.runOnUIThread(callback); AndroidUtilities.runOnUIThread(callback);
} }
} }
}); }, classGuid);
if (replyMessageOwners.isEmpty()) { if (replyMessageOwners.isEmpty()) {
requestsCount[0]--; requestsCount[0]--;
if (requestsCount[0] == 0) { if (requestsCount[0] == 0) {
@ -5617,7 +5617,7 @@ public class MediaDataController extends BaseController {
TLRPC.TL_messages_getScheduledMessages req = new TLRPC.TL_messages_getScheduledMessages(); TLRPC.TL_messages_getScheduledMessages req = new TLRPC.TL_messages_getScheduledMessages();
req.peer = getMessagesController().getInputPeer(dialogId); req.peer = getMessagesController().getInputPeer(dialogId);
req.id = dialogReplyMessagesIds.valueAt(a); req.id = dialogReplyMessagesIds.valueAt(a);
getConnectionsManager().sendRequest(req, (response, error) -> { int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) { if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response; TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
for (int i = 0; i < messagesRes.messages.size(); i++) { for (int i = 0; i < messagesRes.messages.size(); i++) {
@ -5679,11 +5679,14 @@ public class MediaDataController extends BaseController {
} }
} }
}); });
if (classGuid != 0) {
getConnectionsManager().bindRequestToGuid(reqId, classGuid);
}
} else if (channelId != 0) { } else if (channelId != 0) {
TLRPC.TL_channels_getMessages req = new TLRPC.TL_channels_getMessages(); TLRPC.TL_channels_getMessages req = new TLRPC.TL_channels_getMessages();
req.channel = getMessagesController().getInputChannel(channelId); req.channel = getMessagesController().getInputChannel(channelId);
req.id = dialogReplyMessagesIds.valueAt(a); req.id = dialogReplyMessagesIds.valueAt(a);
getConnectionsManager().sendRequest(req, (response, error) -> { int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) { if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response; TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
for (int i = 0; i < messagesRes.messages.size(); i++) { for (int i = 0; i < messagesRes.messages.size(); i++) {
@ -5705,10 +5708,13 @@ public class MediaDataController extends BaseController {
} }
} }
}); });
if (classGuid != 0) {
getConnectionsManager().bindRequestToGuid(reqId, classGuid);
}
} else { } else {
TLRPC.TL_messages_getMessages req = new TLRPC.TL_messages_getMessages(); TLRPC.TL_messages_getMessages req = new TLRPC.TL_messages_getMessages();
req.id = dialogReplyMessagesIds.valueAt(a); req.id = dialogReplyMessagesIds.valueAt(a);
getConnectionsManager().sendRequest(req, (response, error) -> { int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) { if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response; TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
for (int i = 0; i < messagesRes.messages.size(); i++) { for (int i = 0; i < messagesRes.messages.size(); i++) {
@ -5729,6 +5735,9 @@ public class MediaDataController extends BaseController {
} }
} }
}); });
if (classGuid != 0) {
getConnectionsManager().bindRequestToGuid(reqId, classGuid);
}
} }
} }
} else { } else {

View file

@ -4649,7 +4649,7 @@ public class MessageObject {
return FileLoader.MEDIA_DIR_CACHE; return FileLoader.MEDIA_DIR_CACHE;
} }
private static boolean containsUrls(CharSequence message) { public static boolean containsUrls(CharSequence message) {
if (message == null || message.length() < 2 || message.length() > 1024 * 20) { if (message == null || message.length() < 2 || message.length() > 1024 * 20) {
return false; return false;
} }
@ -4835,10 +4835,12 @@ public class MessageObject {
} }
String text = messageOwner.message; String text = messageOwner.message;
ArrayList<TLRPC.MessageEntity> entities = messageOwner.entities; ArrayList<TLRPC.MessageEntity> entities = messageOwner.entities;
boolean forceManualEntities = false;
if (type == TYPE_STORY) { if (type == TYPE_STORY) {
if (messageOwner.media != null && messageOwner.media.storyItem != null) { if (messageOwner.media != null && messageOwner.media.storyItem != null) {
text = messageOwner.media.storyItem.caption; text = messageOwner.media.storyItem.caption;
entities = messageOwner.media.storyItem.entities; entities = messageOwner.media.storyItem.entities;
forceManualEntities = true;
} else { } else {
text = ""; text = "";
entities = new ArrayList<>(); entities = new ArrayList<>();
@ -4861,16 +4863,16 @@ public class MessageObject {
hasEntities = !entities.isEmpty(); hasEntities = !entities.isEmpty();
} }
boolean useManualParse = !hasEntities && ( boolean useManualParse = forceManualEntities || !hasEntities && (
eventId != 0 || eventId != 0 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_old || getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_old ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_layer68 || getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_layer68 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_layer74 || getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_layer74 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_old || getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_old ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_layer68 || getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_layer68 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_layer74 || getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_layer74 ||
isOut() && messageOwner.send_state != MESSAGE_SEND_STATE_SENT || isOut() && messageOwner.send_state != MESSAGE_SEND_STATE_SENT ||
messageOwner.id < 0 messageOwner.id < 0
); );
if (useManualParse) { if (useManualParse) {
@ -7001,7 +7003,7 @@ public class MessageObject {
} }
public boolean shouldAnimateSending() { public boolean shouldAnimateSending() {
return isSending() && (type == MessageObject.TYPE_ROUND_VIDEO || isVoice() || (isAnyKindOfSticker() && sendAnimationData != null) || (messageText != null && sendAnimationData != null)); return wasJustSent && (type == MessageObject.TYPE_ROUND_VIDEO || isVoice() || (isAnyKindOfSticker() && sendAnimationData != null) || (messageText != null && sendAnimationData != null));
} }
public boolean hasAttachedStickers() { public boolean hasAttachedStickers() {
@ -7589,7 +7591,7 @@ public class MessageObject {
if (type == TYPE_EXTENDED_MEDIA_PREVIEW) { if (type == TYPE_EXTENDED_MEDIA_PREVIEW) {
TLRPC.TL_messageExtendedMediaPreview preview = (TLRPC.TL_messageExtendedMediaPreview) messageOwner.media.extended_media; TLRPC.TL_messageExtendedMediaPreview preview = (TLRPC.TL_messageExtendedMediaPreview) messageOwner.media.extended_media;
if (preview.thumb != null) { if (preview.thumb != null) {
File file = FileLoader.getInstance(currentAccount).getPathToAttach(preview.thumb); File file = FileLoader.getInstance(currentAccount).getPathToAttach(preview.thumb, useFileDatabaseQueue);
if (!mediaExists) { if (!mediaExists) {
mediaExists = file.exists() || preview.thumb instanceof TLRPC.TL_photoStrippedSize; mediaExists = file.exists() || preview.thumb instanceof TLRPC.TL_photoStrippedSize;
} }

View file

@ -27,6 +27,7 @@ import android.os.SystemClock;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.SparseBooleanArray; import android.util.SparseBooleanArray;
@ -72,7 +73,6 @@ import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PremiumPreviewFragment; import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.ProfileActivity; import org.telegram.ui.ProfileActivity;
import org.telegram.ui.Stories.StoriesController; import org.telegram.ui.Stories.StoriesController;
import org.telegram.ui.Stories.recorder.DualCameraView;
import org.telegram.ui.TopicsFragment; import org.telegram.ui.TopicsFragment;
import java.io.File; import java.io.File;
@ -137,9 +137,13 @@ public class MessagesController extends BaseController implements NotificationCe
private SparseArray<ChatlistUpdatesStat> chatlistFoldersUpdates = new SparseArray<>(); private SparseArray<ChatlistUpdatesStat> chatlistFoldersUpdates = new SparseArray<>();
public int largeQueueMaxActiveOperations = 2; public int largeQueueMaxActiveOperations = 2;
public int smallQueueMaxActiveOperations = 5; public int smallQueueMaxActiveOperations = 5;
public int stealthModeFuture;
public int stealthModePast;
public int stealthModeCooldown;
public StoriesController storiesController; public StoriesController storiesController;
private boolean hasArchivedChats; private boolean hasArchivedChats;
private boolean hasStories; private boolean hasStories;
public long storiesChangelogUserId;
public static TLRPC.Peer getPeerFromInputPeer(TLRPC.InputPeer peer) { public static TLRPC.Peer getPeerFromInputPeer(TLRPC.InputPeer peer) {
if (peer.chat_id != 0) { if (peer.chat_id != 0) {
@ -458,6 +462,7 @@ public class MessagesController extends BaseController implements NotificationCe
public boolean collectDeviceStats; public boolean collectDeviceStats;
public boolean showFiltersTooltip; public boolean showFiltersTooltip;
public String venueSearchBot; public String venueSearchBot;
public String storyVenueSearchBot;
public String gifSearchBot; public String gifSearchBot;
public String imageSearchBot; public String imageSearchBot;
public String dcDomainName; public String dcDomainName;
@ -504,7 +509,8 @@ public class MessagesController extends BaseController implements NotificationCe
public int publicLinksLimitPremium; public int publicLinksLimitPremium;
public int captionLengthLimitDefault; public int captionLengthLimitDefault;
public int captionLengthLimitPremium; public int captionLengthLimitPremium;
public int storyCaptionLengthLimit; public int storyCaptionLengthLimitDefault;
public int storyCaptionLengthLimitPremium;
public int aboutLengthLimitDefault; public int aboutLengthLimitDefault;
public int aboutLengthLimitPremium; public int aboutLengthLimitPremium;
public int reactionsUserMaxDefault; public int reactionsUserMaxDefault;
@ -518,6 +524,10 @@ public class MessagesController extends BaseController implements NotificationCe
private int chatlistUpdatePeriod; private int chatlistUpdatePeriod;
public int storyExpiringLimitDefault; public int storyExpiringLimitDefault;
public int storyExpiringLimitPremium; public int storyExpiringLimitPremium;
public int storiesSentWeeklyLimitDefault;
public int storiesSentWeeklyLimitPremium;
public int storiesSentMonthlyLimitDefault;
public int storiesSentMonthlyLimitPremium;
public int uploadMaxFileParts; public int uploadMaxFileParts;
public int uploadMaxFilePartsPremium; public int uploadMaxFilePartsPremium;
@ -552,6 +562,7 @@ public class MessagesController extends BaseController implements NotificationCe
public int chatlistJoinedLimitDefault; public int chatlistJoinedLimitDefault;
public int chatlistJoinedLimitPremium; public int chatlistJoinedLimitPremium;
public String storiesPosting; public String storiesPosting;
public String storiesEntities;
public int checkResetLangpack; public int checkResetLangpack;
@ -622,6 +633,7 @@ public class MessagesController extends BaseController implements NotificationCe
getMessagesStorage().saveDialogFiltersOrder(); getMessagesStorage().saveDialogFiltersOrder();
getNotificationCenter().postNotificationName(NotificationCenter.dialogFiltersUpdated); getNotificationCenter().postNotificationName(NotificationCenter.dialogFiltersUpdated);
getStoriesController().onPremiumChanged();
} }
public void lockFiltersInternal() { public void lockFiltersInternal() {
@ -1285,6 +1297,7 @@ public class MessagesController extends BaseController implements NotificationCe
promoPsaType = mainPreferences.getString("promo_psa_type", null); promoPsaType = mainPreferences.getString("promo_psa_type", null);
proxyDialogAddress = mainPreferences.getString("proxyDialogAddress", null); proxyDialogAddress = mainPreferences.getString("proxyDialogAddress", null);
venueSearchBot = mainPreferences.getString("venueSearchBot", "foursquare"); venueSearchBot = mainPreferences.getString("venueSearchBot", "foursquare");
storyVenueSearchBot = mainPreferences.getString("storyVenueSearchBot", "foursquare");
gifSearchBot = mainPreferences.getString("gifSearchBot", "gif"); gifSearchBot = mainPreferences.getString("gifSearchBot", "gif");
imageSearchBot = mainPreferences.getString("imageSearchBot", "pic"); imageSearchBot = mainPreferences.getString("imageSearchBot", "pic");
blockedCountry = mainPreferences.getBoolean("blockedCountry", false); blockedCountry = mainPreferences.getBoolean("blockedCountry", false);
@ -1327,7 +1340,8 @@ public class MessagesController extends BaseController implements NotificationCe
publicLinksLimitPremium = mainPreferences.getInt("publicLinksLimitPremium", 20); publicLinksLimitPremium = mainPreferences.getInt("publicLinksLimitPremium", 20);
captionLengthLimitDefault = mainPreferences.getInt("captionLengthLimitDefault", 1024); captionLengthLimitDefault = mainPreferences.getInt("captionLengthLimitDefault", 1024);
captionLengthLimitPremium = mainPreferences.getInt("captionLengthLimitPremium", 4096); captionLengthLimitPremium = mainPreferences.getInt("captionLengthLimitPremium", 4096);
storyCaptionLengthLimit = mainPreferences.getInt("storyCaptionLengthLimit", 1024); storyCaptionLengthLimitDefault = mainPreferences.getInt("storyCaptionLengthLimit", 200);
storyCaptionLengthLimitPremium = mainPreferences.getInt("storyCaptionLengthLimitPremium", 2048);
aboutLengthLimitDefault = mainPreferences.getInt("aboutLengthLimitDefault", 70); aboutLengthLimitDefault = mainPreferences.getInt("aboutLengthLimitDefault", 70);
aboutLengthLimitPremium = mainPreferences.getInt("aboutLengthLimitPremium", 140); aboutLengthLimitPremium = mainPreferences.getInt("aboutLengthLimitPremium", 140);
reactionsUserMaxDefault = mainPreferences.getInt("reactionsUserMaxDefault", 1); reactionsUserMaxDefault = mainPreferences.getInt("reactionsUserMaxDefault", 1);
@ -1351,14 +1365,23 @@ public class MessagesController extends BaseController implements NotificationCe
checkResetLangpack = mainPreferences.getInt("checkResetLangpack", 0); checkResetLangpack = mainPreferences.getInt("checkResetLangpack", 0);
smallQueueMaxActiveOperations = mainPreferences.getInt("smallQueueMaxActiveOperations", 5); smallQueueMaxActiveOperations = mainPreferences.getInt("smallQueueMaxActiveOperations", 5);
largeQueueMaxActiveOperations = mainPreferences.getInt("largeQueueMaxActiveOperations", 2); largeQueueMaxActiveOperations = mainPreferences.getInt("largeQueueMaxActiveOperations", 2);
stealthModeFuture = mainPreferences.getInt("stories_stealth_future_period", 25 * 60);
storiesChangelogUserId = mainPreferences.getLong("stories_changelog_user_id", 777000);
stealthModePast = mainPreferences.getInt("stories_stealth_past_period", 5 * 60);
stealthModeCooldown = mainPreferences.getInt("stories_stealth_cooldown_period", 60 * 60);
boolean isTest = ConnectionsManager.native_isTestBackend(currentAccount) != 0; boolean isTest = ConnectionsManager.native_isTestBackend(currentAccount) != 0;
chatlistInvitesLimitDefault = mainPreferences.getInt("chatlistInvitesLimitDefault", 3); chatlistInvitesLimitDefault = mainPreferences.getInt("chatlistInvitesLimitDefault", 3);
storyExpiringLimitDefault = mainPreferences.getInt("storyExpiringLimitDefault", 50); storyExpiringLimitDefault = mainPreferences.getInt("storyExpiringLimitDefault", 50);
storyExpiringLimitPremium = mainPreferences.getInt("storyExpiringLimitPremium", 100); storyExpiringLimitPremium = mainPreferences.getInt("storyExpiringLimitPremium", 100);
storiesSentWeeklyLimitDefault = mainPreferences.getInt("storiesSentWeeklyLimitDefault", 7);
storiesSentWeeklyLimitPremium = mainPreferences.getInt("storiesSentWeeklyLimitPremium", 70);
storiesSentMonthlyLimitDefault = mainPreferences.getInt("storiesSentMonthlyLimitDefault", 30);
storiesSentMonthlyLimitPremium = mainPreferences.getInt("storiesSentMonthlyLimitPremium", 300);
chatlistInvitesLimitPremium = mainPreferences.getInt("chatlistInvitesLimitPremium", isTest ? 5 : 20); chatlistInvitesLimitPremium = mainPreferences.getInt("chatlistInvitesLimitPremium", isTest ? 5 : 20);
chatlistJoinedLimitDefault = mainPreferences.getInt("chatlistJoinedLimitDefault", 2); chatlistJoinedLimitDefault = mainPreferences.getInt("chatlistJoinedLimitDefault", 2);
chatlistJoinedLimitPremium = mainPreferences.getInt("chatlistJoinedLimitPremium", isTest ? 5 : 20); chatlistJoinedLimitPremium = mainPreferences.getInt("chatlistJoinedLimitPremium", isTest ? 5 : 20);
storiesPosting = mainPreferences.getString("storiesPosting", "premium"); storiesPosting = mainPreferences.getString("storiesPosting", "enabled");
storiesEntities = mainPreferences.getString("storiesEntities", "premium");
storiesExportNopublicLink = mainPreferences.getBoolean("storiesExportNopublicLink", false); storiesExportNopublicLink = mainPreferences.getBoolean("storiesExportNopublicLink", false);
BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID); BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID);
if (mainPreferences.contains("dcDomainName2")) { if (mainPreferences.contains("dcDomainName2")) {
@ -1499,9 +1522,7 @@ public class MessagesController extends BaseController implements NotificationCe
FileLog.e(e); FileLog.e(e);
} }
} }
if (BuildVars.DEBUG_VERSION) { AndroidUtilities.runOnUIThread(this::loadAppConfig, 2000);
AndroidUtilities.runOnUIThread(this::loadAppConfig, 2000);
}
topicsController = new TopicsController(num); topicsController = new TopicsController(num);
cacheByChatsController = new CacheByChatsController(num); cacheByChatsController = new CacheByChatsController(num);
@ -2131,6 +2152,34 @@ public class MessagesController extends BaseController implements NotificationCe
for (int a = 0, N = object.value.size(); a < N; a++) { for (int a = 0, N = object.value.size(); a < N; a++) {
TLRPC.TL_jsonObjectValue value = object.value.get(a); TLRPC.TL_jsonObjectValue value = object.value.get(a);
switch (value.key) { switch (value.key) {
case "stories_changelog_user_id": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
storiesChangelogUserId = (long) ((TLRPC.TL_jsonNumber) value.value).value;
editor.putLong("stories_changelog_user_id", storiesChangelogUserId);
}
break;
}
case "stories_stealth_future_period": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
stealthModeFuture = (int) ((TLRPC.TL_jsonNumber) value.value).value;
editor.putInt("stories_stealth_future_period", stealthModeFuture);
}
break;
}
case "stories_stealth_past_period": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
stealthModePast = (int) ((TLRPC.TL_jsonNumber) value.value).value;
editor.putInt("stories_stealth_past_period", stealthModePast);
}
break;
}
case "stories_stealth_cooldown_period": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
stealthModeCooldown = (int) ((TLRPC.TL_jsonNumber) value.value).value;
editor.putInt("stories_stealth_cooldown_period", stealthModeCooldown);
}
break;
}
case "large_queue_max_active_operations_count": { case "large_queue_max_active_operations_count": {
if (value.value instanceof TLRPC.TL_jsonNumber) { if (value.value instanceof TLRPC.TL_jsonNumber) {
largeQueueMaxActiveOperations = (int) ((TLRPC.TL_jsonNumber) value.value).value; largeQueueMaxActiveOperations = (int) ((TLRPC.TL_jsonNumber) value.value).value;
@ -2982,12 +3031,23 @@ public class MessagesController extends BaseController implements NotificationCe
} }
break; break;
} }
case "story_caption_length_limit": { case "story_caption_length_limit_default": {
if (value.value instanceof TLRPC.TL_jsonNumber) { if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber number = (TLRPC.TL_jsonNumber) value.value; TLRPC.TL_jsonNumber number = (TLRPC.TL_jsonNumber) value.value;
if (number.value != storyCaptionLengthLimit) { if (number.value != storyCaptionLengthLimitDefault) {
storyCaptionLengthLimit = (int) number.value; storyCaptionLengthLimitDefault = (int) number.value;
editor.putInt("storyCaptionLengthLimit", storyCaptionLengthLimit); editor.putInt("storyCaptionLengthLimit", storyCaptionLengthLimitDefault);
changed = true;
}
}
break;
}
case "story_caption_length_limit_premium": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber number = (TLRPC.TL_jsonNumber) value.value;
if (number.value != storyCaptionLengthLimitPremium) {
storyCaptionLengthLimitPremium = (int) number.value;
editor.putInt("storyCaptionLengthLimitPremium", storyCaptionLengthLimitPremium);
changed = true; changed = true;
} }
} }
@ -3174,6 +3234,50 @@ public class MessagesController extends BaseController implements NotificationCe
} }
break; break;
} }
case "stories_sent_weekly_limit_default": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != storiesSentWeeklyLimitDefault) {
storiesSentWeeklyLimitDefault = (int) num.value;
editor.putInt("storiesSentWeeklyLimitDefault", storiesSentWeeklyLimitDefault);
changed = true;
}
}
break;
}
case "stories_sent_weekly_limit_premium": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != storiesSentWeeklyLimitPremium) {
storiesSentWeeklyLimitPremium = (int) num.value;
editor.putInt("storiesSentWeeklyLimitPremium", storiesSentWeeklyLimitPremium);
changed = true;
}
}
break;
}
case "stories_sent_monthly_limit_default": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != storiesSentMonthlyLimitDefault) {
storiesSentMonthlyLimitDefault = (int) num.value;
editor.putInt("storiesSentMonthlyLimitDefault", storiesSentMonthlyLimitDefault);
changed = true;
}
}
break;
}
case "stories_sent_monthly_limit_premium": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != storiesSentMonthlyLimitPremium) {
storiesSentMonthlyLimitPremium = (int) num.value;
editor.putInt("storiesSentMonthlyLimitPremium", storiesSentMonthlyLimitPremium);
changed = true;
}
}
break;
}
case "chatlist_invites_limit_premium": { case "chatlist_invites_limit_premium": {
if (value.value instanceof TLRPC.TL_jsonNumber) { if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value; TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
@ -3209,14 +3313,24 @@ public class MessagesController extends BaseController implements NotificationCe
} }
case "stories_posting": { case "stories_posting": {
if (value.value instanceof TLRPC.TL_jsonString) { if (value.value instanceof TLRPC.TL_jsonString) {
TLRPC.TL_jsonString bool = (TLRPC.TL_jsonString) value.value; TLRPC.TL_jsonString str = (TLRPC.TL_jsonString) value.value;
if (!TextUtils.equals(bool.value, storiesPosting)) { if (!TextUtils.equals(str.value, storiesPosting)) {
storiesPosting = bool.value; storiesPosting = str.value;
editor.putString("storiesPosting", storiesPosting); editor.putString("storiesPosting", storiesPosting);
changed = storiesChanged = true; changed = storiesChanged = true;
} }
} }
} }
case "stories_entities": {
if (value.value instanceof TLRPC.TL_jsonString) {
TLRPC.TL_jsonString str = (TLRPC.TL_jsonString) value.value;
if (!TextUtils.equals(str.value, storiesEntities)) {
storiesEntities = str.value;
editor.putString("storiesEntities", storiesEntities);
changed = true;
}
}
}
case "stories_export_nopublic_link": { case "stories_export_nopublic_link": {
if (value.value instanceof TLRPC.TL_jsonBool) { if (value.value instanceof TLRPC.TL_jsonBool) {
TLRPC.TL_jsonBool bool = (TLRPC.TL_jsonBool) value.value; TLRPC.TL_jsonBool bool = (TLRPC.TL_jsonBool) value.value;
@ -3227,6 +3341,16 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
case "stories_venue_search_username": {
if (value.value instanceof TLRPC.TL_jsonString) {
TLRPC.TL_jsonString str = (TLRPC.TL_jsonString) value.value;
if (!TextUtils.equals(storyVenueSearchBot, str.value)) {
storyVenueSearchBot = str.value;
editor.putString("storyVenueSearchBot", storyVenueSearchBot);
changed = true;
}
}
}
} }
} }
if (changed) { if (changed) {
@ -3256,6 +3380,7 @@ public class MessagesController extends BaseController implements NotificationCe
private boolean savePremiumFeaturesPreviewOrder(SharedPreferences.Editor editor, ArrayList<TLRPC.JSONValue> value) { private boolean savePremiumFeaturesPreviewOrder(SharedPreferences.Editor editor, ArrayList<TLRPC.JSONValue> value) {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
StringBuilder storiesBuilder = new StringBuilder();
premiumFeaturesTypesToPosition.clear(); premiumFeaturesTypesToPosition.clear();
for (int i = 0; i < value.size(); i++) { for (int i = 0; i < value.size(); i++) {
String s = null; String s = null;
@ -3970,6 +4095,8 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
} else if (id == NotificationCenter.currentUserPremiumStatusChanged) {
loadAppConfig(false);
} }
} }
@ -5729,7 +5856,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
}; };
if ((!user.bot || !ChatObject.isChannelAndNotMegaGroup(chat)) && addingNew) { if (!user.bot && addingNew) {
addUserToChat(chatId, user, 0, botHash, parentFragment, true, () -> getConnectionsManager().sendRequest(req, requestDelegate), onError); addUserToChat(chatId, user, 0, botHash, parentFragment, true, () -> getConnectionsManager().sendRequest(req, requestDelegate), onError);
} else { } else {
getConnectionsManager().sendRequest(req, requestDelegate); getConnectionsManager().sendRequest(req, requestDelegate);
@ -6896,10 +7023,10 @@ public class MessagesController extends BaseController implements NotificationCe
} }
public void loadChannelParticipants(Long chatId) { public void loadChannelParticipants(Long chatId) {
loadChannelParticipants(chatId, null); loadChannelParticipants(chatId, null, 32);
} }
public void loadChannelParticipants(Long chatId, Utilities.Callback<TLRPC.TL_channels_channelParticipants> whenDone) { public void loadChannelParticipants(Long chatId, Utilities.Callback<TLRPC.TL_channels_channelParticipants> whenDone, int count) {
if (whenDone == null && (loadingFullParticipants.contains(chatId) || loadedFullParticipants.contains(chatId))) { if (whenDone == null && (loadingFullParticipants.contains(chatId) || loadedFullParticipants.contains(chatId))) {
return; return;
} }
@ -6909,7 +7036,7 @@ public class MessagesController extends BaseController implements NotificationCe
req.channel = getInputChannel(chatId); req.channel = getInputChannel(chatId);
req.filter = new TLRPC.TL_channelParticipantsRecent(); req.filter = new TLRPC.TL_channelParticipantsRecent();
req.offset = 0; req.offset = 0;
req.limit = 32; req.limit = count;
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (error == null) { if (error == null) {
TLRPC.TL_channels_channelParticipants res = (TLRPC.TL_channels_channelParticipants) response; TLRPC.TL_channels_channelParticipants res = (TLRPC.TL_channels_channelParticipants) response;
@ -8011,6 +8138,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
req.limit = count; req.limit = count;
req.offset_id = max_id; req.offset_id = max_id;
long time = System.currentTimeMillis();
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> { int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) { if (response != null) {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response; TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
@ -8415,7 +8543,7 @@ public class MessagesController extends BaseController implements NotificationCe
} else { } else {
getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoad, dialogId, count, objects, isCache, finalFirst_unread_final, last_message_id, unread_count, last_date, load_type, isEnd, classGuid, loadIndex, max_id, mentionsCount, mode); getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoad, dialogId, count, objects, isCache, finalFirst_unread_final, last_message_id, unread_count, last_date, load_type, isEnd, classGuid, loadIndex, max_id, mentionsCount, mode);
} }
}); }, classGuid);
} else { } else {
getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoad, dialogId, count, objects, isCache, first_unread_final, last_message_id, unread_count, last_date, load_type, isEnd, classGuid, loadIndex, max_id, mentionsCount, mode); getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoad, dialogId, count, objects, isCache, first_unread_final, last_message_id, unread_count, last_date, load_type, isEnd, classGuid, loadIndex, max_id, mentionsCount, mode);
} }
@ -12227,17 +12355,21 @@ public class MessagesController extends BaseController implements NotificationCe
if (!guids.contains(guid)) { if (!guids.contains(guid)) {
guids.add(guid); guids.add(guid);
} }
boolean needGetDifference = false;
if (shortPollChannels.indexOfKey(chat.id) < 0) { if (shortPollChannels.indexOfKey(chat.id) < 0) {
needGetDifference = true; if (needPollConsumer != null) {
AndroidUtilities.runOnUIThread(() -> {
needPollConsumer.accept(true);
});
}
getChannelDifference(chat.id, 3, 0, null); getChannelDifference(chat.id, 3, 0, null);
} else {
if (needPollConsumer != null) {
AndroidUtilities.runOnUIThread(() -> {
needPollConsumer.accept(false);
});
}
} }
boolean finalNeedGetDifference = needGetDifference;
if (needPollConsumer != null) {
AndroidUtilities.runOnUIThread(() -> {
needPollConsumer.accept(finalNeedGetDifference);
});
}
if (chat.megagroup) { if (chat.megagroup) {
if (onlineGuids == null) { if (onlineGuids == null) {
onlineGuids = new ArrayList<>(); onlineGuids = new ArrayList<>();
@ -12750,7 +12882,7 @@ public class MessagesController extends BaseController implements NotificationCe
updateInterfaceWithMessages(dialogId, arr, false); updateInterfaceWithMessages(dialogId, arr, false);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload); getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}); });
}); }, 0);
} }
}); });
@ -14723,6 +14855,7 @@ public class MessagesController extends BaseController implements NotificationCe
blockePeers.delete(id); blockePeers.delete(id);
} }
getNotificationCenter().postNotificationName(NotificationCenter.blockedUsersDidLoad); getNotificationCenter().postNotificationName(NotificationCenter.blockedUsersDidLoad);
getStoriesController().updateBlockUser(id, finalUpdate.blocked_my_stories_from, false);
})); }));
} else if (baseUpdate instanceof TLRPC.TL_updateNotifySettings) { } else if (baseUpdate instanceof TLRPC.TL_updateNotifySettings) {
if (updatesOnMainThread == null) { if (updatesOnMainThread == null) {
@ -14780,6 +14913,11 @@ public class MessagesController extends BaseController implements NotificationCe
} }
pushMessages.add(obj); pushMessages.add(obj);
} }
} else if (baseUpdate instanceof TLRPC.TL_updateStoriesStealthMode) {
if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>();
}
updatesOnMainThread.add(baseUpdate);
} else if (baseUpdate instanceof TLRPC.TL_updateDialogPinned) { } else if (baseUpdate instanceof TLRPC.TL_updateDialogPinned) {
if (updatesOnMainThread == null) { if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>(); updatesOnMainThread = new ArrayList<>();
@ -14912,7 +15050,7 @@ public class MessagesController extends BaseController implements NotificationCe
updatesOnMainThread = new ArrayList<>(); updatesOnMainThread = new ArrayList<>();
} }
updatesOnMainThread.add(baseUpdate); updatesOnMainThread.add(baseUpdate);
} else if (baseUpdate instanceof TLRPC.TL_updateChat) { } else if (baseUpdate instanceof TLRPC.TL_updateChat || baseUpdate instanceof TLRPC.TL_updateSentStoryReaction) {
if (updatesOnMainThread == null) { if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>(); updatesOnMainThread = new ArrayList<>();
} }
@ -15799,6 +15937,9 @@ public class MessagesController extends BaseController implements NotificationCe
} }
int threadId = update.top_msg_id; int threadId = update.top_msg_id;
getMediaDataController().saveDraft(did, threadId, update.draft, null, true); getMediaDataController().saveDraft(did, threadId, update.draft, null, true);
} else if (baseUpdate instanceof TLRPC.TL_updateStoriesStealthMode) {
TLRPC.TL_updateStoriesStealthMode storiesStealthModeUpdate = (TLRPC.TL_updateStoriesStealthMode) baseUpdate;
getStoriesController().setStealthMode(storiesStealthModeUpdate.stealth_mode);
} else if (baseUpdate instanceof TLRPC.TL_updateReadFeaturedStickers) { } else if (baseUpdate instanceof TLRPC.TL_updateReadFeaturedStickers) {
getMediaDataController().markFeaturedStickersAsRead(false, false); getMediaDataController().markFeaturedStickersAsRead(false, false);
} else if (baseUpdate instanceof TLRPC.TL_updateReadFeaturedEmojiStickers) { } else if (baseUpdate instanceof TLRPC.TL_updateReadFeaturedEmojiStickers) {
@ -16096,6 +16237,8 @@ public class MessagesController extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.voiceTranscriptionUpdate, null, (Long) update.transcription_id, (String) update.text, null, (Boolean) !update.pending); getNotificationCenter().postNotificationName(NotificationCenter.voiceTranscriptionUpdate, null, (Long) update.transcription_id, (String) update.text, null, (Boolean) !update.pending);
} }
} }
} else if (baseUpdate instanceof TLRPC.TL_updateSentStoryReaction) {
storiesController.updateStoryReaction(((TLRPC.TL_updateSentStoryReaction) baseUpdate).user_id, ((TLRPC.TL_updateSentStoryReaction) baseUpdate).story_id, ((TLRPC.TL_updateSentStoryReaction) baseUpdate).reaction);
} }
} }
if (editor != null) { if (editor != null) {
@ -16235,7 +16378,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
getMediaDataController().loadReplyMessagesForMessages(arrayList, dialogId, false, 0,null); getMediaDataController().loadReplyMessagesForMessages(arrayList, dialogId, false, 0,null, 0);
getNotificationCenter().postNotificationName(NotificationCenter.replaceMessagesObjects, dialogId, arrayList, false); getNotificationCenter().postNotificationName(NotificationCenter.replaceMessagesObjects, dialogId, arrayList, false);
} }
} }
@ -16967,7 +17110,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
getMediaDataController().loadReplyMessagesForMessages(messages, dialogId, scheduled, 0, null); getMediaDataController().loadReplyMessagesForMessages(messages, dialogId, scheduled, 0, null, 0);
getNotificationCenter().postNotificationName(NotificationCenter.didReceiveNewMessages, dialogId, messages, scheduled); getNotificationCenter().postNotificationName(NotificationCenter.didReceiveNewMessages, dialogId, messages, scheduled);
if (lastMessage == null || scheduled) { if (lastMessage == null || scheduled) {
@ -18241,4 +18384,31 @@ public class MessagesController extends BaseController implements NotificationCe
return false; return false;
} }
} }
public boolean storyEntitiesAllowed() {
switch (storiesEntities) {
case "premium":
return getUserConfig().isPremium();
case "enabled":
return true;
default:
case "disabled":
return false;
}
}
public boolean storyEntitiesAllowed(TLRPC.User user) {
if (user != null && user.id == storiesChangelogUserId) {
return true;
}
switch (storiesEntities) {
case "premium":
return user != null && user.premium;
case "enabled":
return true;
default:
case "disabled":
return false;
}
}
} }

View file

@ -95,7 +95,7 @@ public class MessagesStorage extends BaseController {
} }
} }
public final static int LAST_DB_VERSION = 127; public final static int LAST_DB_VERSION = 128;
private boolean databaseMigrationInProgress; private boolean databaseMigrationInProgress;
public boolean showClearDatabaseAlert; public boolean showClearDatabaseAlert;
private LongSparseIntArray dialogIsForum = new LongSparseIntArray(); private LongSparseIntArray dialogIsForum = new LongSparseIntArray();
@ -202,6 +202,7 @@ public class MessagesStorage extends BaseController {
public MessagesStorage(int instance) { public MessagesStorage(int instance) {
super(instance); super(instance);
storageQueue = new DispatchQueue("storageQueue_" + instance); storageQueue = new DispatchQueue("storageQueue_" + instance);
storageQueue.setPriority(8);
storageQueue.postRunnable(() -> openDatabase(1)); storageQueue.postRunnable(() -> openDatabase(1));
} }
@ -671,7 +672,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE emoji_groups(type INTEGER PRIMARY KEY, data BLOB)").stepThis().dispose(); database.executeFast("CREATE TABLE emoji_groups(type INTEGER PRIMARY KEY, data BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE app_config(data BLOB)").stepThis().dispose(); database.executeFast("CREATE TABLE app_config(data BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE stories (dialog_id INTEGER, story_id INTEGER, data BLOB, local_path TEXT, local_thumb_path TEXT, PRIMARY KEY (dialog_id, story_id));").stepThis().dispose(); database.executeFast("CREATE TABLE stories (dialog_id INTEGER, story_id INTEGER, data BLOB, local_path TEXT, local_thumb_path TEXT, custom_params BLOB, PRIMARY KEY (dialog_id, story_id));").stepThis().dispose();
database.executeFast("CREATE TABLE stories_counter (dialog_id INTEGER PRIMARY KEY, count INTEGER, max_read INTEGER);").stepThis().dispose(); database.executeFast("CREATE TABLE stories_counter (dialog_id INTEGER PRIMARY KEY, count INTEGER, max_read INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE profile_stories (dialog_id INTEGER, story_id INTEGER, data BLOB, PRIMARY KEY(dialog_id, story_id));").stepThis().dispose(); database.executeFast("CREATE TABLE profile_stories (dialog_id INTEGER, story_id INTEGER, data BLOB, PRIMARY KEY(dialog_id, story_id));").stepThis().dispose();

View file

@ -110,6 +110,7 @@ public class NotificationCenter {
public static final int paymentFinished = totalEvents++; public static final int paymentFinished = totalEvents++;
public static final int channelRightsUpdated = totalEvents++; public static final int channelRightsUpdated = totalEvents++;
public static final int openArticle = totalEvents++; public static final int openArticle = totalEvents++;
public static final int articleClosed = totalEvents++;
public static final int updateMentionsCount = totalEvents++; public static final int updateMentionsCount = totalEvents++;
public static final int didUpdatePollResults = totalEvents++; public static final int didUpdatePollResults = totalEvents++;
public static final int chatOnlineCountDidLoad = totalEvents++; public static final int chatOnlineCountDidLoad = totalEvents++;
@ -211,6 +212,8 @@ public class NotificationCenter {
public static final int didUpdatePremiumGiftStickers = totalEvents++; public static final int didUpdatePremiumGiftStickers = totalEvents++;
public static final int didUpdatePremiumGiftFieldIcon = totalEvents++; public static final int didUpdatePremiumGiftFieldIcon = totalEvents++;
public static final int storiesEnabledUpdate = totalEvents++; public static final int storiesEnabledUpdate = totalEvents++;
public static final int storiesBlocklistUpdate = totalEvents++;
public static final int storiesLimitUpdate = totalEvents++;
//global //global
public static final int pushMessagesUpdated = totalEvents++; public static final int pushMessagesUpdated = totalEvents++;

View file

@ -868,7 +868,7 @@ public class PushListenerController {
break; break;
} }
case "CHAT_DELETE_MEMBER": { case "CHAT_DELETE_MEMBER": {
messageText = LocaleController.formatString("NotificationGroupKickMember", R.string.NotificationGroupKickMember, args[0], args[1]); messageText = LocaleController.formatString("NotificationGroupKickMember", R.string.NotificationGroupKickMember, args[0], args[1], args.length <= 2 ? "" : args[2]);
break; break;
} }
case "CHAT_DELETE_YOU": { case "CHAT_DELETE_YOU": {

View file

@ -231,11 +231,13 @@ public class SharedConfig {
public static boolean searchMessagesAsListUsed; public static boolean searchMessagesAsListUsed;
public static boolean stickersReorderingHintUsed; public static boolean stickersReorderingHintUsed;
public static int dayNightWallpaperSwitchHint; public static int dayNightWallpaperSwitchHint;
public static boolean storyReactionsLongPressHint;
public static boolean disableVoiceAudioEffects; public static boolean disableVoiceAudioEffects;
public static boolean forceDisableTabletMode; public static boolean forceDisableTabletMode;
public static boolean updateStickersOrderOnSend = true; public static boolean updateStickersOrderOnSend = true;
public static boolean bigCameraForRound; public static boolean bigCameraForRound;
public static boolean useSurfaceInStories; public static boolean useSurfaceInStories;
public static int stealthModeSendMessageConfirm = 2;
private static int lastLocalId = -210000; private static int lastLocalId = -210000;
public static String storageCacheDir; public static String storageCacheDir;
@ -591,6 +593,7 @@ public class SharedConfig {
searchMessagesAsListHintShows = preferences.getInt("searchMessagesAsListHintShows", 0); searchMessagesAsListHintShows = preferences.getInt("searchMessagesAsListHintShows", 0);
searchMessagesAsListUsed = preferences.getBoolean("searchMessagesAsListUsed", false); searchMessagesAsListUsed = preferences.getBoolean("searchMessagesAsListUsed", false);
stickersReorderingHintUsed = preferences.getBoolean("stickersReorderingHintUsed", false); stickersReorderingHintUsed = preferences.getBoolean("stickersReorderingHintUsed", false);
storyReactionsLongPressHint = preferences.getBoolean("storyReactionsLongPressHint", false);
textSelectionHintShows = preferences.getInt("textSelectionHintShows", 0); textSelectionHintShows = preferences.getInt("textSelectionHintShows", 0);
scheduledOrNoSoundHintShows = preferences.getInt("scheduledOrNoSoundHintShows", 0); scheduledOrNoSoundHintShows = preferences.getInt("scheduledOrNoSoundHintShows", 0);
forwardingOptionsHintShown = preferences.getBoolean("forwardingOptionsHintShown", false); forwardingOptionsHintShown = preferences.getBoolean("forwardingOptionsHintShown", false);
@ -601,6 +604,7 @@ public class SharedConfig {
messageSeenHintCount = preferences.getInt("messageSeenCount", 3); messageSeenHintCount = preferences.getInt("messageSeenCount", 3);
emojiInteractionsHintCount = preferences.getInt("emojiInteractionsHintCount", 3); emojiInteractionsHintCount = preferences.getInt("emojiInteractionsHintCount", 3);
dayNightThemeSwitchHintCount = preferences.getInt("dayNightThemeSwitchHintCount", 3); dayNightThemeSwitchHintCount = preferences.getInt("dayNightThemeSwitchHintCount", 3);
stealthModeSendMessageConfirm = preferences.getInt("stealthModeSendMessageConfirm", 2);
mediaColumnsCount = preferences.getInt("mediaColumnsCount", 3); mediaColumnsCount = preferences.getInt("mediaColumnsCount", 3);
storiesColumnsCount = preferences.getInt("storiesColumnsCount", 3); storiesColumnsCount = preferences.getInt("storiesColumnsCount", 3);
fastScrollHintCount = preferences.getInt("fastScrollHintCount", 3); fastScrollHintCount = preferences.getInt("fastScrollHintCount", 3);
@ -797,6 +801,7 @@ public class SharedConfig {
messageSeenHintCount = 3; messageSeenHintCount = 3;
emojiInteractionsHintCount = 3; emojiInteractionsHintCount = 3;
dayNightThemeSwitchHintCount = 3; dayNightThemeSwitchHintCount = 3;
stealthModeSendMessageConfirm = 2;
dayNightWallpaperSwitchHint = 0; dayNightWallpaperSwitchHint = 0;
saveConfig(); saveConfig();
} }
@ -825,6 +830,14 @@ public class SharedConfig {
editor.apply(); editor.apply();
} }
public static void setStoriesReactionsLongPressHintUsed(boolean value) {
storyReactionsLongPressHint = value;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("storyReactionsLongPressHint", storyReactionsLongPressHint);
editor.apply();
}
public static void increaseTextSelectionHintShowed() { public static void increaseTextSelectionHintShowed() {
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit(); SharedPreferences.Editor editor = preferences.edit();
@ -1423,6 +1436,12 @@ public class SharedConfig {
preferences.edit().putInt("dayNightThemeSwitchHintCount", dayNightThemeSwitchHintCount).apply(); preferences.edit().putInt("dayNightThemeSwitchHintCount", dayNightThemeSwitchHintCount).apply();
} }
public static void updateStealthModeSendMessageConfirm(int count) {
stealthModeSendMessageConfirm = count;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
preferences.edit().putInt("stealthModeSendMessageConfirm", stealthModeSendMessageConfirm).apply();
}
public final static int PERFORMANCE_CLASS_LOW = 0; public final static int PERFORMANCE_CLASS_LOW = 0;
public final static int PERFORMANCE_CLASS_AVERAGE = 1; public final static int PERFORMANCE_CLASS_AVERAGE = 1;
public final static int PERFORMANCE_CLASS_HIGH = 2; public final static int PERFORMANCE_CLASS_HIGH = 2;

View file

@ -1016,4 +1016,255 @@ public class TranslateController extends BaseController {
private void resetTranslatingDialogsCache() { private void resetTranslatingDialogsCache() {
MessagesController.getMainSettings(currentAccount).edit().remove("translating_dialog_languages2").remove("hidden_translation_at").apply(); MessagesController.getMainSettings(currentAccount).edit().remove("translating_dialog_languages2").remove("hidden_translation_at").apply();
} }
private final HashSet<StoryKey> detectingStories = new HashSet<>();
private final HashSet<StoryKey> translatingStories = new HashSet<>();
// ensure dialogId in storyItem is valid
public void detectStoryLanguage(TLRPC.StoryItem storyItem) {
if (storyItem == null || storyItem.detectedLng != null || storyItem.caption == null || storyItem.caption.length() == 0 || !LanguageDetector.hasSupport()) {
return;
}
final StoryKey key = new StoryKey(storyItem);
if (detectingStories.contains(key)) {
return;
}
detectingStories.add(key);
LanguageDetector.detectLanguage(storyItem.caption, lng -> AndroidUtilities.runOnUIThread(() -> {
storyItem.detectedLng = lng;
getMessagesController().getStoriesController().getStoriesStorage().putStoryInternal(storyItem.dialogId, storyItem);
detectingStories.remove(key);
}), err -> AndroidUtilities.runOnUIThread(() -> {
storyItem.detectedLng = UNKNOWN_LANGUAGE;
getMessagesController().getStoriesController().getStoriesStorage().putStoryInternal(storyItem.dialogId, storyItem);
detectingStories.remove(key);
}));
}
public boolean canTranslateStory(TLRPC.StoryItem storyItem) {
return storyItem != null && !TextUtils.isEmpty(storyItem.caption) && !Emoji.fullyConsistsOfEmojis(storyItem.caption) && (
storyItem.detectedLng == null && storyItem.translatedText != null && TextUtils.equals(storyItem.translatedLng, TranslateAlert2.getToLanguage()) ||
storyItem.detectedLng != null && !RestrictedLanguagesSelectActivity.getRestrictedLanguages().contains(storyItem.detectedLng)
);
}
public void translateStory(TLRPC.StoryItem storyItem, Runnable done) {
if (storyItem == null) {
return;
}
final StoryKey key = new StoryKey(storyItem);
String toLang = TranslateAlert2.getToLanguage();
if (storyItem.translatedText != null && TextUtils.equals(storyItem.translatedLng, toLang)) {
if (done != null) {
done.run();
}
return;
}
if (translatingStories.contains(key)) {
if (done != null) {
done.run();
}
return;
}
translatingStories.add(key);
TLRPC.TL_messages_translateText req = new TLRPC.TL_messages_translateText();
req.flags |= 2;
final TLRPC.TL_textWithEntities text = new TLRPC.TL_textWithEntities();
text.text = storyItem.caption;
text.entities = storyItem.entities;
req.text.add(text);
req.to_lang = toLang;
getConnectionsManager().sendRequest(req, (res, err) -> {
if (res instanceof TLRPC.TL_messages_translateResult) {
ArrayList<TLRPC.TL_textWithEntities> result = ((TLRPC.TL_messages_translateResult) res).result;
if (result.size() <= 0) {
AndroidUtilities.runOnUIThread(() -> {
storyItem.translatedLng = toLang;
storyItem.translatedText = null;
getMessagesController().getStoriesController().getStoriesStorage().putStoryInternal(storyItem.dialogId, storyItem);
translatingStories.remove(key);
if (done != null) {
done.run();
}
});
return;
}
final TLRPC.TL_textWithEntities textWithEntities = result.get(0);
AndroidUtilities.runOnUIThread(() -> {
storyItem.translatedLng = toLang;
storyItem.translatedText = TranslateAlert2.preprocess(text, textWithEntities);
getMessagesController().getStoriesController().getStoriesStorage().putStoryInternal(storyItem.dialogId, storyItem);
translatingStories.remove(key);
if (done != null) {
done.run();
}
});
} else {
AndroidUtilities.runOnUIThread(() -> {
storyItem.translatedLng = toLang;
storyItem.translatedText = null;
getMessagesController().getStoriesController().getStoriesStorage().putStoryInternal(storyItem.dialogId, storyItem);
translatingStories.remove(key);
if (done != null) {
done.run();
}
});
}
});
}
public boolean isTranslatingStory(TLRPC.StoryItem storyItem) {
if (storyItem == null) {
return false;
}
return translatingStories.contains(new StoryKey(storyItem));
}
private static class StoryKey {
public long dialogId;
public int storyId;
public StoryKey(TLRPC.StoryItem storyItem) {
dialogId = storyItem.dialogId;
storyId = storyItem.id;
}
}
private final HashSet<MessageKey> detectingPhotos = new HashSet<>();
private final HashSet<MessageKey> translatingPhotos = new HashSet<>();
public void detectPhotoLanguage(MessageObject messageObject, Utilities.Callback<String> done) {
if (messageObject == null || messageObject.messageOwner == null || !LanguageDetector.hasSupport() || TextUtils.isEmpty(messageObject.messageOwner.message)) {
return;
}
if (!TextUtils.isEmpty(messageObject.messageOwner.originalLanguage)) {
if (done != null) {
done.run(messageObject.messageOwner.originalLanguage);
}
return;
}
MessageKey key = new MessageKey(messageObject);
if (detectingPhotos.contains(key)) {
return;
}
detectingPhotos.add(key);
LanguageDetector.detectLanguage(messageObject.messageOwner.message, lng -> AndroidUtilities.runOnUIThread(() -> {
messageObject.messageOwner.originalLanguage = lng;
getMessagesStorage().updateMessageCustomParams(key.dialogId, messageObject.messageOwner);
detectingPhotos.remove(key);
if (done != null) {
done.run(lng);
}
}), err -> AndroidUtilities.runOnUIThread(() -> {
messageObject.messageOwner.originalLanguage = UNKNOWN_LANGUAGE;
getMessagesStorage().updateMessageCustomParams(key.dialogId, messageObject.messageOwner);
detectingPhotos.remove(key);
if (done != null) {
done.run(UNKNOWN_LANGUAGE);
}
}));
}
public boolean canTranslatePhoto(MessageObject messageObject, String detectedLanguage) {
if (messageObject != null && messageObject.messageOwner != null && messageObject.messageOwner.originalLanguage != null) {
detectedLanguage = messageObject.messageOwner.originalLanguage;
}
return messageObject != null && messageObject.messageOwner != null && !TextUtils.isEmpty(messageObject.messageOwner.message) && (
detectedLanguage == null && messageObject.messageOwner.translatedText != null && TextUtils.equals(messageObject.messageOwner.translatedToLanguage, TranslateAlert2.getToLanguage()) ||
detectedLanguage != null && !RestrictedLanguagesSelectActivity.getRestrictedLanguages().contains(messageObject.messageOwner.originalLanguage)
) && !messageObject.translated;
}
public void translatePhoto(MessageObject messageObject, Runnable done) {
if (messageObject == null || messageObject.messageOwner == null) {
return;
}
final MessageKey key = new MessageKey(messageObject);
String toLang = TranslateAlert2.getToLanguage();
if (messageObject.messageOwner.translatedText != null && TextUtils.equals(messageObject.messageOwner.translatedToLanguage, toLang)) {
if (done != null) {
done.run();
}
return;
}
if (translatingPhotos.contains(key)) {
if (done != null) {
done.run();
}
return;
}
translatingPhotos.add(key);
TLRPC.TL_messages_translateText req = new TLRPC.TL_messages_translateText();
req.flags |= 2;
final TLRPC.TL_textWithEntities text = new TLRPC.TL_textWithEntities();
text.text = messageObject.messageOwner.message;
text.entities = messageObject.messageOwner.entities;
if (text.entities == null) {
text.entities = new ArrayList<>();
}
req.text.add(text);
req.to_lang = toLang;
final long start = System.currentTimeMillis();
getConnectionsManager().sendRequest(req, (res, err) -> {
if (res instanceof TLRPC.TL_messages_translateResult) {
ArrayList<TLRPC.TL_textWithEntities> result = ((TLRPC.TL_messages_translateResult) res).result;
if (result.size() <= 0) {
AndroidUtilities.runOnUIThread(() -> {
messageObject.messageOwner.translatedToLanguage = toLang;
messageObject.messageOwner.translatedText = null;
getMessagesStorage().updateMessageCustomParams(key.dialogId, messageObject.messageOwner);
translatingPhotos.remove(key);
if (done != null) {
AndroidUtilities.runOnUIThread(done, Math.max(0, 400L - (System.currentTimeMillis() - start)));
}
});
return;
}
final TLRPC.TL_textWithEntities textWithEntities = result.get(0);
AndroidUtilities.runOnUIThread(() -> {
messageObject.messageOwner.translatedToLanguage = toLang;
messageObject.messageOwner.translatedText = TranslateAlert2.preprocess(text, textWithEntities);
getMessagesStorage().updateMessageCustomParams(key.dialogId, messageObject.messageOwner);
translatingPhotos.remove(key);
if (done != null) {
AndroidUtilities.runOnUIThread(done, Math.max(0, 400L - (System.currentTimeMillis() - start)));
}
});
} else {
AndroidUtilities.runOnUIThread(() -> {
messageObject.messageOwner.translatedToLanguage = toLang;
messageObject.messageOwner.translatedText = null;
getMessagesStorage().updateMessageCustomParams(key.dialogId, messageObject.messageOwner);
translatingPhotos.remove(key);
if (done != null) {
AndroidUtilities.runOnUIThread(done, Math.max(0, 400L - (System.currentTimeMillis() - start)));
}
});
}
});
}
private static class MessageKey {
public long dialogId;
public int id;
public MessageKey(MessageObject msg) {
dialogId = msg.getDialogId();
id = msg.getId();
}
}
} }

View file

@ -107,6 +107,7 @@ public class VideoEditedInfo {
public static final int TYPE_STICKER = 0; public static final int TYPE_STICKER = 0;
public static final int TYPE_TEXT = 1; public static final int TYPE_TEXT = 1;
public static final int TYPE_PHOTO = 2; public static final int TYPE_PHOTO = 2;
public static final int TYPE_LOCATION = 3;
public byte type; public byte type;
public byte subType; public byte subType;
@ -115,6 +116,7 @@ public class VideoEditedInfo {
public float rotation; public float rotation;
public float width; public float width;
public float height; public float height;
public float additionalWidth, additionalHeight;
public String text; public String text;
public ArrayList<EmojiEntity> entities = new ArrayList<>(); public ArrayList<EmojiEntity> entities = new ArrayList<>();
public int color; public int color;
@ -146,6 +148,12 @@ public class VideoEditedInfo {
public AnimatedFileDrawable animatedFileDrawable; public AnimatedFileDrawable animatedFileDrawable;
public Canvas roundRadiusCanvas; public Canvas roundRadiusCanvas;
public TLRPC.MediaArea mediaArea;
public TLRPC.MessageMedia mediaGeo;
public float density;
public int W, H;
public MediaEntity() { public MediaEntity() {
} }
@ -185,6 +193,20 @@ public class VideoEditedInfo {
document = TLRPC.Document.TLdeserialize(data, magic, false); document = TLRPC.Document.TLdeserialize(data, magic, false);
} }
} }
if (type == TYPE_LOCATION) {
density = data.readFloat(false);
mediaArea = TLRPC.MediaArea.TLdeserialize(data, data.readInt32(false), false);
mediaGeo = TLRPC.MessageMedia.TLdeserialize(data, data.readInt32(false), false);
if (data.remaining() > 0) {
int magic = data.readInt32(false);
if (magic == 0xdeadbeef) {
String emoji = data.readString(false);
if (mediaGeo instanceof TLRPC.TL_messageMediaVenue) {
((TLRPC.TL_messageMediaVenue) mediaGeo).emoji = emoji;
}
}
}
}
} }
public void serializeTo(AbstractSerializedData data, boolean full) { public void serializeTo(AbstractSerializedData data, boolean full) {
@ -218,6 +240,26 @@ public class VideoEditedInfo {
document.serializeToStream(data); document.serializeToStream(data);
} }
} }
if (type == TYPE_LOCATION) {
data.writeFloat(density);
mediaArea.serializeToStream(data);
if (mediaGeo.provider == null) {
mediaGeo.provider = "";
}
if (mediaGeo.venue_id == null) {
mediaGeo.venue_id = "";
}
if (mediaGeo.venue_type == null) {
mediaGeo.venue_type = "";
}
mediaGeo.serializeToStream(data);
if (mediaGeo instanceof TLRPC.TL_messageMediaVenue && ((TLRPC.TL_messageMediaVenue) mediaGeo).emoji != null) {
data.writeInt32(0xdeadbeef);
data.writeString(((TLRPC.TL_messageMediaVenue) mediaGeo).emoji);
} else {
data.writeInt32(TLRPC.TL_null.constructor);
}
}
} }
public MediaEntity copy() { public MediaEntity copy() {

View file

@ -254,7 +254,7 @@ public class Browser {
if (tryTelegraph) { if (tryTelegraph) {
try { try {
String host = AndroidUtilities.getHostAuthority(uri); String host = AndroidUtilities.getHostAuthority(uri);
if (isTelegraphUrl(host, true) || uri.toString().toLowerCase().contains("telegram.org/faq") || uri.toString().toLowerCase().contains("telegram.org/privacy")) { if (isTelegraphUrl(host, true) || "telegram.org".equalsIgnoreCase(host) && (uri.toString().toLowerCase().contains("telegram.org/faq") || uri.toString().toLowerCase().contains("telegram.org/privacy") || uri.toString().toLowerCase().contains("telegram.org/blog"))) {
final AlertDialog[] progressDialog = new AlertDialog[] { final AlertDialog[] progressDialog = new AlertDialog[] {
new AlertDialog(context, AlertDialog.ALERT_TYPE_SPINNER) new AlertDialog(context, AlertDialog.ALERT_TYPE_SPINNER)
}; };
@ -515,6 +515,8 @@ public class Browser {
} }
return true; return true;
} }
} else if ("telegram.org".equals(host) && uri != null && uri.getPath() != null && uri.getPath().startsWith("/blog/")) {
return true;
} else if (all) { } else if (all) {
if (host.endsWith("telegram.org") || host.endsWith("telegra.ph") || host.endsWith("telesco.pe")) { if (host.endsWith("telegram.org") || host.endsWith("telegra.ph") || host.endsWith("telesco.pe")) {
return true; return true;

View file

@ -57,12 +57,14 @@ import org.telegram.messenger.MessageObject;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.messenger.VideoEditedInfo; import org.telegram.messenger.VideoEditedInfo;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan; import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AnimatedFileDrawable; import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.EditTextEffects; import org.telegram.ui.Components.EditTextEffects;
import org.telegram.ui.Components.FilterShaders; import org.telegram.ui.Components.FilterShaders;
import org.telegram.ui.Components.Paint.Views.EditTextOutline; import org.telegram.ui.Components.Paint.Views.EditTextOutline;
import org.telegram.ui.Components.Paint.Views.LocationMarker;
import org.telegram.ui.Components.Paint.Views.PaintTextOptionsView; import org.telegram.ui.Components.Paint.Views.PaintTextOptionsView;
import org.telegram.ui.Components.RLottieDrawable; import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.Rect; import org.telegram.ui.Components.Rect;
@ -556,10 +558,13 @@ public class TextureRenderer {
private void drawEntity(VideoEditedInfo.MediaEntity entity, int textColor) { private void drawEntity(VideoEditedInfo.MediaEntity entity, int textColor) {
if (entity.ptr != 0) { if (entity.ptr != 0) {
RLottieDrawable.getFrame(entity.ptr, (int) entity.currentFrame, stickerBitmap, 512, 512, stickerBitmap.getRowBytes(), true); if (entity.bitmap == null || entity.W <= 0 || entity.H <= 0) {
applyRoundRadius(entity, stickerBitmap, (entity.subType & 8) != 0 ? textColor : 0); return;
}
RLottieDrawable.getFrame(entity.ptr, (int) entity.currentFrame, entity.bitmap, entity.W, entity.H, entity.bitmap.getRowBytes(), true);
applyRoundRadius(entity, entity.bitmap, (entity.subType & 8) != 0 ? textColor : 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, stickerBitmap, 0); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, entity.bitmap, 0);
entity.currentFrame += entity.framesPerDraw; entity.currentFrame += entity.framesPerDraw;
if (entity.currentFrame >= entity.metadata[0]) { if (entity.currentFrame >= entity.metadata[0]) {
entity.currentFrame = 0; entity.currentFrame = 0;
@ -594,7 +599,7 @@ public class TextureRenderer {
if (entity.bitmap != null) { if (entity.bitmap != null) {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, entity.bitmap, 0); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, entity.bitmap, 0);
drawTexture(false, stickerTexture[0], entity.x, entity.y, entity.width, entity.height, entity.rotation, entity.type == VideoEditedInfo.MediaEntity.TYPE_PHOTO && (entity.subType & 2) != 0); drawTexture(false, stickerTexture[0], entity.x - entity.additionalWidth / 2f, entity.y - entity.additionalHeight / 2f, entity.width + entity.additionalWidth, entity.height + entity.additionalHeight, entity.rotation, entity.type == VideoEditedInfo.MediaEntity.TYPE_PHOTO && (entity.subType & 2) != 0);
} }
if (entity.entities != null && !entity.entities.isEmpty()) { if (entity.entities != null && !entity.entities.isEmpty()) {
for (int i = 0; i < entity.entities.size(); ++i) { for (int i = 0; i < entity.entities.size(); ++i) {
@ -899,6 +904,7 @@ public class TextureRenderer {
initStickerEntity(entity); initStickerEntity(entity);
} else if (entity.type == VideoEditedInfo.MediaEntity.TYPE_TEXT) { } else if (entity.type == VideoEditedInfo.MediaEntity.TYPE_TEXT) {
EditTextOutline editText = new EditTextOutline(ApplicationLoader.applicationContext); EditTextOutline editText = new EditTextOutline(ApplicationLoader.applicationContext);
editText.getPaint().setAntiAlias(true);
editText.betterFraming = useMatrixForImagePath; editText.betterFraming = useMatrixForImagePath;
editText.drawAnimatedEmojiDrawables = false; editText.drawAnimatedEmojiDrawables = false;
editText.setBackgroundColor(Color.TRANSPARENT); editText.setBackgroundColor(Color.TRANSPARENT);
@ -916,7 +922,6 @@ public class TextureRenderer {
e.entity = new VideoEditedInfo.MediaEntity(); e.entity = new VideoEditedInfo.MediaEntity();
e.entity.text = e.documentAbsolutePath; e.entity.text = e.documentAbsolutePath;
e.entity.subType = e.subType; e.entity.subType = e.subType;
initStickerEntity(e.entity);
AnimatedEmojiSpan span = new AnimatedEmojiSpan(0L, 1f, editText.getPaint().getFontMetricsInt()) { AnimatedEmojiSpan span = new AnimatedEmojiSpan(0L, 1f, editText.getPaint().getFontMetricsInt()) {
@Override @Override
public void draw(@NonNull Canvas canvas, CharSequence charSequence, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) { public void draw(@NonNull Canvas canvas, CharSequence charSequence, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
@ -940,6 +945,9 @@ public class TextureRenderer {
e.entity.x = tcx - e.entity.width / 2f; e.entity.x = tcx - e.entity.width / 2f;
e.entity.y = tcy - e.entity.height / 2f; e.entity.y = tcy - e.entity.height / 2f;
e.entity.rotation = entity.rotation; e.entity.rotation = entity.rotation;
if (e.entity.bitmap == null)
initStickerEntity(e.entity);
} }
}; };
text.setSpan(span, e.offset, e.offset + e.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.setSpan(span, e.offset, e.offset + e.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@ -1013,6 +1021,57 @@ public class TextureRenderer {
entity.bitmap = Bitmap.createBitmap(entity.viewWidth, entity.viewHeight, Bitmap.Config.ARGB_8888); entity.bitmap = Bitmap.createBitmap(entity.viewWidth, entity.viewHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(entity.bitmap); Canvas canvas = new Canvas(entity.bitmap);
editText.draw(canvas); editText.draw(canvas);
} else if (entity.type == VideoEditedInfo.MediaEntity.TYPE_LOCATION) {
LocationMarker marker = new LocationMarker(ApplicationLoader.applicationContext, entity.density);
marker.setText(entity.text);
marker.setType(entity.subType, entity.color);
marker.setMaxWidth(entity.viewWidth);
if (entity.entities.size() == 1) {
marker.forceEmoji();
}
marker.measure(View.MeasureSpec.makeMeasureSpec(entity.viewWidth, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(entity.viewHeight, View.MeasureSpec.EXACTLY));
marker.layout(0, 0, entity.viewWidth, entity.viewHeight);
float scale = entity.width * transformedWidth / entity.viewWidth;
int w = (int) (entity.viewWidth * scale), h = (int) (entity.viewHeight * scale), pad = 8;
entity.bitmap = Bitmap.createBitmap(w + pad + pad, h + pad + pad, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(entity.bitmap);
canvas.translate(pad, pad);
canvas.scale(scale, scale);
marker.draw(canvas);
entity.additionalWidth = (2 * pad) * scale / transformedWidth;
entity.additionalHeight = (2 * pad) * scale / transformedHeight;
if (entity.entities.size() == 1) {
VideoEditedInfo.EmojiEntity e = entity.entities.get(0);
e.entity = new VideoEditedInfo.MediaEntity();
e.entity.text = e.documentAbsolutePath;
e.entity.subType = e.subType;
RectF bounds = new RectF();
marker.getEmojiBounds(bounds);
float tcx = entity.x + (bounds.centerX()) / entity.viewWidth * entity.width;
float tcy = entity.y + (bounds.centerY()) / entity.viewHeight * entity.height;
if (entity.rotation != 0) {
float mx = entity.x + entity.width / 2f;
float my = entity.y + entity.height / 2f;
float ratio = transformedWidth / (float) transformedHeight;
float x1 = tcx - mx;
float y1 = (tcy - my) / ratio;
tcx = (float) (x1 * Math.cos(-entity.rotation) - y1 * Math.sin(-entity.rotation)) + mx;
tcy = (float) (x1 * Math.sin(-entity.rotation) + y1 * Math.cos(-entity.rotation)) * ratio + my;
}
e.entity.width = (float) bounds.width() / entity.viewWidth * entity.width;
e.entity.height = (float) bounds.height() / entity.viewHeight * entity.height;
e.entity.width *= LocationMarker.SCALE;
e.entity.height *= LocationMarker.SCALE;
e.entity.x = tcx - e.entity.width / 2f;
e.entity.y = tcy - e.entity.height / 2f;
e.entity.rotation = entity.rotation;
initStickerEntity(e.entity);
}
} }
} }
} catch (Throwable e) { } catch (Throwable e) {
@ -1022,9 +1081,23 @@ public class TextureRenderer {
} }
private void initStickerEntity(VideoEditedInfo.MediaEntity entity) { private void initStickerEntity(VideoEditedInfo.MediaEntity entity) {
entity.W = (int) (entity.width * transformedWidth);
entity.H = (int) (entity.height * transformedHeight);
if (entity.W > 512) {
entity.H = (int) (entity.H / (float) entity.W * 512);
entity.W = 512;
}
if (entity.H > 512) {
entity.W = (int) (entity.W / (float) entity.H * 512);
entity.H = 512;
}
if ((entity.subType & 1) != 0) { if ((entity.subType & 1) != 0) {
if (entity.W <= 0 || entity.H <= 0) {
return;
}
entity.bitmap = Bitmap.createBitmap(entity.W, entity.H, Bitmap.Config.ARGB_8888);
entity.metadata = new int[3]; entity.metadata = new int[3];
entity.ptr = RLottieDrawable.create(entity.text, null, 512, 512, entity.metadata, false, null, false, 0); entity.ptr = RLottieDrawable.create(entity.text, null, entity.W, entity.H, entity.metadata, false, null, false, 0);
entity.framesPerDraw = entity.metadata[1] / videoFps; entity.framesPerDraw = entity.metadata[1] / videoFps;
} else if ((entity.subType & 4) != 0) { } else if ((entity.subType & 4) != 0) {
entity.animatedFileDrawable = new AnimatedFileDrawable(new File(entity.text), true, 0, 0, null, null, null, 0, UserConfig.selectedAccount, true, 512, 512, null); entity.animatedFileDrawable = new AnimatedFileDrawable(new File(entity.text), true, 0, 0, null, null, null, 0, UserConfig.selectedAccount, true, 512, 512, null);
@ -1149,6 +1222,10 @@ public class TextureRenderer {
if (entity.view instanceof EditTextEffects) { if (entity.view instanceof EditTextEffects) {
((EditTextEffects) entity.view).recycleEmojis(); ((EditTextEffects) entity.view).recycleEmojis();
} }
if (entity.bitmap != null) {
entity.bitmap.recycle();
entity.bitmap = null;
}
} }
} }
} }

View file

@ -10,6 +10,7 @@ import android.os.SystemClock;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
import com.google.android.exoplayer2.util.Log;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig; import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import org.json.JSONArray; import org.json.JSONArray;
@ -412,6 +413,9 @@ public class ConnectionsManager extends BaseController {
} }
public void bindRequestToGuid(int requestToken, int guid) { public void bindRequestToGuid(int requestToken, int guid) {
if (guid == 0) {
return;
}
native_bindRequestToGuid(currentAccount, requestToken, guid); native_bindRequestToGuid(currentAccount, requestToken, guid);
} }

File diff suppressed because it is too large Load diff

View file

@ -1226,8 +1226,8 @@ public class ActionBar extends FrameLayout {
if (searchFieldIsVisible && !this.isSearchFieldVisible) { if (searchFieldIsVisible && !this.isSearchFieldVisible) {
menuWidth = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST); menuWidth = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST);
menu.measure(menuWidth, actionBarHeightSpec); menu.measure(menuWidth, actionBarHeightSpec);
int itemsWidth = menu.getItemsMeasuredWidth(); int itemsWidth = menu.getItemsMeasuredWidth(true);
menuWidth = MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 74 : 66) + menu.getItemsMeasuredWidth(), MeasureSpec.EXACTLY); menuWidth = MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 74 : 66) + menu.getItemsMeasuredWidth(true), MeasureSpec.EXACTLY);
if (!isMenuOffsetSuppressed) { if (!isMenuOffsetSuppressed) {
menu.translateXItems(-itemsWidth); menu.translateXItems(-itemsWidth);
} }

View file

@ -964,7 +964,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
if (GroupCallPip.onBackPressed()) { if (GroupCallPip.onBackPressed()) {
return; return;
} }
if (currentActionBar != null && !currentActionBar.isActionModeShowed() && currentActionBar.isSearchFieldVisible) { if (!storyViewerAttached() && currentActionBar != null && !currentActionBar.isActionModeShowed() && currentActionBar.isSearchFieldVisible) {
currentActionBar.closeSearchField(); currentActionBar.closeSearchField();
return; return;
} }

View file

@ -518,11 +518,14 @@ public class ActionBarMenu extends LinearLayout {
} }
} }
public int getItemsMeasuredWidth() { public int getItemsMeasuredWidth(boolean ignoreAlpha) {
int w = 0; int w = 0;
int count = getChildCount(); int count = getChildCount();
for (int a = 0; a < count; a++) { for (int a = 0; a < count; a++) {
View view = getChildAt(a); View view = getChildAt(a);
if (!ignoreAlpha && (view.getAlpha() == 0 || view.getVisibility() != View.VISIBLE)) {
continue;
}
if (view instanceof ActionBarMenuItem) { if (view instanceof ActionBarMenuItem) {
w += view.getMeasuredWidth(); w += view.getMeasuredWidth();
} }

View file

@ -81,6 +81,17 @@ public class ActionBarMenuItem extends FrameLayout {
private FrameLayout wrappedSearchFrameLayout; private FrameLayout wrappedSearchFrameLayout;
public static void addText(ActionBarPopupWindow.ActionBarPopupWindowLayout popupLayout, String text, Theme.ResourcesProvider resourcesProvider) {
final TextView textView = new TextView(popupLayout.getContext());
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
textView.setPadding(AndroidUtilities.dp(13), AndroidUtilities.dp(8), AndroidUtilities.dp(13), AndroidUtilities.dp(8));
textView.setText(text);
textView.setTag(R.id.fit_width_tag, 1);
textView.setMaxWidth(AndroidUtilities.dp(200));
popupLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
}
public void setSearchPaddingStart(int padding) { public void setSearchPaddingStart(int padding) {
searchItemPaddingStart = padding; searchItemPaddingStart = padding;
if (searchContainer != null) { if (searchContainer != null) {
@ -525,6 +536,7 @@ public class ActionBarMenuItem extends FrameLayout {
View cell = new View(popupLayout.getContext()); View cell = new View(popupLayout.getContext());
cell.setTag(id); cell.setTag(id);
cell.setTag(R.id.object_tag, 1); cell.setTag(R.id.object_tag, 1);
cell.setTag(R.id.fit_width_tag, 1);
popupLayout.addView(cell); popupLayout.addView(cell);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) cell.getLayoutParams(); LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) cell.getLayoutParams();
if (LocaleController.isRTL) { if (LocaleController.isRTL) {

View file

@ -203,6 +203,10 @@ public class ActionBarMenuSubItem extends FrameLayout {
imageView.setImageResource(resId); imageView.setImageResource(resId);
} }
public void setIcon(Drawable drawable) {
imageView.setImageDrawable(drawable);
}
public void setAnimatedIcon(int resId) { public void setAnimatedIcon(int resId) {
imageView.setAnimation(resId, 24, 24); imageView.setAnimation(resId, 24, 24);
} }

View file

@ -950,6 +950,9 @@ public abstract class BaseFragment {
} }
public boolean isLightStatusBar() { public boolean isLightStatusBar() {
if (storyViewer != null && storyViewer.isShown()) {
return false;
}
if (hasForceLightStatusBar() && !Theme.getCurrentTheme().isDark()) { if (hasForceLightStatusBar() && !Theme.getCurrentTheme().isDark()) {
return true; return true;
} }

View file

@ -31,6 +31,7 @@ import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.VelocityTracker; import android.view.VelocityTracker;
import android.view.View; import android.view.View;
@ -770,6 +771,10 @@ public class BottomSheet extends Dialog {
return !keyboardVisible && drawNavigationBar && insets != null && (insets.left != 0 || insets.right != 0) ? insets.bottom : 0; return !keyboardVisible && drawNavigationBar && insets != null && (insets.left != 0 || insets.right != 0) ? insets.bottom : 0;
} }
public boolean isKeyboardVisible() {
return keyboardVisible;
}
public interface BottomSheetDelegateInterface { public interface BottomSheetDelegateInterface {
void onOpenAnimationStart(); void onOpenAnimationStart();
void onOpenAnimationEnd(); void onOpenAnimationEnd();
@ -1905,6 +1910,11 @@ public class BottomSheet extends Dialog {
} }
} }
@Override
public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
return super.dispatchKeyEvent(event);
}
public void setImageReceiverNumLevel(int playingImages, int onShowing) { public void setImageReceiverNumLevel(int playingImages, int onShowing) {
this.playingImagesLayerNum = playingImages; this.playingImagesLayerNum = playingImages;
this.openedLayerNum = onShowing; this.openedLayerNum = onShowing;

View file

@ -25,6 +25,8 @@ import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Outline; import android.graphics.Outline;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region; import android.graphics.Region;
import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.AnimatedVectorDrawable;
@ -32,6 +34,7 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.Size; import android.util.Size;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
@ -49,23 +52,30 @@ import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import android.view.animation.Transformation; import android.view.animation.Transformation;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ListView; import android.widget.ListView;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.Space;
import android.widget.TextView; import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BotWebViewVibrationEffect;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -90,6 +100,11 @@ public final class FloatingToolbar {
public static final int STYLE_THEME = 1; public static final int STYLE_THEME = 1;
public static final int STYLE_BLACK = 2; public static final int STYLE_BLACK = 2;
private Runnable premiumLockClickListener;
public void setOnPremiumLockClick(Runnable listener) {
premiumLockClickListener = listener;
}
private final OnLayoutChangeListener mOrientationChangeHandler = new OnLayoutChangeListener() { private final OnLayoutChangeListener mOrientationChangeHandler = new OnLayoutChangeListener() {
private final Rect mNewRect = new Rect(); private final Rect mNewRect = new Rect();
private final Rect mOldRect = new Rect(); private final Rect mOldRect = new Rect();
@ -220,7 +235,7 @@ public final class FloatingToolbar {
Menu subMenu = menuItem.getSubMenu(); Menu subMenu = menuItem.getSubMenu();
if (subMenu != null) { if (subMenu != null) {
menuItems.addAll(getVisibleAndEnabledMenuItems(subMenu)); menuItems.addAll(getVisibleAndEnabledMenuItems(subMenu));
} else if (menuItem.getItemId() != TRANSLATE) { } else if (menuItem.getItemId() != TRANSLATE && (menuItem.getItemId() != R.id.menu_regular || premiumLockClickListener == null)) {
menuItems.add(menuItem); menuItems.add(menuItem);
} }
} }
@ -237,6 +252,16 @@ public final class FloatingToolbar {
mWindowView.removeOnLayoutChangeListener(mOrientationChangeHandler); mWindowView.removeOnLayoutChangeListener(mOrientationChangeHandler);
} }
private static final List<Integer> premiumOptions = Arrays.asList(
R.id.menu_bold,
R.id.menu_italic,
R.id.menu_strike,
R.id.menu_link,
R.id.menu_mono,
R.id.menu_underline,
R.id.menu_spoiler
);
private final class FloatingToolbarPopup { private final class FloatingToolbarPopup {
private static final int MIN_OVERFLOW_SIZE = 2; private static final int MIN_OVERFLOW_SIZE = 2;
@ -251,7 +276,10 @@ public final class FloatingToolbar {
private final ViewGroup mContentContainer; private final ViewGroup mContentContainer;
private final ViewGroup mMainPanel; private final ViewGroup mMainPanel;
private final OverflowPanel mOverflowPanel; private final OverflowPanel mOverflowPanel;
private final ImageButton mOverflowButton; private final FrameLayout mOverflowButton;
private final View mOverflowButtonShadow;
private final ImageView mOverflowButtonIcon;
private final TextView mOverflowButtonText;
private final Drawable mArrow; private final Drawable mArrow;
private final Drawable mOverflow; private final Drawable mOverflow;
@ -338,8 +366,52 @@ public final class FloatingToolbar {
mToOverflow = (AnimatedVectorDrawable) mContext.getDrawable(R.drawable.ft_avd_tooverflow_animation).mutate(); mToOverflow = (AnimatedVectorDrawable) mContext.getDrawable(R.drawable.ft_avd_tooverflow_animation).mutate();
mToOverflow.setAutoMirrored(true); mToOverflow.setAutoMirrored(true);
mOverflowButton = createOverflowButton(); mOverflowButton = new FrameLayout(mContext);
mOverflowButtonSize = measure(mOverflowButton); mOverflowButtonIcon = new ImageButton(mContext) {
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (mIsOverflowOpen) {
return false;
}
return super.dispatchTouchEvent(event);
}
};
mOverflowButtonIcon.setLayoutParams(new ViewGroup.LayoutParams(AndroidUtilities.dp(56), AndroidUtilities.dp(48)));
mOverflowButtonIcon.setPaddingRelative(AndroidUtilities.dp(16), AndroidUtilities.dp(12), AndroidUtilities.dp(16), AndroidUtilities.dp(12));
mOverflowButtonIcon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
mOverflowButtonIcon.setImageDrawable(mOverflow);
mOverflowButtonText = new TextView(mContext);
mOverflowButtonText.setText(LocaleController.getString(R.string.Back));
mOverflowButtonText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
mOverflowButtonText.setAlpha(0f);
mOverflowButtonShadow = new View(mContext);
int color;
if (currentStyle == STYLE_DIALOG) {
color = getThemedColor(Theme.key_dialogTextBlack);
mOverflowButtonIcon.setBackground(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector), Theme.RIPPLE_MASK_CIRCLE_20DP));
mOverflowButton.setBackground(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector), Theme.RIPPLE_MASK_ALL));
mOverflowButtonShadow.setBackgroundColor(Theme.multAlpha(getThemedColor(Theme.key_dialogTextBlack), .4f));
} else if (currentStyle == STYLE_BLACK) {
color = 0xfffafafa;
mOverflowButtonIcon.setBackground(Theme.createSelectorDrawable(0x20ffffff, Theme.RIPPLE_MASK_CIRCLE_20DP));
mOverflowButton.setBackground(Theme.createSelectorDrawable(0x20ffffff, Theme.RIPPLE_MASK_ALL));
mOverflowButtonShadow.setBackgroundColor(0xff000000);
} else {
color = getThemedColor(Theme.key_windowBackgroundWhiteBlackText);
mOverflowButtonIcon.setBackground(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector), Theme.RIPPLE_MASK_CIRCLE_20DP));
mOverflowButton.setBackground(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector), Theme.RIPPLE_MASK_ALL));
mOverflowButtonShadow.setBackgroundColor(getThemedColor(Theme.key_divider));
}
mOverflow.setTint(color);
mArrow.setTint(color);
mToArrow.setTint(color);
mToOverflow.setTint(color);
mOverflowButtonText.setTextColor(color);
mOverflowButtonIcon.setOnClickListener(v -> onBackPressed());
mOverflowButton.addView(mOverflowButtonIcon, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.LEFT));
mOverflowButton.addView(mOverflowButtonText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.LEFT, 56, 0, 0, 0));
mOverflowButton.addView(mOverflowButtonShadow, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 1f / AndroidUtilities.density, Gravity.TOP | Gravity.FILL_HORIZONTAL));
mOverflowButtonSize = measure(mOverflowButtonIcon);
mMainPanel = createMainPanel(); mMainPanel = createMainPanel();
mOverflowPanelViewHelper = new OverflowPanelViewHelper(mContext, mIconTextSpacing); mOverflowPanelViewHelper = new OverflowPanelViewHelper(mContext, mIconTextSpacing);
mOverflowPanel = createOverflowPanel(); mOverflowPanel = createOverflowPanel();
@ -369,6 +441,26 @@ public final class FloatingToolbar {
}); });
} }
private void onBackPressed() {
if (mIsOverflowOpen) {
mOverflowButtonIcon.setImageDrawable(mToOverflow);
mToOverflow.start();
closeOverflow();
mOverflowButton.setClickable(false);
mOverflowButton.setOnClickListener(null);
mOverflowButtonIcon.setClickable(true);
mOverflowButtonIcon.setOnClickListener(v -> onBackPressed());
} else {
mOverflowButtonIcon.setImageDrawable(mToArrow);
mToArrow.start();
openOverflow();
mOverflowButton.setClickable(true);
mOverflowButton.setOnClickListener(v -> onBackPressed());
mOverflowButtonIcon.setClickable(false);
mOverflowButtonIcon.setOnClickListener(null);
}
}
public boolean setOutsideTouchable(boolean outsideTouchable, PopupWindow.OnDismissListener onDismiss) { public boolean setOutsideTouchable(boolean outsideTouchable, PopupWindow.OnDismissListener onDismiss) {
boolean ret = false; boolean ret = false;
if (mPopupWindow.isOutsideTouchable() ^ outsideTouchable) { if (mPopupWindow.isOutsideTouchable() ^ outsideTouchable) {
@ -562,7 +654,7 @@ public final class FloatingToolbar {
} }
}; };
final float overflowButtonStartX = mOverflowButton.getX(); final float overflowButtonStartX = mOverflowButton.getX();
final float overflowButtonTargetX = isInRTLMode() ? overflowButtonStartX + targetWidth - mOverflowButton.getWidth() : overflowButtonStartX - targetWidth + mOverflowButton.getWidth(); final float overflowButtonTargetX = isInRTLMode() ? overflowButtonStartX + targetWidth - mOverflowButtonIcon.getWidth() : overflowButtonStartX - targetWidth + mOverflowButtonIcon.getWidth();
Animation overflowButtonAnimation = new Animation() { Animation overflowButtonAnimation = new Animation() {
@Override @Override
protected void applyTransformation(float interpolatedTime, Transformation t) { protected void applyTransformation(float interpolatedTime, Transformation t) {
@ -570,6 +662,8 @@ public final class FloatingToolbar {
float deltaContainerWidth = isInRTLMode() ? 0 : mContentContainer.getWidth() - startWidth; float deltaContainerWidth = isInRTLMode() ? 0 : mContentContainer.getWidth() - startWidth;
float actualOverflowButtonX = overflowButtonX + deltaContainerWidth; float actualOverflowButtonX = overflowButtonX + deltaContainerWidth;
mOverflowButton.setX(actualOverflowButtonX); mOverflowButton.setX(actualOverflowButtonX);
mOverflowButtonText.setAlpha(interpolatedTime);
mOverflowButtonShadow.setAlpha(interpolatedTime);
} }
}; };
widthAnimation.setInterpolator(mLogAccelerateInterpolator); widthAnimation.setInterpolator(mLogAccelerateInterpolator);
@ -585,6 +679,9 @@ public final class FloatingToolbar {
mContentContainer.startAnimation(mOpenOverflowAnimation); mContentContainer.startAnimation(mOpenOverflowAnimation);
mIsOverflowOpen = true; mIsOverflowOpen = true;
mMainPanel.animate().alpha(0).withLayer().setInterpolator(mLinearOutSlowInInterpolator).setDuration(250).start(); mMainPanel.animate().alpha(0).withLayer().setInterpolator(mLinearOutSlowInInterpolator).setDuration(250).start();
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) mOverflowButton.getLayoutParams();
lp.width = mOverflowPanel.getWidth();
mOverflowButton.setLayoutParams(lp);
mOverflowPanel.setAlpha(1); mOverflowPanel.setAlpha(1);
} }
@ -624,7 +721,7 @@ public final class FloatingToolbar {
} }
}; };
final float overflowButtonStartX = mOverflowButton.getX(); final float overflowButtonStartX = mOverflowButton.getX();
final float overflowButtonTargetX = isInRTLMode() ? overflowButtonStartX - startWidth + mOverflowButton.getWidth() : overflowButtonStartX + startWidth - mOverflowButton.getWidth(); final float overflowButtonTargetX = isInRTLMode() ? overflowButtonStartX - startWidth + mOverflowButtonIcon.getWidth() : overflowButtonStartX + startWidth - mOverflowButtonIcon.getWidth();
Animation overflowButtonAnimation = new Animation() { Animation overflowButtonAnimation = new Animation() {
@Override @Override
protected void applyTransformation(float interpolatedTime, Transformation t) { protected void applyTransformation(float interpolatedTime, Transformation t) {
@ -632,6 +729,8 @@ public final class FloatingToolbar {
float deltaContainerWidth = isInRTLMode() ? 0 : mContentContainer.getWidth() - startWidth; float deltaContainerWidth = isInRTLMode() ? 0 : mContentContainer.getWidth() - startWidth;
float actualOverflowButtonX = overflowButtonX + deltaContainerWidth; float actualOverflowButtonX = overflowButtonX + deltaContainerWidth;
mOverflowButton.setX(actualOverflowButtonX); mOverflowButton.setX(actualOverflowButtonX);
mOverflowButtonText.setAlpha(1f - interpolatedTime);
mOverflowButtonShadow.setAlpha(1f - interpolatedTime);
} }
}; };
widthAnimation.setInterpolator(mFastOutSlowInInterpolator); widthAnimation.setInterpolator(mFastOutSlowInInterpolator);
@ -668,7 +767,7 @@ public final class FloatingToolbar {
mMainPanel.setVisibility(View.INVISIBLE); mMainPanel.setVisibility(View.INVISIBLE);
mOverflowPanel.setAlpha(1); mOverflowPanel.setAlpha(1);
mOverflowPanel.setVisibility(View.VISIBLE); mOverflowPanel.setVisibility(View.VISIBLE);
mOverflowButton.setImageDrawable(mArrow); mOverflowButtonIcon.setImageDrawable(mArrow);
mOverflowButton.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions)); mOverflowButton.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions));
if (isInRTLMode()) { if (isInRTLMode()) {
@ -700,7 +799,7 @@ public final class FloatingToolbar {
mMainPanel.setVisibility(View.VISIBLE); mMainPanel.setVisibility(View.VISIBLE);
mOverflowPanel.setAlpha(0); mOverflowPanel.setAlpha(0);
mOverflowPanel.setVisibility(View.INVISIBLE); mOverflowPanel.setVisibility(View.INVISIBLE);
mOverflowButton.setImageDrawable(mOverflow); mOverflowButtonIcon.setImageDrawable(mOverflow);
mOverflowButton.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions)); mOverflowButton.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions));
if (hasOverflow()) { if (hasOverflow()) {
if (isInRTLMode()) { if (isInRTLMode()) {
@ -832,9 +931,15 @@ public final class FloatingToolbar {
mMainPanel.removeAllViews(); mMainPanel.removeAllViews();
mMainPanel.setPaddingRelative(0, 0, 0, 0); mMainPanel.setPaddingRelative(0, 0, 0, 0);
boolean isFirstItem = true; boolean isFirstItem = true;
while (!remainingMenuItems.isEmpty()) { Iterator<MenuItem> it = remainingMenuItems.iterator();
final MenuItem menuItem = remainingMenuItems.peek(); while (it.hasNext()) {
boolean isLastItem = remainingMenuItems.size() == 1; final MenuItem menuItem = it.next();
boolean isLastItem = !it.hasNext();
if (menuItem != null && premiumLockClickListener != null) {
if (premiumOptions.contains(menuItem.getItemId())) {
continue;
}
}
/*if (!isFirstItem && menuItem.requiresOverflow()) { /*if (!isFirstItem && menuItem.requiresOverflow()) {
break; break;
}*/ }*/
@ -855,7 +960,7 @@ public final class FloatingToolbar {
params.width = menuItemButtonWidth; params.width = menuItemButtonWidth;
menuItemButton.setLayoutParams(params); menuItemButton.setLayoutParams(params);
availableWidth -= menuItemButtonWidth; availableWidth -= menuItemButtonWidth;
remainingMenuItems.pop(); it.remove();
} else { } else {
break; break;
} }
@ -876,6 +981,13 @@ public final class FloatingToolbar {
private void layoutOverflowPanelItems(List<MenuItem> menuItems) { private void layoutOverflowPanelItems(List<MenuItem> menuItems) {
ArrayAdapter<MenuItem> overflowPanelAdapter = (ArrayAdapter<MenuItem>) mOverflowPanel.getAdapter(); ArrayAdapter<MenuItem> overflowPanelAdapter = (ArrayAdapter<MenuItem>) mOverflowPanel.getAdapter();
overflowPanelAdapter.clear(); overflowPanelAdapter.clear();
if (premiumLockClickListener != null) {
Collections.sort(menuItems, (a, b) -> {
final int aPremium = premiumOptions.contains(a.getItemId()) ? 1 : 0;
final int bPremium = premiumOptions.contains(b.getItemId()) ? 1 : 0;
return aPremium - bPremium;
});
}
final int size = menuItems.size(); final int size = menuItems.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
overflowPanelAdapter.add(menuItems.get(i)); overflowPanelAdapter.add(menuItems.get(i));
@ -987,40 +1099,7 @@ public final class FloatingToolbar {
}; };
} }
private ImageButton createOverflowButton() { private int shiftDp = -4;
final ImageButton overflowButton = new ImageButton(mContext);
overflowButton.setLayoutParams(new ViewGroup.LayoutParams(AndroidUtilities.dp(56), AndroidUtilities.dp(48)));
overflowButton.setPaddingRelative(AndroidUtilities.dp(16), AndroidUtilities.dp(12), AndroidUtilities.dp(16), AndroidUtilities.dp(12));
overflowButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
overflowButton.setImageDrawable(mOverflow);
int color;
if (currentStyle == STYLE_DIALOG) {
color = getThemedColor(Theme.key_dialogTextBlack);
overflowButton.setBackgroundDrawable(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector), 1));
} else if (currentStyle == STYLE_BLACK) {
color = 0xfffafafa;
overflowButton.setBackgroundDrawable(Theme.createSelectorDrawable(0x40ffffff, 1));
} else {
color = getThemedColor(Theme.key_windowBackgroundWhiteBlackText);
overflowButton.setBackgroundDrawable(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector), 1));
}
mOverflow.setTint(color);
mArrow.setTint(color);
mToArrow.setTint(color);
mToOverflow.setTint(color);
overflowButton.setOnClickListener(v -> {
if (mIsOverflowOpen) {
overflowButton.setImageDrawable(mToOverflow);
mToOverflow.start();
closeOverflow();
} else {
overflowButton.setImageDrawable(mToArrow);
mToArrow.start();
openOverflow();
}
});
return overflowButton;
}
private OverflowPanel createOverflowPanel() { private OverflowPanel createOverflowPanel() {
final OverflowPanel overflowPanel = new OverflowPanel(this); final OverflowPanel overflowPanel = new OverflowPanel(this);
@ -1036,7 +1115,11 @@ public final class FloatingToolbar {
overflowPanel.setAdapter(adapter); overflowPanel.setAdapter(adapter);
overflowPanel.setOnItemClickListener((parent, view, position, id) -> { overflowPanel.setOnItemClickListener((parent, view, position, id) -> {
MenuItem menuItem = (MenuItem) overflowPanel.getAdapter().getItem(position); MenuItem menuItem = (MenuItem) overflowPanel.getAdapter().getItem(position);
if (mOnMenuItemClickListener != null) { if (premiumLockClickListener != null && premiumOptions.contains(menuItem.getItemId())) {
AndroidUtilities.shakeViewSpring(view, shiftDp = -shiftDp);
BotWebViewVibrationEffect.APP_ERROR.vibrate();
premiumLockClickListener.run();
} else if (mOnMenuItemClickListener != null) {
mOnMenuItemClickListener.onMenuItemClick(menuItem); mOnMenuItemClickListener.onMenuItemClick(menuItem);
} }
}); });
@ -1167,7 +1250,7 @@ public final class FloatingToolbar {
public View getView(MenuItem menuItem, int minimumWidth, View convertView) { public View getView(MenuItem menuItem, int minimumWidth, View convertView) {
if (convertView != null) { if (convertView != null) {
updateMenuItemButton(convertView, menuItem, mIconTextSpacing); updateMenuItemButton(convertView, menuItem, mIconTextSpacing, premiumLockClickListener != null);
} else { } else {
convertView = createMenuButton(menuItem); convertView = createMenuButton(menuItem);
} }
@ -1176,7 +1259,7 @@ public final class FloatingToolbar {
} }
public int calculateWidth(MenuItem menuItem) { public int calculateWidth(MenuItem menuItem) {
updateMenuItemButton(mCalculator, menuItem, mIconTextSpacing); updateMenuItemButton(mCalculator, menuItem, mIconTextSpacing, premiumLockClickListener != null);
mCalculator.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); mCalculator.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
return mCalculator.getMeasuredWidth(); return mCalculator.getMeasuredWidth();
} }
@ -1206,30 +1289,43 @@ public final class FloatingToolbar {
textView.setFocusable(false); textView.setFocusable(false);
textView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); textView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
textView.setFocusableInTouchMode(false); textView.setFocusableInTouchMode(false);
int color;
int selectorColor = getThemedColor(Theme.key_listSelector); int selectorColor = getThemedColor(Theme.key_listSelector);
if (currentStyle == STYLE_DIALOG) { if (currentStyle == STYLE_DIALOG) {
textView.setTextColor(getThemedColor(Theme.key_dialogTextBlack)); textView.setTextColor(color = getThemedColor(Theme.key_dialogTextBlack));
} else if (currentStyle == STYLE_BLACK) { } else if (currentStyle == STYLE_BLACK) {
textView.setTextColor(0xfffafafa); textView.setTextColor(color = 0xfffafafa);
selectorColor = 0x40ffffff; selectorColor = 0x20ffffff;
} else if (currentStyle == STYLE_THEME) { } else if (currentStyle == STYLE_THEME) {
textView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText)); textView.setTextColor(color = getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
} else {
color = getThemedColor(Theme.key_windowBackgroundWhiteBlackText);
} }
if (first || last) { if (first || last) {
menuItemButton.setBackgroundDrawable(Theme.createRadSelectorDrawable(selectorColor, first ? 6 : 0, last ? 6 : 0, last ? 6 : 0, first ? 6 : 0)); menuItemButton.setBackground(Theme.createRadSelectorDrawable(selectorColor, first ? 6 : 0, last ? 6 : 0, last ? 6 : 0, first ? 6 : 0));
} else { } else {
menuItemButton.setBackgroundDrawable(Theme.getSelectorDrawable(selectorColor, false)); menuItemButton.setBackground(Theme.getSelectorDrawable(selectorColor, false));
} }
textView.setPaddingRelative(AndroidUtilities.dp(11), 0, 0, 0); textView.setPaddingRelative(AndroidUtilities.dp(11), 0, 0, 0);
menuItemButton.addView(textView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, AndroidUtilities.dp(48))); menuItemButton.addView(textView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, AndroidUtilities.dp(48)));
menuItemButton.addView(new Space(context), new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1, 1));
ImageView lockView = new ImageView(context);
lockView.setImageResource(R.drawable.msg_mini_lock3);
lockView.setScaleType(ImageView.ScaleType.CENTER);
lockView.setColorFilter(new PorterDuffColorFilter(Theme.multAlpha(color, .4f), PorterDuff.Mode.SRC_IN));
lockView.setVisibility(View.GONE);
menuItemButton.addView(lockView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, 0, 0, 12, 0, 0, 0));
if (menuItem != null) { if (menuItem != null) {
updateMenuItemButton(menuItemButton, menuItem, iconTextSpacing); updateMenuItemButton(menuItemButton, menuItem, iconTextSpacing, premiumLockClickListener != null);
} }
return menuItemButton; return menuItemButton;
} }
private static void updateMenuItemButton(View menuItemButton, MenuItem menuItem, int iconTextSpacing) { private static void updateMenuItemButton(View menuItemButton, MenuItem menuItem, int iconTextSpacing, boolean containsPremium) {
ViewGroup viewGroup = (ViewGroup) menuItemButton; ViewGroup viewGroup = (ViewGroup) menuItemButton;
final TextView buttonText = (TextView) viewGroup.getChildAt(0); final TextView buttonText = (TextView) viewGroup.getChildAt(0);
buttonText.setEllipsize(null); buttonText.setEllipsize(null);
@ -1240,6 +1336,9 @@ public final class FloatingToolbar {
buttonText.setText(menuItem.getTitle()); buttonText.setText(menuItem.getTitle());
} }
buttonText.setPaddingRelative(0, 0, 0, 0); buttonText.setPaddingRelative(0, 0, 0, 0);
final boolean premium = containsPremium && premiumOptions.contains(menuItem.getItemId());
viewGroup.getChildAt(2).setVisibility(premium ? View.VISIBLE : View.GONE);
/*final CharSequence contentDescription = menuItem.getContentDescription(); TODO /*final CharSequence contentDescription = menuItem.getContentDescription(); TODO
if (TextUtils.isEmpty(contentDescription)) { if (TextUtils.isEmpty(contentDescription)) {
menuItemButton.setContentDescription(menuItem.getTitle()); menuItemButton.setContentDescription(menuItem.getTitle());

View file

@ -161,8 +161,8 @@ public class SimpleTextView extends View implements Drawable.Callback {
wasLayout = false; wasLayout = false;
} }
public void setTextSize(int size) { public void setTextSize(int sizeInDp) {
int newSize = AndroidUtilities.dp(size); int newSize = AndroidUtilities.dp(sizeInDp);
if (newSize == textPaint.getTextSize()) { if (newSize == textPaint.getTextSize()) {
return; return;
} }

View file

@ -4015,6 +4015,13 @@ public class Theme {
public static final int key_topics_unreadCounter = colorsCount++; public static final int key_topics_unreadCounter = colorsCount++;
public static final int key_topics_unreadCounterMuted = colorsCount++; public static final int key_topics_unreadCounterMuted = colorsCount++;
public static final int key_stories_circle1 = colorsCount++;
public static final int key_stories_circle2 = colorsCount++;
public static final int key_stories_circle_dialog1 = colorsCount++;
public static final int key_stories_circle_dialog2 = colorsCount++;
public static final int key_stories_circle_closeFriends1 = colorsCount++;
public static final int key_stories_circle_closeFriends2 = colorsCount++;
public static final String key_drawable_botInline = "drawableBotInline"; public static final String key_drawable_botInline = "drawableBotInline";
public static final String key_drawable_botLink = "drawableBotLink"; public static final String key_drawable_botLink = "drawableBotLink";
public static final String key_drawable_botWebView = "drawableBotWebView"; public static final String key_drawable_botWebView = "drawableBotWebView";
@ -4357,6 +4364,13 @@ public class Theme {
themeAccentExclusionKeys.add(key_premiumStartSmallStarsColor); themeAccentExclusionKeys.add(key_premiumStartSmallStarsColor);
themeAccentExclusionKeys.add(key_premiumStartGradient1); themeAccentExclusionKeys.add(key_premiumStartGradient1);
themeAccentExclusionKeys.add(key_premiumStartGradient2); themeAccentExclusionKeys.add(key_premiumStartGradient2);
themeAccentExclusionKeys.add(key_stories_circle1);
themeAccentExclusionKeys.add(key_stories_circle2);
themeAccentExclusionKeys.add(key_stories_circle_dialog1);
themeAccentExclusionKeys.add(key_stories_circle_dialog2);
themeAccentExclusionKeys.add(key_stories_circle_closeFriends1);
themeAccentExclusionKeys.add(key_stories_circle_closeFriends2);
themes = new ArrayList<>(); themes = new ArrayList<>();
otherThemes = new ArrayList<>(); otherThemes = new ArrayList<>();

View file

@ -760,6 +760,13 @@ public class ThemeColors {
defaultColors[key_topics_unreadCounter] = 0xff4ecc5e; defaultColors[key_topics_unreadCounter] = 0xff4ecc5e;
defaultColors[key_topics_unreadCounterMuted] = 0xff8b8d8f; defaultColors[key_topics_unreadCounterMuted] = 0xff8b8d8f;
defaultColors[key_stories_circle1] = 0xFF39DF3C;
defaultColors[key_stories_circle2] = 0xFF4DBBFF;
defaultColors[key_stories_circle_dialog1] = 0xFF4AED55;
defaultColors[key_stories_circle_dialog2] = 0xFF4DC3FF;
defaultColors[key_stories_circle_closeFriends1] = 0xFFC9EB38;
defaultColors[key_stories_circle_closeFriends2] = 0xFF09C167;
return defaultColors; return defaultColors;
} }
@ -1481,6 +1488,12 @@ public class ThemeColors {
colorKeysMap.put(key_premiumGradientBottomSheet3, "premiumGradientBottomSheet3"); colorKeysMap.put(key_premiumGradientBottomSheet3, "premiumGradientBottomSheet3");
colorKeysMap.put(key_topics_unreadCounter, "topics_unreadCounter"); colorKeysMap.put(key_topics_unreadCounter, "topics_unreadCounter");
colorKeysMap.put(key_topics_unreadCounterMuted, "topics_unreadCounterMuted"); colorKeysMap.put(key_topics_unreadCounterMuted, "topics_unreadCounterMuted");
colorKeysMap.put(key_stories_circle1, "stories_circle1");
colorKeysMap.put(key_stories_circle2, "stories_circle2");
colorKeysMap.put(key_stories_circle_dialog1, "stories_circle_dialog1");
colorKeysMap.put(key_stories_circle_dialog2, "stories_circle_dialog2");
colorKeysMap.put(key_stories_circle_closeFriends1, "stories_circle_closeFriends1");
colorKeysMap.put(key_stories_circle_closeFriends2, "stories_circle_closeFriends2");
return colorKeysMap; return colorKeysMap;
} }

View file

@ -775,7 +775,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
} }
@Override @Override
public void onLocationAddressAvailable(String address, String displayAddress, Location location) { public void onLocationAddressAvailable(String address, String displayAddress, TLRPC.TL_messageMediaVenue city, TLRPC.TL_messageMediaVenue street, Location location) {
if (subtitleTextView == null) { if (subtitleTextView == null) {
return; return;
} }

View file

@ -8,13 +8,20 @@
package org.telegram.ui.Adapters; package org.telegram.ui.Adapters;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location; import android.location.Location;
import android.os.Build; import android.os.Build;
import android.text.TextUtils;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.DialogObject; import org.telegram.messenger.DialogObject;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.LocationController;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
@ -23,17 +30,27 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdapter { public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdapter {
public final boolean stories;
public BaseLocationAdapter(boolean stories) {
this.stories = stories;
}
public interface BaseLocationAdapterDelegate { public interface BaseLocationAdapterDelegate {
void didLoadSearchResult(ArrayList<TLRPC.TL_messageMediaVenue> places); void didLoadSearchResult(ArrayList<TLRPC.TL_messageMediaVenue> places);
} }
protected boolean searched = false; protected boolean searched = false;
protected boolean searching; protected boolean searching;
protected boolean searchingLocations;
protected ArrayList<TLRPC.TL_messageMediaVenue> locations = new ArrayList<>();
protected ArrayList<TLRPC.TL_messageMediaVenue> places = new ArrayList<>(); protected ArrayList<TLRPC.TL_messageMediaVenue> places = new ArrayList<>();
protected ArrayList<String> iconUrls = new ArrayList<>();
private Location lastSearchLocation; private Location lastSearchLocation;
private String lastSearchQuery; private String lastSearchQuery;
private String lastFoundQuery; private String lastFoundQuery;
@ -43,7 +60,7 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
private int currentAccount = UserConfig.selectedAccount; private int currentAccount = UserConfig.selectedAccount;
private long dialogId; private long dialogId;
private boolean searchingUser; private boolean searchingUser;
private boolean searchInProgress; protected boolean searchInProgress;
public void destroy() { public void destroy() {
if (currentRequestNum != 0) { if (currentRequestNum != 0) {
@ -60,6 +77,7 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
public void searchDelayed(final String query, final Location coordinate) { public void searchDelayed(final String query, final Location coordinate) {
if (query == null || query.length() == 0) { if (query == null || query.length() == 0) {
places.clear(); places.clear();
locations.clear();
searchInProgress = false; searchInProgress = false;
notifyDataSetChanged(); notifyDataSetChanged();
} else { } else {
@ -82,7 +100,9 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
} }
searchingUser = true; searchingUser = true;
TLRPC.TL_contacts_resolveUsername req = new TLRPC.TL_contacts_resolveUsername(); TLRPC.TL_contacts_resolveUsername req = new TLRPC.TL_contacts_resolveUsername();
req.username = MessagesController.getInstance(currentAccount).venueSearchBot; req.username = stories ?
MessagesController.getInstance(currentAccount).venueSearchBot : // MessagesController.getInstance(currentAccount).storyVenueSearchBot :
MessagesController.getInstance(currentAccount).venueSearchBot;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> { ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) { if (response != null) {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
@ -118,7 +138,7 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
notifyItemRangeRemoved(fromIndex, getItemCount() - fromIndex); notifyItemRangeRemoved(fromIndex, getItemCount() - fromIndex);
} }
} else { } else {
int placesCount = places.size() + 3; int placesCount = 3 + places.size() + locations.size();
int offset = oldItemCount - placesCount; int offset = oldItemCount - placesCount;
notifyItemInserted(offset); notifyItemInserted(offset);
notifyItemRangeRemoved(offset, placesCount); notifyItemRangeRemoved(offset, placesCount);
@ -129,10 +149,10 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
} }
public void searchPlacesWithQuery(final String query, final Location coordinate, boolean searchUser, boolean animated) { public void searchPlacesWithQuery(final String query, final Location coordinate, boolean searchUser, boolean animated) {
if (coordinate == null || lastSearchLocation != null && coordinate.distanceTo(lastSearchLocation) < 200) { if (coordinate == null && !stories || lastSearchLocation != null && coordinate != null && coordinate.distanceTo(lastSearchLocation) < 200) {
return; return;
} }
lastSearchLocation = new Location(coordinate); lastSearchLocation = coordinate == null ? null : new Location(coordinate);
lastSearchQuery = query; lastSearchQuery = query;
if (searching) { if (searching) {
searching = false; searching = false;
@ -147,7 +167,11 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
boolean wasSearched = searched; boolean wasSearched = searched;
searched = true; searched = true;
TLObject object = MessagesController.getInstance(currentAccount).getUserOrChat(MessagesController.getInstance(currentAccount).venueSearchBot); TLObject object = MessagesController.getInstance(currentAccount).getUserOrChat(
stories ?
MessagesController.getInstance(currentAccount).venueSearchBot : // MessagesController.getInstance(currentAccount).storyVenueSearchBot :
MessagesController.getInstance(currentAccount).venueSearchBot
);
if (!(object instanceof TLRPC.User)) { if (!(object instanceof TLRPC.User)) {
if (searchUser) { if (searchUser) {
searchBotUser(); searchBotUser();
@ -161,10 +185,12 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
req.bot = MessagesController.getInstance(currentAccount).getInputUser(user); req.bot = MessagesController.getInstance(currentAccount).getInputUser(user);
req.offset = ""; req.offset = "";
req.geo_point = new TLRPC.TL_inputGeoPoint(); if (coordinate != null) {
req.geo_point.lat = AndroidUtilities.fixLocationCoord(coordinate.getLatitude()); req.geo_point = new TLRPC.TL_inputGeoPoint();
req.geo_point._long = AndroidUtilities.fixLocationCoord(coordinate.getLongitude()); req.geo_point.lat = AndroidUtilities.fixLocationCoord(coordinate.getLatitude());
req.flags |= 1; req.geo_point._long = AndroidUtilities.fixLocationCoord(coordinate.getLongitude());
req.flags |= 1;
}
if (DialogObject.isEncryptedDialog(dialogId)) { if (DialogObject.isEncryptedDialog(dialogId)) {
req.peer = new TLRPC.TL_inputPeerEmpty(); req.peer = new TLRPC.TL_inputPeerEmpty();
@ -172,12 +198,174 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId); req.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId);
} }
if (!TextUtils.isEmpty(query) && stories) {
searchingLocations = true;
final Locale locale = LocaleController.getInstance().getCurrentLocale();
final String finalQuery = query;
Utilities.globalQueue.postRunnable(() -> {
final ArrayList<TLRPC.TL_messageMediaVenue> locations = new ArrayList<>();
try {
Geocoder geocoder = new Geocoder(ApplicationLoader.applicationContext, locale);
List<Address> addresses = geocoder.getFromLocationName(finalQuery, 5);
HashSet<String> countries = new HashSet<>();
HashSet<String> cities = new HashSet<>();
String arg, lc;
for (int i = 0; i < addresses.size(); ++i) {
Address address = addresses.get(i);
if (!address.hasLatitude() || !address.hasLongitude())
continue;
double lat = address.getLatitude();
double _long = address.getLongitude();
StringBuilder countryBuilder = new StringBuilder();
StringBuilder cityBuilder = new StringBuilder();
StringBuilder streetBuilder = new StringBuilder();
boolean onlyCountry = true;
boolean onlyCity = true;
String locality = address.getLocality();
if (TextUtils.isEmpty(locality)) {
locality = address.getAdminArea();
}
arg = address.getThoroughfare();
if (!TextUtils.isEmpty(arg) && !TextUtils.equals(arg, address.getAdminArea())) {
if (streetBuilder.length() > 0) {
streetBuilder.append(", ");
}
streetBuilder.append(arg);
onlyCity = false;
} else {
arg = address.getSubLocality();
if (!TextUtils.isEmpty(arg)) {
if (streetBuilder.length() > 0) {
streetBuilder.append(", ");
}
streetBuilder.append(arg);
onlyCity = false;
} else {
arg = address.getLocality();
if (!TextUtils.isEmpty(arg) && !TextUtils.equals(arg, locality)) {
if (streetBuilder.length() > 0) {
streetBuilder.append(", ");
}
streetBuilder.append(arg);
onlyCity = false;
} else {
streetBuilder = null;
}
}
}
if (!TextUtils.isEmpty(locality)) {
if (cityBuilder.length() > 0) {
cityBuilder.append(", ");
}
cityBuilder.append(locality);
onlyCountry = false;
if (streetBuilder != null) {
if (streetBuilder.length() > 0) {
streetBuilder.append(", ");
}
streetBuilder.append(locality);
}
}
arg = address.getCountryName();
if (!TextUtils.isEmpty(arg)) {
String shortCountry = arg;
if ("US".equals(address.getCountryCode()) || "AE".equals(address.getCountryCode()) || "GB".equals(address.getCountryCode()) && "en".equals(locale.getLanguage())) {
shortCountry = "";
String[] words = arg.split(" ");
for (String word : words) {
if (word.length() > 0)
shortCountry += word.charAt(0);
}
}
if (cityBuilder.length() > 0) {
cityBuilder.append(", ");
}
cityBuilder.append(shortCountry);
if (countryBuilder.length() > 0) {
countryBuilder.append(", ");
}
countryBuilder.append(arg);
}
if (countryBuilder.length() > 0 && !countries.contains(countryBuilder.toString())) {
TLRPC.TL_messageMediaVenue countryLocation = new TLRPC.TL_messageMediaVenue();
countryLocation.geo = new TLRPC.TL_geoPoint();
countryLocation.geo.lat = lat;
countryLocation.geo._long = _long;
countryLocation.query_id = -1;
countryLocation.title = countryBuilder.toString();
countryLocation.icon = "https://ss3.4sqi.net/img/categories_v2/building/government_capitolbuilding_64.png";
countryLocation.emoji = LocationController.countryCodeToEmoji(address.getCountryCode());
countries.add(countryLocation.title);
countryLocation.address = LocaleController.getString("Country", R.string.Country);
locations.add(countryLocation);
if (locations.size() >= 5) {
break;
}
}
if (!onlyCountry && !cities.contains(cityBuilder.toString())) {
TLRPC.TL_messageMediaVenue cityLocation = new TLRPC.TL_messageMediaVenue();
cityLocation.geo = new TLRPC.TL_geoPoint();
cityLocation.geo.lat = lat;
cityLocation.geo._long = _long;
cityLocation.query_id = -1;
cityLocation.title = cityBuilder.toString();
cityLocation.icon = "https://ss3.4sqi.net/img/categories_v2/travel/hotel_64.png";
cityLocation.emoji = LocationController.countryCodeToEmoji(address.getCountryCode());
cities.add(cityLocation.title);
cityLocation.address = LocaleController.getString("PassportCity", R.string.PassportCity);
locations.add(cityLocation);
if (locations.size() >= 5) {
break;
}
}
if (streetBuilder != null && streetBuilder.length() > 0) {
TLRPC.TL_messageMediaVenue streetLocation = new TLRPC.TL_messageMediaVenue();
streetLocation.geo = new TLRPC.TL_geoPoint();
streetLocation.geo.lat = lat;
streetLocation.geo._long = _long;
streetLocation.query_id = -1;
streetLocation.title = streetBuilder.toString();
streetLocation.icon = "pin";
streetLocation.address = onlyCity ? LocaleController.getString("PassportCity", R.string.PassportCity) : LocaleController.getString("PassportStreet1", R.string.PassportStreet1);
locations.add(streetLocation);
if (locations.size() >= 5) {
break;
}
}
}
} catch (Exception ignore) {}
AndroidUtilities.runOnUIThread(() -> {
searchingLocations = false;
if (coordinate == null) {
currentRequestNum = 0;
searching = false;
places.clear();
searchInProgress = false;
lastFoundQuery = query;
}
BaseLocationAdapter.this.locations.clear();
BaseLocationAdapter.this.locations.addAll(locations);
notifyDataSetChanged();
});
});
} else {
searchingLocations = false;
}
if (coordinate == null) {
return;
}
currentRequestNum = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { currentRequestNum = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (error == null) { if (error == null) {
currentRequestNum = 0; currentRequestNum = 0;
searching = false; searching = false;
places.clear(); places.clear();
iconUrls.clear();
searchInProgress = false; searchInProgress = false;
lastFoundQuery = query; lastFoundQuery = query;
@ -188,14 +376,16 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
continue; continue;
} }
TLRPC.TL_botInlineMessageMediaVenue mediaVenue = (TLRPC.TL_botInlineMessageMediaVenue) result.send_message; TLRPC.TL_botInlineMessageMediaVenue mediaVenue = (TLRPC.TL_botInlineMessageMediaVenue) result.send_message;
iconUrls.add("https://ss3.4sqi.net/img/categories_v2/" + mediaVenue.venue_type + "_64.png");
TLRPC.TL_messageMediaVenue venue = new TLRPC.TL_messageMediaVenue(); TLRPC.TL_messageMediaVenue venue = new TLRPC.TL_messageMediaVenue();
venue.geo = mediaVenue.geo; venue.geo = mediaVenue.geo;
venue.address = mediaVenue.address; venue.address = mediaVenue.address;
venue.title = mediaVenue.title; venue.title = mediaVenue.title;
venue.icon = "https://ss3.4sqi.net/img/categories_v2/" + mediaVenue.venue_type + "_64.png";
venue.venue_type = mediaVenue.venue_type; venue.venue_type = mediaVenue.venue_type;
venue.venue_id = mediaVenue.venue_id; venue.venue_id = mediaVenue.venue_id;
venue.provider = mediaVenue.provider; venue.provider = mediaVenue.provider;
venue.query_id = res.query_id;
venue.result_id = result.id;
places.add(venue); places.add(venue);
} }
} }

View file

@ -94,7 +94,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
VIEW_TYPE_HEADER = 7, VIEW_TYPE_HEADER = 7,
VIEW_TYPE_SHADOW = 8, VIEW_TYPE_SHADOW = 8,
// VIEW_TYPE_ARCHIVE = 9, // VIEW_TYPE_ARCHIVE = 9,
VIEW_TYPE_LAST_EMPTY = 10, VIEW_TYPE_LAST_EMPTY = 10,
VIEW_TYPE_NEW_CHAT_HINT = 11, VIEW_TYPE_NEW_CHAT_HINT = 11,
VIEW_TYPE_TEXT = 12, VIEW_TYPE_TEXT = 12,
VIEW_TYPE_CONTACTS_FLICKER = 13, VIEW_TYPE_CONTACTS_FLICKER = 13,
@ -312,7 +312,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
public ItemInternal(int viewTypeEmpty) { public ItemInternal(int viewTypeEmpty) {
super(viewTypeEmpty, true); super(viewTypeEmpty, true);
this.emptyType = emptyType; this.emptyType = viewTypeEmpty;
if (viewTypeEmpty == VIEW_TYPE_LAST_EMPTY) { if (viewTypeEmpty == VIEW_TYPE_LAST_EMPTY) {
stableId = 1; stableId = 1;
} else { } else {
@ -728,14 +728,6 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
case VIEW_TYPE_FOLDER_UPDATE_HINT: case VIEW_TYPE_FOLDER_UPDATE_HINT:
view = new DialogsHintCell(mContext); view = new DialogsHintCell(mContext);
break; break;
case VIEW_TYPE_TEXT:
default: {
view = new TextCell(mContext);
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
}
break;
}
case VIEW_TYPE_STORIES: { case VIEW_TYPE_STORIES: {
view = new View(mContext) { view = new View(mContext) {
@Override @Override
@ -745,6 +737,14 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}; };
break; break;
} }
case VIEW_TYPE_TEXT:
default: {
view = new TextCell(mContext);
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
}
break;
}
} }
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, viewType == VIEW_TYPE_EMPTY || viewType == VIEW_TYPE_ARCHIVE_FULLSCREEN ? RecyclerView.LayoutParams.MATCH_PARENT : RecyclerView.LayoutParams.WRAP_CONTENT)); view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, viewType == VIEW_TYPE_EMPTY || viewType == VIEW_TYPE_ARCHIVE_FULLSCREEN ? RecyclerView.LayoutParams.MATCH_PARENT : RecyclerView.LayoutParams.WRAP_CONTENT));
return new RecyclerListView.Holder(view); return new RecyclerListView.Holder(view);
@ -955,6 +955,9 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
break; break;
} }
case VIEW_TYPE_TEXT: { case VIEW_TYPE_TEXT: {
if (!(holder.itemView instanceof TextCell)) {
return;
}
TextCell cell = (TextCell) holder.itemView; TextCell cell = (TextCell) holder.itemView;
cell.setColors(Theme.key_windowBackgroundWhiteBlueText4, Theme.key_windowBackgroundWhiteBlueText4); cell.setColors(Theme.key_windowBackgroundWhiteBlueText4, Theme.key_windowBackgroundWhiteBlueText4);
if (requestPeerType != null) { if (requestPeerType != null) {
@ -1107,7 +1110,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
} }
} }
parentFragment.getOrCreateStoryViewer().open(mContext, null, peerIds, 0, null, null, StoriesListPlaceProvider.of(recyclerListView, true), false); parentFragment.getOrCreateStoryViewer().open(mContext, null, peerIds, 0, null, null, StoriesListPlaceProvider.of(recyclerListView), false);
} }
public void setIsTransitionSupport() { public void setIsTransitionSupport() {
@ -1307,6 +1310,8 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
} else { } else {
dialogsHeight += cellHeight; dialogsHeight += cellHeight;
} }
} else if (itemInternals.get(i).viewType == VIEW_TYPE_FLICKER) {
dialogsHeight += cellHeight;
} }
} }
dialogsHeight += size - 1; dialogsHeight += size - 1;
@ -1480,6 +1485,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
if (dialogsCount != 0) { if (dialogsCount != 0) {
itemInternals.add(new ItemInternal(VIEW_TYPE_FLICKER)); itemInternals.add(new ItemInternal(VIEW_TYPE_FLICKER));
} }
itemInternals.add(new ItemInternal(VIEW_TYPE_LAST_EMPTY));
} else if (dialogsCount == 0) { } else if (dialogsCount == 0) {
isEmpty = true; isEmpty = true;
if (requestPeerType != null) { if (requestPeerType != null) {

View file

@ -17,6 +17,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.LocationController; import org.telegram.messenger.LocationController;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
@ -32,6 +33,7 @@ import org.telegram.ui.Cells.LocationPoweredCell;
import org.telegram.ui.Cells.SendLocationCell; import org.telegram.ui.Cells.SendLocationCell;
import org.telegram.ui.Cells.ShadowSectionCell; import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.SharingLiveLocationCell; import org.telegram.ui.Cells.SharingLiveLocationCell;
import org.telegram.ui.Components.ChatAttachAlertLocationLayout;
import org.telegram.ui.Components.CombinedDrawable; import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.FlickerLoadingView; import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
@ -64,25 +66,30 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
private Runnable updateRunnable; private Runnable updateRunnable;
private final Theme.ResourcesProvider resourcesProvider; private final Theme.ResourcesProvider resourcesProvider;
private FlickerLoadingView globalGradientView; public boolean animated = true;
public TLRPC.TL_messageMediaVenue city, street;
public LocationActivityAdapter(Context context, int type, long did, boolean emptyView, Theme.ResourcesProvider resourcesProvider, boolean stories) {
super(stories);
public LocationActivityAdapter(Context context, int type, long did, boolean emptyView, Theme.ResourcesProvider resourcesProvider) {
super();
mContext = context; mContext = context;
locationType = type; locationType = type;
dialogId = did; dialogId = did;
needEmptyView = emptyView; needEmptyView = emptyView;
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
globalGradientView = new FlickerLoadingView(context);
globalGradientView.setIsSingleCell(true);
} }
private boolean myLocationDenied = false; private boolean myLocationDenied = false;
public void setMyLocationDenied(boolean myLocationDenied) { private boolean askingForMyLocation = false;
if (this.myLocationDenied == myLocationDenied) public void setMyLocationDenied(boolean myLocationDenied, boolean askingForLocation) {
if (this.myLocationDenied == myLocationDenied && this.askingForMyLocation == askingForLocation)
return; return;
this.myLocationDenied = myLocationDenied; this.myLocationDenied = myLocationDenied;
this.askingForMyLocation = askingForLocation;
if (askingForMyLocation) {
city = null;
street = null;
}
notifyDataSetChanged(); notifyDataSetChanged();
} }
@ -200,11 +207,33 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
} }
@Override @Override
public void onLocationAddressAvailable(String address, String displayAddress, Location location) { public void onLocationAddressAvailable(String address, String displayAddress, TLRPC.TL_messageMediaVenue city, TLRPC.TL_messageMediaVenue street, Location location) {
fetchingLocation = false; fetchingLocation = false;
previousFetchedLocation = location; previousFetchedLocation = location;
addressName = address; addressName = address;
updateCell();
if (locationType == ChatAttachAlertLocationLayout.LOCATION_TYPE_STORY && askingForMyLocation) {
this.city = null;
this.street = null;
}
boolean wasStreet = this.street != null;
if (locationType == ChatAttachAlertLocationLayout.LOCATION_TYPE_STORY) {
this.city = city;
this.street = street;
if (wasStreet == (this.street == null)) {
notifyItemChanged(1);
if (this.street == null) {
notifyItemRemoved(2);
} else {
notifyItemInserted(2);
}
} else {
notifyItemRangeChanged(1, 2);
}
} else {
updateCell();
}
} }
protected void onDirectionClick() { protected void onDirectionClick() {
@ -257,9 +286,21 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
return 2 + currentLiveLocations.size(); return 2 + currentLiveLocations.size();
} else { } else {
if (searching || !searched || places.isEmpty()) { if (searching || !searched || places.isEmpty()) {
return (locationType != LocationActivity.LOCATION_TYPE_SEND ? 6 : 5) + (!myLocationDenied && (searching || !searched) ? 2 : 0) + (needEmptyView ? 1 : 0) - (myLocationDenied ? 2 : 0); int count = 6;
if (locationType == LocationActivity.LOCATION_TYPE_SEND) {
count = 5;
} else if (locationType == ChatAttachAlertLocationLayout.LOCATION_TYPE_STORY) {
count = 5 + (this.street != null ? 1 : 0);
}
return count + (!myLocationDenied && (searching || !searched) ? 2 : 0) + (needEmptyView ? 1 : 0) - (myLocationDenied ? 2 : 0);
} }
return (locationType == LocationActivity.LOCATION_TYPE_SEND_WITH_LIVE ? 6 : 5) + places.size() + (needEmptyView ? 1 : 0); int count = 5;
if (locationType == LocationActivity.LOCATION_TYPE_SEND_WITH_LIVE) {
count = 6;
} else if (locationType == ChatAttachAlertLocationLayout.LOCATION_TYPE_STORY) {
count = 5;// + (this.street != null ? 1 : 0);
}
return count + locations.size() + places.size() + (needEmptyView ? 1 : 0);
} }
} }
@ -269,7 +310,7 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view; View view;
switch (viewType) { switch (viewType) {
case 0: case VIEW_TYPE_PADDING:
// view = emptyCell = new EmptyCell(mContext) { // view = emptyCell = new EmptyCell(mContext) {
// @Override // @Override
// public ViewPropertyAnimator animate() { // public ViewPropertyAnimator animate() {
@ -287,38 +328,38 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
view = emptyCell = new FrameLayout(mContext); view = emptyCell = new FrameLayout(mContext);
emptyCell.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, overScrollHeight)); emptyCell.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, overScrollHeight));
break; break;
case 1: case VIEW_TYPE_SEND_LOCATION:
view = new SendLocationCell(mContext, false, resourcesProvider); view = new SendLocationCell(mContext, false, resourcesProvider);
break; break;
case 2: case VIEW_TYPE_HEADER:
view = new HeaderCell(mContext, resourcesProvider); view = new HeaderCell(mContext, resourcesProvider);
break; break;
case 3: case VIEW_TYPE_LOCATION:
LocationCell locationCell = new LocationCell(mContext, false, resourcesProvider); LocationCell locationCell = new LocationCell(mContext, false, resourcesProvider);
view = locationCell; view = locationCell;
break; break;
case 4: case VIEW_TYPE_LOADING:
view = new LocationLoadingCell(mContext, resourcesProvider); view = new LocationLoadingCell(mContext, resourcesProvider);
break; break;
case 5: case VIEW_TYPE_FOOTER:
view = new LocationPoweredCell(mContext, resourcesProvider); view = new LocationPoweredCell(mContext, resourcesProvider);
break; break;
case 6: { case VIEW_TYPE_LIVE_LOCATION: {
SendLocationCell cell = new SendLocationCell(mContext, true, resourcesProvider); SendLocationCell cell = new SendLocationCell(mContext, true, resourcesProvider);
cell.setDialogId(dialogId); cell.setDialogId(dialogId);
view = cell; view = cell;
break; break;
} }
case 7: case VIEW_TYPE_SHARING:
view = new SharingLiveLocationCell(mContext, true, locationType == LocationActivity.LOCATION_TYPE_GROUP || locationType == LocationActivity.LOCATION_TYPE_GROUP_VIEW ? 16 : 54, resourcesProvider); view = new SharingLiveLocationCell(mContext, true, locationType == LocationActivity.LOCATION_TYPE_GROUP || locationType == LocationActivity.LOCATION_TYPE_GROUP_VIEW ? 16 : 54, resourcesProvider);
break; break;
case 8: { case VIEW_TYPE_DIRECTION: {
LocationDirectionCell cell = new LocationDirectionCell(mContext, resourcesProvider); LocationDirectionCell cell = new LocationDirectionCell(mContext, resourcesProvider);
cell.setOnButtonClick(v -> onDirectionClick()); cell.setOnButtonClick(v -> onDirectionClick());
view = cell; view = cell;
break; break;
} }
case 9: { case VIEW_TYPE_SHADOW: {
view = new ShadowSectionCell(mContext); view = new ShadowSectionCell(mContext);
Drawable drawable = Theme.getThemedDrawableByKey(mContext, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow); Drawable drawable = Theme.getThemedDrawableByKey(mContext, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow);
CombinedDrawable combinedDrawable = new CombinedDrawable(new ColorDrawable(getThemedColor(Theme.key_windowBackgroundGray)), drawable); CombinedDrawable combinedDrawable = new CombinedDrawable(new ColorDrawable(getThemedColor(Theme.key_windowBackgroundGray)), drawable);
@ -326,7 +367,13 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
view.setBackgroundDrawable(combinedDrawable); view.setBackgroundDrawable(combinedDrawable);
break; break;
} }
case 10: case VIEW_TYPE_STORY_LOCATION: {
LocationCell locationCell2 = new LocationCell(mContext, false, resourcesProvider);
locationCell2.setAllowTextAnimation(true);
view = locationCell2;
break;
}
case VIEW_TYPE_EMPTY:
default: { default: {
view = new View(mContext); view = new View(mContext);
break; break;
@ -335,10 +382,23 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
return new RecyclerListView.Holder(view); return new RecyclerListView.Holder(view);
} }
public static final int VIEW_TYPE_PADDING = 0;
public static final int VIEW_TYPE_SEND_LOCATION = 1;
public static final int VIEW_TYPE_HEADER = 2;
public static final int VIEW_TYPE_LOCATION = 3;
public static final int VIEW_TYPE_LOADING = 4;
public static final int VIEW_TYPE_FOOTER = 5;
public static final int VIEW_TYPE_LIVE_LOCATION = 6;
public static final int VIEW_TYPE_SHARING = 7;
public static final int VIEW_TYPE_DIRECTION = 8;
public static final int VIEW_TYPE_SHADOW = 9;
public static final int VIEW_TYPE_EMPTY = 10;
public static final int VIEW_TYPE_STORY_LOCATION = 11;
@Override @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) { switch (holder.getItemViewType()) {
case 0: case VIEW_TYPE_PADDING:
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
if (lp == null) { if (lp == null) {
lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, overScrollHeight); lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, overScrollHeight);
@ -347,11 +407,11 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
} }
holder.itemView.setLayoutParams(lp); holder.itemView.setLayoutParams(lp);
break; break;
case 1: case VIEW_TYPE_SEND_LOCATION:
sendLocationCell = (SendLocationCell) holder.itemView; sendLocationCell = (SendLocationCell) holder.itemView;
updateCell(); updateCell();
break; break;
case 2: { case VIEW_TYPE_HEADER: {
HeaderCell cell = (HeaderCell) holder.itemView; HeaderCell cell = (HeaderCell) holder.itemView;
if (currentMessageObject != null) { if (currentMessageObject != null) {
cell.setText(LocaleController.getString("LiveLocations", R.string.LiveLocations)); cell.setText(LocaleController.getString("LiveLocations", R.string.LiveLocations));
@ -360,25 +420,43 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
} }
break; break;
} }
case 3: { case VIEW_TYPE_LOCATION: {
LocationCell cell = (LocationCell) holder.itemView; LocationCell cell = (LocationCell) holder.itemView;
if (locationType == 0) { if (locationType == 0) {
position -= 4; position -= 4;
} else if (locationType == ChatAttachAlertLocationLayout.LOCATION_TYPE_STORY) {
position -= 4;
if (this.street != null) {
position--;
}
} else { } else {
position -= 5; position -= 5;
} }
TLRPC.TL_messageMediaVenue place = position < 0 || position >= places.size() || !searched ? null : places.get(position); boolean shouldHave = searched && (locationType != ChatAttachAlertLocationLayout.LOCATION_TYPE_STORY || !searching);
String iconUrl = position < 0 || position >= iconUrls.size() || !searched ? null : iconUrls.get(position); TLRPC.TL_messageMediaVenue place = null;
cell.setLocation(place, iconUrl, position, true); int p = position;
if (shouldHave) {
if (position >= 0 && position < locations.size()) {
place = locations.get(position);
p = 2;
} else {
position -= locations.size();
if (position >= 0 && position < places.size()) {
place = places.get(position);
}
}
}
cell.setLocation(place, p, true);
break; break;
} }
case 4: case VIEW_TYPE_LOADING:
((LocationLoadingCell) holder.itemView).setLoading(searching); ((LocationLoadingCell) holder.itemView).setLoading(searching);
break; break;
case 6: case VIEW_TYPE_LIVE_LOCATION:
((SendLocationCell) holder.itemView).setHasLocation(gpsLocation != null); ((SendLocationCell) holder.itemView).setHasLocation(gpsLocation != null);
break; break;
case 7: case VIEW_TYPE_SHARING:
SharingLiveLocationCell locationCell = (SharingLiveLocationCell) holder.itemView; SharingLiveLocationCell locationCell = (SharingLiveLocationCell) holder.itemView;
if (locationType == LocationActivity.LOCATION_TYPE_LIVE_VIEW) { if (locationType == LocationActivity.LOCATION_TYPE_LIVE_VIEW) {
locationCell.setDialog(currentMessageObject, gpsLocation, myLocationDenied); locationCell.setDialog(currentMessageObject, gpsLocation, myLocationDenied);
@ -390,9 +468,21 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
locationCell.setDialog(currentLiveLocations.get(position - (currentMessageObject != null ? 5 : 2)), gpsLocation); locationCell.setDialog(currentLiveLocations.get(position - (currentMessageObject != null ? 5 : 2)), gpsLocation);
} }
break; break;
case 10: case VIEW_TYPE_EMPTY:
View emptyView = holder.itemView; View emptyView = holder.itemView;
emptyView.setBackgroundColor(Theme.getColor(myLocationDenied ? Theme.key_dialogBackgroundGray : Theme.key_dialogBackground)); emptyView.setBackgroundColor(Theme.getColor(myLocationDenied ? Theme.key_dialogBackgroundGray : Theme.key_dialogBackground, resourcesProvider));
break;
case VIEW_TYPE_STORY_LOCATION:
LocationCell cell = (LocationCell) holder.itemView;
if (askingForMyLocation) {
cell.setLocation(null, 2, position == 1 && this.street != null);
} else {
if (position == 1) {
cell.setLocation(city, null, 2, this.street != null, animated);
} else {
cell.setLocation(street, null, 2, false, animated);
}
}
break; break;
} }
} }
@ -425,10 +515,19 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
return currentLiveLocations.get(i - 2); return currentLiveLocations.get(i - 2);
} }
return null; return null;
} else if (locationType == 1) { } else if (locationType == LocationActivity.LOCATION_TYPE_SEND_WITH_LIVE) {
if (i > 4 && i < places.size() + 5) { if (i > 4 && i < places.size() + 5) {
return places.get(i - 5); return places.get(i - 5);
} }
} else if (locationType == ChatAttachAlertLocationLayout.LOCATION_TYPE_STORY) {
int x = this.street == null ? 3 : 4;
if (i > x && i < locations.size() + (x + 1)) {
return locations.get(i - (x + 1));
}
x += locations.size();
if (i > x && i < places.size() + (x + 1)) {
return places.get(i - (x + 1));
}
} else { } else {
if (i > 3 && i < places.size() + 4) { if (i > 3 && i < places.size() + 4) {
return places.get(i - 4); return places.get(i - 4);
@ -440,87 +539,101 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
if (position == 0) { if (position == 0) {
return 0; return VIEW_TYPE_PADDING;
} }
if (locationType == LocationActivity.LOCATION_TYPE_LIVE_VIEW) { if (locationType == LocationActivity.LOCATION_TYPE_LIVE_VIEW) {
return 7; return VIEW_TYPE_SHARING;
} }
if (needEmptyView && position == getItemCount() - 1) { if (needEmptyView && position == getItemCount() - 1) {
return 10; return VIEW_TYPE_EMPTY;
} }
if (locationType == LocationActivity.LOCATION_TYPE_GROUP_VIEW) { if (locationType == LocationActivity.LOCATION_TYPE_GROUP_VIEW) {
return 7; return VIEW_TYPE_SHARING;
} }
if (locationType == LocationActivity.LOCATION_TYPE_GROUP) { if (locationType == LocationActivity.LOCATION_TYPE_GROUP) {
return 1; return VIEW_TYPE_SEND_LOCATION;
} }
if (currentMessageObject != null) { if (currentMessageObject != null) {
if (currentLiveLocations.isEmpty()) { if (currentLiveLocations.isEmpty()) {
if (position == 2) { if (position == 2) {
return 8; return VIEW_TYPE_DIRECTION;
} }
} else { } else {
if (position == 2) { if (position == 2) {
return 9; return VIEW_TYPE_SHADOW;
} else if (position == 3) { } else if (position == 3) {
return 2; return VIEW_TYPE_HEADER;
} else if (position == 4) { } else if (position == 4) {
shareLiveLocationPotistion = position; shareLiveLocationPotistion = position;
return 6; return VIEW_TYPE_LIVE_LOCATION;
} }
} }
return 7; return VIEW_TYPE_SHARING;
} }
if (locationType == 2) { if (locationType == 2) {
if (position == 1) { if (position == 1) {
shareLiveLocationPotistion = position; shareLiveLocationPotistion = position;
return 6; return VIEW_TYPE_LIVE_LOCATION;
} else { } else {
return 7; return VIEW_TYPE_SHARING;
} }
} }
if (locationType == LocationActivity.LOCATION_TYPE_SEND_WITH_LIVE) { if (locationType == LocationActivity.LOCATION_TYPE_SEND_WITH_LIVE) {
if (position == 1) { if (position == 1) {
return 1; return VIEW_TYPE_SEND_LOCATION;
} else if (position == 2) { } else if (position == 2) {
shareLiveLocationPotistion = position; shareLiveLocationPotistion = position;
return 6; return VIEW_TYPE_LIVE_LOCATION;
} else if (position == 3) { } else if (position == 3) {
return 9; return VIEW_TYPE_SHADOW;
} else if (position == 4) { } else if (position == 4) {
return 2; return VIEW_TYPE_HEADER;
} else if (searching || places.isEmpty() || !searched) { } else if (searching || places.isEmpty() || !searched) {
if (position <= 4 + 3 && (searching || !searched) && !myLocationDenied) if (position <= 4 + 3 && (searching || !searched) && !myLocationDenied)
return 3; return VIEW_TYPE_LOCATION;
return 4; return VIEW_TYPE_LOADING;
} else if (position == places.size() + 5) { } else if (position == places.size() + 5) {
return 5; return VIEW_TYPE_FOOTER;
} }
} else { } else {
int i = 4;
int placesCount = places.size() + locations.size();
if (locationType == ChatAttachAlertLocationLayout.LOCATION_TYPE_STORY) {
if (position == 1) {
return VIEW_TYPE_STORY_LOCATION;
}
if (this.street != null) {
if (position == 2) {
return VIEW_TYPE_STORY_LOCATION;
}
position--;
i--;
}
}
if (position == 1) { if (position == 1) {
return 1; return VIEW_TYPE_SEND_LOCATION;
} else if (position == 2) { } else if (position == 2) {
return 9; return VIEW_TYPE_SHADOW;
} else if (position == 3) { } else if (position == 3) {
return 2; return VIEW_TYPE_HEADER;
} else if (searching || places.isEmpty()) { } else if (searching || places.isEmpty() && locations.isEmpty()) {
if (position <= 3 + 3 && (searching || !searched) && !myLocationDenied) if (position <= 3 + 3 && (searching || !searched) && !myLocationDenied)
return 3; return VIEW_TYPE_LOCATION;
return 4; return VIEW_TYPE_LOADING;
} else if (position == places.size() + 4) { } else if (position == placesCount + i) {
return 5; return VIEW_TYPE_FOOTER;
} }
} }
return 3; return VIEW_TYPE_LOCATION;
} }
@Override @Override
public boolean isEnabled(RecyclerView.ViewHolder holder) { public boolean isEnabled(RecyclerView.ViewHolder holder) {
int viewType = holder.getItemViewType(); int viewType = holder.getItemViewType();
if (viewType == 6) { if (viewType == VIEW_TYPE_LIVE_LOCATION) {
return !(LocationController.getInstance(currentAccount).getSharingLocationInfo(dialogId) == null && gpsLocation == null); return !(LocationController.getInstance(currentAccount).getSharingLocationInfo(dialogId) == null && gpsLocation == null);
} }
return viewType == 1 || viewType == 3 || viewType == 7; return viewType == VIEW_TYPE_SEND_LOCATION || viewType == VIEW_TYPE_LOCATION || viewType == VIEW_TYPE_SHARING || viewType == VIEW_TYPE_STORY_LOCATION;
} }
private int getThemedColor(int key) { private int getThemedColor(int key) {

View file

@ -9,9 +9,14 @@
package org.telegram.ui.Adapters; package org.telegram.ui.Adapters;
import android.content.Context; import android.content.Context;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.GraySectionCell;
import org.telegram.ui.Cells.LocationCell; import org.telegram.ui.Cells.LocationCell;
import org.telegram.ui.Components.FlickerLoadingView; import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
@ -20,12 +25,25 @@ import androidx.recyclerview.widget.RecyclerView;
public class LocationActivitySearchAdapter extends BaseLocationAdapter { public class LocationActivitySearchAdapter extends BaseLocationAdapter {
private static final int VIEW_TYPE_LOCATION = 0;
private static final int VIEW_TYPE_SECTION = 1;
private Context mContext; private Context mContext;
private Theme.ResourcesProvider resourcesProvider;
private boolean myLocationDenied = false;
public void setMyLocationDenied(boolean myLocationDenied) {
if (this.myLocationDenied == myLocationDenied)
return;
this.myLocationDenied = myLocationDenied;
}
private FlickerLoadingView globalGradientView; private FlickerLoadingView globalGradientView;
public LocationActivitySearchAdapter(Context context) { public LocationActivitySearchAdapter(Context context, Theme.ResourcesProvider resourcesProvider, boolean stories) {
super(); super(stories);
mContext = context; mContext = context;
this.resourcesProvider = resourcesProvider;
globalGradientView = new FlickerLoadingView(context); globalGradientView = new FlickerLoadingView(context);
globalGradientView.setIsSingleCell(true); globalGradientView.setIsSingleCell(true);
@ -33,31 +51,93 @@ public class LocationActivitySearchAdapter extends BaseLocationAdapter {
@Override @Override
public int getItemCount() { public int getItemCount() {
return (isSearching() ? 3 : places.size()); int count = 0;
if (!locations.isEmpty()) {
count += 1 + locations.size();
}
if (!myLocationDenied) {
if (isSearching()) {
count += 3;
} else {
if (!locations.isEmpty() && !places.isEmpty()) {
count++;
}
count += places.size();
}
}
return count;
} }
public boolean isEmpty() { return places.size() == 0; } public boolean isEmpty() { return places.size() == 0 && locations.size() == 0; }
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LocationCell locationCell = new LocationCell(mContext, false, null); View view;
return new RecyclerListView.Holder(locationCell); if (viewType == VIEW_TYPE_LOCATION) {
view = new LocationCell(mContext, false, resourcesProvider);
} else {
view = new GraySectionCell(mContext, resourcesProvider);
}
return new RecyclerListView.Holder(view);
} }
@Override @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
TLRPC.TL_messageMediaVenue place = getItem(position); if (holder.getItemViewType() == VIEW_TYPE_LOCATION) {
String iconUrl = !isSearching() && position >= 0 && position < iconUrls.size() ? iconUrls.get(position) : null; TLRPC.TL_messageMediaVenue place = null;
String iconUrl = null;
LocationCell locationCell = (LocationCell) holder.itemView; int oposition = position;
locationCell.setLocation(place, iconUrl, position, position != getItemCount() - 1); int p = position;
if (!locations.isEmpty()) {
position--;
}
if (position >= 0 && position < locations.size()) {
place = locations.get(position);
iconUrl = "pin";
p = 2;
} else if (!isSearching()) {
position -= locations.size();
if (!searchingLocations && !locations.isEmpty()) {
position -= 1;
}
if (position >= 0 && position < places.size()) {
place = places.get(position);
p = position;
}
}
LocationCell locationCell = (LocationCell) holder.itemView;
locationCell.setLocation(place, p, oposition != getItemCount() - 1 && (searchingLocations || locations.isEmpty() || oposition != (locations.size())));
} else if (holder.getItemViewType() == VIEW_TYPE_SECTION) {
if (position == 0 && !locations.isEmpty()) {
((GraySectionCell) holder.itemView).setText(LocaleController.getString("LocationOnMap", R.string.LocationOnMap));
} else {
((GraySectionCell) holder.itemView).setText(LocaleController.getString("NearbyVenue", R.string.NearbyVenue));
}
}
} }
public TLRPC.TL_messageMediaVenue getItem(int i) { @Override
if (isSearching()) public int getItemViewType(int position) {
return null; if ((position == 0 || position == (1 + locations.size())) && !locations.isEmpty()) {
if (i >= 0 && i < places.size()) { return VIEW_TYPE_SECTION;
return places.get(i); }
return VIEW_TYPE_LOCATION;
}
public TLRPC.TL_messageMediaVenue getItem(int position) {
if (!locations.isEmpty()) {
position--;
}
if (position >= 0 && position < locations.size()) {
return locations.get(position);
} else if (!isSearching()) {
position -= locations.size();
if (!locations.isEmpty()) {
position -= 1;
}
if (position >= 0 && position < places.size()) {
return places.get(position);
}
} }
return null; return null;
} }

View file

@ -4680,6 +4680,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
FileLog.e(e); FileLog.e(e);
} }
}); });
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.articleClosed);
} }
private void loadChannel(final BlockChannelCell cell, WebpageAdapter adapter, TLRPC.Chat channel) { private void loadChannel(final BlockChannelCell cell, WebpageAdapter adapter, TLRPC.Chat channel) {

View file

@ -31,7 +31,8 @@ public class BasePermissionsActivity extends Activity {
REQUEST_CODE_VIDEO_MESSAGE = 150, REQUEST_CODE_VIDEO_MESSAGE = 150,
REQUEST_CODE_EXTERNAL_STORAGE_FOR_AVATAR = 151, REQUEST_CODE_EXTERNAL_STORAGE_FOR_AVATAR = 151,
REQUEST_CODE_SIGN_IN_WITH_GOOGLE = 200, REQUEST_CODE_SIGN_IN_WITH_GOOGLE = 200,
REQUEST_CODE_PAYMENT_FORM = 210; REQUEST_CODE_PAYMENT_FORM = 210,
REQUEST_CODE_MEDIA_GEO = 211;
protected int currentAccount = -1; protected int currentAccount = -1;
@ -95,6 +96,8 @@ public class BasePermissionsActivity extends Activity {
} }
} else if (requestCode == REQUEST_CODE_GEOLOCATION) { } else if (requestCode == REQUEST_CODE_GEOLOCATION) {
NotificationCenter.getGlobalInstance().postNotificationName(granted ? NotificationCenter.locationPermissionGranted : NotificationCenter.locationPermissionDenied); NotificationCenter.getGlobalInstance().postNotificationName(granted ? NotificationCenter.locationPermissionGranted : NotificationCenter.locationPermissionDenied);
} else if (requestCode == REQUEST_CODE_MEDIA_GEO) {
NotificationCenter.getGlobalInstance().postNotificationName(granted ? NotificationCenter.locationPermissionGranted : NotificationCenter.locationPermissionDenied, 1);
} }
return true; return true;
} }

View file

@ -2595,7 +2595,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
} else { } else {
selected = CacheControlActivity.this.selected[item.index]; selected = CacheControlActivity.this.selected[item.index];
} }
cell.setText(getCheckBoxTitle(item.headerName, percents[item.index < 0 ? 8 : item.index], item.index < 0), AndroidUtilities.formatFileSize(item.size), selected, item.index < 0 ? !collapsed : !item.last); cell.setText(getCheckBoxTitle(item.headerName, percents[item.index < 0 ? 9 : item.index], item.index < 0), AndroidUtilities.formatFileSize(item.size), selected, item.index < 0 ? !collapsed : !item.last);
cell.setCheckBoxColor(item.colorKey, Theme.key_windowBackgroundWhiteGrayIcon, Theme.key_checkboxCheck); cell.setCheckBoxColor(item.colorKey, Theme.key_windowBackgroundWhiteGrayIcon, Theme.key_checkboxCheck);
cell.setCollapsed(item.index < 0 ? collapsed : null); cell.setCollapsed(item.index < 0 ? collapsed : null);
if (item.index == -1) { if (item.index == -1) {

View file

@ -648,9 +648,15 @@ public class CameraScanActivity extends BaseFragment {
if (getParentActivity() == null) { if (getParentActivity() == null) {
return; return;
} }
if (Build.VERSION.SDK_INT >= 23) { final Activity activity = getParentActivity();
if (getParentActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT >= 33) {
getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE); if (activity.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
return;
}
} else if (Build.VERSION.SDK_INT >= 23) {
if (activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
return; return;
} }
} }

View file

@ -1119,13 +1119,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private boolean drawName; private boolean drawName;
private boolean drawNameLayout; private boolean drawNameLayout;
private StaticLayout[] forwardedNameLayout = new StaticLayout[2]; private final StaticLayout[] forwardedNameLayout = new StaticLayout[2];
private int forwardedNameWidth; private int forwardedNameWidth;
private boolean drawForwardedName; private boolean drawForwardedName;
private float forwardNameX; private float forwardNameX;
private int forwardNameY; private int forwardNameY;
private int forwardHeight; private int forwardHeight;
private float[] forwardNameOffsetX = new float[2]; private final float[] forwardNameOffsetX = new float[2];
private float drawTimeX; private float drawTimeX;
private float drawTimeY; private float drawTimeY;
@ -1292,11 +1292,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
// Public for enter transition // Public for enter transition
public List<SpoilerEffect> replySpoilers = new ArrayList<>(); public List<SpoilerEffect> replySpoilers = new ArrayList<>();
private Stack<SpoilerEffect> replySpoilersPool = new Stack<>(); private final Stack<SpoilerEffect> replySpoilersPool = new Stack<>();
private List<SpoilerEffect> captionSpoilers = new ArrayList<>(); private final List<SpoilerEffect> captionSpoilers = new ArrayList<>();
private Stack<SpoilerEffect> captionSpoilersPool = new Stack<>(); private final Stack<SpoilerEffect> captionSpoilersPool = new Stack<>();
private AtomicReference<Layout> captionPatchedSpoilersLayout = new AtomicReference<>(); private final AtomicReference<Layout> captionPatchedSpoilersLayout = new AtomicReference<>();
private Path sPath = new Path(); private final Path sPath = new Path();
public boolean isBlurred; public boolean isBlurred;
public ChatMessageCell(Context context) { public ChatMessageCell(Context context) {
@ -7467,7 +7467,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoHeight += AndroidUtilities.dp(1); photoHeight += AndroidUtilities.dp(1);
} }
} else if (currentPosition != null && currentMessageObject.isDocument()) { } else if (currentPosition != null && currentMessageObject.isDocument()) {
if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && !messageObject.isOutOwner()) { if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && !messageObject.isOutOwner() && !drawPhotoImage) {
totalHeight -= AndroidUtilities.dp(2); totalHeight -= AndroidUtilities.dp(2);
} }
} }
@ -12721,7 +12721,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else { } else {
currentNameString = ""; currentNameString = "";
} }
CharSequence nameStringFinal = TextUtils.ellipsize(currentNameString.replace('\n', ' ').replace('\u200F', ' '), Theme.chat_namePaint, nameWidth - (viaBot ? viaWidth : 0), TextUtils.TruncateAt.END); CharSequence nameStringFinal = currentNameString.replace('\n', ' ').replace('\u200F', ' ');
try {
nameStringFinal = Emoji.replaceEmoji(nameStringFinal, Theme.chat_namePaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
} catch (Exception ignore) {}
nameStringFinal = TextUtils.ellipsize(nameStringFinal, Theme.chat_namePaint, nameWidth - (viaBot ? viaWidth : 0), TextUtils.TruncateAt.END);
if (viaBot) { if (viaBot) {
viaNameWidth = (int) Math.ceil(Theme.chat_namePaint.measureText(nameStringFinal, 0, nameStringFinal.length())); viaNameWidth = (int) Math.ceil(Theme.chat_namePaint.measureText(nameStringFinal, 0, nameStringFinal.length()));
if (viaNameWidth != 0) { if (viaNameWidth != 0) {
@ -12747,10 +12751,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
nameStringFinal = TextUtils.ellipsize(nameStringFinal, Theme.chat_namePaint, nameWidth, TextUtils.TruncateAt.END); nameStringFinal = TextUtils.ellipsize(nameStringFinal, Theme.chat_namePaint, nameWidth, TextUtils.TruncateAt.END);
} }
try {
nameStringFinal = Emoji.replaceEmoji(nameStringFinal, Theme.chat_namePaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
} catch (Exception ignore) {
}
try { try {
nameLayout = new StaticLayout(nameStringFinal, Theme.chat_namePaint, nameWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); nameLayout = new StaticLayout(nameStringFinal, Theme.chat_namePaint, nameWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (nameLayout.getLineCount() > 0) { if (nameLayout.getLineCount() > 0) {
@ -13909,7 +13909,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (isDrawSelectionBackground() && (currentPosition == null || currentMessageObject.isMusic() || currentMessageObject.isDocument() || getBackground() != null)) { if (isDrawSelectionBackground() && (currentPosition == null || currentMessageObject.isMusic() || currentMessageObject.isDocument() || getBackground() != null)) {
if (currentPosition != null) { if (currentPosition != null) {
canvas.save(); canvas.save();
// canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight()); canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
} }
currentSelectedBackgroundAlpha = 1f; currentSelectedBackgroundAlpha = 1f;
currentBackgroundSelectedDrawable.setAlpha((int) (255 * alphaInternal)); currentBackgroundSelectedDrawable.setAlpha((int) (255 * alphaInternal));

View file

@ -47,8 +47,11 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.messenger.WebFile; import org.telegram.messenger.WebFile;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AnimationProperties; import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.ButtonBounce;
import org.telegram.ui.Components.CheckBox2; import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LetterDrawable; import org.telegram.ui.Components.LetterDrawable;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
@ -119,9 +122,7 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
private int buttonState; private int buttonState;
private RadialProgress2 radialProgress; private RadialProgress2 radialProgress;
private long lastUpdateTime;
private boolean scaled; private boolean scaled;
private float scale;
private static AccelerateInterpolator interpolator = new AccelerateInterpolator(0.5f); private static AccelerateInterpolator interpolator = new AccelerateInterpolator(0.5f);
private boolean hideLoadProgress; private boolean hideLoadProgress;
@ -130,6 +131,8 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
private ContextLinkCellDelegate delegate; private ContextLinkCellDelegate delegate;
private ButtonBounce buttonBounce;
public ContextLinkCell(Context context) { public ContextLinkCell(Context context) {
this(context, false, null); this(context, false, null);
} }
@ -165,6 +168,12 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
setWillNotDraw(false); setWillNotDraw(false);
} }
public void allowButtonBounce(boolean allow) {
if (allow != (buttonBounce != null)) {
buttonBounce = allow ? new ButtonBounce(this, 1f, 3f).setReleaseDelay(120L) : null;
}
}
@SuppressLint("DrawAllocation") @SuppressLint("DrawAllocation")
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
@ -591,8 +600,9 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
public void setScaled(boolean value) { public void setScaled(boolean value) {
scaled = value; scaled = value;
lastUpdateTime = System.currentTimeMillis(); if (buttonBounce != null) {
invalidate(); buttonBounce.setPressed(isPressed() || scaled);
}
} }
public void setCanPreviewGif(boolean value) { public void setCanPreviewGif(boolean value) {
@ -816,24 +826,11 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
linkImageView.setVisible(!PhotoViewer.isShowingImage(inlineResult), false); linkImageView.setVisible(!PhotoViewer.isShowingImage(inlineResult), false);
} }
canvas.save(); canvas.save();
if (scaled && scale != 0.8f || !scaled && scale != 1.0f) { float s = imageScale;
long newTime = System.currentTimeMillis(); if (buttonBounce != null) {
long dt = (newTime - lastUpdateTime); s *= buttonBounce.getScale(.1f);
lastUpdateTime = newTime;
if (scaled && scale != 0.8f) {
scale -= dt / 400.0f;
if (scale < 0.8f) {
scale = 0.8f;
}
} else {
scale += dt / 400.0f;
if (scale > 1.0f) {
scale = 1.0f;
}
}
invalidate();
} }
canvas.scale(scale * imageScale, scale * imageScale, getMeasuredWidth() / 2, getMeasuredHeight() / 2); canvas.scale(s, s, getMeasuredWidth() / 2, getMeasuredHeight() / 2);
linkImageView.draw(canvas); linkImageView.draw(canvas);
canvas.restore(); canvas.restore();
} }
@ -1148,4 +1145,12 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
invalidate(); invalidate();
} }
} }
@Override
public void setPressed(boolean pressed) {
super.setPressed(pressed);
if (buttonBounce != null) {
buttonBounce.setPressed(pressed || scaled);
}
}
} }

View file

@ -188,6 +188,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
private Path thumbPath; private Path thumbPath;
private SpoilerEffect thumbSpoiler = new SpoilerEffect(); private SpoilerEffect thumbSpoiler = new SpoilerEffect();
private boolean drawForwardIcon;
public void setMoving(boolean moving) { public void setMoving(boolean moving) {
this.moving = moving; this.moving = moving;
@ -951,6 +952,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
drawNameLock = false; drawNameLock = false;
drawVerified = false; drawVerified = false;
drawPremium = false; drawPremium = false;
drawForwardIcon = false;
drawScam = 0; drawScam = 0;
drawPinBackground = false; drawPinBackground = false;
thumbsCount = 0; thumbsCount = 0;
@ -1577,6 +1579,15 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} }
} }
} }
if (message.isForwarded()) {
drawForwardIcon = true;
SpannableStringBuilder builder = SpannableStringBuilder.valueOf(messageString);
builder.insert(0, "d ");
ColoredImageSpan coloredImageSpan = new ColoredImageSpan(ContextCompat.getDrawable(getContext(), R.drawable.mini_forwarded).mutate());
coloredImageSpan.setAlpha(0.9f);
builder.setSpan(coloredImageSpan, 0, 1, 0);
messageString = builder;
}
} }
} }
if (currentDialogFolderId != 0) { if (currentDialogFolderId != 0) {
@ -2355,7 +2366,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
float x1 = layout.getPrimaryHorizontal(spanOffset); float x1 = layout.getPrimaryHorizontal(spanOffset);
float x2 = layout.getPrimaryHorizontal(spanOffset + 1); float x2 = layout.getPrimaryHorizontal(spanOffset + 1);
int offset = (int) Math.ceil(Math.min(x1, x2)); int offset = (int) Math.ceil(Math.min(x1, x2));
if (offset != 0) { if (offset != 0 && !drawForwardIcon) {
offset += AndroidUtilities.dp(3); offset += AndroidUtilities.dp(3);
} }
for (int i = 0; i < thumbsCount; ++i) { for (int i = 0; i < thumbsCount; ++i) {
@ -3829,9 +3840,9 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} else { } else {
drawCounterMuted = chat != null && chat.forum && forumTopic == null ? !hasUnmutedTopics : dialogMuted; drawCounterMuted = chat != null && chat.forum && forumTopic == null ? !hasUnmutedTopics : dialogMuted;
} }
int countLeftLocal = (int) (storyParams.originalAvatarRect.left + avatarImage.getImageWidth() - countWidth - AndroidUtilities.dp(5f)); int countLeftLocal = (int) (storyParams.originalAvatarRect.left + storyParams.originalAvatarRect.width() - countWidth - AndroidUtilities.dp(5f));
int countLeftOld = (int) (storyParams.originalAvatarRect.left + avatarImage.getImageWidth() - countWidthOld - AndroidUtilities.dp(5f)); int countLeftOld = (int) (storyParams.originalAvatarRect.left + storyParams.originalAvatarRect.width() - countWidthOld - AndroidUtilities.dp(5f));
int countTop = (int) (avatarImage.getImageY() + avatarImage.getImageHeight() - AndroidUtilities.dp(22)); int countTop = (int) (avatarImage.getImageY() + storyParams.originalAvatarRect.height() - AndroidUtilities.dp(22));
drawCounter(canvas, drawCounterMuted, countTop, countLeftLocal, countLeftOld, rightFragmentOpenedProgress, true); drawCounter(canvas, drawCounterMuted, countTop, countLeftLocal, countLeftOld, rightFragmentOpenedProgress, true);
} }
@ -4884,7 +4895,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
@Override @Override
public boolean onInterceptTouchEvent(MotionEvent ev) { public boolean onInterceptTouchEvent(MotionEvent ev) {
if (rightFragmentOpenedProgress == 0 && storyParams.checkOnTouchEvent(ev, this)) { if (rightFragmentOpenedProgress == 0 && !isTopic && storyParams.checkOnTouchEvent(ev, this)) {
return true; return true;
} }
return super.onInterceptTouchEvent(ev); return super.onInterceptTouchEvent(ev);
@ -4892,7 +4903,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
@Override @Override
public boolean dispatchTouchEvent(MotionEvent ev) { public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) { if (!isTopic && ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
storyParams.checkOnTouchEvent(ev, this); storyParams.checkOnTouchEvent(ev, this);
} }
return super.dispatchTouchEvent(ev); return super.dispatchTouchEvent(ev);
@ -4900,7 +4911,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
if (rightFragmentOpenedProgress == 0 && storyParams.checkOnTouchEvent(event, this)) { if (rightFragmentOpenedProgress == 0 && !isTopic && storyParams.checkOnTouchEvent(event, this)) {
return true; return true;
} }
if (delegate == null || delegate.canClickButtonInside()) { if (delegate == null || delegate.canClickButtonInside()) {

View file

@ -50,23 +50,13 @@ public class DrawerActionCell extends FrameLayout {
textView.setTextColor(Theme.getColor(Theme.key_chats_menuItemText)); textView.setTextColor(Theme.getColor(Theme.key_chats_menuItemText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setGravity(Gravity.CENTER_VERTICAL); textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
toggleRTL(true); addView(imageView, LayoutHelper.createFrame(24, 24, Gravity.LEFT | Gravity.TOP, 19, 12, 0, 0));
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 72, 0, 16, 0));
setWillNotDraw(false); setWillNotDraw(false);
} }
private boolean wasRTL;
public void toggleRTL(boolean force) {
if (wasRTL != LocaleController.isRTL || force) {
wasRTL = LocaleController.isRTL;
removeAllViews();
addView(imageView, LayoutHelper.createFrame(24, 24, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 19, 12, LocaleController.isRTL ? 19 : 0, 0));
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 16 : 72, 0, LocaleController.isRTL ? 72 : 16, 0));
}
}
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
super.onDraw(canvas); super.onDraw(canvas);
@ -76,7 +66,7 @@ public class DrawerActionCell extends FrameLayout {
if (suggestions.contains("VALIDATE_PHONE_NUMBER") || suggestions.contains("VALIDATE_PASSWORD")) { if (suggestions.contains("VALIDATE_PHONE_NUMBER") || suggestions.contains("VALIDATE_PASSWORD")) {
int countTop = AndroidUtilities.dp(12.5f); int countTop = AndroidUtilities.dp(12.5f);
int countWidth = AndroidUtilities.dp(9); int countWidth = AndroidUtilities.dp(9);
int countLeft = LocaleController.isRTL ? countWidth + AndroidUtilities.dp(25) : getMeasuredWidth() - countWidth - AndroidUtilities.dp(25); int countLeft = getMeasuredWidth() - countWidth - AndroidUtilities.dp(25);
int x = countLeft - AndroidUtilities.dp(5.5f); int x = countLeft - AndroidUtilities.dp(5.5f);
rect.set(x, countTop, x + countWidth + AndroidUtilities.dp(14), countTop + AndroidUtilities.dp(23)); rect.set(x, countTop, x + countWidth + AndroidUtilities.dp(14), countTop + AndroidUtilities.dp(23));
@ -103,7 +93,6 @@ public class DrawerActionCell extends FrameLayout {
} }
public void setTextAndIcon(int id, String text, int resId) { public void setTextAndIcon(int id, String text, int resId) {
toggleRTL(false);
currentId = id; currentId = id;
try { try {
textView.setText(text); textView.setText(text);

View file

@ -14,6 +14,10 @@ import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.ShapeDrawable;
import android.os.SystemClock; import android.os.SystemClock;
import android.text.TextUtils; import android.text.TextUtils;
@ -24,18 +28,26 @@ import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedTextView;
import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.FlickerLoadingView; import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
public class LocationCell extends FrameLayout { public class LocationCell extends FrameLayout {
private TextView nameTextView; private AnimatedTextView nameTextView;
private TextView addressTextView; private AnimatedTextView addressTextView;
private BackupImageView imageView; private BackupImageView imageView;
private ShapeDrawable circleDrawable; private ShapeDrawable circleDrawable;
private boolean needDivider; private boolean needDivider;
@ -52,24 +64,24 @@ public class LocationCell extends FrameLayout {
imageView.setSize(AndroidUtilities.dp(30), AndroidUtilities.dp(30)); imageView.setSize(AndroidUtilities.dp(30), AndroidUtilities.dp(30));
addView(imageView, LayoutHelper.createFrame(42, 42, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 15, 11, LocaleController.isRTL ? 15 : 0, 0)); addView(imageView, LayoutHelper.createFrame(42, 42, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 15, 11, LocaleController.isRTL ? 15 : 0, 0));
nameTextView = new TextView(context); nameTextView = new AnimatedTextView(context, true, true, true);
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); nameTextView.setAnimationProperties(0.4f, 0, 240, CubicBezierInterpolator.EASE_OUT_QUINT);
nameTextView.setMaxLines(1); nameTextView.setTextSize(AndroidUtilities.dp(16));
nameTextView.setEllipsize(TextUtils.TruncateAt.END); nameTextView.setEllipsizeByGradient(true);
nameTextView.setSingleLine(true);
nameTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText)); nameTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); nameTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), (LocaleController.isRTL ? 16 : 73), 10, (LocaleController.isRTL ? 73 : 16), 0)); nameTextView.getDrawable().setOverrideFullWidth(AndroidUtilities.displaySize.x);
NotificationCenter.listenEmojiLoading(nameTextView);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 22, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), (LocaleController.isRTL ? 16 : 73), 10, (LocaleController.isRTL ? 73 : 16), 0));
addressTextView = new TextView(context); addressTextView = new AnimatedTextView(context, true, true, true);
addressTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); addressTextView.setAnimationProperties(0.4f, 0, 240, CubicBezierInterpolator.EASE_OUT_QUINT);
addressTextView.setMaxLines(1); addressTextView.setTextSize(AndroidUtilities.dp(14));
addressTextView.setEllipsize(TextUtils.TruncateAt.END); addressTextView.setEllipsizeByGradient(true);
addressTextView.setSingleLine(true);
addressTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText3)); addressTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText3));
addressTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); addressTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
addView(addressTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), (LocaleController.isRTL ? 16 : 73), 35, (LocaleController.isRTL ? 73 : 16), 0)); addView(addressTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), (LocaleController.isRTL ? 16 : 73), 35, (LocaleController.isRTL ? 73 : 16), 0));
imageView.setAlpha(enterAlpha); imageView.setAlpha(enterAlpha);
nameTextView.setAlpha(enterAlpha); nameTextView.setAlpha(enterAlpha);
@ -89,8 +101,13 @@ public class LocationCell extends FrameLayout {
return imageView; return imageView;
} }
public void setLocation(TLRPC.TL_messageMediaVenue location, String icon, int pos, boolean divider) { public void setLocation(TLRPC.TL_messageMediaVenue location, int pos, boolean divider) {
setLocation(location, icon, null, pos, divider); setLocation(location, null, pos, divider, false);
}
private boolean allowTextAnimation;
public void setAllowTextAnimation(boolean allow) {
allowTextAnimation = allow;
} }
public static int getColorForIndex(int index) { public static int getColorForIndex(int index) {
@ -113,20 +130,51 @@ public class LocationCell extends FrameLayout {
} }
} }
private CharSequence lastCompleteTitle;
private String lastEmoji, lastTitle;
private CharSequence getTitle(TLRPC.TL_messageMediaVenue location) {
if (location == null) {
return "";
}
if (TextUtils.equals(lastEmoji, location.emoji) && TextUtils.equals(lastTitle, location.title)) {
return lastCompleteTitle;
}
CharSequence title = location.title;
if (!TextUtils.isEmpty(location.emoji)) {
title = location.emoji + " " + title;
title = Emoji.replaceEmoji(title, nameTextView.getPaint().getFontMetricsInt(), false);
}
lastEmoji = location.emoji;
lastTitle = location.title;
return lastCompleteTitle = title;
}
private float enterAlpha = 0f; private float enterAlpha = 0f;
private ValueAnimator enterAnimator; private ValueAnimator enterAnimator;
public void setLocation(TLRPC.TL_messageMediaVenue location, String icon, String label, int pos, boolean divider) { public void setLocation(TLRPC.TL_messageMediaVenue location, String label, int pos, boolean divider, boolean animated) {
needDivider = divider; needDivider = divider;
circleDrawable.getPaint().setColor(getColorForIndex(pos)); if (location != null) {
if (location != null) nameTextView.setText(getTitle(location), allowTextAnimation && !LocaleController.isRTL && animated);
nameTextView.setText(location.title);
if (label != null) {
addressTextView.setText(label);
} else if (location != null) {
addressTextView.setText(location.address);
} }
if (icon != null) if (label != null) {
imageView.setImage(icon, null, null); addressTextView.setText(label, allowTextAnimation && !LocaleController.isRTL);
} else if (location != null) {
addressTextView.setText(location.address, allowTextAnimation && !LocaleController.isRTL && animated);
}
int color = getColorForIndex(pos);
if (location != null && location.icon != null) {
if ("pin".equals(location.icon) || location.icon.startsWith("emoji")) {
Drawable drawable = getResources().getDrawable(R.drawable.pin).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_location_sendLocationIcon), PorterDuff.Mode.MULTIPLY));
CombinedDrawable combinedDrawable = new CombinedDrawable(Theme.createCircleDrawable(AndroidUtilities.dp(42), 0), drawable);
combinedDrawable.setCustomSize(AndroidUtilities.dp(42), AndroidUtilities.dp(42));
combinedDrawable.setIconSize(AndroidUtilities.dp(24), AndroidUtilities.dp(24));
imageView.setImageDrawable(combinedDrawable);
} else {
imageView.setImage(location.icon, null, null);
}
}
circleDrawable.getPaint().setColor(color);
setWillNotDraw(false); setWillNotDraw(false);
setClickable(location == null); setClickable(location == null);
@ -163,7 +211,7 @@ public class LocationCell extends FrameLayout {
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
if (globalGradientView == null) { if (globalGradientView == null) {
globalGradientView = new FlickerLoadingView(getContext()); globalGradientView = new FlickerLoadingView(getContext(), resourcesProvider);
globalGradientView.setIsSingleCell(true); globalGradientView.setIsSingleCell(true);
} }
@ -180,12 +228,16 @@ public class LocationCell extends FrameLayout {
super.onDraw(canvas); super.onDraw(canvas);
if (needDivider) { if (needDivider) {
Paint dividerPaint = resourcesProvider == null ? null : resourcesProvider.getPaint(Theme.key_paint_divider);
if (dividerPaint == null) {
dividerPaint = Theme.dividerPaint;
}
canvas.drawLine( canvas.drawLine(
LocaleController.isRTL ? 0 : AndroidUtilities.dp(72), LocaleController.isRTL ? 0 : AndroidUtilities.dp(72),
getHeight() - 1, getHeight() - 1,
LocaleController.isRTL ? getWidth() - AndroidUtilities.dp(72) : getWidth(), LocaleController.isRTL ? getWidth() - AndroidUtilities.dp(72) : getWidth(),
getHeight() - 1, getHeight() - 1,
Theme.dividerPaint dividerPaint
); );
} }
} }

View file

@ -23,7 +23,7 @@ public class LocationDirectionCell extends FrameLayout {
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
frameLayout = new FrameLayout(context); frameLayout = new FrameLayout(context);
frameLayout.setBackground(Theme.AdaptiveRipple.filledRect(getThemedColor(Theme.key_featuredStickers_addButton), 4)); frameLayout.setBackground(Theme.AdaptiveRipple.filledRect(getThemedColor(Theme.key_featuredStickers_addButton), 8));
addView(frameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.TOP, 16, 10, 16, 0)); addView(frameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.TOP, 16, 10, 16, 0));
buttonTextView = new SimpleTextView(context); buttonTextView = new SimpleTextView(context);

View file

@ -1,7 +1,12 @@
package org.telegram.ui.Cells; package org.telegram.ui.Cells;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.Gravity; import android.view.Gravity;
@ -12,6 +17,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
@ -32,6 +38,7 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MessageSeenCheckDrawable; import org.telegram.ui.Components.MessageSeenCheckDrawable;
import org.telegram.ui.Components.Premium.PremiumGradient; import org.telegram.ui.Components.Premium.PremiumGradient;
@ -40,6 +47,7 @@ import org.telegram.messenger.LocaleController;
import org.telegram.ui.Stories.StoriesUtilities; import org.telegram.ui.Stories.StoriesUtilities;
public class ReactedUserHolderView extends FrameLayout { public class ReactedUserHolderView extends FrameLayout {
public boolean drawDivider;
int currentAccount; int currentAccount;
public static int STYLE_DEFAULT = 0; public static int STYLE_DEFAULT = 0;
@ -57,12 +65,7 @@ public class ReactedUserHolderView extends FrameLayout {
Theme.ResourcesProvider resourcesProvider; Theme.ResourcesProvider resourcesProvider;
int style; int style;
public long dialogId; public long dialogId;
public StoriesUtilities.AvatarStoryParams params = new StoriesUtilities.AvatarStoryParams(false) { public StoriesUtilities.AvatarStoryParams params;
@Override
public void openStory(long dialogId, Runnable onDone) {
ReactedUserHolderView.this.openStory(dialogId, onDone);
}
};
public void openStory(long dialogId, Runnable onDone) { public void openStory(long dialogId, Runnable onDone) {
@ -76,6 +79,12 @@ public class ReactedUserHolderView extends FrameLayout {
this.style = style; this.style = style;
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
this.params = new StoriesUtilities.AvatarStoryParams(false, resourcesProvider) {
@Override
public void openStory(long dialogId, Runnable onDone) {
ReactedUserHolderView.this.openStory(dialogId, onDone);
}
};
setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AndroidUtilities.dp(ITEM_HEIGHT_DP))); setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AndroidUtilities.dp(ITEM_HEIGHT_DP)));
int avatarSize = style == STYLE_STORY ? 48 : 34; int avatarSize = style == STYLE_STORY ? 48 : 34;
@ -140,7 +149,7 @@ public class ReactedUserHolderView extends FrameLayout {
addView(overlaySelectorView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); addView(overlaySelectorView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
} }
public void setUserReaction(TLRPC.User user, TLRPC.Chat chat, TLRPC.Reaction reaction, long date, boolean dateIsSeen, boolean animated) { public void setUserReaction(TLRPC.User user, TLRPC.Chat chat, TLRPC.Reaction reaction, boolean like, long date, boolean dateIsSeen, boolean animated) {
TLObject u = user; TLObject u = user;
if (u == null) { if (u == null) {
u = chat; u = chat;
@ -184,7 +193,13 @@ public class ReactedUserHolderView extends FrameLayout {
String contentDescription; String contentDescription;
boolean hasReactImage = false; boolean hasReactImage = false;
if (reaction != null) { if (like) {
hasReactImage = true;
Drawable likeDrawableFilled = ContextCompat.getDrawable(getContext(), R.drawable.media_like_active).mutate();
reactView.setColorFilter(new PorterDuffColorFilter(0xFFFF2E38, PorterDuff.Mode.MULTIPLY));
reactView.setImageDrawable(likeDrawableFilled);
contentDescription = LocaleController.formatString("AccDescrLike", R.string.AccDescrLike);
} else if (reaction != null) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(reaction); ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(reaction);
if (visibleReaction.emojicon != null) { if (visibleReaction.emojicon != null) {
TLRPC.TL_availableReaction r = MediaDataController.getInstance(currentAccount).getReactionsMap().get(visibleReaction.emojicon); TLRPC.TL_availableReaction r = MediaDataController.getInstance(currentAccount).getReactionsMap().get(visibleReaction.emojicon);
@ -195,6 +210,7 @@ public class ReactedUserHolderView extends FrameLayout {
} else { } else {
reactView.setImageDrawable(null); reactView.setImageDrawable(null);
} }
reactView.setColorFilter(null);
} else { } else {
AnimatedEmojiDrawable drawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, currentAccount, visibleReaction.documentId); AnimatedEmojiDrawable drawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, currentAccount, visibleReaction.documentId);
drawable.setColorFilter(Theme.getAnimatedEmojiColorFilter(resourcesProvider)); drawable.setColorFilter(Theme.getAnimatedEmojiColorFilter(resourcesProvider));
@ -203,6 +219,7 @@ public class ReactedUserHolderView extends FrameLayout {
} }
contentDescription = LocaleController.formatString("AccDescrReactedWith", R.string.AccDescrReactedWith, titleView.getText(), visibleReaction.emojicon != null ? visibleReaction.emojicon : reaction); contentDescription = LocaleController.formatString("AccDescrReactedWith", R.string.AccDescrReactedWith, titleView.getText(), visibleReaction.emojicon != null ? visibleReaction.emojicon : reaction);
} else { } else {
reactView.setAnimatedEmojiDrawable(null);
reactView.setImageDrawable(null); reactView.setImageDrawable(null);
contentDescription = LocaleController.formatString("AccDescrPersonHasSeen", R.string.AccDescrPersonHasSeen, titleView.getText()); contentDescription = LocaleController.formatString("AccDescrPersonHasSeen", R.string.AccDescrPersonHasSeen, titleView.getText());
} }
@ -247,7 +264,7 @@ public class ReactedUserHolderView extends FrameLayout {
} else { } else {
chat = MessagesController.getInstance(currentAccount).getChat(-dialogId); chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
} }
setUserReaction(user, chat, reaction.reaction, reaction.date, reaction.dateIsSeen, false); setUserReaction(user, chat, reaction.reaction, false, reaction.date, reaction.dateIsSeen, false);
} }
@Override @Override
@ -282,4 +299,62 @@ public class ReactedUserHolderView extends FrameLayout {
public void setObject(TLRPC.User user, long date, boolean b) { public void setObject(TLRPC.User user, long date, boolean b) {
} }
private float alphaInternal = 1f;
private ValueAnimator alphaAnimator;
public void animateAlpha(float alpha, boolean animated) {
if (alphaAnimator != null) {
alphaAnimator.cancel();
alphaAnimator = null;
}
if (animated) {
alphaAnimator = ValueAnimator.ofFloat(alphaInternal, alpha);
alphaAnimator.addUpdateListener(anm -> {
alphaInternal = (float) anm.getAnimatedValue();
invalidate();
});
alphaAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
alphaInternal = alpha;
invalidate();
}
});
alphaAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
alphaAnimator.setDuration(420);
alphaAnimator.start();
} else {
alphaInternal = alpha;
invalidate();
}
}
public float getAlphaInternal() {
return alphaInternal;
}
@Override
protected void dispatchDraw(Canvas canvas) {
boolean restore = false;
if (alphaInternal < 1) {
canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), (int) (0xFF * alphaInternal), Canvas.ALL_SAVE_FLAG);
restore = true;
}
super.dispatchDraw(canvas);
if (drawDivider) {
float leftMargin = AndroidUtilities.dp(style == STYLE_STORY ? 73 : 55);
if (LocaleController.isRTL) {
canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth() - leftMargin, getMeasuredHeight() - 1, Theme.getThemePaint(Theme.key_paint_divider, resourcesProvider));
} else {
canvas.drawLine(leftMargin, getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, Theme.getThemePaint(Theme.key_paint_divider, resourcesProvider));
}
}
if (restore) {
canvas.restore();
}
}
public Theme.ResourcesProvider getResourcesProvider() {
return resourcesProvider;
}
} }

View file

@ -71,7 +71,7 @@ public class SendLocationCell extends FrameLayout {
AndroidUtilities.runOnUIThread(invalidateRunnable, 1000); AndroidUtilities.runOnUIThread(invalidateRunnable, 1000);
setWillNotDraw(false); setWillNotDraw(false);
} else { } else {
Drawable drawable = getResources().getDrawable(R.drawable.pin); Drawable drawable = getResources().getDrawable(R.drawable.pin).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_location_sendLocationIcon), PorterDuff.Mode.MULTIPLY)); drawable.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_location_sendLocationIcon), PorterDuff.Mode.MULTIPLY));
CombinedDrawable combinedDrawable = new CombinedDrawable(circle, drawable); CombinedDrawable combinedDrawable = new CombinedDrawable(circle, drawable);
combinedDrawable.setCustomSize(AndroidUtilities.dp(42), AndroidUtilities.dp(42)); combinedDrawable.setCustomSize(AndroidUtilities.dp(42), AndroidUtilities.dp(42));

View file

@ -14,22 +14,30 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location; import android.location.Location;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.Gravity; import android.view.Gravity;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ContactsController; import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject; import org.telegram.messenger.DialogObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.IMapsProvider; import org.telegram.messenger.IMapsProvider;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.LocationController; import org.telegram.messenger.LocationController;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject; import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.SimpleTextView; import org.telegram.ui.ActionBar.SimpleTextView;
@ -38,8 +46,14 @@ import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CombinedDrawable; import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LoadingSpan;
import org.telegram.ui.Components.Paint.Views.LocationView;
import org.telegram.ui.LocationActivity; import org.telegram.ui.LocationActivity;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class SharingLiveLocationCell extends FrameLayout { public class SharingLiveLocationCell extends FrameLayout {
private BackupImageView avatarImageView; private BackupImageView avatarImageView;
@ -74,14 +88,16 @@ public class SharingLiveLocationCell extends FrameLayout {
avatarDrawable = new AvatarDrawable(); avatarDrawable = new AvatarDrawable();
nameTextView = new SimpleTextView(context); nameTextView = new SimpleTextView(context);
NotificationCenter.listenEmojiLoading(nameTextView);
nameTextView.setTextSize(16); nameTextView.setTextSize(16);
nameTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText)); nameTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); nameTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
nameTextView.setScrollNonFitText(true);
if (distance) { if (distance) {
addView(avatarImageView, LayoutHelper.createFrame(42, 42, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 15, 12, LocaleController.isRTL ? 15 : 0, 0)); addView(avatarImageView, LayoutHelper.createFrame(42, 42, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 15, 12, LocaleController.isRTL ? 15 : 0, 0));
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? padding : 73, 12, LocaleController.isRTL ? 73 : padding, 0)); addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? padding : 73, 12, LocaleController.isRTL ? 73 : 16, 0));
distanceTextView = new SimpleTextView(context); distanceTextView = new SimpleTextView(context);
distanceTextView.setTextSize(14); distanceTextView.setTextSize(14);
@ -141,6 +157,66 @@ public class SharingLiveLocationCell extends FrameLayout {
distanceTextView.setText(address); distanceTextView.setText(address);
} }
private boolean loading;
private double lastLat, lastLong;
private SpannableString loadingString;
private CharSequence lastName = "";
private CharSequence getName(double lat, double _long) {
if (loading) {
return lastName;
}
if (Math.abs(lastLat - lat) > 0.000001d || Math.abs(lastLong - _long) > 0.000001d || TextUtils.isEmpty(lastName)) {
loading = true;
Utilities.globalQueue.postRunnable(() -> {
try {
Geocoder geocoder = new Geocoder(ApplicationLoader.applicationContext, LocaleController.getInstance().getCurrentLocale());
List<Address> addresses = geocoder.getFromLocation(lat, _long, 1);
if (addresses.isEmpty()) {
lastName = LocationController.detectOcean(_long, lat);
if (lastName == null) {
lastName = "";
} else {
lastName = "🌊 " + lastName;
}
} else {
Address addr = addresses.get(0);
StringBuilder sb = new StringBuilder();
HashSet<String> parts = new HashSet<>();
parts.add(addr.getSubAdminArea());
parts.add(addr.getAdminArea());
parts.add(addr.getLocality());
parts.add(addr.getCountryName());
for (String part : parts) {
if (TextUtils.isEmpty(part)) {
continue;
}
if (sb.length() > 0) {
sb.append(", ");
}
sb.append(part);
}
lastName = sb.toString();
String emoji = LocationController.countryCodeToEmoji(addr.getCountryCode());
if (emoji != null && Emoji.getEmojiDrawable(emoji) != null) {
lastName = emoji + " " + lastName;
}
}
} catch (Exception ignore) {}
AndroidUtilities.runOnUIThread(() -> {
lastLat = lat;
lastLong = _long;
loading = false;
lastName = Emoji.replaceEmoji(lastName, nameTextView.getPaint().getFontMetricsInt(), false);
nameTextView.setText(lastName);
});
});
}
return lastName;
}
public void setDialog(MessageObject messageObject, Location userLocation, boolean userLocationDenied) { public void setDialog(MessageObject messageObject, Location userLocation, boolean userLocationDenied) {
long fromId = messageObject.getFromChatId(); long fromId = messageObject.getFromChatId();
if (messageObject.isForwarded()) { if (messageObject.isForwarded()) {
@ -148,12 +224,49 @@ public class SharingLiveLocationCell extends FrameLayout {
} }
currentAccount = messageObject.currentAccount; currentAccount = messageObject.currentAccount;
String address = null; String address = null;
String name; CharSequence name = "";
if (!TextUtils.isEmpty(messageObject.messageOwner.media.address)) { if (!TextUtils.isEmpty(messageObject.messageOwner.media.address)) {
address = messageObject.messageOwner.media.address; address = messageObject.messageOwner.media.address;
} }
if (!TextUtils.isEmpty(messageObject.messageOwner.media.title)) { boolean noTitle = TextUtils.isEmpty(messageObject.messageOwner.media.title);
name = messageObject.messageOwner.media.title; if (noTitle) {
name = "";
avatarDrawable = null;
if (fromId > 0) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(fromId);
if (user != null) {
avatarDrawable = new AvatarDrawable(user);
name = UserObject.getUserName(user);
avatarImageView.setForUserOrChat(user, avatarDrawable);
} else {
noTitle = false;
name = getName(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long);
}
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-fromId);
if (chat != null) {
avatarDrawable = new AvatarDrawable(chat);
name = chat.title;
avatarImageView.setForUserOrChat(chat, avatarDrawable);
} else {
noTitle = false;
name = getName(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long);
}
}
} else {
name = "";
}
if (TextUtils.isEmpty(name)) {
if (loadingString == null) {
loadingString = new SpannableString("dkaraush has been here");
loadingString.setSpan(new LoadingSpan(nameTextView, AndroidUtilities.dp(100), 0, resourcesProvider), 0, loadingString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
name = loadingString;
}
if (!noTitle) {
if (!TextUtils.isEmpty(messageObject.messageOwner.media.title)) {
name = messageObject.messageOwner.media.title;
}
Drawable drawable = getResources().getDrawable(R.drawable.pin); Drawable drawable = getResources().getDrawable(R.drawable.pin);
drawable.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_location_sendLocationIcon), PorterDuff.Mode.MULTIPLY)); drawable.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_location_sendLocationIcon), PorterDuff.Mode.MULTIPLY));
@ -163,24 +276,6 @@ public class SharingLiveLocationCell extends FrameLayout {
combinedDrawable.setCustomSize(AndroidUtilities.dp(42), AndroidUtilities.dp(42)); combinedDrawable.setCustomSize(AndroidUtilities.dp(42), AndroidUtilities.dp(42));
combinedDrawable.setIconSize(AndroidUtilities.dp(24), AndroidUtilities.dp(24)); combinedDrawable.setIconSize(AndroidUtilities.dp(24), AndroidUtilities.dp(24));
avatarImageView.setImageDrawable(combinedDrawable); avatarImageView.setImageDrawable(combinedDrawable);
} else {
name = "";
avatarDrawable = null;
if (fromId > 0) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(fromId);
if (user != null) {
avatarDrawable = new AvatarDrawable(user);
name = UserObject.getUserName(user);
avatarImageView.setForUserOrChat(user, avatarDrawable);
}
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-fromId);
if (chat != null) {
avatarDrawable = new AvatarDrawable(chat);
name = chat.title;
avatarImageView.setForUserOrChat(chat, avatarDrawable);
}
}
} }
nameTextView.setText(name); nameTextView.setText(name);

View file

@ -19,6 +19,7 @@ import android.text.Layout;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.Spanned; import android.text.Spanned;
import android.text.StaticLayout; import android.text.StaticLayout;
import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import android.util.TypedValue; import android.util.TypedValue;
@ -69,6 +70,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
protected int textY; protected int textY;
protected int maybeTextX; protected int maybeTextX;
protected int maybeTextY; protected int maybeTextY;
boolean allowDiscard;
float movingOffsetX; float movingOffsetX;
float movingOffsetY; float movingOffsetY;
@ -107,6 +109,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
private Callback callback; private Callback callback;
protected RecyclerListView parentRecyclerView; protected RecyclerListView parentRecyclerView;
protected NestedScrollView parentNestedScrollView;
protected ViewGroup parentView; protected ViewGroup parentView;
private Magnifier magnifier; private Magnifier magnifier;
private float magnifierYanimated; private float magnifierYanimated;
@ -145,7 +148,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
private Runnable scrollRunnable = new Runnable() { private Runnable scrollRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
if (scrolling && parentRecyclerView != null) { if (scrolling && (parentRecyclerView != null || parentNestedScrollView != null)) {
int dy; int dy;
if (multiselect && selectedView == null) { if (multiselect && selectedView == null) {
dy = AndroidUtilities.dp(8); dy = AndroidUtilities.dp(8);
@ -155,7 +158,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
return; return;
} }
if (!multiselect) { if (!multiselect && !allowScrollPrentRelative) {
if (scrollDown) { if (scrollDown) {
if (selectedView.getBottom() - dy < parentView.getMeasuredHeight() - getParentBottomPadding()) { if (selectedView.getBottom() - dy < parentView.getMeasuredHeight() - getParentBottomPadding()) {
dy = selectedView.getBottom() - parentView.getMeasuredHeight() + getParentBottomPadding(); dy = selectedView.getBottom() - parentView.getMeasuredHeight() + getParentBottomPadding();
@ -166,7 +169,12 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
} }
} }
parentRecyclerView.scrollBy(0, scrollDown ? dy : -dy); if (parentRecyclerView != null) {
parentRecyclerView.scrollBy(0, scrollDown ? dy : -dy);
}
if (parentNestedScrollView != null) {
parentNestedScrollView.setScrollY(parentNestedScrollView.getScrollY() + (scrollDown ? dy : -dy));
}
AndroidUtilities.runOnUIThread(this); AndroidUtilities.runOnUIThread(this);
} }
} }
@ -279,12 +287,14 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
onOffsetChanged(); onOffsetChanged();
} }
tryCapture = false; tryCapture = false;
allowDiscard = false;
} }
}; };
protected Theme.ResourcesProvider resourcesProvider; protected Theme.ResourcesProvider resourcesProvider;
public boolean useMovingOffset = true; public boolean useMovingOffset = true;
private boolean invalidateParent; private boolean invalidateParent;
public boolean allowScrollPrentRelative;
public TextSelectionHelper() { public TextSelectionHelper() {
longpressDelay = ViewConfiguration.getLongPressTimeout(); longpressDelay = ViewConfiguration.getLongPressTimeout();
@ -312,6 +322,12 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
parentView = view; parentView = view;
} }
public void setScrollingParent(View scrollingParent) {
if (scrollingParent instanceof NestedScrollView) {
parentNestedScrollView = (NestedScrollView) scrollingParent;
}
}
public void setMaybeTextCord(int x, int y) { public void setMaybeTextCord(int x, int y) {
maybeTextX = x; maybeTextX = x;
maybeTextY = y; maybeTextY = y;
@ -324,7 +340,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
capturedY = (int) event.getY(); capturedY = (int) event.getY();
tryCapture = false; tryCapture = false;
textArea.inset(-AndroidUtilities.dp(8), -AndroidUtilities.dp(8)); textArea.inset(-AndroidUtilities.dp(8), -AndroidUtilities.dp(8));
if (textArea.contains(capturedX, capturedY)) { if (textArea.contains(capturedX, capturedY) && maybeSelectedView != null) {
textArea.inset(AndroidUtilities.dp(8), AndroidUtilities.dp(8)); textArea.inset(AndroidUtilities.dp(8), AndroidUtilities.dp(8));
int x = capturedX; int x = capturedX;
int y = capturedY; int y = capturedY;
@ -358,7 +374,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int y = (int) event.getY(); int y = (int) event.getY();
int x = (int) event.getX(); int x = (int) event.getX();
int r = (capturedY - y) * (capturedY - y) + (capturedX - x) * (capturedX - x); int r = (capturedY - y) * (capturedY - y) + (capturedX - x) * (capturedX - x);
if (r > touchSlop) { if (r > touchSlop * touchSlop) {
AndroidUtilities.cancelRunOnUIThread(startSelectionRunnable); AndroidUtilities.cancelRunOnUIThread(startSelectionRunnable);
tryCapture = false; tryCapture = false;
} }
@ -788,6 +804,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
movingHandle = false; movingHandle = false;
allowDiscard = true;
break; break;
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
if (movingHandle) { if (movingHandle) {
@ -827,7 +844,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
y -= coordsInParent[1]; y -= coordsInParent[1];
x -= coordsInParent[0]; x -= coordsInParent[0];
boolean canScrollDown = event.getY() - touchSlop > parentView.getMeasuredHeight() - getParentBottomPadding() && (multiselect || selectedView.getBottom() > parentView.getMeasuredHeight() - getParentBottomPadding()); boolean canScrollDown = event.getY() - touchSlop > parentView.getMeasuredHeight() - getParentBottomPadding() && (allowScrollPrentRelative || multiselect || selectedView.getBottom() > parentView.getMeasuredHeight() - getParentBottomPadding());
boolean canScrollUp = event.getY() < ((View) parentView.getParent()).getTop() + getParentTopPadding() && (multiselect || selectedView.getTop() < getParentTopPadding()); boolean canScrollUp = event.getY() < ((View) parentView.getParent()).getTop() + getParentTopPadding() && (multiselect || selectedView.getTop() < getParentTopPadding());
if (canScrollDown || canScrollUp) { if (canScrollDown || canScrollUp) {
if (!scrolling) { if (!scrolling) {
@ -1253,17 +1270,19 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int[] coordsInParent = getCoordsInParent(); int[] coordsInParent = getCoordsInParent();
lastMotionY += coordsInParent[1] + textY; lastMotionY += coordsInParent[1] + textY;
} }
if (!movingHandle && (lastMotionY < startArea.top - AndroidUtilities.dp(8) || lastMotionY > endArea.bottom + AndroidUtilities.dp(8))) { if (!movingHandle && allowDiscard) {
clear(); clear();
} }
} }
float cancelPressedX, cancelPressedY; float cancelPressedX, cancelPressedY;
public void checkCancelAction(MotionEvent ev) { public void checkCancelAction(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) { if (ev.getAction() == MotionEvent.ACTION_DOWN) {
cancelPressedX = ev.getX(); cancelPressedX = ev.getX();
cancelPressedY = ev.getY(); cancelPressedY = ev.getY();
} else if (Math.abs(ev.getX() - cancelPressedX) < AndroidUtilities.touchSlop && Math.abs(ev.getY() - cancelPressedY) < AndroidUtilities.touchSlop && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP)) { allowDiscard = isInSelectionMode();
} else if (allowDiscard && Math.abs(ev.getX() - cancelPressedX) < AndroidUtilities.touchSlop && Math.abs(ev.getY() - cancelPressedY) < AndroidUtilities.touchSlop && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP)) {
checkCancel(ev.getX(), ev.getY(), true); checkCancel(ev.getX(), ev.getY(), true);
} }
} }
@ -1755,14 +1774,19 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int line = -1; int line = -1;
for (int i = 0; i < layout.getLineCount(); i++) { for (int i = 0; i < layout.getLineCount(); i++) {
if (y > layoutBlock.yOffset + layout.getLineTop(i) && y < layoutBlock.yOffset + layout.getLineBottom(i)) { if (y > offsetY + layout.getLineTop(i) && y < offsetY + layout.getLineBottom(i)) {
line = i; line = i;
break; break;
} }
} }
if (line >= 0) { if (line >= 0) {
int k = layoutBlock.charOffset + layout.getOffsetForHorizontal(line, x);; try {
return k; int k = layoutBlock.charOffset + layout.getOffsetForHorizontal(line, x);
return k;
} catch (Exception e) {
FileLog.e(e);
}
} }
return -1; return -1;

View file

@ -2131,7 +2131,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
dialog_id = -chatId; dialog_id = -chatId;
if (ChatObject.isChannel(currentChat)) { if (ChatObject.isChannel(currentChat)) {
if (ChatObject.isNotInChat(currentChat)) { if (ChatObject.isNotInChat(currentChat) && !isThreadChat() && !isInScheduleMode()) {
waitingForGetDifference = true; waitingForGetDifference = true;
getMessagesController().startShortPoll(currentChat, classGuid, false, isGettingDifference -> { getMessagesController().startShortPoll(currentChat, classGuid, false, isGettingDifference -> {
waitingForGetDifference = isGettingDifference; waitingForGetDifference = isGettingDifference;
@ -7212,7 +7212,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
private void createTopPanel() { private void createTopPanel() {
if (topChatPanelView != null || getContext() == null) { if (contentView == null || topChatPanelView != null || getContext() == null) {
return; return;
} }
@ -7395,6 +7395,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
args.putBoolean("addContact", true); args.putBoolean("addContact", true);
ContactAddActivity activity = new ContactAddActivity(args); ContactAddActivity activity = new ContactAddActivity(args);
activity.setDelegate(() -> { activity.setDelegate(() -> {
if (undoView != null || getContext() == null) {
return;
}
createUndoView(); createUndoView();
undoView.showWithAction(dialog_id, UndoView.ACTION_CONTACT_ADDED, currentUser); undoView.showWithAction(dialog_id, UndoView.ACTION_CONTACT_ADDED, currentUser);
}); });
@ -10452,13 +10455,21 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
FileLog.e(e); FileLog.e(e);
} }
} else if (which == attach_gallery) { } else if (which == attach_gallery) {
if (Build.VERSION.SDK_INT >= 23 && getParentActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { final Activity activity = getParentActivity();
try { if (Build.VERSION.SDK_INT >= 33) {
getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE); if (activity.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
} catch (Throwable ignore) { try {
getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
} catch (Throwable ignore) {}
return;
}
} else if (Build.VERSION.SDK_INT >= 23) {
if (activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
try {
getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
} catch (Throwable ignore) {}
return;
} }
return;
} }
boolean allowGifs; boolean allowGifs;
if (ChatObject.isChannel(currentChat) && currentChat.banned_rights != null && currentChat.banned_rights.send_gifs) { if (ChatObject.isChannel(currentChat) && currentChat.banned_rights != null && currentChat.banned_rights.send_gifs) {
@ -15609,7 +15620,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
Collections.reverse(messArr); Collections.reverse(messArr);
} }
if (currentEncryptedChat == null) { if (currentEncryptedChat == null) {
getMediaDataController().loadReplyMessagesForMessages(messArr, dialog_id, chatMode == MODE_SCHEDULED, 0, null); getMediaDataController().loadReplyMessagesForMessages(messArr, dialog_id, chatMode == MODE_SCHEDULED, 0, null, classGuid);
} }
int approximateHeightSum = 0; int approximateHeightSum = 0;
if (!chatWasReset && (load_type == 2 || load_type == 1) && messArr.isEmpty() && !isCache) { if (!chatWasReset && (load_type == 2 || load_type == 1) && messArr.isEmpty() && !isCache) {
@ -16760,7 +16771,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
ArrayList<MessageObject> messArr = new ArrayList<>(); ArrayList<MessageObject> messArr = new ArrayList<>();
messArr.add(obj); messArr.add(obj);
if (currentEncryptedChat == null) { if (currentEncryptedChat == null) {
getMediaDataController().loadReplyMessagesForMessages(messArr, dialog_id, chatMode == MODE_SCHEDULED, 0, null); getMediaDataController().loadReplyMessagesForMessages(messArr, dialog_id, chatMode == MODE_SCHEDULED, 0, null, classGuid);
} }
if (chatAdapter != null) { if (chatAdapter != null) {
chatAdapter.updateRowWithMessageObject(obj, false, false); chatAdapter.updateRowWithMessageObject(obj, false, false);
@ -17558,7 +17569,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
boolean updated = false; boolean updated = false;
if (arrayList != null) { if (arrayList != null) {
getMediaDataController().loadReplyMessagesForMessages(arrayList, dialog_id, false, 0, null); getMediaDataController().loadReplyMessagesForMessages(arrayList, dialog_id, false, 0, null, classGuid);
} }
for (int a = 0, N = ids.size(); a < N; a++) { for (int a = 0, N = ids.size(); a < N; a++) {
Integer mid = ids.get(a); Integer mid = ids.get(a);
@ -17651,7 +17662,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
loadingPinnedMessages.remove(message.getId()); loadingPinnedMessages.remove(message.getId());
} }
getMediaDataController().loadReplyMessagesForMessages(arrayList, dialog_id, false, 0, null); getMediaDataController().loadReplyMessagesForMessages(arrayList, dialog_id, false, 0, null, classGuid);
updateMessagesVisiblePart(false); updateMessagesVisiblePart(false);
} else { } else {
pinnedMessageIds.clear(); pinnedMessageIds.clear();
@ -17997,7 +18008,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
totalPinnedMessagesCount = (Integer) args[3]; totalPinnedMessagesCount = (Integer) args[3];
pinnedEndReached = (Boolean) args[4]; pinnedEndReached = (Boolean) args[4];
getMediaDataController().loadReplyMessagesForMessages(new ArrayList<>(pinnedMessageObjects.values()), dialog_id, false, 0, null); getMediaDataController().loadReplyMessagesForMessages(new ArrayList<>(pinnedMessageObjects.values()), dialog_id, false, 0, null, classGuid);
if (!inMenuMode && !loadingPinnedMessagesList && totalPinnedMessagesCount == 0 && !pinnedEndReached) { if (!inMenuMode && !loadingPinnedMessagesList && totalPinnedMessagesCount == 0 && !pinnedEndReached) {
getMediaDataController().loadPinnedMessages(dialog_id, 0, fallbackId); getMediaDataController().loadPinnedMessages(dialog_id, 0, fallbackId);
@ -20231,6 +20242,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
flagSecure.detach(); flagSecure.detach();
super.onBecomeFullyHidden();
} }
public void saveKeyboardPositionBeforeTransition() { public void saveKeyboardPositionBeforeTransition() {
@ -23151,6 +23164,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
private CharSequence getMessageCaption(MessageObject messageObject, MessageObject.GroupedMessages group, int[] msgId) { private CharSequence getMessageCaption(MessageObject messageObject, MessageObject.GroupedMessages group, int[] msgId) {
if (messageObject == null) {
return null;
}
String restrictionReason = MessagesController.getRestrictionReason(messageObject.messageOwner.restriction_reason); String restrictionReason = MessagesController.getRestrictionReason(messageObject.messageOwner.restriction_reason);
if (!TextUtils.isEmpty(restrictionReason)) { if (!TextUtils.isEmpty(restrictionReason)) {
return restrictionReason; return restrictionReason;
@ -26683,6 +26699,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
private void runCloseInstantCameraAnimation() { private void runCloseInstantCameraAnimation() {
if (instantCameraView == null) {
return;
}
instantCameraView.cancelBlur(); instantCameraView.cancelBlur();
final InstantCameraView.InstantViewCameraContainer cameraContainer = instantCameraView.getCameraContainer(); final InstantCameraView.InstantViewCameraContainer cameraContainer = instantCameraView.getCameraContainer();

View file

@ -628,6 +628,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
flickerLoadingView.setViewType(FlickerLoadingView.USERS_TYPE); flickerLoadingView.setViewType(FlickerLoadingView.USERS_TYPE);
flickerLoadingView.showDate(false); flickerLoadingView.showDate(false);
flickerLoadingView.setUseHeaderOffset(true); flickerLoadingView.setUseHeaderOffset(true);
flickerLoadingView.setColors(Theme.key_actionBarDefaultSubmenuBackground, Theme.key_listSelector, Theme.key_listSelector);
progressLayout.addView(flickerLoadingView); progressLayout.addView(flickerLoadingView);
progressBar = new RadialProgressView(context); progressBar = new RadialProgressView(context);

View file

@ -17,14 +17,17 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Outline; import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.media.AudioManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
@ -34,6 +37,7 @@ import android.text.Editable;
import android.text.Html; import android.text.Html;
import android.text.InputFilter; import android.text.InputFilter;
import android.text.InputType; import android.text.InputType;
import android.text.Layout;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
@ -55,10 +59,12 @@ import android.view.inputmethod.EditorInfo;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.RawRes; import androidx.annotation.RawRes;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.core.util.Consumer; import androidx.core.util.Consumer;
@ -108,6 +114,7 @@ import org.telegram.ui.Components.voip.VoIPHelper;
import org.telegram.ui.LanguageSelectActivity; import org.telegram.ui.LanguageSelectActivity;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import org.telegram.ui.LoginActivity; import org.telegram.ui.LoginActivity;
import org.telegram.ui.NotificationPermissionDialog;
import org.telegram.ui.NotificationsCustomSettingsActivity; import org.telegram.ui.NotificationsCustomSettingsActivity;
import org.telegram.ui.NotificationsSettingsActivity; import org.telegram.ui.NotificationsSettingsActivity;
import org.telegram.ui.ProfileNotificationsActivity; import org.telegram.ui.ProfileNotificationsActivity;

View file

@ -481,7 +481,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public AnimatedFileDrawable(File file, boolean createDecoder, long streamSize, int streamLoadingPriority, TLRPC.Document document, ImageLocation location, Object parentObject, long seekTo, int account, boolean preview, int w, int h, BitmapsCache.CacheOptions cacheOptions) { public AnimatedFileDrawable(File file, boolean createDecoder, long streamSize, int streamLoadingPriority, TLRPC.Document document, ImageLocation location, Object parentObject, long seekTo, int account, boolean preview, int w, int h, BitmapsCache.CacheOptions cacheOptions) {
path = file; path = file;
PRERENDER_FRAME = SharedConfig.deviceIsAboveAverage() && limitFps; PRERENDER_FRAME = SharedConfig.deviceIsAboveAverage();
streamFileSize = streamSize; streamFileSize = streamSize;
this.streamLoadingPriority = streamLoadingPriority; this.streamLoadingPriority = streamLoadingPriority;
currentAccount = account; currentAccount = account;
@ -518,8 +518,8 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public void setIsWebmSticker(boolean b) { public void setIsWebmSticker(boolean b) {
isWebmSticker = b; isWebmSticker = b;
PRERENDER_FRAME = false;
if (isWebmSticker) { if (isWebmSticker) {
PRERENDER_FRAME = false;
useSharedQueue = true; useSharedQueue = true;
} }
} }
@ -723,6 +723,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
try { try {
secondParentViews.clear();
recycle(); recycle();
} finally { } finally {
super.finalize(); super.finalize();

View file

@ -58,6 +58,10 @@ public class AnimatedTextView extends View {
private Part[] oldParts; private Part[] oldParts;
private CharSequence oldText; private CharSequence oldText;
public void setSplitByWords(boolean b) {
splitByWords = b;
}
private static class Part { private static class Part {
StaticLayout layout; StaticLayout layout;
float offset; float offset;

View file

@ -39,7 +39,7 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
private float shadowAlpha = 1f; private float shadowAlpha = 1f;
public BottomSheetWithRecyclerListView(BaseFragment fragment, boolean needFocus, boolean hasFixedSize) { public BottomSheetWithRecyclerListView(BaseFragment fragment, boolean needFocus, boolean hasFixedSize) {
this(fragment, needFocus, hasFixedSize, false, null); this(fragment, needFocus, hasFixedSize, false, fragment == null ? null : fragment.getResourceProvider());
} }
public BottomSheetWithRecyclerListView(BaseFragment fragment, boolean needFocus, boolean hasFixedSize, boolean useNested, Theme.ResourcesProvider resourcesProvider) { public BottomSheetWithRecyclerListView(BaseFragment fragment, boolean needFocus, boolean hasFixedSize, boolean useNested, Theme.ResourcesProvider resourcesProvider) {

View file

@ -186,6 +186,12 @@ public class Bulletin {
} }
} }
public static void hideVisible(ViewGroup container) {
if (visibleBulletin != null && visibleBulletin.containerLayout == container) {
visibleBulletin.hide();
}
}
public Bulletin setDuration(int duration) { public Bulletin setDuration(int duration) {
this.duration = duration; this.duration = duration;
return this; return this;
@ -1745,32 +1751,20 @@ public class Bulletin {
// to make bulletin above everything // to make bulletin above everything
// use as BulletinFactory.of(BulletinWindow.make(context), resourcesProvider)... // use as BulletinFactory.of(BulletinWindow.make(context), resourcesProvider)...
public static class BulletinWindow extends Dialog { public static class BulletinWindow extends Dialog {
public static FrameLayout make(Context context) {
return new BulletinWindow(context).container; public static BulletinWindowLayout make(Context context, Delegate delegate) {
return new BulletinWindow(context, delegate).container;
} }
private final FrameLayout container; public static BulletinWindowLayout make(Context context) {
private BulletinWindow(Context context) { return new BulletinWindow(context, null).container;
}
private final BulletinWindowLayout container;
private BulletinWindow(Context context, Delegate delegate) {
super(context); super(context);
setContentView( setContentView(
container = new FrameLayout(context) { container = new BulletinWindowLayout(context),
@Override
public void addView(View child) {
super.addView(child);
BulletinWindow.this.show();
}
@Override
public void removeView(View child) {
super.removeView(child);
try {
BulletinWindow.this.dismiss();
} catch (Exception ignore) {
}
removeDelegate(container);
}
},
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
); );
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
@ -1794,12 +1788,17 @@ public class Bulletin {
addDelegate(container, new Delegate() { addDelegate(container, new Delegate() {
@Override @Override
public int getBottomOffset(int tag) { public int getBottomOffset(int tag) {
return 0; return delegate == null ? 0 : delegate.getBottomOffset(tag);
} }
@Override @Override
public int getTopOffset(int tag) { public int getTopOffset(int tag) {
return AndroidUtilities.statusBarHeight; return delegate == null ? AndroidUtilities.statusBarHeight : delegate.getTopOffset(tag);
}
@Override
public boolean clipWithGradient(int tag) {
return delegate != null && delegate.clipWithGradient(tag);
} }
}); });
@ -1807,8 +1806,9 @@ public class Bulletin {
Window window = getWindow(); Window window = getWindow();
window.setWindowAnimations(R.style.DialogNoAnimation); window.setWindowAnimations(R.style.DialogNoAnimation);
window.setBackgroundDrawable(null); window.setBackgroundDrawable(null);
WindowManager.LayoutParams params = window.getAttributes(); params = window.getAttributes();
params.width = ViewGroup.LayoutParams.MATCH_PARENT; params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.TOP | Gravity.LEFT; params.gravity = Gravity.TOP | Gravity.LEFT;
params.dimAmount = 0; params.dimAmount = 0;
params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND; params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
@ -1823,7 +1823,6 @@ public class Bulletin {
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
} }
params.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN; params.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
if (Build.VERSION.SDK_INT >= 28) { if (Build.VERSION.SDK_INT >= 28) {
params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
} }
@ -1843,6 +1842,52 @@ public class Bulletin {
); );
} }
} }
private WindowManager.LayoutParams params;
public class BulletinWindowLayout extends FrameLayout {
public BulletinWindowLayout(Context context) {
super(context);
}
@Override
public void addView(View child) {
super.addView(child);
BulletinWindow.this.show();
}
@Override
public void removeView(View child) {
super.removeView(child);
try {
BulletinWindow.this.dismiss();
} catch (Exception ignore) {
}
removeDelegate(container);
}
public void setTouchable(boolean touchable) {
if (params == null) {
return;
}
if (!touchable) {
params.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
} else {
params.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
}
BulletinWindow.this.getWindow().setAttributes(params);
}
@Nullable
public WindowManager.LayoutParams getLayout() {
return params;
}
public void updateLayout() {
BulletinWindow.this.getWindow().setAttributes(params);
}
}
} }
public Bulletin setTag(int tag) { public Bulletin setTag(int tag) {

View file

@ -171,6 +171,17 @@ public final class BulletinFactory {
return create(layout, text.length() < 20 ? Bulletin.DURATION_SHORT : Bulletin.DURATION_LONG); return create(layout, text.length() < 20 ? Bulletin.DURATION_SHORT : Bulletin.DURATION_LONG);
} }
public Bulletin createSimpleLargeBulletin(int iconRawId, CharSequence title, CharSequence subtitle) {
final Bulletin.TwoLineLayout layout = new Bulletin.TwoLineLayout(getContext(), resourcesProvider);
layout.imageView.setImageResource(iconRawId);
layout.titleTextView.setText(title);
layout.subtitleTextView.setText(subtitle);
layout.subtitleTextView.setSingleLine(false);
layout.subtitleTextView.setMaxLines(5);
return create(layout, Bulletin.DURATION_PROLONG);
}
public Bulletin createSimpleBulletin(int iconRawId, CharSequence text, int maxLines) { public Bulletin createSimpleBulletin(int iconRawId, CharSequence text, int maxLines) {
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider); final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider);
layout.setAnimation(iconRawId, 36, 36); layout.setAnimation(iconRawId, 36, 36);
@ -1032,6 +1043,21 @@ public final class BulletinFactory {
return Bulletin.make(fragment, layout, Bulletin.DURATION_SHORT); return Bulletin.make(fragment, layout, Bulletin.DURATION_SHORT);
} }
@CheckResult
public Bulletin createBanBulletin(boolean banned) {
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider);
final String text;
if (banned) {
layout.setAnimation(R.raw.ic_ban, "Hand");
text = LocaleController.getString("UserBlocked", R.string.UserBlocked);
} else {
layout.setAnimation(R.raw.ic_unban, "Main", "Finger 1", "Finger 2", "Finger 3", "Finger 4");
text = LocaleController.getString("UserUnblocked", R.string.UserUnblocked);
}
layout.textView.setText(AndroidUtilities.replaceTags(text));
return create(layout, Bulletin.DURATION_SHORT);
}
@CheckResult @CheckResult
public static Bulletin createCopyLinkBulletin(BaseFragment fragment) { public static Bulletin createCopyLinkBulletin(BaseFragment fragment) {
return of(fragment).createCopyLinkBulletin(); return of(fragment).createCopyLinkBulletin();

View file

@ -4,6 +4,7 @@ package org.telegram.ui.Components;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.animation.OvershootInterpolator; import android.view.animation.OvershootInterpolator;
@ -11,15 +12,24 @@ public class ButtonBounce {
private View view; private View view;
private final float durationMultiplier; private final float durationMultiplier;
private final float overshoot;
private long releaseDelay = 0;
public ButtonBounce(View viewToInvalidate) { public ButtonBounce(View viewToInvalidate) {
view = viewToInvalidate; view = viewToInvalidate;
durationMultiplier = 1f; durationMultiplier = 1f;
overshoot = 5.0f;
} }
public ButtonBounce(View viewToInvalidate, float durationMultiplier) { public ButtonBounce(View viewToInvalidate, float durationMultiplier, float overshoot) {
view = viewToInvalidate; view = viewToInvalidate;
this.durationMultiplier = durationMultiplier; this.durationMultiplier = durationMultiplier;
this.overshoot = overshoot;
}
public ButtonBounce setReleaseDelay(long releaseDelay) {
this.releaseDelay = releaseDelay;
return this;
} }
public void setView(View view) { public void setView(View view) {
@ -33,8 +43,10 @@ public class ButtonBounce {
public void setPressed(boolean pressed) { public void setPressed(boolean pressed) {
if (isPressed != pressed) { if (isPressed != pressed) {
isPressed = pressed; isPressed = pressed;
if (animator != null) { ValueAnimator pastAnimator = animator;
animator.cancel(); animator = null;
if (pastAnimator != null) {
pastAnimator.cancel();
} }
animator = ValueAnimator.ofFloat(pressedT, pressed ? 1 : 0); animator = ValueAnimator.ofFloat(pressedT, pressed ? 1 : 0);
animator.addUpdateListener(anm -> { animator.addUpdateListener(anm -> {
@ -44,17 +56,21 @@ public class ButtonBounce {
animator.addListener(new AnimatorListenerAdapter() { animator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
animator = null; if (animation == animator) {
pressedT = pressed ? 1 : 0; animator = null;
invalidate(); pressedT = pressed ? 1 : 0;
invalidate();
}
} }
}); });
if (isPressed) { if (isPressed) {
animator.setInterpolator(CubicBezierInterpolator.DEFAULT); animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
animator.setDuration((long) (60 * durationMultiplier)); animator.setDuration((long) (60 * durationMultiplier));
animator.setStartDelay(0);
} else { } else {
animator.setInterpolator(new OvershootInterpolator(5.0f)); animator.setInterpolator(new OvershootInterpolator(overshoot));
animator.setDuration((long) (350 * durationMultiplier)); animator.setDuration((long) (350 * durationMultiplier));
animator.setStartDelay(releaseDelay);
} }
animator.start(); animator.start();
} }

View file

@ -108,7 +108,9 @@ public class CacheChart extends View {
private static long particlesStart = -1; private static long particlesStart = -1;
class Sector { class Sector {
Paint particlePaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); Paint particlePaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); {
particlePaint.setColor(0xFFFFFFFF);
}
Bitmap particle; Bitmap particle;
float angleCenter, angleSize; float angleCenter, angleSize;

View file

@ -180,6 +180,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private Runnable animationEndRunnable; private Runnable animationEndRunnable;
private float attachLayoutTranslationX; private float attachLayoutTranslationX;
private float attachLayoutPaddingTranslationX; private float attachLayoutPaddingTranslationX;
private float attachLayoutAlpha = 1f;
private float attachLayoutPaddingAlpha = 1f;
private float messageTextTranslationX; private float messageTextTranslationX;
private float messageTextPaddingTranslationX; private float messageTextPaddingTranslationX;
private float horizontalPadding = 0; private float horizontalPadding = 0;
@ -935,6 +937,19 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
} }
}; };
private final Property<? super View, Float> ATTACH_LAYOUT_ALPHA = new Property<View, Float>(Float.class, "attach_scale") {
@Override
public Float get(View object) {
return attachLayoutAlpha;
}
@Override
public void set(View object, Float value) {
attachLayoutAlpha = value;
updateAttachLayoutParams();
}
};
private final Property<? super View, Float> EMOJI_BUTTON_ALPHA = new Property<View, Float>(Float.class, "emoji_button_alpha") { private final Property<? super View, Float> EMOJI_BUTTON_ALPHA = new Property<View, Float>(Float.class, "emoji_button_alpha") {
@Override @Override
public Float get(View object) { public Float get(View object) {
@ -2089,7 +2104,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
} }
attachLayout.addView(attachButton, LayoutHelper.createLinear(48, 48)); attachLayout.addView(attachButton, LayoutHelper.createLinear(48, 48));
attachButton.setOnClickListener(v -> { attachButton.setOnClickListener(v -> {
if (adjustPanLayoutHelper != null && adjustPanLayoutHelper.animationInProgress()) { if (adjustPanLayoutHelper != null && adjustPanLayoutHelper.animationInProgress() || attachLayoutPaddingAlpha == 0f) {
return; return;
} }
delegate.didPressAttachButton(); delegate.didPressAttachButton();
@ -3624,7 +3639,12 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (sendPopupWindow != null && sendPopupWindow.isShowing()) { if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss(); sendPopupWindow.dismiss();
} }
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), this::sendMessageInternal, resourcesProvider); AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), new AlertsCreator.ScheduleDatePickerDelegate() {
@Override
public void didSelectDate(boolean notify, int scheduleDate) {
sendMessageInternal(notify, scheduleDate, true);
}
}, resourcesProvider);
}); });
sendPopupLayout.addView(scheduleButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48)); sendPopupLayout.addView(scheduleButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
if (!self && dialog_id > 0) { if (!self && dialog_id > 0) {
@ -3635,7 +3655,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (sendPopupWindow != null && sendPopupWindow.isShowing()) { if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss(); sendPopupWindow.dismiss();
} }
sendMessageInternal(true, 0x7FFFFFFE); sendMessageInternal(true, 0x7FFFFFFE, true);
}); });
sendPopupLayout.addView(sendWhenOnlineButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48)); sendPopupLayout.addView(sendWhenOnlineButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
} }
@ -3648,7 +3668,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (sendPopupWindow != null && sendPopupWindow.isShowing()) { if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss(); sendPopupWindow.dismiss();
} }
sendMessageInternal(false, 0); sendMessageInternal(false, 0, true);
}); });
sendPopupLayout.addView(sendWithoutSoundButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48)); sendPopupLayout.addView(sendWithoutSoundButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
} }
@ -5486,14 +5506,19 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private void sendMessage() { private void sendMessage() {
if (isInScheduleMode()) { if (isInScheduleMode()) {
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), this::sendMessageInternal, resourcesProvider); AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), new AlertsCreator.ScheduleDatePickerDelegate() {
@Override
public void didSelectDate(boolean notify, int scheduleDate) {
sendMessageInternal(notify, scheduleDate, true);
}
}, resourcesProvider);
} else { } else {
sendMessageInternal(true, 0); sendMessageInternal(true, 0, true);
} }
} }
private boolean premiumEmojiBulletin = true; private boolean premiumEmojiBulletin = true;
private void sendMessageInternal(boolean notify, int scheduleDate) { private void sendMessageInternal(boolean notify, int scheduleDate, boolean allowConfirm) {
if (slowModeTimer == Integer.MAX_VALUE && !isInScheduleMode()) { if (slowModeTimer == Integer.MAX_VALUE && !isInScheduleMode()) {
if (delegate != null) { if (delegate != null) {
delegate.scrollToSendingMessage(); delegate.scrollToSendingMessage();
@ -5514,6 +5539,11 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
emojiView.hideSearchKeyboard(); emojiView.hideSearchKeyboard();
} }
} }
if (allowConfirm && showConfirmAlert(() -> {
sendMessageInternal(notify, scheduleDate, false);
})) {
return;
}
if (videoToSendMessageObject != null) { if (videoToSendMessageObject != null) {
delegate.needStartRecordVideo(4, notify, scheduleDate); delegate.needStartRecordVideo(4, notify, scheduleDate);
hideRecordedAudioPanel(true); hideRecordedAudioPanel(true);
@ -5579,6 +5609,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
} }
} }
protected boolean showConfirmAlert(Runnable onConfirmed) {
return false;
}
public static boolean checkPremiumAnimatedEmoji(int currentAccount, long dialogId, BaseFragment parentFragment, FrameLayout container, CharSequence message) { public static boolean checkPremiumAnimatedEmoji(int currentAccount, long dialogId, BaseFragment parentFragment, FrameLayout container, CharSequence message) {
if (message == null || parentFragment == null) { if (message == null || parentFragment == null) {
return false; return false;
@ -5850,7 +5884,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) { if (attachLayout != null) {
runningAnimation2 = new AnimatorSet(); runningAnimation2 = new AnimatorSet();
ArrayList<Animator> animators = new ArrayList<>(); ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 0.0f)); animators.add(ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 0.0f));
animators.add(ObjectAnimator.ofFloat(attachLayout, View.SCALE_X, 0.0f)); animators.add(ObjectAnimator.ofFloat(attachLayout, View.SCALE_X, 0.0f));
scheduleButtonHidden = false; scheduleButtonHidden = false;
boolean hasScheduled = delegate != null && delegate.hasScheduledMessages(); boolean hasScheduled = delegate != null && delegate.hasScheduledMessages();
@ -6034,7 +6068,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) { if (attachLayout != null) {
runningAnimation2 = new AnimatorSet(); runningAnimation2 = new AnimatorSet();
ArrayList<Animator> animators = new ArrayList<>(); ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 0.0f)); animators.add(ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 0.0f));
animators.add(ObjectAnimator.ofFloat(attachLayout, View.SCALE_X, 0.0f)); animators.add(ObjectAnimator.ofFloat(attachLayout, View.SCALE_X, 0.0f));
boolean hasScheduled = delegate != null && delegate.hasScheduledMessages(); boolean hasScheduled = delegate != null && delegate.hasScheduledMessages();
scheduleButtonHidden = true; scheduleButtonHidden = true;
@ -6226,7 +6260,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
attachLayout.setVisibility(VISIBLE); attachLayout.setVisibility(VISIBLE);
runningAnimation2 = new AnimatorSet(); runningAnimation2 = new AnimatorSet();
ArrayList<Animator> animators = new ArrayList<>(); ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 1.0f)); animators.add(ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 1.0f));
animators.add(ObjectAnimator.ofFloat(attachLayout, View.SCALE_X, 1.0f)); animators.add(ObjectAnimator.ofFloat(attachLayout, View.SCALE_X, 1.0f));
boolean hasScheduled = delegate != null && delegate.hasScheduledMessages(); boolean hasScheduled = delegate != null && delegate.hasScheduledMessages();
scheduleButtonHidden = false; scheduleButtonHidden = false;
@ -6386,12 +6420,13 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) { if (attachLayout != null) {
if (attachLayout.getVisibility() != View.VISIBLE) { if (attachLayout.getVisibility() != View.VISIBLE) {
attachLayout.setVisibility(VISIBLE); attachLayout.setVisibility(VISIBLE);
attachLayout.setAlpha(0f); attachLayoutAlpha = 0f;
updateAttachLayoutParams();
attachLayout.setScaleX(0f); attachLayout.setScaleX(0f);
} }
runningAnimation2 = new AnimatorSet(); runningAnimation2 = new AnimatorSet();
ArrayList<Animator> animators = new ArrayList<>(); ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 1.0f)); animators.add(ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 1.0f));
animators.add(ObjectAnimator.ofFloat(attachLayout, View.SCALE_X, 1.0f)); animators.add(ObjectAnimator.ofFloat(attachLayout, View.SCALE_X, 1.0f));
boolean hasScheduled = delegate != null && delegate.hasScheduledMessages(); boolean hasScheduled = delegate != null && delegate.hasScheduledMessages();
scheduleButtonHidden = false; scheduleButtonHidden = false;
@ -6524,7 +6559,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (getVisibility() == VISIBLE) { if (getVisibility() == VISIBLE) {
delegate.onAttachButtonShow(); delegate.onAttachButtonShow();
} }
attachLayout.setAlpha(1.0f); attachLayoutAlpha = 1.0f;
updateAttachLayoutParams();
attachLayout.setScaleX(1.0f); attachLayout.setScaleX(1.0f);
attachLayout.setVisibility(VISIBLE); attachLayout.setVisibility(VISIBLE);
updateFieldRight(1); updateFieldRight(1);
@ -6715,7 +6751,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) { if (attachLayout != null) {
viewTransition.playTogether( viewTransition.playTogether(
ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_TRANSLATION_X, AndroidUtilities.dp(30)), ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_TRANSLATION_X, AndroidUtilities.dp(30)),
ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 0f) ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 0f)
); );
} }
@ -6826,7 +6862,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) { if (attachLayout != null) {
runningAnimationAudio.playTogether( runningAnimationAudio.playTogether(
ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_TRANSLATION_X, 0), ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_TRANSLATION_X, 0),
ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 1f) ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 1f)
); );
} }
@ -7072,7 +7108,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
); );
if (attachLayout != null) { if (attachLayout != null) {
iconsAnimator.playTogether( iconsAnimator.playTogether(
ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 1f), ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 1f),
ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_TRANSLATION_X, 0) ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_TRANSLATION_X, 0)
); );
} }
@ -7108,7 +7144,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) { if (attachLayout != null) {
icons2.playTogether( icons2.playTogether(
ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_TRANSLATION_X, 0), ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_TRANSLATION_X, 0),
ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 1f) ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 1f)
); );
} }
if (scheduledButton != null) { if (scheduledButton != null) {
@ -7198,7 +7234,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
attachLayoutTranslationX = 0; attachLayoutTranslationX = 0;
updateAttachLayoutParams(); updateAttachLayoutParams();
iconsAnimator.playTogether( iconsAnimator.playTogether(
ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 1f) ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 1f)
); );
} }
if (scheduledButton != null) { if (scheduledButton != null) {
@ -7546,7 +7582,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
setSlowModeButtonVisible(true); setSlowModeButtonVisible(true);
} }
attachLayout.setScaleX(0.01f); attachLayout.setScaleX(0.01f);
attachLayout.setAlpha(0.0f); attachLayoutAlpha = 0f;
updateAttachLayoutParams();
attachLayout.setVisibility(GONE); attachLayout.setVisibility(GONE);
audioVideoButtonContainer.setScaleX(0.1f); audioVideoButtonContainer.setScaleX(0.1f);
audioVideoButtonContainer.setScaleY(0.1f); audioVideoButtonContainer.setScaleY(0.1f);
@ -7562,7 +7599,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
slowModeButton.setAlpha(0.0f); slowModeButton.setAlpha(0.0f);
setSlowModeButtonVisible(false); setSlowModeButtonVisible(false);
attachLayout.setScaleX(1.0f); attachLayout.setScaleX(1.0f);
attachLayout.setAlpha(1.0f); attachLayoutAlpha = 1.0f;
updateAttachLayoutParams();
attachLayout.setVisibility(VISIBLE); attachLayout.setVisibility(VISIBLE);
audioVideoButtonContainer.setScaleX(1.0f); audioVideoButtonContainer.setScaleX(1.0f);
audioVideoButtonContainer.setScaleY(1.0f); audioVideoButtonContainer.setScaleY(1.0f);
@ -8642,50 +8680,56 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
} }
return; return;
} }
if (stickersExpanded) { Runnable runnable = () -> {
if (searchingType != 0) {
emojiView.hideSearchKeyboard();
}
setStickersExpanded(false, true, false);
}
TLRPC.StoryItem storyItem = delegate != null ? delegate.getReplyToStory() : null;
if (gif instanceof TLRPC.Document) {
TLRPC.Document document = (TLRPC.Document) gif;
SendMessagesHelper.getInstance(currentAccount).sendSticker(document, query, dialog_id, replyingMessageObject, getThreadMessage(), storyItem, null, notify, scheduleDate, false, parent);
MediaDataController.getInstance(currentAccount).addRecentGif(document, (int) (System.currentTimeMillis() / 1000), true);
if (DialogObject.isEncryptedDialog(dialog_id)) {
accountInstance.getMessagesController().saveGif(parent, document);
}
} else if (gif instanceof TLRPC.BotInlineResult) {
TLRPC.BotInlineResult result = (TLRPC.BotInlineResult) gif;
if (result.document != null) { if (stickersExpanded) {
MediaDataController.getInstance(currentAccount).addRecentGif(result.document, (int) (System.currentTimeMillis() / 1000), false); if (searchingType != 0) {
emojiView.hideSearchKeyboard();
}
setStickersExpanded(false, true, false);
}
TLRPC.StoryItem storyItem = delegate != null ? delegate.getReplyToStory() : null;
if (gif instanceof TLRPC.Document) {
TLRPC.Document document = (TLRPC.Document) gif;
SendMessagesHelper.getInstance(currentAccount).sendSticker(document, query, dialog_id, replyingMessageObject, getThreadMessage(), storyItem, null, notify, scheduleDate, false, parent);
MediaDataController.getInstance(currentAccount).addRecentGif(document, (int) (System.currentTimeMillis() / 1000), true);
if (DialogObject.isEncryptedDialog(dialog_id)) { if (DialogObject.isEncryptedDialog(dialog_id)) {
accountInstance.getMessagesController().saveGif(parent, result.document); accountInstance.getMessagesController().saveGif(parent, document);
}
} else if (gif instanceof TLRPC.BotInlineResult) {
TLRPC.BotInlineResult result = (TLRPC.BotInlineResult) gif;
if (result.document != null) {
MediaDataController.getInstance(currentAccount).addRecentGif(result.document, (int) (System.currentTimeMillis() / 1000), false);
if (DialogObject.isEncryptedDialog(dialog_id)) {
accountInstance.getMessagesController().saveGif(parent, result.document);
}
}
TLRPC.User bot = (TLRPC.User) parent;
HashMap<String, String> params = new HashMap<>();
params.put("id", result.id);
params.put("query_id", "" + result.query_id);
params.put("force_gif", "1");
if (storyItem == null) {
SendMessagesHelper.prepareSendingBotContextResult(parentFragment, accountInstance, result, params, dialog_id, replyingMessageObject, getThreadMessage(), storyItem, notify, scheduleDate);
} else {
SendMessagesHelper.getInstance(currentAccount).sendSticker(result.document, query, dialog_id, replyingMessageObject, getThreadMessage(), storyItem, null, notify, scheduleDate, false, parent);
}
if (searchingType != 0) {
setSearchingTypeInternal(0, true);
emojiView.closeSearch(true);
emojiView.hideSearchKeyboard();
} }
} }
if (delegate != null) {
TLRPC.User bot = (TLRPC.User) parent; delegate.onMessageSend(null, notify, scheduleDate);
HashMap<String, String> params = new HashMap<>();
params.put("id", result.id);
params.put("query_id", "" + result.query_id);
params.put("force_gif", "1");
if (storyItem == null) {
SendMessagesHelper.prepareSendingBotContextResult(parentFragment, accountInstance, result, params, dialog_id, replyingMessageObject, getThreadMessage(), storyItem, notify, scheduleDate);
} else {
SendMessagesHelper.getInstance(currentAccount).sendSticker(result.document, query, dialog_id, replyingMessageObject, getThreadMessage(), storyItem, null, notify, scheduleDate, false, parent);
} }
if (searchingType != 0) { };
setSearchingTypeInternal(0, true); if (!showConfirmAlert(runnable)) {
emojiView.closeSearch(true); runnable.run();
emojiView.hideSearchKeyboard();
}
}
if (delegate != null) {
delegate.onMessageSend(null, notify, scheduleDate);
} }
} }
} }
@ -8911,27 +8955,32 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (isInScheduleMode() && scheduleDate == 0) { if (isInScheduleMode() && scheduleDate == 0) {
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (n, s) -> onStickerSelected(sticker, query, parent, sendAnimationData, clearsInputField, n, s), resourcesProvider); AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (n, s) -> onStickerSelected(sticker, query, parent, sendAnimationData, clearsInputField, n, s), resourcesProvider);
} else { } else {
if (slowModeTimer > 0 && !isInScheduleMode()) { Runnable runnable = () -> {
if (delegate != null) { if (slowModeTimer > 0 && !isInScheduleMode()) {
delegate.onUpdateSlowModeButton(slowModeButton, true, slowModeButton.getText()); if (delegate != null) {
delegate.onUpdateSlowModeButton(slowModeButton, true, slowModeButton.getText());
}
return;
} }
return; if (searchingType != 0) {
setSearchingTypeInternal(0, true);
emojiView.closeSearch(true);
emojiView.hideSearchKeyboard();
}
setStickersExpanded(false, true, false);
TLRPC.StoryItem storyItem = delegate != null ? delegate.getReplyToStory() : null;
SendMessagesHelper.getInstance(currentAccount).sendSticker(sticker, query, dialog_id, replyingMessageObject, getThreadMessage(), storyItem, sendAnimationData, notify, scheduleDate, parent instanceof TLRPC.TL_messages_stickerSet, parent);
if (delegate != null) {
delegate.onMessageSend(null, true, scheduleDate);
}
if (clearsInputField) {
setFieldText("");
}
MediaDataController.getInstance(currentAccount).addRecentSticker(MediaDataController.TYPE_IMAGE, parent, sticker, (int) (System.currentTimeMillis() / 1000), false);
};
if (!showConfirmAlert(runnable)) {
runnable.run();
} }
if (searchingType != 0) {
setSearchingTypeInternal(0, true);
emojiView.closeSearch(true);
emojiView.hideSearchKeyboard();
}
setStickersExpanded(false, true, false);
TLRPC.StoryItem storyItem = delegate != null ? delegate.getReplyToStory() : null;
SendMessagesHelper.getInstance(currentAccount).sendSticker(sticker, query, dialog_id, replyingMessageObject, getThreadMessage(), storyItem, sendAnimationData, notify, scheduleDate, parent instanceof TLRPC.TL_messages_stickerSet, parent);
if (delegate != null) {
delegate.onMessageSend(null, true, scheduleDate);
}
if (clearsInputField) {
setFieldText("");
}
MediaDataController.getInstance(currentAccount).addRecentSticker(MediaDataController.TYPE_IMAGE, parent, sticker, (int) (System.currentTimeMillis() / 1000), false);
} }
} }
@ -10330,7 +10379,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
float offsetY = enableTransition ? 0 : cancelToProgress * AndroidUtilities.dp(12); float offsetY = enableTransition ? 0 : cancelToProgress * AndroidUtilities.dp(12);
if (cancelToProgress != 1) { if (cancelToProgress != 1) {
int slideDelta = (int) (-getMeasuredWidth() / 4 * (1f - slideProgress)); int slideDelta = (int) (-getMeasuredWidth() / 4 * (1f - slideProgress) + recordCircle.getTranslationX() * 0.3f);
canvas.save(); canvas.save();
canvas.clipRect((recordTimerView == null ? 0 : recordTimerView.getLeftProperty()) + AndroidUtilities.dp(4), 0, getMeasuredWidth(), getMeasuredHeight()); canvas.clipRect((recordTimerView == null ? 0 : recordTimerView.getLeftProperty()) + AndroidUtilities.dp(4), 0, getMeasuredWidth(), getMeasuredHeight());
canvas.save(); canvas.save();
@ -10774,29 +10823,34 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
} }
public void setHorizontalPadding(float padding, float progress, boolean allowShare) { public void setHorizontalPadding(float padding, float progress, boolean allowShare) {
float v = -padding * (1f - progress); float leftPadding = -padding * (1f - progress);
float rightPadding = -(padding + AndroidUtilities.dp(40)) * (1f - progress);
float s = 0.5f + 0.5f * progress; float s = 0.5f + 0.5f * progress;
emojiButtonPaddingScale = s; emojiButtonPaddingScale = s;
emojiButtonPaddingAlpha = progress; emojiButtonPaddingAlpha = progress;
updateEmojiButtonParams(); updateEmojiButtonParams();
emojiButton.setTranslationX(-v); emojiButton.setTranslationX(-leftPadding);
messageTextPaddingTranslationX = -v - AndroidUtilities.dp(31) * (1f - progress); messageTextPaddingTranslationX = -leftPadding - AndroidUtilities.dp(31) * (1f - progress);
if (recordDeleteImageView != null) { if (recordDeleteImageView != null) {
recordDeleteImageView.setTranslationX(-v); recordDeleteImageView.setTranslationX(-leftPadding);
}
if (recordCircle != null) {
recordCircle.setTranslationX(rightPadding);
} }
if (recordTimeContainer != null) { if (recordTimeContainer != null) {
recordTimeContainer.setTranslationX(-v); recordTimeContainer.setTranslationX(-leftPadding);
} }
if (recordedAudioPlayButton != null) { if (recordedAudioPlayButton != null) {
recordedAudioPlayButton.setTranslationX(-v); recordedAudioPlayButton.setTranslationX(-leftPadding);
} }
if (recordedAudioTimeTextView != null) { if (recordedAudioTimeTextView != null) {
recordedAudioTimeTextView.setTranslationX(v); recordedAudioTimeTextView.setTranslationX(leftPadding);
} }
sendButtonContainer.setTranslationX(v); sendButtonContainer.setTranslationX(rightPadding);
sendButtonContainer.setAlpha(allowShare ? progress : 1f); sendButtonContainer.setAlpha(allowShare ? progress : 1f);
sendButtonEnabled = allowShare ? progress == 1f : true; sendButtonEnabled = allowShare ? progress == 1f : true;
attachLayoutPaddingTranslationX = v; attachLayoutPaddingTranslationX = rightPadding;
attachLayoutPaddingAlpha = progress;
updateAttachLayoutParams(); updateAttachLayoutParams();
updateMessageTextParams(); updateMessageTextParams();
float newPadding = padding * (1f - progress); float newPadding = padding * (1f - progress);
@ -10823,6 +10877,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private void updateAttachLayoutParams() { private void updateAttachLayoutParams() {
if (attachLayout != null) { if (attachLayout != null) {
attachLayout.setTranslationX(attachLayoutPaddingTranslationX + attachLayoutTranslationX); attachLayout.setTranslationX(attachLayoutPaddingTranslationX + attachLayoutTranslationX);
attachLayout.setAlpha(attachLayoutAlpha * attachLayoutPaddingAlpha);
attachLayout.setVisibility(attachLayout.getAlpha() > 0 ? View.VISIBLE : View.GONE);
} }
} }
@ -10833,8 +10889,12 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
} }
public void setOverrideHint(CharSequence overrideHint) { public void setOverrideHint(CharSequence overrideHint) {
setOverrideHint(overrideHint, false);
}
public void setOverrideHint(CharSequence overrideHint, boolean animated) {
this.overrideHint = overrideHint; this.overrideHint = overrideHint;
updateFieldHint(false); updateFieldHint(animated);
} }
public void setOverrideKeyboardAnimation(boolean overrideKeyboardAnimation) { public void setOverrideKeyboardAnimation(boolean overrideKeyboardAnimation) {

View file

@ -15,6 +15,7 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.ContextWrapper; import android.content.ContextWrapper;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -109,6 +110,7 @@ import org.telegram.ui.PhotoPickerActivity;
import org.telegram.ui.PhotoPickerSearchActivity; import org.telegram.ui.PhotoPickerSearchActivity;
import org.telegram.ui.PremiumPreviewFragment; import org.telegram.ui.PremiumPreviewFragment;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -127,6 +129,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
public boolean canOpenPreview = false; public boolean canOpenPreview = false;
private boolean isSoundPicker = false; private boolean isSoundPicker = false;
public boolean isStoryLocationPicker = false;
private ImageUpdater.AvatarFor setAvatarFor; private ImageUpdater.AvatarFor setAvatarFor;
public boolean pinnedToTop; public boolean pinnedToTop;
@ -1514,6 +1517,38 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
super.requestLayout(); super.requestLayout();
} }
private float getY(View child) {
if (child instanceof AttachAlertLayout) {
AttachAlertLayout layout = (AttachAlertLayout) child;
int actionBarType = layout.needsActionBar();
int offset = AndroidUtilities.dp(13) + (int) ((headerView != null ? headerView.getAlpha() : 0f) * AndroidUtilities.dp(26));
int top = getScrollOffsetY(0) - backgroundPaddingTop - offset;
if (currentSheetAnimationType == 1 || viewChangeAnimator != null) {
top += child.getTranslationY();
}
int y = top + AndroidUtilities.dp(20);
int h = (actionBarType != 0 ? ActionBar.getCurrentActionBarHeight() : backgroundPaddingTop);
if (actionBarType != 2 && top + backgroundPaddingTop < h) {
float toMove = offset;
if (layout == locationLayout) {
toMove += AndroidUtilities.dp(11);
} else if (layout == pollLayout) {
toMove -= AndroidUtilities.dp(3);
} else {
toMove += AndroidUtilities.dp(4);
}
float availableToMove = h - toMove + AndroidUtilities.statusBarHeight;
y -= (int) (availableToMove * actionBar.getAlpha());
}
if (Build.VERSION.SDK_INT >= 21 && !inBubbleMode) {
y += AndroidUtilities.statusBarHeight;
}
return y;
}
return 0;
}
private void drawChildBackground(Canvas canvas, View child) { private void drawChildBackground(Canvas canvas, View child) {
if (child instanceof AttachAlertLayout) { if (child instanceof AttachAlertLayout) {
canvas.save(); canvas.save();
@ -1522,7 +1557,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
AttachAlertLayout layout = (AttachAlertLayout) child; AttachAlertLayout layout = (AttachAlertLayout) child;
int actionBarType = layout.needsActionBar(); int actionBarType = layout.needsActionBar();
int offset = AndroidUtilities.dp(13) + (headerView != null ? AndroidUtilities.dp(headerView.getAlpha() * 26) : 0); int offset = AndroidUtilities.dp(13) + (int) ((headerView != null ? headerView.getAlpha() : 0f) * AndroidUtilities.dp(26));
int top = getScrollOffsetY(0) - backgroundPaddingTop - offset; int top = getScrollOffsetY(0) - backgroundPaddingTop - offset;
if (currentSheetAnimationType == 1 || viewChangeAnimator != null) { if (currentSheetAnimationType == 1 || viewChangeAnimator != null) {
top += child.getTranslationY(); top += child.getTranslationY();
@ -1537,7 +1572,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (top < h) { if (top < h) {
rad = Math.max(0, 1.0f - (h - top) / (float) backgroundPaddingTop); rad = Math.max(0, 1.0f - (h - top) / (float) backgroundPaddingTop);
} }
} else if (top + backgroundPaddingTop < h) { } else {
float toMove = offset; float toMove = offset;
if (layout == locationLayout) { if (layout == locationLayout) {
toMove += AndroidUtilities.dp(11); toMove += AndroidUtilities.dp(11);
@ -1546,8 +1581,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
} else { } else {
toMove += AndroidUtilities.dp(4); toMove += AndroidUtilities.dp(4);
} }
float moveProgress = Math.min(1.0f, (h - top - backgroundPaddingTop) / toMove); float moveProgress = actionBar.getAlpha();
float availableToMove = h - toMove; float availableToMove = h - toMove + AndroidUtilities.statusBarHeight;
int diff = (int) (availableToMove * moveProgress); int diff = (int) (availableToMove * moveProgress);
top -= diff; top -= diff;
@ -1673,24 +1708,10 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
} }
} }
boolean clip = !drawBackground && (headerView != null && headerView.getAlpha() > .9f) && (currentAttachLayout instanceof ChatAttachAlertPhotoLayoutPreview || nextAttachLayout instanceof ChatAttachAlertPhotoLayoutPreview) && (viewChangeAnimator instanceof SpringAnimation && ((SpringAnimation) viewChangeAnimator).isRunning()); canvas.save();
if (clip) { canvas.clipRect(backgroundPaddingLeft, actionBar.getY() + actionBar.getMeasuredHeight() - currentPanTranslationY, getMeasuredWidth() - backgroundPaddingLeft, getMeasuredHeight());
canvas.save();
int finalMove;
if (AndroidUtilities.isTablet()) {
finalMove = 16;
} else if (AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y) {
finalMove = 6;
} else {
finalMove = 12;
}
int clipTop = (int) (baseSelectedTextViewTranslationY + AndroidUtilities.statusBarHeight + headerView.getHeight() + AndroidUtilities.dp(finalMove * headerView.getAlpha()));
canvas.clipRect(backgroundPaddingLeft, clipTop, getMeasuredWidth() - backgroundPaddingLeft, getMeasuredHeight());
}
boolean result = super.drawChild(canvas, child, drawingTime); boolean result = super.drawChild(canvas, child, drawingTime);
if (clip) { canvas.restore();
canvas.restore();
}
if (drawBackground) { if (drawBackground) {
if (rad != 1.0f && actionBarType != 2) { if (rad != 1.0f && actionBarType != 2) {
@ -1723,6 +1744,19 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
} }
canvas.restore(); canvas.restore();
return result; return result;
} else if (child == actionBar) {
final float alpha = actionBar.getAlpha();
if (alpha <= 0) {
return false;
}
if (alpha >= 1) {
return super.drawChild(canvas, child, drawingTime);
}
canvas.save();
canvas.clipRect(actionBar.getX(), getY(currentAttachLayout), actionBar.getX() + actionBar.getWidth(), actionBar.getY() + actionBar.getHeight());
boolean result = super.drawChild(canvas, child, drawingTime);
canvas.restore();
return result;
} }
return super.drawChild(canvas, child, drawingTime); return super.drawChild(canvas, child, drawingTime);
} }
@ -1732,10 +1766,10 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (inBubbleMode) { if (inBubbleMode) {
return; return;
} }
int color1 = currentAttachLayout.hasCustomBackground() ? currentAttachLayout.getCustomBackground() : getThemedColor(forceDarkTheme ? Theme.key_voipgroup_listViewBackground : Theme.key_dialogBackground); // int color1 = currentAttachLayout.hasCustomBackground() ? currentAttachLayout.getCustomBackground() : getThemedColor(forceDarkTheme ? Theme.key_voipgroup_listViewBackground : Theme.key_dialogBackground);
int finalColor = Color.argb((int) (255 * actionBar.getAlpha()), Color.red(color1), Color.green(color1), Color.blue(color1)); // int finalColor = Color.argb((int) (255 * actionBar.getAlpha()), Color.red(color1), Color.green(color1), Color.blue(color1));
Theme.dialogs_onlineCirclePaint.setColor(finalColor); // Theme.dialogs_onlineCirclePaint.setColor(finalColor);
canvas.drawRect(backgroundPaddingLeft, currentPanTranslationY, getMeasuredWidth() - backgroundPaddingLeft, AndroidUtilities.statusBarHeight + currentPanTranslationY, Theme.dialogs_onlineCirclePaint); // canvas.drawRect(backgroundPaddingLeft, currentPanTranslationY, getMeasuredWidth() - backgroundPaddingLeft, AndroidUtilities.statusBarHeight + currentPanTranslationY, Theme.dialogs_onlineCirclePaint);
} }
private int getCurrentTop() { private int getCurrentTop() {
@ -1749,7 +1783,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
@Override @Override
protected void dispatchDraw(Canvas canvas) { protected void dispatchDraw(Canvas canvas) {
canvas.save(); canvas.save();
canvas.clipRect(0, getPaddingTop() + currentPanTranslationY, getMeasuredWidth(), getMeasuredHeight() + currentPanTranslationY - getPaddingBottom()); // canvas.clipRect(0, getPaddingTop() + currentPanTranslationY, getMeasuredWidth(), getMeasuredHeight() + currentPanTranslationY - getPaddingBottom());
if (currentAttachLayout == photoPreviewLayout || nextAttachLayout == photoPreviewLayout || (currentAttachLayout == photoLayout && nextAttachLayout == null)) { if (currentAttachLayout == photoPreviewLayout || nextAttachLayout == photoPreviewLayout || (currentAttachLayout == photoLayout && nextAttachLayout == null)) {
drawChildBackground(canvas, currentAttachLayout); drawChildBackground(canvas, currentAttachLayout);
} }
@ -2083,6 +2117,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
return; return;
} }
if (view instanceof AttachButton) { if (view instanceof AttachButton) {
final Activity activity = baseFragment.getParentActivity();
int num = (Integer) view.getTag(); int num = (Integer) view.getTag();
if (num == 1) { if (num == 1) {
if (!photosEnabled && !videosEnabled) { if (!photosEnabled && !videosEnabled) {
@ -2090,13 +2125,24 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
} }
showLayout(photoLayout); showLayout(photoLayout);
} else if (num == 3) { } else if (num == 3) {
if (Build.VERSION.SDK_INT >= 23 && getContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT >= 33) {
if (activity.checkSelfPermission(Manifest.permission.READ_MEDIA_AUDIO) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.READ_MEDIA_AUDIO}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
return;
}
} else if (Build.VERSION.SDK_INT >= 23 && activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
AndroidUtilities.findActivity(getContext()).requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE); AndroidUtilities.findActivity(getContext()).requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
return; return;
} }
openAudioLayout(true); openAudioLayout(true);
} else if (num == 4) { } else if (num == 4) {
if (Build.VERSION.SDK_INT >= 23 && getContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT >= 33) {
if (activity.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED ||
activity.checkSelfPermission(Manifest.permission.READ_MEDIA_VIDEO) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
return;
}
} else if (Build.VERSION.SDK_INT >= 23 && activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
AndroidUtilities.findActivity(getContext()).requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE); AndroidUtilities.findActivity(getContext()).requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
return; return;
} }
@ -3771,6 +3817,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
actionBarAnimation = null; actionBarAnimation = null;
} }
}); });
actionBarAnimation.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
actionBarAnimation.setDuration(380);
actionBarAnimation.start(); actionBarAnimation.start();
} else { } else {
if (show) { if (show) {
@ -3813,7 +3861,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
animated = false; animated = false;
} }
if (layout == currentAttachLayout) { if (layout == currentAttachLayout) {
updateActionBarVisibility(show, animated); updateActionBarVisibility(show, true);
} }
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) layout.getLayoutParams(); FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) layout.getLayoutParams();
newOffset += (layoutParams == null ? 0 : layoutParams.topMargin) - AndroidUtilities.dp(11); newOffset += (layoutParams == null ? 0 : layoutParams.topMargin) - AndroidUtilities.dp(11);
@ -3969,7 +4017,14 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
enterCommentEventSent = false; enterCommentEventSent = false;
setFocusable(false); setFocusable(false);
ChatAttachAlert.AttachAlertLayout layoutToSet; ChatAttachAlert.AttachAlertLayout layoutToSet;
if (isSoundPicker) { if (isStoryLocationPicker) {
if (locationLayout == null) {
layouts[5] = locationLayout = new ChatAttachAlertLocationLayout(this, getContext(), resourcesProvider);
locationLayout.setDelegate((location, live, notify, scheduleDate) -> ((ChatActivity) baseFragment).didSelectLocation(location, live, notify, scheduleDate));
}
selectedId = 5;
layoutToSet = locationLayout;
} else if (isSoundPicker) {
openDocumentsLayout(false); openDocumentsLayout(false);
layoutToSet = documentLayout; layoutToSet = documentLayout;
selectedId = 4; selectedId = 4;
@ -4106,6 +4161,29 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
selectedTextView.setText(LocaleController.getString("ChoosePhotoOrVideo", R.string.ChoosePhotoOrVideo)); selectedTextView.setText(LocaleController.getString("ChoosePhotoOrVideo", R.string.ChoosePhotoOrVideo));
} }
public boolean storyLocationPickerFileIsVideo;
public File storyLocationPickerPhotoFile;
public double[] storyLocationPickerLatLong;
public void setStoryLocationPicker() {
isStoryLocationPicker = true;
buttonsRecyclerView.setVisibility(View.GONE);
shadow.setVisibility(View.GONE);
}
public void setStoryLocationPicker(boolean isVideo, File photo) {
storyLocationPickerFileIsVideo = isVideo;
storyLocationPickerPhotoFile = photo;
isStoryLocationPicker = true;
buttonsRecyclerView.setVisibility(View.GONE);
shadow.setVisibility(View.GONE);
}
public void setStoryLocationPicker(double lat, double lon) {
storyLocationPickerLatLong = new double[] { lat, lon };
isStoryLocationPicker = true;
buttonsRecyclerView.setVisibility(View.GONE);
shadow.setVisibility(View.GONE);
}
public void setMaxSelectedPhotos(int value, boolean order) { public void setMaxSelectedPhotos(int value, boolean order) {
if (editingMessageObject != null) { if (editingMessageObject != null) {
return; return;

View file

@ -29,6 +29,8 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.location.Location; import android.location.Location;
import android.location.LocationManager; import android.location.LocationManager;
import android.media.ExifInterface;
import android.media.MediaMetadataRetriever;
import android.os.Build; import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.TypedValue; import android.util.TypedValue;
@ -44,6 +46,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller; import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -69,6 +72,7 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ActionBar.ThemeDescription; import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Adapters.LocationActivityAdapter; import org.telegram.ui.Adapters.LocationActivityAdapter;
import org.telegram.ui.Adapters.LocationActivitySearchAdapter; import org.telegram.ui.Adapters.LocationActivitySearchAdapter;
import org.telegram.ui.BasePermissionsActivity;
import org.telegram.ui.Cells.HeaderCell; import org.telegram.ui.Cells.HeaderCell;
import org.telegram.ui.Cells.LocationCell; import org.telegram.ui.Cells.LocationCell;
import org.telegram.ui.Cells.LocationDirectionCell; import org.telegram.ui.Cells.LocationDirectionCell;
@ -79,9 +83,12 @@ import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.SharingLiveLocationCell; import org.telegram.ui.Cells.SharingLiveLocationCell;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLayout implements NotificationCenter.NotificationCenterDelegate { public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLayout implements NotificationCenter.NotificationCenterDelegate {
@ -119,6 +126,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
private boolean currentMapStyleDark; private boolean currentMapStyleDark;
private boolean checkGpsEnabled = true; private boolean checkGpsEnabled = true;
private boolean askedForLocation = false;
private boolean locationDenied = false; private boolean locationDenied = false;
private boolean isFirstLocation = true; private boolean isFirstLocation = true;
@ -151,6 +159,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
private Location userLocation; private Location userLocation;
private int markerTop; private int markerTop;
private boolean ignoreIdleCamera;
private boolean userLocationMoved; private boolean userLocationMoved;
private boolean searchedForCustomLocations; private boolean searchedForCustomLocations;
private boolean firstWas; private boolean firstWas;
@ -169,6 +178,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
public final static int LOCATION_TYPE_SEND = 0; public final static int LOCATION_TYPE_SEND = 0;
public final static int LOCATION_TYPE_SEND_WITH_LIVE = 1; public final static int LOCATION_TYPE_SEND_WITH_LIVE = 1;
public final static int LOCATION_TYPE_STORY = 7;
public static class VenueLocation { public static class VenueLocation {
public int num; public int num;
@ -362,7 +372,9 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
AndroidUtilities.fixGoogleMapsBug(); AndroidUtilities.fixGoogleMapsBug();
ChatActivity chatActivity = (ChatActivity) parentAlert.baseFragment; ChatActivity chatActivity = (ChatActivity) parentAlert.baseFragment;
dialogId = chatActivity.getDialogId(); dialogId = chatActivity.getDialogId();
if (chatActivity.getCurrentEncryptedChat() == null && !chatActivity.isInScheduleMode() && !UserObject.isUserSelf(chatActivity.getCurrentUser())) { if (parentAlert.isStoryLocationPicker) {
locationType = LOCATION_TYPE_STORY;
} else if (chatActivity.getCurrentEncryptedChat() == null && !chatActivity.isInScheduleMode() && !UserObject.isUserSelf(chatActivity.getCurrentUser())) {
locationType = LOCATION_TYPE_SEND_WITH_LIVE; locationType = LOCATION_TYPE_SEND_WITH_LIVE;
} else { } else {
locationType = LOCATION_TYPE_SEND; locationType = LOCATION_TYPE_SEND;
@ -443,7 +455,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
searchAdapter.searchDelayed(text, userLocation); searchAdapter.searchDelayed(text, userLocation);
} }
}); });
searchItem.setVisibility(locationDenied ? View.GONE : View.VISIBLE); searchItem.setVisibility(locationDenied && !parentAlert.isStoryLocationPicker ? View.GONE : View.VISIBLE);
searchItem.setSearchFieldHint(LocaleController.getString("Search", R.string.Search)); searchItem.setSearchFieldHint(LocaleController.getString("Search", R.string.Search));
searchItem.setContentDescription(LocaleController.getString("Search", R.string.Search)); searchItem.setContentDescription(LocaleController.getString("Search", R.string.Search));
EditTextBoldCursor editText = searchItem.getSearchField(); EditTextBoldCursor editText = searchItem.getSearchField();
@ -676,9 +688,15 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
} }
}; };
listView.setClipToPadding(false); listView.setClipToPadding(false);
listView.setAdapter(adapter = new LocationActivityAdapter(context, locationType, dialogId, true, resourcesProvider)); listView.setAdapter(adapter = new LocationActivityAdapter(context, locationType, dialogId, true, resourcesProvider, parentAlert.isStoryLocationPicker));
DefaultItemAnimator itemAnimator = new DefaultItemAnimator();
itemAnimator.setDurations(350);
itemAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
itemAnimator.setDelayAnimations(false);
itemAnimator.setSupportsChangeAnimations(false);
listView.setItemAnimator(itemAnimator);
adapter.setUpdateRunnable(this::updateClipView); adapter.setUpdateRunnable(this::updateClipView);
adapter.setMyLocationDenied(locationDenied); adapter.setMyLocationDenied(locationDenied, askedForLocation);
listView.setVerticalScrollBarEnabled(false); listView.setVerticalScrollBarEnabled(false);
listView.setLayoutManager(layoutManager = new FillLastLinearLayoutManager(context, LinearLayoutManager.VERTICAL, false, 0, listView) { listView.setLayoutManager(layoutManager = new FillLastLinearLayoutManager(context, LinearLayoutManager.VERTICAL, false, 0, listView) {
@Override @Override
@ -732,7 +750,17 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
} }
}); });
listView.setOnItemClickListener((view, position) -> { listView.setOnItemClickListener((view, position) -> {
if (position == 1) { if (locationType == LOCATION_TYPE_STORY) {
if (position == 1 && adapter.city != null) {
delegate.didSelectLocation(adapter.city, locationType, true, 0);
parentAlert.dismiss(true);
return;
} else if (position == 2 && adapter.street != null) {
delegate.didSelectLocation(adapter.street, locationType, true, 0);
parentAlert.dismiss(true);
return;
}
} else if (position == 1) {
if (delegate != null && userLocation != null) { if (delegate != null && userLocation != null) {
if (lastPressedMarkerView != null) { if (lastPressedMarkerView != null) {
lastPressedMarkerView.callOnClick(); lastPressedMarkerView.callOnClick();
@ -754,6 +782,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
} else if (locationDenied) { } else if (locationDenied) {
AlertsCreator.createLocationRequiredDialog(getParentActivity(), true).show(); AlertsCreator.createLocationRequiredDialog(getParentActivity(), true).show();
} }
return;
} else if (position == 2 && locationType == LOCATION_TYPE_SEND_WITH_LIVE) { } else if (position == 2 && locationType == LOCATION_TYPE_SEND_WITH_LIVE) {
if (getLocationController().isSharingLocation(dialogId)) { if (getLocationController().isSharingLocation(dialogId)) {
getLocationController().removeSharingLocation(dialogId); getLocationController().removeSharingLocation(dialogId);
@ -765,22 +794,23 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
openShareLiveLocation(); openShareLiveLocation();
} }
} }
} else { return;
Object object = adapter.getItem(position); }
if (object instanceof TLRPC.TL_messageMediaVenue) {
if (chatActivity.isInScheduleMode()) { Object object = adapter.getItem(position);
AlertsCreator.createScheduleDatePickerDialog(getParentActivity(), chatActivity.getDialogId(), (notify, scheduleDate) -> { if (object instanceof TLRPC.TL_messageMediaVenue) {
delegate.didSelectLocation((TLRPC.TL_messageMediaVenue) object, locationType, notify, scheduleDate); if (chatActivity.isInScheduleMode()) {
parentAlert.dismiss(true); AlertsCreator.createScheduleDatePickerDialog(getParentActivity(), chatActivity.getDialogId(), (notify, scheduleDate) -> {
}, resourcesProvider); delegate.didSelectLocation((TLRPC.TL_messageMediaVenue) object, locationType, notify, scheduleDate);
} else {
delegate.didSelectLocation((TLRPC.TL_messageMediaVenue) object, locationType, true, 0);
parentAlert.dismiss(true); parentAlert.dismiss(true);
} }, resourcesProvider);
} else if (object instanceof LiveLocation) { } else {
LiveLocation liveLocation = (LiveLocation) object; delegate.didSelectLocation((TLRPC.TL_messageMediaVenue) object, locationType, true, 0);
map.animateCamera(ApplicationLoader.getMapsProvider().newCameraUpdateLatLngZoom(new IMapsProvider.LatLng(liveLocation.marker.getPosition().latitude, liveLocation.marker.getPosition().longitude), map.getMaxZoomLevel() - 4)); parentAlert.dismiss(true);
} }
} else if (object instanceof LiveLocation) {
LiveLocation liveLocation = (LiveLocation) object;
map.animateCamera(ApplicationLoader.getMapsProvider().newCameraUpdateLatLngZoom(new IMapsProvider.LatLng(liveLocation.marker.getPosition().latitude, liveLocation.marker.getPosition().longitude), map.getMaxZoomLevel() - 4));
} }
}); });
adapter.setDelegate(dialogId, this::updatePlacesMarkers); adapter.setDelegate(dialogId, this::updatePlacesMarkers);
@ -819,7 +849,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
animatorSet.setDuration(200); animatorSet.setDuration(200);
animatorSet.playTogether(ObjectAnimator.ofFloat(markerImageView, View.TRANSLATION_Y, markerTop)); animatorSet.playTogether(ObjectAnimator.ofFloat(markerImageView, View.TRANSLATION_Y, markerTop));
animatorSet.start(); animatorSet.start();
adapter.fetchLocationAddress(); // adapter.fetchLocationAddress();
} }
if (ev.getAction() == MotionEvent.ACTION_MOVE) { if (ev.getAction() == MotionEvent.ACTION_MOVE) {
if (!userLocationMoved) { if (!userLocationMoved) {
@ -880,7 +910,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
searchListView = new RecyclerListView(context, resourcesProvider); searchListView = new RecyclerListView(context, resourcesProvider);
searchListView.setVisibility(GONE); searchListView.setVisibility(GONE);
searchListView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)); searchListView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
searchAdapter = new LocationActivitySearchAdapter(context) { searchAdapter = new LocationActivitySearchAdapter(context, resourcesProvider, parentAlert.isStoryLocationPicker) {
@Override @Override
public void notifyDataSetChanged() { public void notifyDataSetChanged() {
if (searchItem != null) { if (searchItem != null) {
@ -892,6 +922,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
super.notifyDataSetChanged(); super.notifyDataSetChanged();
} }
}; };
searchAdapter.setMyLocationDenied(locationDenied);
searchAdapter.setDelegate(0, places -> { searchAdapter.setDelegate(0, places -> {
searchInProgress = false; searchInProgress = false;
updateEmptyView(); updateEmptyView();
@ -1109,6 +1140,9 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
} }
private void showSearchPlacesButton(boolean show) { private void showSearchPlacesButton(boolean show) {
if (locationDenied) {
show = false;
}
if (show && searchAreaButton != null && searchAreaButton.getTag() == null) { if (show && searchAreaButton != null && searchAreaButton.getTag() == null) {
if (myLocation == null || userLocation == null || userLocation.distanceTo(myLocation) < 300) { if (myLocation == null || userLocation == null || userLocation.distanceTo(myLocation) < 300) {
show = false; show = false;
@ -1262,11 +1296,28 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
} }
} }
}); });
map.setOnCameraIdleListener(() -> {
if (ignoreIdleCamera) {
ignoreIdleCamera = false;
return;
}
if (map != null) {
if (userLocation != null) {
userLocation.setLatitude(map.getCameraPosition().target.latitude);
userLocation.setLongitude(map.getCameraPosition().target.longitude);
}
}
adapter.setCustomLocation(userLocation);
adapter.fetchLocationAddress();
});
map.setOnMyLocationChangeListener(location -> { map.setOnMyLocationChangeListener(location -> {
if (parentAlert == null || parentAlert.baseFragment == null) { if (parentAlert == null || parentAlert.baseFragment == null) {
return; return;
} }
positionMarker(location); positionMarker(location);
if (adapter != null && locationType == LOCATION_TYPE_STORY && !userLocationMoved) {
adapter.setCustomLocation(userLocation);
}
getLocationController().setMapLocation(location, isFirstLocation); getLocationController().setMapLocation(location, isFirstLocation);
isFirstLocation = false; isFirstLocation = false;
}); });
@ -1288,12 +1339,12 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
overlayView.updatePositions(); overlayView.updatePositions();
} }
}); });
positionMarker();
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
if (loadingMapView.getTag() == null) { if (loadingMapView.getTag() == null) {
loadingMapView.animate().alpha(0.0f).setDuration(180).start(); loadingMapView.animate().alpha(0.0f).setDuration(180).start();
} }
}, 200); }, 200);
positionMarker(myLocation = getLastLocation());
if (checkGpsEnabled && getParentActivity() != null) { if (checkGpsEnabled && getParentActivity() != null) {
checkGpsEnabled = false; checkGpsEnabled = false;
@ -1306,7 +1357,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
LocationManager lm = (LocationManager) ApplicationLoader.applicationContext.getSystemService(Context.LOCATION_SERVICE); LocationManager lm = (LocationManager) ApplicationLoader.applicationContext.getSystemService(Context.LOCATION_SERVICE);
if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity(), resourcesProvider); AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity(), resourcesProvider);
builder.setTopAnimation(R.raw.permission_request_location, AlertsCreator.PERMISSIONS_REQUEST_TOP_ICON_SIZE, false, Theme.getColor(Theme.key_dialogTopBackground)); builder.setTopAnimation(R.raw.permission_request_location, AlertsCreator.PERMISSIONS_REQUEST_TOP_ICON_SIZE, false, Theme.getColor(Theme.key_dialogTopBackground, resourcesProvider));
builder.setMessage(LocaleController.getString("GpsDisabledAlertText", R.string.GpsDisabledAlertText)); builder.setMessage(LocaleController.getString("GpsDisabledAlertText", R.string.GpsDisabledAlertText));
builder.setPositiveButton(LocaleController.getString("ConnectingToProxyEnable", R.string.ConnectingToProxyEnable), (dialog, id) -> { builder.setPositiveButton(LocaleController.getString("ConnectingToProxyEnable", R.string.ConnectingToProxyEnable), (dialog, id) -> {
if (getParentActivity() == null) { if (getParentActivity() == null) {
@ -1328,6 +1379,48 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
updateClipView(); updateClipView();
} }
private void resetMapPosition(double lat, double _long) {
if (map == null) {
return;
}
if (lat != 0 && _long != 0) {
userLocation = new Location("");
userLocation.reset();
userLocation.setLatitude(lat);
userLocation.setLongitude(_long);
} else {
myLocation = new Location("");
myLocation.reset();
myLocation.setLatitude(lat);
myLocation.setLongitude(_long);
}
IMapsProvider.LatLng latLng = new IMapsProvider.LatLng(lat, _long);
IMapsProvider.ICameraUpdate position;
if (lat != 0 && _long != 0) {
position = ApplicationLoader.getMapsProvider().newCameraUpdateLatLngZoom(latLng, map.getMaxZoomLevel() - 4);
} else {
position = ApplicationLoader.getMapsProvider().newCameraUpdateLatLngZoom(latLng, map.getMinZoomLevel());
}
forceUpdate = position;
map.moveCamera(position);
if (lat != 0 && _long != 0) {
adapter.setCustomLocation(userLocation);
} else {
adapter.setGpsLocation(myLocation);
}
adapter.fetchLocationAddress();
listView.smoothScrollBy(0, 1);
ignoreIdleCamera = true;
if (lat != 0 && _long != 0) {
userLocationMoved = true;
showSearchPlacesButton(false);
adapter.searchPlacesWithQuery(null, userLocation, true, true);
searchedForCustomLocations = true;
showResults();
}
}
private void removeInfoView() { private void removeInfoView() {
if (lastPressedMarker != null) { if (lastPressedMarker != null) {
markerImageView.setVisibility(VISIBLE); markerImageView.setVisibility(VISIBLE);
@ -1418,7 +1511,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
IMapsProvider.LatLng location; IMapsProvider.LatLng location;
if (lastPressedMarker != null) { if (lastPressedMarker != null) {
location = new IMapsProvider.LatLng(lastPressedMarker.getPosition().latitude, lastPressedMarker.getPosition().longitude); location = new IMapsProvider.LatLng(lastPressedMarker.getPosition().latitude, lastPressedMarker.getPosition().longitude);
} else if (userLocationMoved) { } else if (userLocationMoved && userLocation != null) {
location = new IMapsProvider.LatLng(userLocation.getLatitude(), userLocation.getLongitude()); location = new IMapsProvider.LatLng(userLocation.getLatitude(), userLocation.getLongitude());
} else if (myLocation != null) { } else if (myLocation != null) {
location = new IMapsProvider.LatLng(myLocation.getLatitude(), myLocation.getLongitude()); location = new IMapsProvider.LatLng(myLocation.getLatitude(), myLocation.getLongitude());
@ -1450,7 +1543,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
private int buttonsHeight() { private int buttonsHeight() {
int buttonsHeight = AndroidUtilities.dp(66); int buttonsHeight = AndroidUtilities.dp(66);
if (locationType == LOCATION_TYPE_SEND_WITH_LIVE) if (locationType == LOCATION_TYPE_SEND_WITH_LIVE || locationType == LOCATION_TYPE_STORY)
buttonsHeight += AndroidUtilities.dp(66); buttonsHeight += AndroidUtilities.dp(66);
return buttonsHeight; return buttonsHeight;
} }
@ -1513,6 +1606,55 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
return l; return l;
} }
private void positionMarker() {
if (parentAlert.isStoryLocationPicker) {
if (parentAlert.storyLocationPickerLatLong != null) {
AndroidUtilities.runOnUIThread(() -> resetMapPosition(parentAlert.storyLocationPickerLatLong[0], parentAlert.storyLocationPickerLatLong[1]));
} else if (!locationDenied) {
boolean reset = true;
final File file = parentAlert.storyLocationPickerPhotoFile;
final boolean isVideo = parentAlert.storyLocationPickerFileIsVideo;
if (file != null) {
try {
if (isVideo) {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(file.getAbsolutePath());
String location = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION);
if (location != null) {
Matcher m = Pattern.compile("([+\\-][0-9.]+)([+\\-][0-9.]+)").matcher(location);
if (m.find() && m.groupCount() == 2) {
String latstr = m.group(1);
String lonstr = m.group(2);
try {
double lat = Double.parseDouble(latstr);
double lon = Double.parseDouble(lonstr);
AndroidUtilities.runOnUIThread(() -> resetMapPosition(lat, lon));
reset = false;
} catch (NumberFormatException ignored) {
}
}
}
} else {
ExifInterface ei = new ExifInterface(file.getAbsolutePath());
float[] latlong = new float[2];
if (ei.getLatLong(latlong)) {
AndroidUtilities.runOnUIThread(() -> resetMapPosition(latlong[0], latlong[1]));
reset = false;
}
}
} catch (Exception e) {}
}
if (reset) {
positionMarker(myLocation = getLastLocation());
}
} else {
AndroidUtilities.runOnUIThread(() -> resetMapPosition(0, 0));
}
} else {
positionMarker(myLocation = getLastLocation());
}
}
private void positionMarker(Location location) { private void positionMarker(Location location) {
if (location == null) { if (location == null) {
return; return;
@ -1547,8 +1689,13 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
public void didReceivedNotification(int id, int account, Object... args) { public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.locationPermissionGranted) { if (id == NotificationCenter.locationPermissionGranted) {
locationDenied = false; locationDenied = false;
askedForLocation = false;
positionMarker();
if (adapter != null) { if (adapter != null) {
adapter.setMyLocationDenied(locationDenied); adapter.setMyLocationDenied(locationDenied, askedForLocation);
}
if (searchAdapter != null) {
searchAdapter.setMyLocationDenied(locationDenied);
} }
if (map != null) { if (map != null) {
try { try {
@ -1559,12 +1706,16 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
} }
} else if (id == NotificationCenter.locationPermissionDenied) { } else if (id == NotificationCenter.locationPermissionDenied) {
locationDenied = true; locationDenied = true;
askedForLocation = false;
if (adapter != null) { if (adapter != null) {
adapter.setMyLocationDenied(locationDenied); adapter.setMyLocationDenied(locationDenied, askedForLocation);
}
if (searchAdapter != null) {
searchAdapter.setMyLocationDenied(locationDenied);
} }
} }
fixLayoutInternal(true); fixLayoutInternal(true);
searchItem.setVisibility(locationDenied ? View.GONE : View.VISIBLE); searchItem.setVisibility(locationDenied && !parentAlert.isStoryLocationPicker ? View.GONE : View.VISIBLE);
} }
@Override @Override
@ -1612,7 +1763,20 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
if (activity != null) { if (activity != null) {
checkPermission = false; checkPermission = false;
if (activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { if (activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 2); String[] permissions = parentAlert.isStoryLocationPicker && parentAlert.storyLocationPickerPhotoFile != null && Build.VERSION.SDK_INT >= 29 ?
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_MEDIA_LOCATION} :
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
askedForLocation = true;
if (adapter != null) {
adapter.setMyLocationDenied(locationDenied, askedForLocation);
}
activity.requestPermissions(permissions, BasePermissionsActivity.REQUEST_CODE_GEOLOCATION);
} else if (Build.VERSION.SDK_INT >= 29 && parentAlert.isStoryLocationPicker && parentAlert.storyLocationPickerPhotoFile != null && activity.checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION) != PackageManager.PERMISSION_GRANTED) {
askedForLocation = true;
if (adapter != null) {
adapter.setMyLocationDenied(locationDenied, askedForLocation);
}
activity.requestPermissions(new String[]{Manifest.permission.ACCESS_MEDIA_LOCATION}, BasePermissionsActivity.REQUEST_CODE_MEDIA_GEO);
} }
} }
} }
@ -1730,4 +1894,16 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
return themeDescriptions; return themeDescriptions;
} }
@Override
public void onPanTransitionStart(boolean keyboardVisible, int contentHeight) {
if (keyboardVisible) {
adapter.animated = false;
}
}
@Override
public void onPanTransitionEnd() {
adapter.animated = parentAlert != null && !parentAlert.isKeyboardVisible();
}
} }

View file

@ -16,6 +16,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -738,10 +739,14 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
} }
return; return;
} else if (noGalleryPermissions) { } else if (noGalleryPermissions) {
try { if (Build.VERSION.SDK_INT >= 33) {
fragment.getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE); try {
} catch (Exception ignore) { fragment.getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_MEDIA_VIDEO, Manifest.permission.READ_MEDIA_IMAGES}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
} catch (Exception ignore) {}
} else {
try {
fragment.getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
} catch (Exception ignore) {}
} }
return; return;
} }
@ -2898,9 +2903,26 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
} }
} }
private boolean isNoGalleryPermissions() {
Activity activity = AndroidUtilities.findActivity(getContext());
if (activity == null) {
activity = parentAlert.baseFragment.getParentActivity();
}
return Build.VERSION.SDK_INT >= 23 && (
activity == null ||
Build.VERSION.SDK_INT >= 33 && (
activity.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED ||
activity.checkSelfPermission(Manifest.permission.READ_MEDIA_VIDEO) != PackageManager.PERMISSION_GRANTED
) ||
Build.VERSION.SDK_INT < 33 && activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
);
}
public void checkStorage() { public void checkStorage() {
if (noGalleryPermissions && Build.VERSION.SDK_INT >= 23) { if (noGalleryPermissions && Build.VERSION.SDK_INT >= 23) {
noGalleryPermissions = parentAlert.baseFragment.getParentActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED; final Activity activity = parentAlert.baseFragment.getParentActivity();
noGalleryPermissions = isNoGalleryPermissions();
if (!noGalleryPermissions) { if (!noGalleryPermissions) {
loadGalleryPhotos(); loadGalleryPhotos();
} }
@ -3255,7 +3277,7 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
} }
} }
if (Build.VERSION.SDK_INT >= 23) { if (Build.VERSION.SDK_INT >= 23) {
noGalleryPermissions = parentAlert.getContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED; noGalleryPermissions = isNoGalleryPermissions();
} }
if (galleryAlbumEntry != null) { if (galleryAlbumEntry != null) {
for (int a = 0; a < Math.min(100, galleryAlbumEntry.photos.size()); a++) { for (int a = 0; a < Math.min(100, galleryAlbumEntry.photos.size()); a++) {
@ -4014,7 +4036,7 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
return 1; return 1;
} }
int count = 0; int count = 0;
if (needCamera && selectedAlbumEntry != null && galleryAlbumEntry != null && selectedAlbumEntry.bucketId == galleryAlbumEntry.bucketId) { if (needCamera && selectedAlbumEntry == galleryAlbumEntry) {
count++; count++;
} }
if (showAvatarConstructor) { if (showAvatarConstructor) {

View file

@ -23,7 +23,9 @@ public class ColoredImageSpan extends ReplacementSpan {
boolean usePaintColor = true; boolean usePaintColor = true;
int colorKey; int colorKey;
private int topOffset = 0; private int topOffset = 0;
private float translateX; private float translateX, translateY;
private float alpha = 1f;
private int overrideColor;
private int size; private int size;
private int sizeWidth; private int sizeWidth;
@ -32,7 +34,7 @@ public class ColoredImageSpan extends ReplacementSpan {
public static final int ALIGN_BASELINE = 1; public static final int ALIGN_BASELINE = 1;
public static final int ALIGN_CENTER = 2; public static final int ALIGN_CENTER = 2;
private final int verticalAlignment; private final int verticalAlignment;
private float scale = 1f; private float scaleX = 1f, scaleY = 1f;
private Runnable checkColorDelegate; private Runnable checkColorDelegate;
public ColoredImageSpan(int imageRes) { public ColoredImageSpan(int imageRes) {
@ -59,10 +61,20 @@ public class ColoredImageSpan extends ReplacementSpan {
this.size = size; this.size = size;
drawable.setBounds(0, 0, size, size); drawable.setBounds(0, 0, size, size);
} }
public void setTranslateX(float tx) { public void setTranslateX(float tx) {
translateX = tx; translateX = tx;
} }
public void setTranslateY(float ty) {
translateY = ty;
}
public void translate(float tx, float ty) {
translateX = tx;
translateY = ty;
}
public void setWidth(int width) { public void setWidth(int width) {
sizeWidth = width; sizeWidth = width;
} }
@ -70,8 +82,8 @@ public class ColoredImageSpan extends ReplacementSpan {
@Override @Override
public int getSize(@NonNull Paint paint, CharSequence charSequence, int i, int i1, @Nullable Paint.FontMetricsInt fontMetricsInt) { public int getSize(@NonNull Paint paint, CharSequence charSequence, int i, int i1, @Nullable Paint.FontMetricsInt fontMetricsInt) {
if (sizeWidth != 0) if (sizeWidth != 0)
return (int) (scale * sizeWidth); return (int) (Math.abs(scaleX) * sizeWidth);
return (int) (scale * (size != 0 ? size : drawable.getIntrinsicWidth())); return (int) (Math.abs(scaleX) * (size != 0 ? size : drawable.getIntrinsicWidth()));
} }
@Override @Override
@ -80,7 +92,9 @@ public class ColoredImageSpan extends ReplacementSpan {
if (checkColorDelegate != null) { if (checkColorDelegate != null) {
checkColorDelegate.run(); checkColorDelegate.run();
} else { } else {
if (usePaintColor) { if (overrideColor != 0) {
color = overrideColor;
} else if (usePaintColor) {
color = paint.getColor(); color = paint.getColor();
} else { } else {
color = Theme.getColor(colorKey); color = Theme.getColor(colorKey);
@ -103,10 +117,13 @@ public class ColoredImageSpan extends ReplacementSpan {
int padding = (lineHeight - drawableHeight) / 2; int padding = (lineHeight - drawableHeight) / 2;
transY = top + padding + AndroidUtilities.dp(topOffset); transY = top + padding + AndroidUtilities.dp(topOffset);
} }
canvas.translate(x + translateX, transY); canvas.translate(x + translateX, transY + translateY);
if (drawable != null) { if (drawable != null) {
if (scale != 1f) { if (scaleX != 1f || scaleY != 1f) {
canvas.scale(scale, scale, 0, drawable.getBounds().centerY()); canvas.scale(scaleX, scaleY, 0, drawable.getBounds().centerY());
}
if (alpha != 1f) {
drawable.setAlpha((int) (alpha * 255));
} }
drawable.draw(canvas); drawable.draw(canvas);
} }
@ -126,7 +143,20 @@ public class ColoredImageSpan extends ReplacementSpan {
this.checkColorDelegate = checkColorDelegate; this.checkColorDelegate = checkColorDelegate;
} }
public void setScale(float v) { public void setScale(float sx) {
scale = v; scaleX = sx;
}
public void setScale(float sx, float sy) {
scaleX = sx;
scaleY = sy;
}
public void setOverrideColor(int red) {
overrideColor = red;
}
public void setAlpha(float v) {
this.alpha = v;
} }
} }

View file

@ -125,8 +125,10 @@ public class CombinedDrawable extends Drawable implements Drawable.Callback {
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
background.setBounds(getBounds()); if (background != null) {
background.draw(canvas); background.setBounds(getBounds());
background.draw(canvas);
}
if (icon != null) { if (icon != null) {
if (fullSize) { if (fullSize) {
android.graphics.Rect bounds = getBounds(); android.graphics.Rect bounds = getBounds();

View file

@ -26,6 +26,7 @@ import android.os.Build;
import android.os.SystemClock; import android.os.SystemClock;
import androidx.annotation.Keep; import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
@ -99,6 +100,7 @@ public class EditTextBoldCursor extends EditTextEffects {
private float lineSpacingExtra; private float lineSpacingExtra;
private Rect rect = new Rect(); private Rect rect = new Rect();
private StaticLayout hintLayout; private StaticLayout hintLayout;
private AnimatedTextView.AnimatedTextDrawable hintAnimatedDrawable;
private CharSequence hint; private CharSequence hint;
private StaticLayout errorLayout; private StaticLayout errorLayout;
private CharSequence errorText; private CharSequence errorText;
@ -193,6 +195,17 @@ public class EditTextBoldCursor extends EditTextEffects {
init(); init();
} }
public void useAnimatedTextDrawable() {
hintAnimatedDrawable = new AnimatedTextView.AnimatedTextDrawable() {
@Override
public void invalidateSelf() {
invalidate();
}
};
hintAnimatedDrawable.setTextColor(hintColor);
hintAnimatedDrawable.setTextSize(getPaint().getTextSize());
}
@Override @Override
public void addTextChangedListener(TextWatcher watcher) { public void addTextChangedListener(TextWatcher watcher) {
registeredTextWatchers.add(watcher); registeredTextWatchers.add(watcher);
@ -462,6 +475,9 @@ public class EditTextBoldCursor extends EditTextEffects {
public void setHintColor(int value) { public void setHintColor(int value) {
hintColor = value; hintColor = value;
if (hintAnimatedDrawable != null) {
hintAnimatedDrawable.setTextColor(hintColor);
}
invalidate(); invalidate();
} }
@ -470,6 +486,14 @@ public class EditTextBoldCursor extends EditTextEffects {
invalidate(); invalidate();
} }
@Override
public void setTextSize(int unit, float size) {
if (hintAnimatedDrawable != null) {
hintAnimatedDrawable.setTextSize(AndroidUtilities.dp(size));
}
super.setTextSize(unit, size);
}
public void setNextSetTextAnimated(boolean value) { public void setNextSetTextAnimated(boolean value) {
nextSetTextAnimated = value; nextSetTextAnimated = value;
} }
@ -521,7 +545,10 @@ public class EditTextBoldCursor extends EditTextEffects {
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int currentSize = getMeasuredHeight() + (getMeasuredWidth() << 16); int currentSize = getMeasuredHeight() + (getMeasuredWidth() << 16);
if (hintLayout != null) { if (hintAnimatedDrawable != null) {
hintAnimatedDrawable.setBounds(getPaddingLeft(), getPaddingTop(), getMeasuredWidth() - getPaddingRight(), getMeasuredHeight() - getPaddingBottom());
}
if (hintLayout != null && hintAnimatedDrawable == null) {
if (lastSize != currentSize) { if (lastSize != currentSize) {
setHintText(hint); setHintText(hint);
} }
@ -537,30 +564,34 @@ public class EditTextBoldCursor extends EditTextEffects {
} }
public void setHintText(CharSequence text, boolean animated) { public void setHintText(CharSequence text, boolean animated) {
if (text == null) { if (hintAnimatedDrawable != null) {
text = ""; hintAnimatedDrawable.setText(text, true);
}
if (getMeasuredWidth() == 0) {
animated = false;
}
if (animated) {
if (hintAnimator == null) {
hintAnimator = new SubstringLayoutAnimator(this);
}
hintAnimator.create(hintLayout, hint, text, getPaint());
} else { } else {
if (hintAnimator != null) { if (text == null) {
hintAnimator.cancel(); text = "";
} }
} if (getMeasuredWidth() == 0) {
hint = text; animated = false;
if (getMeasuredWidth() != 0) {
text = TextUtils.ellipsize(text, getPaint(), getMeasuredWidth(), TextUtils.TruncateAt.END);
if (hintLayout != null && TextUtils.equals(hintLayout.getText(), text)) {
return;
} }
if (animated) {
if (hintAnimator == null) {
hintAnimator = new SubstringLayoutAnimator(this);
}
hintAnimator.create(hintLayout, hint, text, getPaint());
} else {
if (hintAnimator != null) {
hintAnimator.cancel();
}
}
hint = text;
if (getMeasuredWidth() != 0) {
text = TextUtils.ellipsize(text, getPaint(), getMeasuredWidth(), TextUtils.TruncateAt.END);
if (hintLayout != null && TextUtils.equals(hintLayout.getText(), text)) {
return;
}
}
hintLayout = new StaticLayout(text, getPaint(), AndroidUtilities.dp(1000), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
} }
hintLayout = new StaticLayout(text, getPaint(), AndroidUtilities.dp(1000), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
} }
public Layout getHintLayoutEx() { public Layout getHintLayoutEx() {
@ -665,7 +696,7 @@ public class EditTextBoldCursor extends EditTextEffects {
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
if ((length() == 0 || transformHintToHeader) && hintLayout != null && (hintVisible || hintAlpha != 0)) { if (length() == 0 || transformHintToHeader) {
if (hintVisible && hintAlpha != 1.0f || !hintVisible && hintAlpha != 0.0f) { if (hintVisible && hintAlpha != 1.0f || !hintVisible && hintAlpha != 0.0f) {
long newTime = System.currentTimeMillis(); long newTime = System.currentTimeMillis();
long dt = newTime - hintLastUpdateTime; long dt = newTime - hintLastUpdateTime;
@ -686,46 +717,51 @@ public class EditTextBoldCursor extends EditTextEffects {
} }
invalidate(); invalidate();
} }
int oldColor = getPaint().getColor(); if (hintAnimatedDrawable != null && !TextUtils.isEmpty(hintAnimatedDrawable.getText()) && (hintVisible || hintAlpha != 0)) {
hintAnimatedDrawable.setAlpha((int) (Color.alpha(hintColor) * hintAlpha));
hintAnimatedDrawable.draw(canvas);
} else if (hintLayout != null && (hintVisible || hintAlpha != 0)) {
int oldColor = getPaint().getColor();
canvas.save();
int left = 0;
float lineLeft = hintLayout.getLineLeft(0);
float hintWidth = hintLayout.getLineWidth(0);
if (lineLeft != 0) {
left -= lineLeft;
}
if (supportRtlHint && LocaleController.isRTL) {
float offset = getMeasuredWidth() - hintWidth;
canvas.translate(left + getScrollX() + offset, lineY - hintLayout.getHeight() - AndroidUtilities.dp(7));
} else {
canvas.translate(left + getScrollX(), lineY - hintLayout.getHeight() - AndroidUtilities.dp2(7));
}
if (transformHintToHeader) {
float scale = 1.0f - 0.3f * headerAnimationProgress;
if (supportRtlHint && LocaleController.isRTL) {
canvas.translate((hintWidth + lineLeft) - (hintWidth + lineLeft) * scale, 0);
} else if (lineLeft != 0) {
canvas.translate(lineLeft * (1.0f - scale), 0);
}
canvas.scale(scale, scale);
canvas.translate(0, -AndroidUtilities.dp(22) * headerAnimationProgress);
getPaint().setColor(ColorUtils.blendARGB(hintColor, headerHintColor, headerAnimationProgress));
} else {
getPaint().setColor(hintColor);
getPaint().setAlpha((int) (255 * hintAlpha * (Color.alpha(hintColor) / 255.0f)));
}
if (hintAnimator != null && hintAnimator.animateTextChange) {
canvas.save(); canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight()); int left = 0;
hintAnimator.draw(canvas, getPaint()); float lineLeft = hintLayout.getLineLeft(0);
float hintWidth = hintLayout.getLineWidth(0);
if (lineLeft != 0) {
left -= lineLeft;
}
if (supportRtlHint && LocaleController.isRTL) {
float offset = getMeasuredWidth() - hintWidth;
canvas.translate(left + getScrollX() + offset, lineY - hintLayout.getHeight() - AndroidUtilities.dp(7));
} else {
canvas.translate(left + getScrollX(), lineY - hintLayout.getHeight() - AndroidUtilities.dp2(7));
}
if (transformHintToHeader) {
float scale = 1.0f - 0.3f * headerAnimationProgress;
if (supportRtlHint && LocaleController.isRTL) {
canvas.translate((hintWidth + lineLeft) - (hintWidth + lineLeft) * scale, 0);
} else if (lineLeft != 0) {
canvas.translate(lineLeft * (1.0f - scale), 0);
}
canvas.scale(scale, scale);
canvas.translate(0, -AndroidUtilities.dp(22) * headerAnimationProgress);
getPaint().setColor(ColorUtils.blendARGB(hintColor, headerHintColor, headerAnimationProgress));
} else {
getPaint().setColor(hintColor);
getPaint().setAlpha((int) (255 * hintAlpha * (Color.alpha(hintColor) / 255.0f)));
}
if (hintAnimator != null && hintAnimator.animateTextChange) {
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
hintAnimator.draw(canvas, getPaint());
canvas.restore();
} else {
hintLayout.draw(canvas);
}
getPaint().setColor(oldColor);
canvas.restore(); canvas.restore();
} else {
hintLayout.draw(canvas);
} }
getPaint().setColor(oldColor);
canvas.restore();
} }
int topPadding = getExtendedPaddingTop(); int topPadding = getExtendedPaddingTop();
@ -999,6 +1035,7 @@ public class EditTextBoldCursor extends EditTextEffects {
} }
cleanupFloatingActionModeViews(); cleanupFloatingActionModeViews();
floatingToolbar = new FloatingToolbar(getContext(), windowView != null ? windowView : attachedToWindow, getActionModeStyle(), getResourcesProvider()); floatingToolbar = new FloatingToolbar(getContext(), windowView != null ? windowView : attachedToWindow, getActionModeStyle(), getResourcesProvider());
floatingToolbar.setOnPremiumLockClick(onPremiumMenuLockClickListener);
floatingActionMode = new FloatingActionMode(getContext(), new ActionModeCallback2Wrapper(callback), this, floatingToolbar); floatingActionMode = new FloatingActionMode(getContext(), new ActionModeCallback2Wrapper(callback), this, floatingToolbar);
floatingToolbarPreDrawListener = () -> { floatingToolbarPreDrawListener = () -> {
if (floatingActionMode != null) { if (floatingActionMode != null) {
@ -1091,4 +1128,9 @@ public class EditTextBoldCursor extends EditTextEffects {
setTextSelectHandleRight(right); setTextSelectHandleRight(right);
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
private Runnable onPremiumMenuLockClickListener;
public void setOnPremiumMenuLockClickListener(Runnable listener) {
onPremiumMenuLockClickListener = listener;
}
} }

View file

@ -597,9 +597,9 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
} }
} else { } else {
final boolean free = newPack.free; // isFreeEmojiPack(newPack.set, newPack.documents); final boolean free = newPack.free; // isFreeEmojiPack(newPack.set, newPack.documents);
DelayedAnimatedEmojiDrawable drawable = currentPackButton == null ? null : (DelayedAnimatedEmojiDrawable) currentPackButton.getDrawable(); DelayedAnimatedEmojiDrawable drawable = currentPackButton == null || !(currentPackButton.getDrawable() instanceof DelayedAnimatedEmojiDrawable) ? null : (DelayedAnimatedEmojiDrawable) currentPackButton.getDrawable();
TLRPC.Document thumbDocument = getThumbDocument(newPack.set, newPack.documents); TLRPC.Document thumbDocument = getThumbDocument(newPack.set, newPack.documents);
if (thumbDocument != null && (drawable == null || !drawable.equals(thumbDocument.id))) { if (thumbDocument != null && (drawable == null || drawable.documentId != thumbDocument.id)) {
drawable = new DelayedAnimatedEmojiDrawable(UserConfig.selectedAccount, animatedEmojiCacheType, thumbDocument); drawable = new DelayedAnimatedEmojiDrawable(UserConfig.selectedAccount, animatedEmojiCacheType, thumbDocument);
} }
if (currentPackButton == null) { if (currentPackButton == null) {
@ -610,6 +610,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
} else if (currentPackButton.getDrawable() != drawable) { } else if (currentPackButton.getDrawable() != drawable) {
currentPackButton.setDrawable(drawable); currentPackButton.setDrawable(drawable);
} }
currentPackButton.updateSelect(selected == i, false);
if (currentType == SelectAnimatedEmojiDialog.TYPE_AVATAR_CONSTRUCTOR) { if (currentType == SelectAnimatedEmojiDialog.TYPE_AVATAR_CONSTRUCTOR) {
currentPackButton.setLock(null); currentPackButton.setLock(null);
} else if (!isPremium && !free) { } else if (!isPremium && !free) {
@ -1065,14 +1066,14 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
@Override @Override
protected void dispatchDraw(Canvas canvas) { protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas); super.dispatchDraw(canvas);
if (lottieDrawable != null && wasVisible) { if (lottieDrawable != null && isVisible) {
lottieDrawable.draw(canvas); lottieDrawable.draw(canvas);
} }
} }
@Override @Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) { protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (!wasVisible) { if (!isVisible) {
return true; return true;
} }
return super.drawChild(canvas, child, drawingTime); return super.drawChild(canvas, child, drawingTime);
@ -1080,7 +1081,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
if (!wasVisible) { if (!isVisible) {
return; return;
} }
super.onDraw(canvas); super.onDraw(canvas);
@ -1118,17 +1119,17 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
} }
} }
private boolean wasVisible; private boolean isVisible;
public void updateVisibilityInbounds(boolean visible, boolean ignore) { public void updateVisibilityInbounds(boolean visible, boolean ignore) {
if (!wasVisible && visible) { if (!isVisible && visible) {
if (lottieDrawable != null && !lottieDrawable.isRunning() && !ignore) { if (lottieDrawable != null && !lottieDrawable.isRunning() && !ignore) {
lottieDrawable.setProgress(0); lottieDrawable.setProgress(0);
lottieDrawable.start(); lottieDrawable.start();
} }
} }
if (wasVisible != visible) { if (isVisible != visible) {
wasVisible = visible; isVisible = visible;
if (visible) { if (visible) {
invalidate(); invalidate();
if (lockView != null) { if (lockView != null) {
@ -1254,14 +1255,14 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
newEmoji = (DelayedAnimatedEmojiDrawable) drawable; newEmoji = (DelayedAnimatedEmojiDrawable) drawable;
} }
if (animatedEmoji != newEmoji) { if (animatedEmoji != newEmoji) {
if (animatedEmoji != null && attached && wasVisible) { if (animatedEmoji != null) {
animatedEmoji.removeView(); animatedEmoji.removeView();
} }
animatedEmoji = newEmoji; animatedEmoji = newEmoji;
if (animatedEmoji != null && attached && wasVisible) { if (animatedEmoji != null && attached && isVisible) {
animatedEmoji.updateView(imageView); animatedEmoji.updateView(imageView);
} }
if (wasVisible && animatedEmoji != null) { if (isVisible && animatedEmoji != null) {
animatedEmoji.load(); animatedEmoji.load();
} }
initLock(); initLock();
@ -1287,7 +1288,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
private void updateAttachState() { private void updateAttachState() {
if (animatedEmoji != null) { if (animatedEmoji != null) {
if ((keepAttached || attached) && wasVisible) { if ((keepAttached || attached) && isVisible) {
animatedEmoji.updateView(imageView); animatedEmoji.updateView(imageView);
} else { } else {
animatedEmoji.removeView(); animatedEmoji.removeView();

View file

@ -20,6 +20,7 @@ public class FillLastLinearLayoutManager extends LinearLayoutManager {
private boolean canScrollVertically = true; private boolean canScrollVertically = true;
boolean fixedLastItemHeight; boolean fixedLastItemHeight;
private int minimumHeight; private int minimumHeight;
private boolean setMeassuredHeightToLastItem = true;
public FillLastLinearLayoutManager(Context context, int h, RecyclerView recyclerView) { public FillLastLinearLayoutManager(Context context, int h, RecyclerView recyclerView) {
super(context); super(context);
@ -163,11 +164,13 @@ public class FillLastLinearLayoutManager extends LinearLayoutManager {
@Override @Override
public void measureChildWithMargins(View child, int widthUsed, int heightUsed) { public void measureChildWithMargins(View child, int widthUsed, int heightUsed) {
RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child); if (setMeassuredHeightToLastItem) {
int pos = holder.getAdapterPosition(); RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child);
if (pos == getItemCount() - 1) { int pos = holder.getAdapterPosition();
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); if (pos == getItemCount() - 1) {
layoutParams.height = Math.max(lastItemHeight, 0); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
layoutParams.height = Math.max(lastItemHeight, 0);
}
} }
super.measureChildWithMargins(child, 0, 0); super.measureChildWithMargins(child, 0, 0);
} }
@ -179,4 +182,12 @@ public class FillLastLinearLayoutManager extends LinearLayoutManager {
public void setMinimumLastViewHeight(int height) { public void setMinimumLastViewHeight(int height) {
minimumHeight = height; minimumHeight = height;
} }
public void setSetMeassuredHeightToLastItem(boolean setMeassuredHeightToLastItem) {
this.setMeassuredHeightToLastItem = setMeassuredHeightToLastItem;
}
public int getLastItemHeight() {
return lastItemHeight;
}
} }

View file

@ -69,7 +69,7 @@ public class FlickerLoadingView extends View {
private int colorKey1 = Theme.key_actionBarDefaultSubmenuBackground; private int colorKey1 = Theme.key_actionBarDefaultSubmenuBackground;
private int colorKey2 = Theme.key_listSelector; private int colorKey2 = Theme.key_listSelector;
private int colorKey3; private int colorKey3 = -1;
private int itemsCount = 1; private int itemsCount = 1;
private final Theme.ResourcesProvider resourcesProvider; private final Theme.ResourcesProvider resourcesProvider;

View file

@ -33,9 +33,10 @@ public class GradientTools {
Bitmap gradientBitmap = null; Bitmap gradientBitmap = null;
int[] colors = new int[4]; int[] colors = new int[4];
public boolean isLinear;
public void setColors(int color1, int color2) { public void setColors(int color1, int color2) {
setColors(color1, color2, 0, 0); setColors(color1, color2, 0, 0);
} }
public void setColors(int color1, int color2, int color3) { public void setColors(int color1, int color2, int color3) {
@ -60,11 +61,19 @@ public class GradientTools {
paint.setShader(shader = new LinearGradient(isDiagonal ? INTERNAL_HEIGHT : 0, 0, 0, INTERNAL_HEIGHT, new int[]{color1, color2}, null, Shader.TileMode.CLAMP)); paint.setShader(shader = new LinearGradient(isDiagonal ? INTERNAL_HEIGHT : 0, 0, 0, INTERNAL_HEIGHT, new int[]{color1, color2}, null, Shader.TileMode.CLAMP));
} }
} else { } else {
if (gradientBitmap == null) { if (isLinear) {
gradientBitmap = Bitmap.createBitmap(INTERNAL_WIDTH, INTERNAL_HEIGHT, Bitmap.Config.ARGB_8888); if (isDiagonal && isRotate) {
paint.setShader(shader = new LinearGradient(0, 0, INTERNAL_HEIGHT, INTERNAL_HEIGHT, new int[]{color1, color2, color3}, null, Shader.TileMode.CLAMP));
} else {
paint.setShader(shader = new LinearGradient(isDiagonal ? INTERNAL_HEIGHT : 0, 0, 0, INTERNAL_HEIGHT, new int[]{color1, color2, color3}, null, Shader.TileMode.CLAMP));
}
} else {
if (gradientBitmap == null) {
gradientBitmap = Bitmap.createBitmap(INTERNAL_WIDTH, INTERNAL_HEIGHT, Bitmap.Config.ARGB_8888);
}
Utilities.generateGradient(gradientBitmap, true, 0, 0, gradientBitmap.getWidth(), gradientBitmap.getHeight(), gradientBitmap.getRowBytes(), colors);
paint.setShader(shader = new BitmapShader(gradientBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
} }
Utilities.generateGradient(gradientBitmap, true, 0, 0, gradientBitmap.getWidth(), gradientBitmap.getHeight(), gradientBitmap.getRowBytes(), colors);
paint.setShader(shader = new BitmapShader(gradientBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
} }
updateBounds(); updateBounds();
} }

View file

@ -688,9 +688,15 @@ public class ImageUpdater implements NotificationCenter.NotificationCenterDelega
if (parentFragment == null) { if (parentFragment == null) {
return; return;
} }
if (Build.VERSION.SDK_INT >= 23 && parentFragment.getParentActivity() != null) { final Activity activity = parentFragment.getParentActivity();
if (parentFragment.getParentActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT >= 33 && activity != null) {
parentFragment.getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE_FOR_AVATAR); if (activity.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED || activity.checkSelfPermission(Manifest.permission.READ_MEDIA_VIDEO) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE_FOR_AVATAR);
return;
}
} else if (Build.VERSION.SDK_INT >= 23 && activity != null) {
if (activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE_FOR_AVATAR);
return; return;
} }
} }

View file

@ -1906,9 +1906,6 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
public void startRecording(File outputFile, android.opengl.EGLContext sharedContext) { public void startRecording(File outputFile, android.opengl.EGLContext sharedContext) {
int resolution = MessagesController.getInstance(currentAccount).roundVideoSize; int resolution = MessagesController.getInstance(currentAccount).roundVideoSize;
int bitrate = MessagesController.getInstance(currentAccount).roundVideoBitrate * 1024; int bitrate = MessagesController.getInstance(currentAccount).roundVideoBitrate * 1024;
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.stopAllHeavyOperations, 512);
});
videoFile = outputFile; videoFile = outputFile;
videoWidth = resolution; videoWidth = resolution;
@ -1950,9 +1947,6 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
public void stopRecording(int send) { public void stopRecording(int send) {
handler.sendMessage(handler.obtainMessage(MSG_STOP_RECORDING, send, 0)); handler.sendMessage(handler.obtainMessage(MSG_STOP_RECORDING, send, 0));
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.stopAllHeavyOperations, 512);
});
} }
long prevTimestamp; long prevTimestamp;
@ -2885,6 +2879,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
} }
} }
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
if (fileWriteQueue != null) { if (fileWriteQueue != null) {

View file

@ -28,6 +28,7 @@ import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.util.Consumer; import com.google.android.exoplayer2.util.Consumer;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BotWebViewVibrationEffect;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.ActionBarMenuSubItem; import org.telegram.ui.ActionBar.ActionBarMenuSubItem;
@ -36,6 +37,7 @@ import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.UserCell; import org.telegram.ui.Cells.UserCell;
import org.telegram.ui.ProfileActivity; import org.telegram.ui.ProfileActivity;
import org.telegram.ui.Stories.recorder.HintView2;
public class ItemOptions { public class ItemOptions {
@ -59,6 +61,7 @@ public class ItemOptions {
private View scrimView; private View scrimView;
private Drawable scrimViewBackground; private Drawable scrimViewBackground;
private int gravity = Gravity.RIGHT; private int gravity = Gravity.RIGHT;
private boolean ignoreX;
private ActionBarPopupWindow actionBarPopupWindow; private ActionBarPopupWindow actionBarPopupWindow;
private final float[] point = new float[2]; private final float[] point = new float[2];
@ -84,10 +87,6 @@ public class ItemOptions {
this.scrimView = scrimView; this.scrimView = scrimView;
this.dimAlpha = AndroidUtilities.computePerceivedBrightness(Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider)) > .705 ? 0x66 : 0x33; this.dimAlpha = AndroidUtilities.computePerceivedBrightness(Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider)) > .705 ? 0x66 : 0x33;
if (fragment.getFragmentView() != null) {
//discard all scrolls/gestures
fragment.getFragmentView().getRootView().dispatchTouchEvent(AndroidUtilities.emptyMotionEvent());
}
init(); init();
} }
@ -115,11 +114,9 @@ public class ItemOptions {
layout = lastLayout; layout = lastLayout;
} }
public ItemOptions addIf(boolean condition, int iconResId, CharSequence text, Runnable onClickListener) { public ItemOptions ignoreX() {
if (!condition) { ignoreX = true;
return this; return this;
}
return add(iconResId, text, onClickListener);
} }
public ItemOptions addIf(boolean condition, int iconResId, CharSequence text, boolean isRed, Runnable onClickListener) { public ItemOptions addIf(boolean condition, int iconResId, CharSequence text, boolean isRed, Runnable onClickListener) {
@ -129,11 +126,11 @@ public class ItemOptions {
return add(iconResId, text, isRed, onClickListener); return add(iconResId, text, isRed, onClickListener);
} }
public ItemOptions addIf(boolean condition, int iconResId, CharSequence text, Runnable onClickListener, Consumer<ActionBarMenuSubItem> onVewCreated) { public ItemOptions addIf(boolean condition, int iconResId, CharSequence text, Runnable onClickListener) {
if (!condition) { if (!condition) {
return this; return this;
} }
return add(iconResId, text, Theme.key_actionBarDefaultSubmenuItemIcon, Theme.key_actionBarDefaultSubmenuItem, onClickListener, onVewCreated); return add(iconResId, text, Theme.key_actionBarDefaultSubmenuItemIcon, Theme.key_actionBarDefaultSubmenuItem, onClickListener);
} }
public ItemOptions add(int iconResId, CharSequence text, Runnable onClickListener) { public ItemOptions add(int iconResId, CharSequence text, Runnable onClickListener) {
@ -141,14 +138,14 @@ public class ItemOptions {
} }
public ItemOptions add(int iconResId, CharSequence text, boolean isRed, Runnable onClickListener) { public ItemOptions add(int iconResId, CharSequence text, boolean isRed, Runnable onClickListener) {
return add(iconResId, text, isRed ? Theme.key_text_RedRegular : Theme.key_actionBarDefaultSubmenuItemIcon, isRed ? Theme.key_text_RedRegular : Theme.key_actionBarDefaultSubmenuItem, onClickListener, null); return add(iconResId, text, isRed ? Theme.key_text_RedRegular : Theme.key_actionBarDefaultSubmenuItemIcon, isRed ? Theme.key_text_RedRegular : Theme.key_actionBarDefaultSubmenuItem, onClickListener);
} }
public ItemOptions add(int iconResId, CharSequence text, int color, Runnable onClickListener) { public ItemOptions add(int iconResId, CharSequence text, int color, Runnable onClickListener) {
return add(iconResId, text, color, color, onClickListener, null); return add(iconResId, text, color, color, onClickListener);
} }
public ItemOptions add(int iconResId, CharSequence text, int iconColorKey, int textColorKey, Runnable onClickListener, Consumer<ActionBarMenuSubItem> onViewCreated) { public ItemOptions add(int iconResId, CharSequence text, int iconColorKey, int textColorKey, Runnable onClickListener) {
if (context == null) { if (context == null) {
return this; return this;
} }
@ -170,16 +167,43 @@ public class ItemOptions {
}); });
if (minWidthDp > 0) { if (minWidthDp > 0) {
subItem.setMinimumWidth(AndroidUtilities.dp(minWidthDp)); subItem.setMinimumWidth(AndroidUtilities.dp(minWidthDp));
lastLayout.addView(subItem, LayoutHelper.createLinear(minWidthDp, LayoutHelper.WRAP_CONTENT));
} else {
lastLayout.addView(subItem, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
} }
if (onViewCreated != null) {
onViewCreated.accept(subItem);
}
lastLayout.addView(subItem, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
return this; return this;
} }
public ItemOptions makeMultiline(boolean changeSize) {
if (context == null || lastLayout.getItemsCount() <= 0) {
return this;
}
View lastChild = lastLayout.getItemAt(lastLayout.getItemsCount() - 1);
if (lastChild instanceof ActionBarMenuSubItem) {
((ActionBarMenuSubItem) lastChild).setMultiline(changeSize);
}
return this;
}
public ItemOptions cutTextInFancyHalf() {
if (context == null || lastLayout.getItemsCount() <= 0) {
return this;
}
View lastChild = lastLayout.getItemAt(lastLayout.getItemsCount() - 1);
if (lastChild instanceof ActionBarMenuSubItem) {
TextView textView = ((ActionBarMenuSubItem) lastChild).getTextView();
textView.setMaxWidth(
HintView2.cutInFancyHalf(textView.getText(), textView.getPaint()) + textView.getPaddingLeft() + textView.getPaddingRight()
);
}
return this;
}
private int shiftDp = -4;
public ItemOptions putPremiumLock(Runnable onLockClick) { public ItemOptions putPremiumLock(Runnable onLockClick) {
if (onLockClick == null || context == null || lastLayout.getItemsCount() <= 0) { if (onLockClick == null || context == null || lastLayout.getItemsCount() <= 0) {
return this; return this;
@ -193,6 +217,8 @@ public class ItemOptions {
lastSubItem.getRightIcon().setAlpha(.4f); lastSubItem.getRightIcon().setAlpha(.4f);
lastSubItem.setOnClickListener(view1 -> { lastSubItem.setOnClickListener(view1 -> {
if (onLockClick != null) { if (onLockClick != null) {
AndroidUtilities.shakeViewSpring(view1, shiftDp = -shiftDp);
BotWebViewVibrationEffect.APP_ERROR.vibrate();
onLockClick.run(); onLockClick.run();
} }
}); });
@ -223,7 +249,12 @@ public class ItemOptions {
return this; return this;
} }
public ItemOptions addView() { public ItemOptions addView(View view) {
if (view == null) {
return this;
}
view.setTag(R.id.fit_width_tag, 1);
lastLayout.addView(view, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
return this; return this;
} }
@ -333,6 +364,9 @@ public class ItemOptions {
getPointOnScreen(scrimView, container, point); getPointOnScreen(scrimView, container, point);
y = point[1]; y = point[1];
} }
if (ignoreX) {
point[0] = 0;
}
final Bitmap cachedBitmap; final Bitmap cachedBitmap;
final Paint cachedBitmapPaint; final Paint cachedBitmapPaint;
@ -449,6 +483,14 @@ public class ItemOptions {
} else { } else {
Y = (container.getHeight() - layout.getMeasuredHeight()) / 2; // at the center Y = (container.getHeight() - layout.getMeasuredHeight()) / 2; // at the center
} }
// discard all scrolls/gestures
if (fragment != null && fragment.getFragmentView() != null) {
fragment.getFragmentView().getRootView().dispatchTouchEvent(AndroidUtilities.emptyMotionEvent());
} else if (this.container != null) {
container.dispatchTouchEvent(AndroidUtilities.emptyMotionEvent());
}
actionBarPopupWindow.showAtLocation( actionBarPopupWindow.showAtLocation(
container, container,
0, 0,

View file

@ -370,6 +370,7 @@ public class LoadingDrawable extends Drawable {
@Override @Override
public void setAlpha(int i) { public void setAlpha(int i) {
paint.setAlpha(i); paint.setAlpha(i);
strokePaint.setAlpha(i);
if (i > 0) { if (i > 0) {
invalidateSelf(); invalidateSelf();
} }

View file

@ -22,12 +22,16 @@ public class MapPlaceholderDrawable extends Drawable {
private Paint linePaint; private Paint linePaint;
public MapPlaceholderDrawable() { public MapPlaceholderDrawable() {
this(Theme.getCurrentTheme().isDark());
}
public MapPlaceholderDrawable(boolean isDark) {
super(); super();
paint = new Paint(); paint = new Paint();
linePaint = new Paint(); linePaint = new Paint();
linePaint.setStrokeWidth(AndroidUtilities.dp(1)); linePaint.setStrokeWidth(AndroidUtilities.dp(1));
if (Theme.getCurrentTheme().isDark()) { if (isDark) {
paint.setColor(0xff1d2c4d); paint.setColor(0xff1d2c4d);
linePaint.setColor(0xff0e1626); linePaint.setColor(0xff0e1626);
} else { } else {

View file

@ -626,6 +626,10 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
@Override @Override
protected void showActionMode(boolean show) { protected void showActionMode(boolean show) {
if (type == TYPE_MEDIA) {
super.showActionMode(show);
return;
}
if (isActionModeShowed == show) { if (isActionModeShowed == show) {
return; return;
} }
@ -707,13 +711,15 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
protected void onActionModeSelectedUpdate(SparseArray<MessageObject> messageObjects) { protected void onActionModeSelectedUpdate(SparseArray<MessageObject> messageObjects) {
final int count = messageObjects.size(); final int count = messageObjects.size();
actionModeMessageObjects = messageObjects; actionModeMessageObjects = messageObjects;
selectedTextView.cancelAnimation(); if (type == TYPE_STORIES) {
selectedTextView.setText(LocaleController.formatPluralString("StoriesSelected", count), !LocaleController.isRTL); selectedTextView.cancelAnimation();
if (button != null) { selectedTextView.setText(LocaleController.formatPluralString("StoriesSelected", count), !LocaleController.isRTL);
button.setEnabled(count > 0); if (button != null) {
button.setCount(count, true); button.setEnabled(count > 0);
if (sharedMediaLayout.getClosestTab() == SharedMediaLayout.TAB_STORIES) { button.setCount(count, true);
button.setText(LocaleController.formatPluralString("ArchiveStories", count), true); if (sharedMediaLayout.getClosestTab() == SharedMediaLayout.TAB_STORIES) {
button.setText(LocaleController.formatPluralString("ArchiveStories", count), true);
}
} }
} }
} }
@ -1106,6 +1112,9 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
@Override @Override
public boolean isLightStatusBar() { public boolean isLightStatusBar() {
if (storyViewer != null && storyViewer.isShown()) {
return false;
}
int color = Theme.getColor(Theme.key_windowBackgroundWhite); int color = Theme.getColor(Theme.key_windowBackgroundWhite);
if (actionBar.isActionModeShowed()) { if (actionBar.isActionModeShowed()) {
color = Theme.getColor(Theme.key_actionBarActionModeDefault); color = Theme.getColor(Theme.key_actionBarActionModeDefault);

View file

@ -7,6 +7,7 @@ import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Build;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.Spanned; import android.text.Spanned;
@ -26,19 +27,29 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject; import org.telegram.messenger.ChatObject;
import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController; import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject; import org.telegram.messenger.UserObject;
import org.telegram.messenger.VideoEditedInfo;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Adapters.MentionsAdapter; import org.telegram.ui.Adapters.MentionsAdapter;
import org.telegram.ui.Adapters.PaddedListAdapter; import org.telegram.ui.Adapters.PaddedListAdapter;
import org.telegram.ui.Cells.ContextLinkCell;
import org.telegram.ui.Cells.StickerCell; import org.telegram.ui.Cells.StickerCell;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.ContentPreviewViewer; import org.telegram.ui.ContentPreviewViewer;
import org.telegram.ui.PhotoViewer;
import java.util.ArrayList;
public class MentionsContainerView extends BlurredFrameLayout implements NotificationCenter.NotificationCenterDelegate { public class MentionsContainerView extends BlurredFrameLayout implements NotificationCenter.NotificationCenterDelegate {
@ -56,6 +67,7 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
private float containerTop, containerBottom, containerPadding, listViewPadding; private float containerTop, containerBottom, containerPadding, listViewPadding;
private boolean allowBlur; private boolean allowBlur;
private RecyclerListView.OnItemClickListener mentionsOnItemClickListener; private RecyclerListView.OnItemClickListener mentionsOnItemClickListener;
private Delegate delegate;
public MentionsContainerView(@NonNull Context context, long dialogId, int threadMessageId, BaseFragment baseFragment, SizeNotifierFrameLayout container, Theme.ResourcesProvider resourcesProvider) { public MentionsContainerView(@NonNull Context context, long dialogId, int threadMessageId, BaseFragment baseFragment, SizeNotifierFrameLayout container, Theme.ResourcesProvider resourcesProvider) {
super(context, container); super(context, container);
@ -418,7 +430,7 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
if (listViewTranslationAnimator != null) { if (listViewTranslationAnimator != null) {
listViewTranslationAnimator.cancel(); listViewTranslationAnimator.cancel();
} }
AndroidUtilities.runOnUIThread(updateVisibilityRunnable, baseFragment.getFragmentBeginToShow() ? 0 : 100); AndroidUtilities.runOnUIThread(updateVisibilityRunnable, (baseFragment != null && baseFragment.getFragmentBeginToShow()) ? 0 : 100);
if (show) { if (show) {
onOpen(); onOpen();
} else { } else {
@ -529,7 +541,54 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
adapter.setDialogId(dialogId); adapter.setDialogId(dialogId);
} }
private ArrayList<Object> botContextResults;
private PhotoViewer.PhotoViewerProvider botContextProvider = new PhotoViewer.EmptyPhotoViewerProvider() {
@Override
public PhotoViewer.PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index, boolean needPreview) {
if (index < 0 || index >= botContextResults.size()) {
return null;
}
int count = getListView().getChildCount();
Object result = botContextResults.get(index);
for (int a = 0; a < count; a++) {
ImageReceiver imageReceiver = null;
View view = getListView().getChildAt(a);
if (view instanceof ContextLinkCell) {
ContextLinkCell cell = (ContextLinkCell) view;
if (cell.getResult() == result) {
imageReceiver = cell.getPhotoImage();
}
}
if (imageReceiver != null) {
int[] coords = new int[2];
view.getLocationInWindow(coords);
PhotoViewer.PlaceProviderObject object = new PhotoViewer.PlaceProviderObject();
object.viewX = coords[0];
object.viewY = coords[1] - (Build.VERSION.SDK_INT >= 21 ? 0 : AndroidUtilities.statusBarHeight);
object.parentView = getListView();
object.imageReceiver = imageReceiver;
object.thumb = imageReceiver.getBitmapSafe();
object.radius = imageReceiver.getRoundRadius();
return object;
}
}
return null;
}
@Override
public void sendButtonPressed(int index, VideoEditedInfo videoEditedInfo, boolean notify, int scheduleDate, boolean forceDocument) {
if (index < 0 || index >= botContextResults.size()) {
return;
}
delegate.sendBotInlineResult((TLRPC.BotInlineResult) botContextResults.get(index), notify, scheduleDate);
}
};
public void withDelegate(Delegate delegate) { public void withDelegate(Delegate delegate) {
this.delegate = delegate;
getListView().setOnItemClickListener(mentionsOnItemClickListener = (view, position) -> { getListView().setOnItemClickListener(mentionsOnItemClickListener = (view, position) -> {
if (position == 0 || getAdapter().isBannedInline()) { if (position == 0 || getAdapter().isBannedInline()) {
return; return;
@ -596,10 +655,20 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
delegate.replaceText(start, len, code, true); delegate.replaceText(start, len, code, true);
} }
updateVisibility(false); updateVisibility(false);
} if (object instanceof TLRPC.BotInlineResult) {
TLRPC.BotInlineResult result = (TLRPC.BotInlineResult) object;
if ((result.type.equals("photo") && (result.photo != null || result.content != null) ||
result.type.equals("gif") && (result.document != null || result.content != null) ||
result.type.equals("video") && (result.document != null/* || result.content_url != null*/))) {
ArrayList<Object> arrayList = botContextResults = new ArrayList<>(getAdapter().getSearchResultBotContext());
PhotoViewer.getInstance().setParentActivity(baseFragment, resourcesProvider);
PhotoViewer.getInstance().openPhotoForSelect(arrayList, getAdapter().getItemPosition(position), 3, false, botContextProvider, null);
} else {
delegate.sendBotInlineResult(result, true, 0);
}
} }
}); });
getListView().setOnTouchListener((v, event) -> ContentPreviewViewer.getInstance().onTouch(event, getListView(), 0, mentionsOnItemClickListener, null, resourcesProvider)); getListView().setOnTouchListener((v, event) -> ContentPreviewViewer.getInstance().onTouch(event, getListView(), 0, mentionsOnItemClickListener, null, resourcesProvider));
} }
public class MentionsListView extends RecyclerListView { public class MentionsListView extends RecyclerListView {
@ -784,6 +853,9 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
default void addEmojiToRecent(String code) { default void addEmojiToRecent(String code) {
} }
default void sendBotInlineResult(TLRPC.BotInlineResult botInlineResult, boolean notify, int scheduleDate) {}
} }
@Override @Override

View file

@ -55,6 +55,7 @@ public class MessageContainsEmojiButton extends FrameLayout implements Notificat
public final static int EMOJI_TYPE = 0; public final static int EMOJI_TYPE = 0;
public final static int REACTIONS_TYPE = 1; public final static int REACTIONS_TYPE = 1;
public final static int EMOJI_STICKER_TYPE = 2; public final static int EMOJI_STICKER_TYPE = 2;
public final static int SINGLE_REACTION_TYPE = 3;
int type; int type;
private class BoldAndAccent extends CharacterStyle { private class BoldAndAccent extends CharacterStyle {
@ -67,8 +68,9 @@ public class MessageContainsEmojiButton extends FrameLayout implements Notificat
} }
} }
private MessageContainsEmojiButton(int currentAccount, Context context, Theme.ResourcesProvider resourcesProvider, int type) { public MessageContainsEmojiButton(int currentAccount, Context context, Theme.ResourcesProvider resourcesProvider, @NonNull ArrayList<TLRPC.InputStickerSet> inputStickerSets, int type) {
super(context); super(context);
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
this.type = type; this.type = type;
@ -77,28 +79,6 @@ public class MessageContainsEmojiButton extends FrameLayout implements Notificat
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(AndroidUtilities.dp(13)); textPaint.setTextSize(AndroidUtilities.dp(13));
textPaint.setColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem, resourcesProvider)); textPaint.setColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem, resourcesProvider));
}
public MessageContainsEmojiButton(int currentAccount, Context context, Theme.ResourcesProvider resourcesProvider, TLObject object) {
this(currentAccount, context, resourcesProvider, EMOJI_STICKER_TYPE);
String string;
if (type == EMOJI_TYPE) {
string = LocaleController.getString("MessageContainsEmojiPack", R.string.MessageContainsEmojiPack);
} else {
string = LocaleController.getString("MessageContainsReactionsPack", R.string.MessageContainsReactionsPack);
}
String[] parts = string.split("%s");
mainText = parts[0];
endText = parts[1];
loadingDrawable = new LoadingDrawable(resourcesProvider);
loadingDrawable.colorKey1 = Theme.key_actionBarDefaultSubmenuBackground;
loadingDrawable.colorKey2 = Theme.key_listSelector;
loadingDrawable.setRadiiDp(4);
}
public MessageContainsEmojiButton(int currentAccount, Context context, Theme.ResourcesProvider resourcesProvider, @NonNull ArrayList<TLRPC.InputStickerSet> inputStickerSets, int type) {
this(currentAccount, context, resourcesProvider, type);
if (inputStickerSets.size() > 1) { if (inputStickerSets.size() > 1) {
String string; String string;
@ -120,6 +100,8 @@ public class MessageContainsEmojiButton extends FrameLayout implements Notificat
String string; String string;
if (type == EMOJI_TYPE) { if (type == EMOJI_TYPE) {
string = LocaleController.getString("MessageContainsEmojiPack", R.string.MessageContainsEmojiPack); string = LocaleController.getString("MessageContainsEmojiPack", R.string.MessageContainsEmojiPack);
} else if (type == SINGLE_REACTION_TYPE) {
string = LocaleController.getString("MessageContainsReactionPack", R.string.MessageContainsReactionPack);
} else { } else {
string = LocaleController.getString("MessageContainsReactionsPack", R.string.MessageContainsReactionsPack); string = LocaleController.getString("MessageContainsReactionsPack", R.string.MessageContainsReactionsPack);
} }

View file

@ -36,11 +36,12 @@ public class PaintTypeface {
public static final PaintTypeface ROBOTO_MEDIUM = new PaintTypeface("roboto", "PhotoEditorTypefaceRoboto", new LazyTypeface(() -> AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM))); public static final PaintTypeface ROBOTO_MEDIUM = new PaintTypeface("roboto", "PhotoEditorTypefaceRoboto", new LazyTypeface(() -> AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)));
public static final PaintTypeface ROBOTO_ITALIC = new PaintTypeface("italic", "PhotoEditorTypefaceItalic", new LazyTypeface(() -> AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM_ITALIC))); public static final PaintTypeface ROBOTO_ITALIC = new PaintTypeface("italic", "PhotoEditorTypefaceItalic", new LazyTypeface(() -> AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM_ITALIC)));
public static final PaintTypeface ROBOTO_SERIF = new PaintTypeface("serif", "PhotoEditorTypefaceSerif", new LazyTypeface(() -> Typeface.create("serif", Typeface.BOLD))); public static final PaintTypeface ROBOTO_SERIF = new PaintTypeface("serif", "PhotoEditorTypefaceSerif", new LazyTypeface(() -> Typeface.create("serif", Typeface.BOLD)));
public static final PaintTypeface ROBOTO_CONDENSED = new PaintTypeface("condensed", "PhotoEditorTypefaceCondensed", new LazyTypeface(() -> AndroidUtilities.getTypeface("fonts/rcondensedbold.ttf")));
public static final PaintTypeface ROBOTO_MONO = new PaintTypeface ("mono", "PhotoEditorTypefaceMono", new LazyTypeface(() -> AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MONO))); public static final PaintTypeface ROBOTO_MONO = new PaintTypeface ("mono", "PhotoEditorTypefaceMono", new LazyTypeface(() -> AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MONO)));
public static final PaintTypeface MW_BOLD = new PaintTypeface("mw_bold", "PhotoEditorTypefaceMerriweather", new LazyTypeface(() -> AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_MERRIWEATHER_BOLD))); public static final PaintTypeface MW_BOLD = new PaintTypeface("mw_bold", "PhotoEditorTypefaceMerriweather", new LazyTypeface(() -> AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_MERRIWEATHER_BOLD)));
public static final PaintTypeface COURIER_NEW_BOLD = new PaintTypeface("courier_new_bold", "PhotoEditorTypefaceCourierNew", new LazyTypeface(() -> AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_COURIER_NEW_BOLD))); public static final PaintTypeface COURIER_NEW_BOLD = new PaintTypeface("courier_new_bold", "PhotoEditorTypefaceCourierNew", new LazyTypeface(() -> AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_COURIER_NEW_BOLD)));
public final static List<PaintTypeface> BUILT_IN_FONTS = Arrays.asList(ROBOTO_MEDIUM, ROBOTO_ITALIC, ROBOTO_SERIF, ROBOTO_MONO, MW_BOLD, COURIER_NEW_BOLD); public final static List<PaintTypeface> BUILT_IN_FONTS = Arrays.asList(ROBOTO_MEDIUM, ROBOTO_ITALIC, ROBOTO_SERIF, ROBOTO_CONDENSED, ROBOTO_MONO, MW_BOLD, COURIER_NEW_BOLD);
private static final List<String> preferable = Arrays.asList( private static final List<String> preferable = Arrays.asList(
"Google Sans", "Google Sans",

View file

@ -20,8 +20,6 @@ import android.text.TextPaint;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.Components.EditTextBoldCursor; import org.telegram.ui.Components.EditTextBoldCursor;
import java.util.Arrays;
public class EditTextOutline extends EditTextBoldCursor { public class EditTextOutline extends EditTextBoldCursor {
private Canvas mCanvas = new Canvas(); private Canvas mCanvas = new Canvas();
@ -37,6 +35,7 @@ public class EditTextOutline extends EditTextBoldCursor {
public boolean betterFraming; public boolean betterFraming;
private RectF[] lines; private RectF[] lines;
public RectF framePadding;
private boolean isFrameDirty; private boolean isFrameDirty;
public EditTextOutline(Context context) { public EditTextOutline(Context context) {
@ -201,6 +200,21 @@ public class EditTextOutline extends EditTextBoldCursor {
lines[i - 1].bottom = lines[i].top; lines[i - 1].bottom = lines[i].top;
} }
} }
if (framePadding == null) {
framePadding = new RectF();
}
framePadding.left = getMeasuredWidth();
framePadding.top = getMeasuredHeight();
framePadding.bottom = 0;
framePadding.right = 0;
for (int i = 0; i < lines.length; ++i) {
framePadding.left = Math.min(framePadding.left, getPaddingLeft() + lines[i].left);
framePadding.top = Math.min(framePadding.top, getPaddingTop() + lines[i].top);
framePadding.right = Math.max(framePadding.right, getPaddingLeft() + lines[i].right);
framePadding.bottom = Math.max(framePadding.bottom, getPaddingTop() + lines[i].bottom);
}
framePadding.right = getMeasuredWidth() - framePadding.right;
framePadding.bottom = getMeasuredHeight() - framePadding.bottom;
} }
path.rewind(); path.rewind();
float h = getHeight(); float h = getHeight();
@ -251,6 +265,8 @@ public class EditTextOutline extends EditTextBoldCursor {
setFrameRoundRadius(r); setFrameRoundRadius(r);
canvas.drawPath(path, paint); canvas.drawPath(path, paint);
canvas.restore(); canvas.restore();
} else {
framePadding = null;
} }
super.onDraw(canvas); super.onDraw(canvas);
} }

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