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 {
minSdkVersion 19
targetSdkVersion 31
targetSdkVersion 33
versionName "8.9.0"
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="android.permission.ACCESS_COARSE_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"/>
<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="android.permission.ACCESS_COARSE_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.FOREGROUND_SERVICE" />
<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="android.permission.ACCESS_COARSE_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"/>
<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="android.permission.ACCESS_COARSE_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.FOREGROUND_SERVICE" />
<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="android.permission.ACCESS_COARSE_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.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />

View file

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

View file

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

View file

@ -924,7 +924,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_onStreamP
return;
}
auto context = (AndroidContext *) instance->_platformContext.get();
std::shared_ptr<BroadcastPartTask> task;
std::shared_ptr<BroadcastPartTask> task = nullptr;
auto q = (VideoChannelDescription::Quality) quality;
if (videoChannel != 0) {
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.WAKE_LOCK" />
<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.READ_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.REQUEST_INSTALL_PACKAGES" />
<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.WRITE"/>

View file

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

View file

@ -8,6 +8,7 @@
package org.telegram.messenger;
import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@ -112,6 +113,7 @@ import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;
import androidx.core.widget.NestedScrollView;
import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.dynamicanimation.animation.SpringAnimation;
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.UndoView;
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.WallpapersListActivity;
@ -454,6 +458,10 @@ public class AndroidUtilities {
}
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 endIndex = str.indexOf("**", startIndex + 1);
str = str.replace("**", "");
@ -473,7 +481,7 @@ public class AndroidUtilities {
super.updateDrawState(ds);
ds.setUnderlineText(false);
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) {
textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
int wasAlpha = textPaint.getAlpha();
textPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText));
textPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText, resourcesProvider));
textPaint.setAlpha(wasAlpha);
}
}, index, index + len, 0);
@ -573,18 +581,25 @@ public class AndroidUtilities {
}
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) {
return false;
}
for (int i = 0; i < container.getChildCount(); 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;
}
child.getHitRect(AndroidUtilities.rectTmp2);
if (AndroidUtilities.rectTmp2.contains((int) x, (int) y) && child.isClickable()) {
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;
}
}
@ -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 {
String url;
int start;
@ -2982,7 +3027,17 @@ public class AndroidUtilities {
}
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);
}
File storageDir = null;
@ -5197,7 +5252,7 @@ public class AndroidUtilities {
}
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) {

View file

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

View file

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

View file

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

View file

@ -1326,6 +1326,13 @@ public class DatabaseMigrationHelper {
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;
}

View file

@ -84,6 +84,15 @@ public class DispatchQueue extends Thread {
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) {
try {
syncLatch.await();

View file

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

View file

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

View file

@ -284,12 +284,25 @@ public class FilesMigrationService extends Service {
public void migrateOldFolder() {
Activity activity = fragment.getParentActivity();
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) {
ArrayList<String> permissions = new ArrayList<>();
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) {
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);

View file

@ -120,6 +120,11 @@ public class GoogleMapsProvider implements IMapsProvider {
return googleMap.getMaxZoomLevel();
}
@Override
public float getMinZoomLevel() {
return googleMap.getMinZoomLevel();
}
@SuppressLint("MissingPermission")
@Override
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
public CameraPosition 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 moveCamera(ICameraUpdate update);
float getMaxZoomLevel();
float getMinZoomLevel();
void setMyLocationEnabled(boolean enabled);
IUISettings getUiSettings();
void setOnCameraIdleListener(Runnable callback);
void setOnCameraMoveStartedListener(OnCameraMoveStartedListener onCameraMoveStartedListener);
CameraPosition getCameraPosition();
void setOnMapLoadedCallback(Runnable callback);

View file

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

View file

@ -139,6 +139,25 @@ public class LinkifyPort {
"\uDB00\uDC00-\uDB3F\uDFFD" +
"\uDB44\uDC00-\uDB7F\uDFFD" +
"&&[^\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 =
"((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]"
@ -146,7 +165,7 @@ public class LinkifyPort {
+ "|[1-9][0-9]|[0-9]))";
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 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 String STRICT_TLD = "(?:" + IANA_TOP_LEVEL_DOMAINS + "|" + PUNYCODE_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.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
import androidx.collection.LongSparseArray;
@ -997,7 +998,7 @@ public class LocationController extends BaseController implements NotificationCe
}
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<>();
@ -1011,15 +1012,24 @@ public class LocationController extends BaseController implements NotificationCe
callbacks.remove(callback);
}
if (location == null) {
callback.onLocationAddressAvailable(null, null, null);
callback.onLocationAddressAvailable(null, null, null, null, null);
return;
}
Locale locale;
try {
locale = LocaleController.getInstance().getCurrentLocale();
} catch (Exception ignore) {
locale = LocaleController.getInstance().getSystemDefaultLocale();
}
final Locale finalLocale = locale;
Utilities.globalQueue.postRunnable(fetchLocationRunnable = () -> {
String name;
String displayName;
String name, displayName, city, street, countryCode = null;
boolean onlyCountry = true;
TLRPC.TL_messageMediaVenue cityLocation = null;
TLRPC.TL_messageMediaVenue streetLocation = null;
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);
if (addresses.size() > 0) {
Address address = addresses.get(0);
@ -1028,6 +1038,74 @@ public class LocationController extends BaseController implements NotificationCe
StringBuilder nameBuilder = 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();
if (!TextUtils.isEmpty(arg)) {
@ -1065,12 +1143,29 @@ public class LocationController extends BaseController implements NotificationCe
}
nameBuilder.append(arg);
}
countryCode = address.getCountryCode();
arg = address.getCountryName();
if (!TextUtils.isEmpty(arg)) {
if (nameBuilder.length() > 0) {
nameBuilder.append(", ");
}
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();
@ -1106,19 +1201,94 @@ public class LocationController extends BaseController implements NotificationCe
name = nameBuilder.toString();
displayName = displayNameBuilder.toString();
city = cityBuilder.toString();
street = streetBuilder == null ? null : streetBuilder.toString();
} else {
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) {
name = displayName = String.format(Locale.US, "Unknown address (%f,%f)", location.getLatitude(), location.getLongitude());
city = null;
street = null;
}
final String nameFinal = name;
final String displayNameFinal = displayName;
final TLRPC.TL_messageMediaVenue finalCityLocation = cityLocation;
final TLRPC.TL_messageMediaVenue finalStreetLocation = streetLocation;
AndroidUtilities.runOnUIThread(() -> {
callbacks.remove(callback);
callback.onLocationAddressAvailable(nameFinal, displayNameFinal, location);
callback.onLocationAddressAvailable(nameFinal, displayNameFinal, finalCityLocation, finalStreetLocation, location);
});
}, 300);
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;
Cursor cursor = null;
try {
if (ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{"COUNT(_id)"}, null, null, null);
final Context context = ApplicationLoader.applicationContext;
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.moveToNext()) {
count += cursor.getInt(0);
@ -934,8 +942,16 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
}
try {
if (ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, new String[]{"COUNT(_id)"}, null, null, null);
final Context context = ApplicationLoader.applicationContext;
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.moveToNext()) {
count += cursor.getInt(0);
@ -1773,8 +1789,32 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (raisedToBack == minCount || accelerometerVertical) {
lastAccelerometerDetected = System.currentTimeMillis();
}
if (proximityTouched && (raisedToBack == minCount || accelerometerVertical || System.currentTimeMillis() - lastAccelerometerDetected < 60) && !VoIPService.isAnyKindOfCallActive() && !manualRecording && !forbidRaiseToListen()) {
if (SharedConfig.enabledRaiseTo(true) && playingMessageObject == null && recordStartRunnable == null && recordingAudio == null && !PhotoViewer.getInstance().isVisible() && ApplicationLoader.isScreenOn && !inputFieldHasText && allowStartRecord && raiseChat != null && !callInProgress) {
final boolean allowRecording = !manualRecording && playingMessageObject == null && SharedConfig.enabledRaiseTo(true) && 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 (BuildVars.LOGS_ENABLED) {
FileLog.d("start record");
@ -1788,40 +1828,40 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (useFrontSpeaker) {
setUseFrontSpeaker(true);
}
ignoreOnPause = true;
if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
proximityWakeLock.acquire();
}
// ignoreOnPause = true;
// if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
// proximityWakeLock.acquire();
// }
}
} else if (SharedConfig.enabledRaiseTo(false) && playingMessageObject != null && (playingMessageObject.isVoice() || playingMessageObject.isRoundVideo())) {
} else if (allowListening) {
if (!useFrontSpeaker) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("start listen");
}
if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
proximityWakeLock.acquire();
}
// if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
// proximityWakeLock.acquire();
// }
setUseFrontSpeaker(true);
startAudioAgain(false);
ignoreOnPause = true;
// ignoreOnPause = true;
}
}
raisedToBack = 0;
raisedToTop = 0;
raisedToTopSign = 0;
countLess = 0;
} else if (proximityTouched && ((accelerometerSensor == null || linearSensor == null) && gravitySensor == null || ignoreAccelerometerGestures()) && !VoIPService.isAnyKindOfCallActive()) {
if (playingMessageObject != null && !ApplicationLoader.mainInterfacePaused && (playingMessageObject.isVoice() || playingMessageObject.isRoundVideo()) && SharedConfig.enabledRaiseTo(false)) {
} else if (proximityTouched && ((accelerometerSensor == null || linearSensor == null) && gravitySensor == null) && !VoIPService.isAnyKindOfCallActive()) {
if (playingMessageObject != null && !ApplicationLoader.mainInterfacePaused && allowListening) {
if (!useFrontSpeaker && !manualRecording && !forbidRaiseToListen()) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("start listen by proximity only");
}
if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
proximityWakeLock.acquire();
}
// if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
// proximityWakeLock.acquire();
// }
setUseFrontSpeaker(true);
startAudioAgain(false);
ignoreOnPause = true;
// ignoreOnPause = true;
}
}
} else if (!proximityTouched && !manualRecording) {
@ -1832,9 +1872,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
stopRecording(2, false, 0);
raiseToEarRecord = false;
ignoreOnPause = false;
if (proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release();
}
// if (!ignoreAccelerometerGestures() && proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
// proximityWakeLock.release();
// }
} else if (useFrontSpeaker) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("stop listen");
@ -1842,9 +1882,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
useFrontSpeaker = false;
startAudioAgain(true);
ignoreOnPause = false;
if (proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release();
}
// if (!ignoreAccelerometerGestures() && proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
// proximityWakeLock.release();
// }
}
}
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);
});
if (proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
if (proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release();
}
}
@ -2072,14 +2112,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
stopProgressTimer();
lastProgress = 0;
isPaused = false;
if (!useFrontSpeaker && !SharedConfig.enabledRaiseTo(true)) {
ChatActivity chat = raiseChat;
stopRaiseToEarSensors(raiseChat, false, false);
raiseChat = chat;
}
if (proximityWakeLock != null && proximityWakeLock.isHeld() && !proximityTouched) {
proximityWakeLock.release();
}
boolean playingNext = false;
if (playingMessageObject != null) {
if (downloadingCurrentMessage) {
FileLoader.getInstance(playingMessageObject.currentAccount).cancelLoadFile(playingMessageObject.getDocument());
@ -2108,10 +2141,10 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
voiceMessagesPlaylistMap = null;
}
}
boolean next = false;
if (voiceMessagesPlaylist != null && index < voiceMessagesPlaylist.size()) {
MessageObject nextVoiceMessage = voiceMessagesPlaylist.get(index);
playMessage(nextVoiceMessage);
playingNext = true;
if (!nextVoiceMessage.isRoundVideo() && pipRoundVideoView != null) {
pipRoundVideoView.close(true);
pipRoundVideoView = null;
@ -2133,6 +2166,11 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
ApplicationLoader.applicationContext.stopService(intent);
}
}
if (!playingNext && byVoiceEnd && !SharedConfig.enabledRaiseTo(true)) {
ChatActivity chat = raiseChat;
stopRaiseToEarSensors(raiseChat, false, false);
raiseChat = chat;
}
}
public boolean isGoingToShowMessageObject(MessageObject messageObject) {
@ -3483,9 +3521,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
startRaiseToEarSensors(raiseChat);
}
if (!ApplicationLoader.mainInterfacePaused && proximityWakeLock != null && !proximityWakeLock.isHeld() && (playingMessageObject.isVoice() || playingMessageObject.isRoundVideo()) && SharedConfig.enabledRaiseTo(false)) {
if (ignoreAccelerometerGestures()) {
proximityWakeLock.acquire();
}
// proximityWakeLock.acquire();
}
startProgressTimer(playingMessageObject);
NotificationCenter.getInstance(messageObject.currentAccount).postNotificationName(NotificationCenter.messagePlayingDidStart, messageObject, oldMessageObject);
@ -3546,10 +3582,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return true;
}
public static boolean ignoreAccelerometerGestures() {
return Build.MANUFACTURER.equalsIgnoreCase("samsung");
}
public void updateSilent(boolean value) {
isSilent = value;
@ -4738,8 +4770,17 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
Cursor cursor = null;
try {
if (Build.VERSION.SDK_INT < 23 || ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
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");
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(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) {
int imageIdColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID);
int bucketIdColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID);
@ -4820,7 +4861,17 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
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");
if (cursor != null) {
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)) {
ArrayList<Long> replyMessages = new ArrayList<>();
LongSparseArray<ArrayList<MessageObject>> replyMessageRandomOwners = new LongSparseArray<>();
@ -5542,7 +5542,7 @@ public class MediaDataController extends BaseController {
AndroidUtilities.runOnUIThread(callback);
}
}
});
}, classGuid);
if (replyMessageOwners.isEmpty()) {
requestsCount[0]--;
if (requestsCount[0] == 0) {
@ -5617,7 +5617,7 @@ public class MediaDataController extends BaseController {
TLRPC.TL_messages_getScheduledMessages req = new TLRPC.TL_messages_getScheduledMessages();
req.peer = getMessagesController().getInputPeer(dialogId);
req.id = dialogReplyMessagesIds.valueAt(a);
getConnectionsManager().sendRequest(req, (response, error) -> {
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
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) {
TLRPC.TL_channels_getMessages req = new TLRPC.TL_channels_getMessages();
req.channel = getMessagesController().getInputChannel(channelId);
req.id = dialogReplyMessagesIds.valueAt(a);
getConnectionsManager().sendRequest(req, (response, error) -> {
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
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 {
TLRPC.TL_messages_getMessages req = new TLRPC.TL_messages_getMessages();
req.id = dialogReplyMessagesIds.valueAt(a);
getConnectionsManager().sendRequest(req, (response, error) -> {
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
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 {

View file

@ -4649,7 +4649,7 @@ public class MessageObject {
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) {
return false;
}
@ -4835,10 +4835,12 @@ public class MessageObject {
}
String text = messageOwner.message;
ArrayList<TLRPC.MessageEntity> entities = messageOwner.entities;
boolean forceManualEntities = false;
if (type == TYPE_STORY) {
if (messageOwner.media != null && messageOwner.media.storyItem != null) {
text = messageOwner.media.storyItem.caption;
entities = messageOwner.media.storyItem.entities;
forceManualEntities = true;
} else {
text = "";
entities = new ArrayList<>();
@ -4861,16 +4863,16 @@ public class MessageObject {
hasEntities = !entities.isEmpty();
}
boolean useManualParse = !hasEntities && (
eventId != 0 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_old ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_layer68 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_layer74 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_old ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_layer68 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_layer74 ||
isOut() && messageOwner.send_state != MESSAGE_SEND_STATE_SENT ||
messageOwner.id < 0
boolean useManualParse = forceManualEntities || !hasEntities && (
eventId != 0 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_old ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_layer68 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto_layer74 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_old ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_layer68 ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument_layer74 ||
isOut() && messageOwner.send_state != MESSAGE_SEND_STATE_SENT ||
messageOwner.id < 0
);
if (useManualParse) {
@ -7001,7 +7003,7 @@ public class MessageObject {
}
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() {
@ -7589,7 +7591,7 @@ public class MessageObject {
if (type == TYPE_EXTENDED_MEDIA_PREVIEW) {
TLRPC.TL_messageExtendedMediaPreview preview = (TLRPC.TL_messageExtendedMediaPreview) messageOwner.media.extended_media;
if (preview.thumb != null) {
File file = FileLoader.getInstance(currentAccount).getPathToAttach(preview.thumb);
File file = FileLoader.getInstance(currentAccount).getPathToAttach(preview.thumb, useFileDatabaseQueue);
if (!mediaExists) {
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.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@ -72,7 +73,6 @@ import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.ProfileActivity;
import org.telegram.ui.Stories.StoriesController;
import org.telegram.ui.Stories.recorder.DualCameraView;
import org.telegram.ui.TopicsFragment;
import java.io.File;
@ -137,9 +137,13 @@ public class MessagesController extends BaseController implements NotificationCe
private SparseArray<ChatlistUpdatesStat> chatlistFoldersUpdates = new SparseArray<>();
public int largeQueueMaxActiveOperations = 2;
public int smallQueueMaxActiveOperations = 5;
public int stealthModeFuture;
public int stealthModePast;
public int stealthModeCooldown;
public StoriesController storiesController;
private boolean hasArchivedChats;
private boolean hasStories;
public long storiesChangelogUserId;
public static TLRPC.Peer getPeerFromInputPeer(TLRPC.InputPeer peer) {
if (peer.chat_id != 0) {
@ -458,6 +462,7 @@ public class MessagesController extends BaseController implements NotificationCe
public boolean collectDeviceStats;
public boolean showFiltersTooltip;
public String venueSearchBot;
public String storyVenueSearchBot;
public String gifSearchBot;
public String imageSearchBot;
public String dcDomainName;
@ -504,7 +509,8 @@ public class MessagesController extends BaseController implements NotificationCe
public int publicLinksLimitPremium;
public int captionLengthLimitDefault;
public int captionLengthLimitPremium;
public int storyCaptionLengthLimit;
public int storyCaptionLengthLimitDefault;
public int storyCaptionLengthLimitPremium;
public int aboutLengthLimitDefault;
public int aboutLengthLimitPremium;
public int reactionsUserMaxDefault;
@ -518,6 +524,10 @@ public class MessagesController extends BaseController implements NotificationCe
private int chatlistUpdatePeriod;
public int storyExpiringLimitDefault;
public int storyExpiringLimitPremium;
public int storiesSentWeeklyLimitDefault;
public int storiesSentWeeklyLimitPremium;
public int storiesSentMonthlyLimitDefault;
public int storiesSentMonthlyLimitPremium;
public int uploadMaxFileParts;
public int uploadMaxFilePartsPremium;
@ -552,6 +562,7 @@ public class MessagesController extends BaseController implements NotificationCe
public int chatlistJoinedLimitDefault;
public int chatlistJoinedLimitPremium;
public String storiesPosting;
public String storiesEntities;
public int checkResetLangpack;
@ -622,6 +633,7 @@ public class MessagesController extends BaseController implements NotificationCe
getMessagesStorage().saveDialogFiltersOrder();
getNotificationCenter().postNotificationName(NotificationCenter.dialogFiltersUpdated);
getStoriesController().onPremiumChanged();
}
public void lockFiltersInternal() {
@ -1285,6 +1297,7 @@ public class MessagesController extends BaseController implements NotificationCe
promoPsaType = mainPreferences.getString("promo_psa_type", null);
proxyDialogAddress = mainPreferences.getString("proxyDialogAddress", null);
venueSearchBot = mainPreferences.getString("venueSearchBot", "foursquare");
storyVenueSearchBot = mainPreferences.getString("storyVenueSearchBot", "foursquare");
gifSearchBot = mainPreferences.getString("gifSearchBot", "gif");
imageSearchBot = mainPreferences.getString("imageSearchBot", "pic");
blockedCountry = mainPreferences.getBoolean("blockedCountry", false);
@ -1327,7 +1340,8 @@ public class MessagesController extends BaseController implements NotificationCe
publicLinksLimitPremium = mainPreferences.getInt("publicLinksLimitPremium", 20);
captionLengthLimitDefault = mainPreferences.getInt("captionLengthLimitDefault", 1024);
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);
aboutLengthLimitPremium = mainPreferences.getInt("aboutLengthLimitPremium", 140);
reactionsUserMaxDefault = mainPreferences.getInt("reactionsUserMaxDefault", 1);
@ -1351,14 +1365,23 @@ public class MessagesController extends BaseController implements NotificationCe
checkResetLangpack = mainPreferences.getInt("checkResetLangpack", 0);
smallQueueMaxActiveOperations = mainPreferences.getInt("smallQueueMaxActiveOperations", 5);
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;
chatlistInvitesLimitDefault = mainPreferences.getInt("chatlistInvitesLimitDefault", 3);
storyExpiringLimitDefault = mainPreferences.getInt("storyExpiringLimitDefault", 50);
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);
chatlistJoinedLimitDefault = mainPreferences.getInt("chatlistJoinedLimitDefault", 2);
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);
BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID);
if (mainPreferences.contains("dcDomainName2")) {
@ -1499,9 +1522,7 @@ public class MessagesController extends BaseController implements NotificationCe
FileLog.e(e);
}
}
if (BuildVars.DEBUG_VERSION) {
AndroidUtilities.runOnUIThread(this::loadAppConfig, 2000);
}
AndroidUtilities.runOnUIThread(this::loadAppConfig, 2000);
topicsController = new TopicsController(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++) {
TLRPC.TL_jsonObjectValue value = object.value.get(a);
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": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
largeQueueMaxActiveOperations = (int) ((TLRPC.TL_jsonNumber) value.value).value;
@ -2982,12 +3031,23 @@ public class MessagesController extends BaseController implements NotificationCe
}
break;
}
case "story_caption_length_limit": {
case "story_caption_length_limit_default": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber number = (TLRPC.TL_jsonNumber) value.value;
if (number.value != storyCaptionLengthLimit) {
storyCaptionLengthLimit = (int) number.value;
editor.putInt("storyCaptionLengthLimit", storyCaptionLengthLimit);
if (number.value != storyCaptionLengthLimitDefault) {
storyCaptionLengthLimitDefault = (int) number.value;
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;
}
}
@ -3174,6 +3234,50 @@ public class MessagesController extends BaseController implements NotificationCe
}
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": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
@ -3209,14 +3313,24 @@ public class MessagesController extends BaseController implements NotificationCe
}
case "stories_posting": {
if (value.value instanceof TLRPC.TL_jsonString) {
TLRPC.TL_jsonString bool = (TLRPC.TL_jsonString) value.value;
if (!TextUtils.equals(bool.value, storiesPosting)) {
storiesPosting = bool.value;
TLRPC.TL_jsonString str = (TLRPC.TL_jsonString) value.value;
if (!TextUtils.equals(str.value, storiesPosting)) {
storiesPosting = str.value;
editor.putString("storiesPosting", storiesPosting);
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": {
if (value.value instanceof TLRPC.TL_jsonBool) {
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) {
@ -3256,6 +3380,7 @@ public class MessagesController extends BaseController implements NotificationCe
private boolean savePremiumFeaturesPreviewOrder(SharedPreferences.Editor editor, ArrayList<TLRPC.JSONValue> value) {
StringBuilder stringBuilder = new StringBuilder();
StringBuilder storiesBuilder = new StringBuilder();
premiumFeaturesTypesToPosition.clear();
for (int i = 0; i < value.size(); i++) {
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);
} else {
getConnectionsManager().sendRequest(req, requestDelegate);
@ -6896,10 +7023,10 @@ public class MessagesController extends BaseController implements NotificationCe
}
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))) {
return;
}
@ -6909,7 +7036,7 @@ public class MessagesController extends BaseController implements NotificationCe
req.channel = getInputChannel(chatId);
req.filter = new TLRPC.TL_channelParticipantsRecent();
req.offset = 0;
req.limit = 32;
req.limit = count;
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (error == null) {
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.offset_id = max_id;
long time = System.currentTimeMillis();
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
@ -8415,7 +8543,7 @@ public class MessagesController extends BaseController implements NotificationCe
} 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);
}
});
}, classGuid);
} 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);
}
@ -12227,17 +12355,21 @@ public class MessagesController extends BaseController implements NotificationCe
if (!guids.contains(guid)) {
guids.add(guid);
}
boolean needGetDifference = false;
if (shortPollChannels.indexOfKey(chat.id) < 0) {
needGetDifference = true;
if (needPollConsumer != null) {
AndroidUtilities.runOnUIThread(() -> {
needPollConsumer.accept(true);
});
}
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 (onlineGuids == null) {
onlineGuids = new ArrayList<>();
@ -12750,7 +12882,7 @@ public class MessagesController extends BaseController implements NotificationCe
updateInterfaceWithMessages(dialogId, arr, false);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
});
});
}, 0);
}
});
@ -14723,6 +14855,7 @@ public class MessagesController extends BaseController implements NotificationCe
blockePeers.delete(id);
}
getNotificationCenter().postNotificationName(NotificationCenter.blockedUsersDidLoad);
getStoriesController().updateBlockUser(id, finalUpdate.blocked_my_stories_from, false);
}));
} else if (baseUpdate instanceof TLRPC.TL_updateNotifySettings) {
if (updatesOnMainThread == null) {
@ -14780,6 +14913,11 @@ public class MessagesController extends BaseController implements NotificationCe
}
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) {
if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>();
@ -14912,7 +15050,7 @@ public class MessagesController extends BaseController implements NotificationCe
updatesOnMainThread = new ArrayList<>();
}
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) {
updatesOnMainThread = new ArrayList<>();
}
@ -15799,6 +15937,9 @@ public class MessagesController extends BaseController implements NotificationCe
}
int threadId = update.top_msg_id;
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) {
getMediaDataController().markFeaturedStickersAsRead(false, false);
} 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);
}
}
} 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) {
@ -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);
}
}
@ -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);
if (lastMessage == null || scheduled) {
@ -18241,4 +18384,31 @@ public class MessagesController extends BaseController implements NotificationCe
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;
public boolean showClearDatabaseAlert;
private LongSparseIntArray dialogIsForum = new LongSparseIntArray();
@ -202,6 +202,7 @@ public class MessagesStorage extends BaseController {
public MessagesStorage(int instance) {
super(instance);
storageQueue = new DispatchQueue("storageQueue_" + instance);
storageQueue.setPriority(8);
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 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 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 channelRightsUpdated = totalEvents++;
public static final int openArticle = totalEvents++;
public static final int articleClosed = totalEvents++;
public static final int updateMentionsCount = totalEvents++;
public static final int didUpdatePollResults = totalEvents++;
public static final int chatOnlineCountDidLoad = totalEvents++;
@ -211,6 +212,8 @@ public class NotificationCenter {
public static final int didUpdatePremiumGiftStickers = totalEvents++;
public static final int didUpdatePremiumGiftFieldIcon = totalEvents++;
public static final int storiesEnabledUpdate = totalEvents++;
public static final int storiesBlocklistUpdate = totalEvents++;
public static final int storiesLimitUpdate = totalEvents++;
//global
public static final int pushMessagesUpdated = totalEvents++;

View file

@ -868,7 +868,7 @@ public class PushListenerController {
break;
}
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;
}
case "CHAT_DELETE_YOU": {

View file

@ -231,11 +231,13 @@ public class SharedConfig {
public static boolean searchMessagesAsListUsed;
public static boolean stickersReorderingHintUsed;
public static int dayNightWallpaperSwitchHint;
public static boolean storyReactionsLongPressHint;
public static boolean disableVoiceAudioEffects;
public static boolean forceDisableTabletMode;
public static boolean updateStickersOrderOnSend = true;
public static boolean bigCameraForRound;
public static boolean useSurfaceInStories;
public static int stealthModeSendMessageConfirm = 2;
private static int lastLocalId = -210000;
public static String storageCacheDir;
@ -591,6 +593,7 @@ public class SharedConfig {
searchMessagesAsListHintShows = preferences.getInt("searchMessagesAsListHintShows", 0);
searchMessagesAsListUsed = preferences.getBoolean("searchMessagesAsListUsed", false);
stickersReorderingHintUsed = preferences.getBoolean("stickersReorderingHintUsed", false);
storyReactionsLongPressHint = preferences.getBoolean("storyReactionsLongPressHint", false);
textSelectionHintShows = preferences.getInt("textSelectionHintShows", 0);
scheduledOrNoSoundHintShows = preferences.getInt("scheduledOrNoSoundHintShows", 0);
forwardingOptionsHintShown = preferences.getBoolean("forwardingOptionsHintShown", false);
@ -601,6 +604,7 @@ public class SharedConfig {
messageSeenHintCount = preferences.getInt("messageSeenCount", 3);
emojiInteractionsHintCount = preferences.getInt("emojiInteractionsHintCount", 3);
dayNightThemeSwitchHintCount = preferences.getInt("dayNightThemeSwitchHintCount", 3);
stealthModeSendMessageConfirm = preferences.getInt("stealthModeSendMessageConfirm", 2);
mediaColumnsCount = preferences.getInt("mediaColumnsCount", 3);
storiesColumnsCount = preferences.getInt("storiesColumnsCount", 3);
fastScrollHintCount = preferences.getInt("fastScrollHintCount", 3);
@ -797,6 +801,7 @@ public class SharedConfig {
messageSeenHintCount = 3;
emojiInteractionsHintCount = 3;
dayNightThemeSwitchHintCount = 3;
stealthModeSendMessageConfirm = 2;
dayNightWallpaperSwitchHint = 0;
saveConfig();
}
@ -825,6 +830,14 @@ public class SharedConfig {
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() {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
@ -1423,6 +1436,12 @@ public class SharedConfig {
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_AVERAGE = 1;
public final static int PERFORMANCE_CLASS_HIGH = 2;

View file

@ -1016,4 +1016,255 @@ public class TranslateController extends BaseController {
private void resetTranslatingDialogsCache() {
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_TEXT = 1;
public static final int TYPE_PHOTO = 2;
public static final int TYPE_LOCATION = 3;
public byte type;
public byte subType;
@ -115,6 +116,7 @@ public class VideoEditedInfo {
public float rotation;
public float width;
public float height;
public float additionalWidth, additionalHeight;
public String text;
public ArrayList<EmojiEntity> entities = new ArrayList<>();
public int color;
@ -146,6 +148,12 @@ public class VideoEditedInfo {
public AnimatedFileDrawable animatedFileDrawable;
public Canvas roundRadiusCanvas;
public TLRPC.MediaArea mediaArea;
public TLRPC.MessageMedia mediaGeo;
public float density;
public int W, H;
public MediaEntity() {
}
@ -185,6 +193,20 @@ public class VideoEditedInfo {
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) {
@ -218,6 +240,26 @@ public class VideoEditedInfo {
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() {

View file

@ -254,7 +254,7 @@ public class Browser {
if (tryTelegraph) {
try {
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[] {
new AlertDialog(context, AlertDialog.ALERT_TYPE_SPINNER)
};
@ -515,6 +515,8 @@ public class Browser {
}
return true;
}
} else if ("telegram.org".equals(host) && uri != null && uri.getPath() != null && uri.getPath().startsWith("/blog/")) {
return true;
} else if (all) {
if (host.endsWith("telegram.org") || host.endsWith("telegra.ph") || host.endsWith("telesco.pe")) {
return true;

View file

@ -57,12 +57,14 @@ import org.telegram.messenger.MessageObject;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.VideoEditedInfo;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.EditTextEffects;
import org.telegram.ui.Components.FilterShaders;
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.RLottieDrawable;
import org.telegram.ui.Components.Rect;
@ -556,10 +558,13 @@ public class TextureRenderer {
private void drawEntity(VideoEditedInfo.MediaEntity entity, int textColor) {
if (entity.ptr != 0) {
RLottieDrawable.getFrame(entity.ptr, (int) entity.currentFrame, stickerBitmap, 512, 512, stickerBitmap.getRowBytes(), true);
applyRoundRadius(entity, stickerBitmap, (entity.subType & 8) != 0 ? textColor : 0);
if (entity.bitmap == null || entity.W <= 0 || entity.H <= 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]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, stickerBitmap, 0);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, entity.bitmap, 0);
entity.currentFrame += entity.framesPerDraw;
if (entity.currentFrame >= entity.metadata[0]) {
entity.currentFrame = 0;
@ -594,7 +599,7 @@ public class TextureRenderer {
if (entity.bitmap != null) {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[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()) {
for (int i = 0; i < entity.entities.size(); ++i) {
@ -899,6 +904,7 @@ public class TextureRenderer {
initStickerEntity(entity);
} else if (entity.type == VideoEditedInfo.MediaEntity.TYPE_TEXT) {
EditTextOutline editText = new EditTextOutline(ApplicationLoader.applicationContext);
editText.getPaint().setAntiAlias(true);
editText.betterFraming = useMatrixForImagePath;
editText.drawAnimatedEmojiDrawables = false;
editText.setBackgroundColor(Color.TRANSPARENT);
@ -916,7 +922,6 @@ public class TextureRenderer {
e.entity = new VideoEditedInfo.MediaEntity();
e.entity.text = e.documentAbsolutePath;
e.entity.subType = e.subType;
initStickerEntity(e.entity);
AnimatedEmojiSpan span = new AnimatedEmojiSpan(0L, 1f, editText.getPaint().getFontMetricsInt()) {
@Override
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.y = tcy - e.entity.height / 2f;
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);
@ -1013,6 +1021,57 @@ public class TextureRenderer {
entity.bitmap = Bitmap.createBitmap(entity.viewWidth, entity.viewHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(entity.bitmap);
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) {
@ -1022,9 +1081,23 @@ public class TextureRenderer {
}
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.W <= 0 || entity.H <= 0) {
return;
}
entity.bitmap = Bitmap.createBitmap(entity.W, entity.H, Bitmap.Config.ARGB_8888);
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;
} 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);
@ -1149,6 +1222,10 @@ public class TextureRenderer {
if (entity.view instanceof EditTextEffects) {
((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.util.Base64;
import com.google.android.exoplayer2.util.Log;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import org.json.JSONArray;
@ -412,6 +413,9 @@ public class ConnectionsManager extends BaseController {
}
public void bindRequestToGuid(int requestToken, int guid) {
if (guid == 0) {
return;
}
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) {
menuWidth = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST);
menu.measure(menuWidth, actionBarHeightSpec);
int itemsWidth = menu.getItemsMeasuredWidth();
menuWidth = MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 74 : 66) + menu.getItemsMeasuredWidth(), MeasureSpec.EXACTLY);
int itemsWidth = menu.getItemsMeasuredWidth(true);
menuWidth = MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 74 : 66) + menu.getItemsMeasuredWidth(true), MeasureSpec.EXACTLY);
if (!isMenuOffsetSuppressed) {
menu.translateXItems(-itemsWidth);
}

View file

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

View file

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

View file

@ -81,6 +81,17 @@ public class ActionBarMenuItem extends FrameLayout {
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) {
searchItemPaddingStart = padding;
if (searchContainer != null) {
@ -525,6 +536,7 @@ public class ActionBarMenuItem extends FrameLayout {
View cell = new View(popupLayout.getContext());
cell.setTag(id);
cell.setTag(R.id.object_tag, 1);
cell.setTag(R.id.fit_width_tag, 1);
popupLayout.addView(cell);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) cell.getLayoutParams();
if (LocaleController.isRTL) {

View file

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

View file

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

View file

@ -31,6 +31,7 @@ import android.os.Bundle;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;
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;
}
public boolean isKeyboardVisible() {
return keyboardVisible;
}
public interface BottomSheetDelegateInterface {
void onOpenAnimationStart();
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) {
this.playingImagesLayerNum = playingImages;
this.openedLayerNum = onShowing;

View file

@ -25,6 +25,8 @@ import android.content.Context;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.AnimatedVectorDrawable;
@ -32,6 +34,7 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.text.TextUtils;
import android.util.Log;
import android.util.Size;
import android.util.TypedValue;
import android.view.Gravity;
@ -49,23 +52,30 @@ import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.Transformation;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.Space;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BotWebViewVibrationEffect;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
@ -90,6 +100,11 @@ public final class FloatingToolbar {
public static final int STYLE_THEME = 1;
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 Rect mNewRect = new Rect();
private final Rect mOldRect = new Rect();
@ -220,7 +235,7 @@ public final class FloatingToolbar {
Menu subMenu = menuItem.getSubMenu();
if (subMenu != null) {
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);
}
}
@ -237,6 +252,16 @@ public final class FloatingToolbar {
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 static final int MIN_OVERFLOW_SIZE = 2;
@ -251,7 +276,10 @@ public final class FloatingToolbar {
private final ViewGroup mContentContainer;
private final ViewGroup mMainPanel;
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 mOverflow;
@ -338,8 +366,52 @@ public final class FloatingToolbar {
mToOverflow = (AnimatedVectorDrawable) mContext.getDrawable(R.drawable.ft_avd_tooverflow_animation).mutate();
mToOverflow.setAutoMirrored(true);
mOverflowButton = createOverflowButton();
mOverflowButtonSize = measure(mOverflowButton);
mOverflowButton = new FrameLayout(mContext);
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();
mOverflowPanelViewHelper = new OverflowPanelViewHelper(mContext, mIconTextSpacing);
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) {
boolean ret = false;
if (mPopupWindow.isOutsideTouchable() ^ outsideTouchable) {
@ -562,7 +654,7 @@ public final class FloatingToolbar {
}
};
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() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
@ -570,6 +662,8 @@ public final class FloatingToolbar {
float deltaContainerWidth = isInRTLMode() ? 0 : mContentContainer.getWidth() - startWidth;
float actualOverflowButtonX = overflowButtonX + deltaContainerWidth;
mOverflowButton.setX(actualOverflowButtonX);
mOverflowButtonText.setAlpha(interpolatedTime);
mOverflowButtonShadow.setAlpha(interpolatedTime);
}
};
widthAnimation.setInterpolator(mLogAccelerateInterpolator);
@ -585,6 +679,9 @@ public final class FloatingToolbar {
mContentContainer.startAnimation(mOpenOverflowAnimation);
mIsOverflowOpen = true;
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);
}
@ -624,7 +721,7 @@ public final class FloatingToolbar {
}
};
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() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
@ -632,6 +729,8 @@ public final class FloatingToolbar {
float deltaContainerWidth = isInRTLMode() ? 0 : mContentContainer.getWidth() - startWidth;
float actualOverflowButtonX = overflowButtonX + deltaContainerWidth;
mOverflowButton.setX(actualOverflowButtonX);
mOverflowButtonText.setAlpha(1f - interpolatedTime);
mOverflowButtonShadow.setAlpha(1f - interpolatedTime);
}
};
widthAnimation.setInterpolator(mFastOutSlowInInterpolator);
@ -668,7 +767,7 @@ public final class FloatingToolbar {
mMainPanel.setVisibility(View.INVISIBLE);
mOverflowPanel.setAlpha(1);
mOverflowPanel.setVisibility(View.VISIBLE);
mOverflowButton.setImageDrawable(mArrow);
mOverflowButtonIcon.setImageDrawable(mArrow);
mOverflowButton.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions));
if (isInRTLMode()) {
@ -700,7 +799,7 @@ public final class FloatingToolbar {
mMainPanel.setVisibility(View.VISIBLE);
mOverflowPanel.setAlpha(0);
mOverflowPanel.setVisibility(View.INVISIBLE);
mOverflowButton.setImageDrawable(mOverflow);
mOverflowButtonIcon.setImageDrawable(mOverflow);
mOverflowButton.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions));
if (hasOverflow()) {
if (isInRTLMode()) {
@ -832,9 +931,15 @@ public final class FloatingToolbar {
mMainPanel.removeAllViews();
mMainPanel.setPaddingRelative(0, 0, 0, 0);
boolean isFirstItem = true;
while (!remainingMenuItems.isEmpty()) {
final MenuItem menuItem = remainingMenuItems.peek();
boolean isLastItem = remainingMenuItems.size() == 1;
Iterator<MenuItem> it = remainingMenuItems.iterator();
while (it.hasNext()) {
final MenuItem menuItem = it.next();
boolean isLastItem = !it.hasNext();
if (menuItem != null && premiumLockClickListener != null) {
if (premiumOptions.contains(menuItem.getItemId())) {
continue;
}
}
/*if (!isFirstItem && menuItem.requiresOverflow()) {
break;
}*/
@ -855,7 +960,7 @@ public final class FloatingToolbar {
params.width = menuItemButtonWidth;
menuItemButton.setLayoutParams(params);
availableWidth -= menuItemButtonWidth;
remainingMenuItems.pop();
it.remove();
} else {
break;
}
@ -876,6 +981,13 @@ public final class FloatingToolbar {
private void layoutOverflowPanelItems(List<MenuItem> menuItems) {
ArrayAdapter<MenuItem> overflowPanelAdapter = (ArrayAdapter<MenuItem>) mOverflowPanel.getAdapter();
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();
for (int i = 0; i < size; i++) {
overflowPanelAdapter.add(menuItems.get(i));
@ -987,40 +1099,7 @@ public final class FloatingToolbar {
};
}
private ImageButton createOverflowButton() {
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 int shiftDp = -4;
private OverflowPanel createOverflowPanel() {
final OverflowPanel overflowPanel = new OverflowPanel(this);
@ -1036,7 +1115,11 @@ public final class FloatingToolbar {
overflowPanel.setAdapter(adapter);
overflowPanel.setOnItemClickListener((parent, view, position, id) -> {
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);
}
});
@ -1167,7 +1250,7 @@ public final class FloatingToolbar {
public View getView(MenuItem menuItem, int minimumWidth, View convertView) {
if (convertView != null) {
updateMenuItemButton(convertView, menuItem, mIconTextSpacing);
updateMenuItemButton(convertView, menuItem, mIconTextSpacing, premiumLockClickListener != null);
} else {
convertView = createMenuButton(menuItem);
}
@ -1176,7 +1259,7 @@ public final class FloatingToolbar {
}
public int calculateWidth(MenuItem menuItem) {
updateMenuItemButton(mCalculator, menuItem, mIconTextSpacing);
updateMenuItemButton(mCalculator, menuItem, mIconTextSpacing, premiumLockClickListener != null);
mCalculator.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
return mCalculator.getMeasuredWidth();
}
@ -1206,30 +1289,43 @@ public final class FloatingToolbar {
textView.setFocusable(false);
textView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
textView.setFocusableInTouchMode(false);
int color;
int selectorColor = getThemedColor(Theme.key_listSelector);
if (currentStyle == STYLE_DIALOG) {
textView.setTextColor(getThemedColor(Theme.key_dialogTextBlack));
textView.setTextColor(color = getThemedColor(Theme.key_dialogTextBlack));
} else if (currentStyle == STYLE_BLACK) {
textView.setTextColor(0xfffafafa);
selectorColor = 0x40ffffff;
textView.setTextColor(color = 0xfffafafa);
selectorColor = 0x20ffffff;
} 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) {
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 {
menuItemButton.setBackgroundDrawable(Theme.getSelectorDrawable(selectorColor, false));
menuItemButton.setBackground(Theme.getSelectorDrawable(selectorColor, false));
}
textView.setPaddingRelative(AndroidUtilities.dp(11), 0, 0, 0);
menuItemButton.addView(textView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, AndroidUtilities.dp(48)));
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) {
updateMenuItemButton(menuItemButton, menuItem, iconTextSpacing);
updateMenuItemButton(menuItemButton, menuItem, iconTextSpacing, premiumLockClickListener != null);
}
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;
final TextView buttonText = (TextView) viewGroup.getChildAt(0);
buttonText.setEllipsize(null);
@ -1240,6 +1336,9 @@ public final class FloatingToolbar {
buttonText.setText(menuItem.getTitle());
}
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
if (TextUtils.isEmpty(contentDescription)) {
menuItemButton.setContentDescription(menuItem.getTitle());

View file

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

View file

@ -4015,6 +4015,13 @@ public class Theme {
public static final int key_topics_unreadCounter = 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_botLink = "drawableBotLink";
public static final String key_drawable_botWebView = "drawableBotWebView";
@ -4357,6 +4364,13 @@ public class Theme {
themeAccentExclusionKeys.add(key_premiumStartSmallStarsColor);
themeAccentExclusionKeys.add(key_premiumStartGradient1);
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<>();
otherThemes = new ArrayList<>();

View file

@ -760,6 +760,13 @@ public class ThemeColors {
defaultColors[key_topics_unreadCounter] = 0xff4ecc5e;
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;
}
@ -1481,6 +1488,12 @@ public class ThemeColors {
colorKeysMap.put(key_premiumGradientBottomSheet3, "premiumGradientBottomSheet3");
colorKeysMap.put(key_topics_unreadCounter, "topics_unreadCounter");
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;
}

View file

@ -775,7 +775,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
}
@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) {
return;
}

View file

@ -8,13 +8,20 @@
package org.telegram.ui.Adapters;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Build;
import android.text.TextUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.LocationController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ConnectionsManager;
@ -23,17 +30,27 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdapter {
public final boolean stories;
public BaseLocationAdapter(boolean stories) {
this.stories = stories;
}
public interface BaseLocationAdapterDelegate {
void didLoadSearchResult(ArrayList<TLRPC.TL_messageMediaVenue> places);
}
protected boolean searched = false;
protected boolean searching;
protected boolean searchingLocations;
protected ArrayList<TLRPC.TL_messageMediaVenue> locations = new ArrayList<>();
protected ArrayList<TLRPC.TL_messageMediaVenue> places = new ArrayList<>();
protected ArrayList<String> iconUrls = new ArrayList<>();
private Location lastSearchLocation;
private String lastSearchQuery;
private String lastFoundQuery;
@ -43,7 +60,7 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
private int currentAccount = UserConfig.selectedAccount;
private long dialogId;
private boolean searchingUser;
private boolean searchInProgress;
protected boolean searchInProgress;
public void destroy() {
if (currentRequestNum != 0) {
@ -60,6 +77,7 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
public void searchDelayed(final String query, final Location coordinate) {
if (query == null || query.length() == 0) {
places.clear();
locations.clear();
searchInProgress = false;
notifyDataSetChanged();
} else {
@ -82,7 +100,9 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
}
searchingUser = true;
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) -> {
if (response != null) {
AndroidUtilities.runOnUIThread(() -> {
@ -118,7 +138,7 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
notifyItemRangeRemoved(fromIndex, getItemCount() - fromIndex);
}
} else {
int placesCount = places.size() + 3;
int placesCount = 3 + places.size() + locations.size();
int offset = oldItemCount - placesCount;
notifyItemInserted(offset);
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) {
if (coordinate == null || lastSearchLocation != null && coordinate.distanceTo(lastSearchLocation) < 200) {
if (coordinate == null && !stories || lastSearchLocation != null && coordinate != null && coordinate.distanceTo(lastSearchLocation) < 200) {
return;
}
lastSearchLocation = new Location(coordinate);
lastSearchLocation = coordinate == null ? null : new Location(coordinate);
lastSearchQuery = query;
if (searching) {
searching = false;
@ -147,7 +167,11 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
boolean wasSearched = searched;
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 (searchUser) {
searchBotUser();
@ -161,10 +185,12 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
req.bot = MessagesController.getInstance(currentAccount).getInputUser(user);
req.offset = "";
req.geo_point = new TLRPC.TL_inputGeoPoint();
req.geo_point.lat = AndroidUtilities.fixLocationCoord(coordinate.getLatitude());
req.geo_point._long = AndroidUtilities.fixLocationCoord(coordinate.getLongitude());
req.flags |= 1;
if (coordinate != null) {
req.geo_point = new TLRPC.TL_inputGeoPoint();
req.geo_point.lat = AndroidUtilities.fixLocationCoord(coordinate.getLatitude());
req.geo_point._long = AndroidUtilities.fixLocationCoord(coordinate.getLongitude());
req.flags |= 1;
}
if (DialogObject.isEncryptedDialog(dialogId)) {
req.peer = new TLRPC.TL_inputPeerEmpty();
@ -172,12 +198,174 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
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(() -> {
if (error == null) {
currentRequestNum = 0;
searching = false;
places.clear();
iconUrls.clear();
searchInProgress = false;
lastFoundQuery = query;
@ -188,14 +376,16 @@ public abstract class BaseLocationAdapter extends RecyclerListView.SelectionAdap
continue;
}
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();
venue.geo = mediaVenue.geo;
venue.address = mediaVenue.address;
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_id = mediaVenue.venue_id;
venue.provider = mediaVenue.provider;
venue.query_id = res.query_id;
venue.result_id = result.id;
places.add(venue);
}
}

View file

@ -94,7 +94,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
VIEW_TYPE_HEADER = 7,
VIEW_TYPE_SHADOW = 8,
// VIEW_TYPE_ARCHIVE = 9,
VIEW_TYPE_LAST_EMPTY = 10,
VIEW_TYPE_LAST_EMPTY = 10,
VIEW_TYPE_NEW_CHAT_HINT = 11,
VIEW_TYPE_TEXT = 12,
VIEW_TYPE_CONTACTS_FLICKER = 13,
@ -312,7 +312,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
public ItemInternal(int viewTypeEmpty) {
super(viewTypeEmpty, true);
this.emptyType = emptyType;
this.emptyType = viewTypeEmpty;
if (viewTypeEmpty == VIEW_TYPE_LAST_EMPTY) {
stableId = 1;
} else {
@ -728,14 +728,6 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
case VIEW_TYPE_FOLDER_UPDATE_HINT:
view = new DialogsHintCell(mContext);
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: {
view = new View(mContext) {
@Override
@ -745,6 +737,14 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
};
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));
return new RecyclerListView.Holder(view);
@ -955,6 +955,9 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
break;
}
case VIEW_TYPE_TEXT: {
if (!(holder.itemView instanceof TextCell)) {
return;
}
TextCell cell = (TextCell) holder.itemView;
cell.setColors(Theme.key_windowBackgroundWhiteBlueText4, Theme.key_windowBackgroundWhiteBlueText4);
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() {
@ -1307,6 +1310,8 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
} else {
dialogsHeight += cellHeight;
}
} else if (itemInternals.get(i).viewType == VIEW_TYPE_FLICKER) {
dialogsHeight += cellHeight;
}
}
dialogsHeight += size - 1;
@ -1480,6 +1485,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
if (dialogsCount != 0) {
itemInternals.add(new ItemInternal(VIEW_TYPE_FLICKER));
}
itemInternals.add(new ItemInternal(VIEW_TYPE_LAST_EMPTY));
} else if (dialogsCount == 0) {
isEmpty = true;
if (requestPeerType != null) {

View file

@ -17,6 +17,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.LocationController;
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.ShadowSectionCell;
import org.telegram.ui.Cells.SharingLiveLocationCell;
import org.telegram.ui.Components.ChatAttachAlertLocationLayout;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.RecyclerListView;
@ -64,25 +66,30 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
private Runnable updateRunnable;
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;
locationType = type;
dialogId = did;
needEmptyView = emptyView;
this.resourcesProvider = resourcesProvider;
globalGradientView = new FlickerLoadingView(context);
globalGradientView.setIsSingleCell(true);
}
private boolean myLocationDenied = false;
public void setMyLocationDenied(boolean myLocationDenied) {
if (this.myLocationDenied == myLocationDenied)
private boolean askingForMyLocation = false;
public void setMyLocationDenied(boolean myLocationDenied, boolean askingForLocation) {
if (this.myLocationDenied == myLocationDenied && this.askingForMyLocation == askingForLocation)
return;
this.myLocationDenied = myLocationDenied;
this.askingForMyLocation = askingForLocation;
if (askingForMyLocation) {
city = null;
street = null;
}
notifyDataSetChanged();
}
@ -200,11 +207,33 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
}
@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;
previousFetchedLocation = location;
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() {
@ -257,9 +286,21 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
return 2 + currentLiveLocations.size();
} else {
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) {
View view;
switch (viewType) {
case 0:
case VIEW_TYPE_PADDING:
// view = emptyCell = new EmptyCell(mContext) {
// @Override
// public ViewPropertyAnimator animate() {
@ -287,38 +328,38 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
view = emptyCell = new FrameLayout(mContext);
emptyCell.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, overScrollHeight));
break;
case 1:
case VIEW_TYPE_SEND_LOCATION:
view = new SendLocationCell(mContext, false, resourcesProvider);
break;
case 2:
case VIEW_TYPE_HEADER:
view = new HeaderCell(mContext, resourcesProvider);
break;
case 3:
case VIEW_TYPE_LOCATION:
LocationCell locationCell = new LocationCell(mContext, false, resourcesProvider);
view = locationCell;
break;
case 4:
case VIEW_TYPE_LOADING:
view = new LocationLoadingCell(mContext, resourcesProvider);
break;
case 5:
case VIEW_TYPE_FOOTER:
view = new LocationPoweredCell(mContext, resourcesProvider);
break;
case 6: {
case VIEW_TYPE_LIVE_LOCATION: {
SendLocationCell cell = new SendLocationCell(mContext, true, resourcesProvider);
cell.setDialogId(dialogId);
view = cell;
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);
break;
case 8: {
case VIEW_TYPE_DIRECTION: {
LocationDirectionCell cell = new LocationDirectionCell(mContext, resourcesProvider);
cell.setOnButtonClick(v -> onDirectionClick());
view = cell;
break;
}
case 9: {
case VIEW_TYPE_SHADOW: {
view = new ShadowSectionCell(mContext);
Drawable drawable = Theme.getThemedDrawableByKey(mContext, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow);
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);
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: {
view = new View(mContext);
break;
@ -335,10 +382,23 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
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
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
case VIEW_TYPE_PADDING:
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
if (lp == null) {
lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, overScrollHeight);
@ -347,11 +407,11 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
}
holder.itemView.setLayoutParams(lp);
break;
case 1:
case VIEW_TYPE_SEND_LOCATION:
sendLocationCell = (SendLocationCell) holder.itemView;
updateCell();
break;
case 2: {
case VIEW_TYPE_HEADER: {
HeaderCell cell = (HeaderCell) holder.itemView;
if (currentMessageObject != null) {
cell.setText(LocaleController.getString("LiveLocations", R.string.LiveLocations));
@ -360,25 +420,43 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
}
break;
}
case 3: {
case VIEW_TYPE_LOCATION: {
LocationCell cell = (LocationCell) holder.itemView;
if (locationType == 0) {
position -= 4;
} else if (locationType == ChatAttachAlertLocationLayout.LOCATION_TYPE_STORY) {
position -= 4;
if (this.street != null) {
position--;
}
} else {
position -= 5;
}
TLRPC.TL_messageMediaVenue place = position < 0 || position >= places.size() || !searched ? null : places.get(position);
String iconUrl = position < 0 || position >= iconUrls.size() || !searched ? null : iconUrls.get(position);
cell.setLocation(place, iconUrl, position, true);
boolean shouldHave = searched && (locationType != ChatAttachAlertLocationLayout.LOCATION_TYPE_STORY || !searching);
TLRPC.TL_messageMediaVenue place = null;
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;
}
case 4:
case VIEW_TYPE_LOADING:
((LocationLoadingCell) holder.itemView).setLoading(searching);
break;
case 6:
case VIEW_TYPE_LIVE_LOCATION:
((SendLocationCell) holder.itemView).setHasLocation(gpsLocation != null);
break;
case 7:
case VIEW_TYPE_SHARING:
SharingLiveLocationCell locationCell = (SharingLiveLocationCell) holder.itemView;
if (locationType == LocationActivity.LOCATION_TYPE_LIVE_VIEW) {
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);
}
break;
case 10:
case VIEW_TYPE_EMPTY:
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;
}
}
@ -425,10 +515,19 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
return currentLiveLocations.get(i - 2);
}
return null;
} else if (locationType == 1) {
} else if (locationType == LocationActivity.LOCATION_TYPE_SEND_WITH_LIVE) {
if (i > 4 && i < places.size() + 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 {
if (i > 3 && i < places.size() + 4) {
return places.get(i - 4);
@ -440,87 +539,101 @@ public class LocationActivityAdapter extends BaseLocationAdapter implements Loca
@Override
public int getItemViewType(int position) {
if (position == 0) {
return 0;
return VIEW_TYPE_PADDING;
}
if (locationType == LocationActivity.LOCATION_TYPE_LIVE_VIEW) {
return 7;
return VIEW_TYPE_SHARING;
}
if (needEmptyView && position == getItemCount() - 1) {
return 10;
return VIEW_TYPE_EMPTY;
}
if (locationType == LocationActivity.LOCATION_TYPE_GROUP_VIEW) {
return 7;
return VIEW_TYPE_SHARING;
}
if (locationType == LocationActivity.LOCATION_TYPE_GROUP) {
return 1;
return VIEW_TYPE_SEND_LOCATION;
}
if (currentMessageObject != null) {
if (currentLiveLocations.isEmpty()) {
if (position == 2) {
return 8;
return VIEW_TYPE_DIRECTION;
}
} else {
if (position == 2) {
return 9;
return VIEW_TYPE_SHADOW;
} else if (position == 3) {
return 2;
return VIEW_TYPE_HEADER;
} else if (position == 4) {
shareLiveLocationPotistion = position;
return 6;
return VIEW_TYPE_LIVE_LOCATION;
}
}
return 7;
return VIEW_TYPE_SHARING;
}
if (locationType == 2) {
if (position == 1) {
shareLiveLocationPotistion = position;
return 6;
return VIEW_TYPE_LIVE_LOCATION;
} else {
return 7;
return VIEW_TYPE_SHARING;
}
}
if (locationType == LocationActivity.LOCATION_TYPE_SEND_WITH_LIVE) {
if (position == 1) {
return 1;
return VIEW_TYPE_SEND_LOCATION;
} else if (position == 2) {
shareLiveLocationPotistion = position;
return 6;
return VIEW_TYPE_LIVE_LOCATION;
} else if (position == 3) {
return 9;
return VIEW_TYPE_SHADOW;
} else if (position == 4) {
return 2;
return VIEW_TYPE_HEADER;
} else if (searching || places.isEmpty() || !searched) {
if (position <= 4 + 3 && (searching || !searched) && !myLocationDenied)
return 3;
return 4;
return VIEW_TYPE_LOCATION;
return VIEW_TYPE_LOADING;
} else if (position == places.size() + 5) {
return 5;
return VIEW_TYPE_FOOTER;
}
} 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) {
return 1;
return VIEW_TYPE_SEND_LOCATION;
} else if (position == 2) {
return 9;
return VIEW_TYPE_SHADOW;
} else if (position == 3) {
return 2;
} else if (searching || places.isEmpty()) {
return VIEW_TYPE_HEADER;
} else if (searching || places.isEmpty() && locations.isEmpty()) {
if (position <= 3 + 3 && (searching || !searched) && !myLocationDenied)
return 3;
return 4;
} else if (position == places.size() + 4) {
return 5;
return VIEW_TYPE_LOCATION;
return VIEW_TYPE_LOADING;
} else if (position == placesCount + i) {
return VIEW_TYPE_FOOTER;
}
}
return 3;
return VIEW_TYPE_LOCATION;
}
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
int viewType = holder.getItemViewType();
if (viewType == 6) {
if (viewType == VIEW_TYPE_LIVE_LOCATION) {
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) {

View file

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

View file

@ -4680,6 +4680,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
FileLog.e(e);
}
});
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.articleClosed);
}
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_EXTERNAL_STORAGE_FOR_AVATAR = 151,
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;
@ -95,6 +96,8 @@ public class BasePermissionsActivity extends Activity {
}
} else if (requestCode == REQUEST_CODE_GEOLOCATION) {
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;
}

View file

@ -2595,7 +2595,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
} else {
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.setCollapsed(item.index < 0 ? collapsed : null);
if (item.index == -1) {

View file

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

View file

@ -1119,13 +1119,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private boolean drawName;
private boolean drawNameLayout;
private StaticLayout[] forwardedNameLayout = new StaticLayout[2];
private final StaticLayout[] forwardedNameLayout = new StaticLayout[2];
private int forwardedNameWidth;
private boolean drawForwardedName;
private float forwardNameX;
private int forwardNameY;
private int forwardHeight;
private float[] forwardNameOffsetX = new float[2];
private final float[] forwardNameOffsetX = new float[2];
private float drawTimeX;
private float drawTimeY;
@ -1292,11 +1292,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
// Public for enter transition
public List<SpoilerEffect> replySpoilers = new ArrayList<>();
private Stack<SpoilerEffect> replySpoilersPool = new Stack<>();
private List<SpoilerEffect> captionSpoilers = new ArrayList<>();
private Stack<SpoilerEffect> captionSpoilersPool = new Stack<>();
private AtomicReference<Layout> captionPatchedSpoilersLayout = new AtomicReference<>();
private Path sPath = new Path();
private final Stack<SpoilerEffect> replySpoilersPool = new Stack<>();
private final List<SpoilerEffect> captionSpoilers = new ArrayList<>();
private final Stack<SpoilerEffect> captionSpoilersPool = new Stack<>();
private final AtomicReference<Layout> captionPatchedSpoilersLayout = new AtomicReference<>();
private final Path sPath = new Path();
public boolean isBlurred;
public ChatMessageCell(Context context) {
@ -7467,7 +7467,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoHeight += AndroidUtilities.dp(1);
}
} 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);
}
}
@ -12721,7 +12721,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
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) {
viaNameWidth = (int) Math.ceil(Theme.chat_namePaint.measureText(nameStringFinal, 0, nameStringFinal.length()));
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);
}
try {
nameStringFinal = Emoji.replaceEmoji(nameStringFinal, Theme.chat_namePaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
} catch (Exception ignore) {
}
try {
nameLayout = new StaticLayout(nameStringFinal, Theme.chat_namePaint, nameWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
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 (currentPosition != null) {
canvas.save();
// canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
}
currentSelectedBackgroundAlpha = 1f;
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.WebFile;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.ButtonBounce;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LetterDrawable;
import org.telegram.ui.ActionBar.Theme;
@ -119,9 +122,7 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
private int buttonState;
private RadialProgress2 radialProgress;
private long lastUpdateTime;
private boolean scaled;
private float scale;
private static AccelerateInterpolator interpolator = new AccelerateInterpolator(0.5f);
private boolean hideLoadProgress;
@ -130,6 +131,8 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
private ContextLinkCellDelegate delegate;
private ButtonBounce buttonBounce;
public ContextLinkCell(Context context) {
this(context, false, null);
}
@ -165,6 +168,12 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
setWillNotDraw(false);
}
public void allowButtonBounce(boolean allow) {
if (allow != (buttonBounce != null)) {
buttonBounce = allow ? new ButtonBounce(this, 1f, 3f).setReleaseDelay(120L) : null;
}
}
@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
@ -591,8 +600,9 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
public void setScaled(boolean value) {
scaled = value;
lastUpdateTime = System.currentTimeMillis();
invalidate();
if (buttonBounce != null) {
buttonBounce.setPressed(isPressed() || scaled);
}
}
public void setCanPreviewGif(boolean value) {
@ -816,24 +826,11 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
linkImageView.setVisible(!PhotoViewer.isShowingImage(inlineResult), false);
}
canvas.save();
if (scaled && scale != 0.8f || !scaled && scale != 1.0f) {
long newTime = System.currentTimeMillis();
long dt = (newTime - lastUpdateTime);
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();
float s = imageScale;
if (buttonBounce != null) {
s *= buttonBounce.getScale(.1f);
}
canvas.scale(scale * imageScale, scale * imageScale, getMeasuredWidth() / 2, getMeasuredHeight() / 2);
canvas.scale(s, s, getMeasuredWidth() / 2, getMeasuredHeight() / 2);
linkImageView.draw(canvas);
canvas.restore();
}
@ -1148,4 +1145,12 @@ public class ContextLinkCell extends FrameLayout implements DownloadController.F
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 SpoilerEffect thumbSpoiler = new SpoilerEffect();
private boolean drawForwardIcon;
public void setMoving(boolean moving) {
this.moving = moving;
@ -951,6 +952,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
drawNameLock = false;
drawVerified = false;
drawPremium = false;
drawForwardIcon = false;
drawScam = 0;
drawPinBackground = false;
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) {
@ -2355,7 +2366,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
float x1 = layout.getPrimaryHorizontal(spanOffset);
float x2 = layout.getPrimaryHorizontal(spanOffset + 1);
int offset = (int) Math.ceil(Math.min(x1, x2));
if (offset != 0) {
if (offset != 0 && !drawForwardIcon) {
offset += AndroidUtilities.dp(3);
}
for (int i = 0; i < thumbsCount; ++i) {
@ -3829,9 +3840,9 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} else {
drawCounterMuted = chat != null && chat.forum && forumTopic == null ? !hasUnmutedTopics : dialogMuted;
}
int countLeftLocal = (int) (storyParams.originalAvatarRect.left + avatarImage.getImageWidth() - countWidth - AndroidUtilities.dp(5f));
int countLeftOld = (int) (storyParams.originalAvatarRect.left + avatarImage.getImageWidth() - countWidthOld - AndroidUtilities.dp(5f));
int countTop = (int) (avatarImage.getImageY() + avatarImage.getImageHeight() - AndroidUtilities.dp(22));
int countLeftLocal = (int) (storyParams.originalAvatarRect.left + storyParams.originalAvatarRect.width() - countWidth - AndroidUtilities.dp(5f));
int countLeftOld = (int) (storyParams.originalAvatarRect.left + storyParams.originalAvatarRect.width() - countWidthOld - AndroidUtilities.dp(5f));
int countTop = (int) (avatarImage.getImageY() + storyParams.originalAvatarRect.height() - AndroidUtilities.dp(22));
drawCounter(canvas, drawCounterMuted, countTop, countLeftLocal, countLeftOld, rightFragmentOpenedProgress, true);
}
@ -4884,7 +4895,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (rightFragmentOpenedProgress == 0 && storyParams.checkOnTouchEvent(ev, this)) {
if (rightFragmentOpenedProgress == 0 && !isTopic && storyParams.checkOnTouchEvent(ev, this)) {
return true;
}
return super.onInterceptTouchEvent(ev);
@ -4892,7 +4903,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
@Override
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);
}
return super.dispatchTouchEvent(ev);
@ -4900,7 +4911,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
@Override
public boolean onTouchEvent(MotionEvent event) {
if (rightFragmentOpenedProgress == 0 && storyParams.checkOnTouchEvent(event, this)) {
if (rightFragmentOpenedProgress == 0 && !isTopic && storyParams.checkOnTouchEvent(event, this)) {
return true;
}
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.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setGravity(Gravity.CENTER_VERTICAL);
toggleRTL(true);
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
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);
}
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
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
@ -76,7 +66,7 @@ public class DrawerActionCell extends FrameLayout {
if (suggestions.contains("VALIDATE_PHONE_NUMBER") || suggestions.contains("VALIDATE_PASSWORD")) {
int countTop = AndroidUtilities.dp(12.5f);
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);
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) {
toggleRTL(false);
currentId = id;
try {
textView.setText(text);

View file

@ -14,6 +14,10 @@ import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
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.os.SystemClock;
import android.text.TextUtils;
@ -24,18 +28,26 @@ import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedTextView;
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.LayoutHelper;
public class LocationCell extends FrameLayout {
private TextView nameTextView;
private TextView addressTextView;
private AnimatedTextView nameTextView;
private AnimatedTextView addressTextView;
private BackupImageView imageView;
private ShapeDrawable circleDrawable;
private boolean needDivider;
@ -52,24 +64,24 @@ public class LocationCell extends FrameLayout {
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));
nameTextView = new TextView(context);
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
nameTextView.setMaxLines(1);
nameTextView.setEllipsize(TextUtils.TruncateAt.END);
nameTextView.setSingleLine(true);
nameTextView = new AnimatedTextView(context, true, true, true);
nameTextView.setAnimationProperties(0.4f, 0, 240, CubicBezierInterpolator.EASE_OUT_QUINT);
nameTextView.setTextSize(AndroidUtilities.dp(16));
nameTextView.setEllipsizeByGradient(true);
nameTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
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.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
addressTextView.setMaxLines(1);
addressTextView.setEllipsize(TextUtils.TruncateAt.END);
addressTextView.setSingleLine(true);
addressTextView = new AnimatedTextView(context, true, true, true);
addressTextView.setAnimationProperties(0.4f, 0, 240, CubicBezierInterpolator.EASE_OUT_QUINT);
addressTextView.setTextSize(AndroidUtilities.dp(14));
addressTextView.setEllipsizeByGradient(true);
addressTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText3));
addressTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
addView(addressTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), (LocaleController.isRTL ? 16 : 73), 35, (LocaleController.isRTL ? 73 : 16), 0));
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);
nameTextView.setAlpha(enterAlpha);
@ -89,8 +101,13 @@ public class LocationCell extends FrameLayout {
return imageView;
}
public void setLocation(TLRPC.TL_messageMediaVenue location, String icon, int pos, boolean divider) {
setLocation(location, icon, null, pos, divider);
public void setLocation(TLRPC.TL_messageMediaVenue location, int pos, boolean divider) {
setLocation(location, null, pos, divider, false);
}
private boolean allowTextAnimation;
public void setAllowTextAnimation(boolean allow) {
allowTextAnimation = allow;
}
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 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;
circleDrawable.getPaint().setColor(getColorForIndex(pos));
if (location != null)
nameTextView.setText(location.title);
if (label != null) {
addressTextView.setText(label);
} else if (location != null) {
addressTextView.setText(location.address);
if (location != null) {
nameTextView.setText(getTitle(location), allowTextAnimation && !LocaleController.isRTL && animated);
}
if (icon != null)
imageView.setImage(icon, null, null);
if (label != 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);
setClickable(location == null);
@ -163,7 +211,7 @@ public class LocationCell extends FrameLayout {
@Override
protected void onDraw(Canvas canvas) {
if (globalGradientView == null) {
globalGradientView = new FlickerLoadingView(getContext());
globalGradientView = new FlickerLoadingView(getContext(), resourcesProvider);
globalGradientView.setIsSingleCell(true);
}
@ -180,12 +228,16 @@ public class LocationCell extends FrameLayout {
super.onDraw(canvas);
if (needDivider) {
Paint dividerPaint = resourcesProvider == null ? null : resourcesProvider.getPaint(Theme.key_paint_divider);
if (dividerPaint == null) {
dividerPaint = Theme.dividerPaint;
}
canvas.drawLine(
LocaleController.isRTL ? 0 : AndroidUtilities.dp(72),
getHeight() - 1,
LocaleController.isRTL ? getWidth() - AndroidUtilities.dp(72) : getWidth(),
getHeight() - 1,
Theme.dividerPaint
dividerPaint
);
}
}

View file

@ -23,7 +23,7 @@ public class LocationDirectionCell extends FrameLayout {
this.resourcesProvider = resourcesProvider;
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));
buttonTextView = new SimpleTextView(context);

View file

@ -1,7 +1,12 @@
package org.telegram.ui.Cells;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.Gravity;
@ -12,6 +17,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
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.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MessageSeenCheckDrawable;
import org.telegram.ui.Components.Premium.PremiumGradient;
@ -40,6 +47,7 @@ import org.telegram.messenger.LocaleController;
import org.telegram.ui.Stories.StoriesUtilities;
public class ReactedUserHolderView extends FrameLayout {
public boolean drawDivider;
int currentAccount;
public static int STYLE_DEFAULT = 0;
@ -57,12 +65,7 @@ public class ReactedUserHolderView extends FrameLayout {
Theme.ResourcesProvider resourcesProvider;
int style;
public long dialogId;
public StoriesUtilities.AvatarStoryParams params = new StoriesUtilities.AvatarStoryParams(false) {
@Override
public void openStory(long dialogId, Runnable onDone) {
ReactedUserHolderView.this.openStory(dialogId, onDone);
}
};
public StoriesUtilities.AvatarStoryParams params;
public void openStory(long dialogId, Runnable onDone) {
@ -76,6 +79,12 @@ public class ReactedUserHolderView extends FrameLayout {
this.style = style;
this.currentAccount = currentAccount;
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)));
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));
}
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;
if (u == null) {
u = chat;
@ -184,7 +193,13 @@ public class ReactedUserHolderView extends FrameLayout {
String contentDescription;
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);
if (visibleReaction.emojicon != null) {
TLRPC.TL_availableReaction r = MediaDataController.getInstance(currentAccount).getReactionsMap().get(visibleReaction.emojicon);
@ -195,6 +210,7 @@ public class ReactedUserHolderView extends FrameLayout {
} else {
reactView.setImageDrawable(null);
}
reactView.setColorFilter(null);
} else {
AnimatedEmojiDrawable drawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, currentAccount, visibleReaction.documentId);
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);
} else {
reactView.setAnimatedEmojiDrawable(null);
reactView.setImageDrawable(null);
contentDescription = LocaleController.formatString("AccDescrPersonHasSeen", R.string.AccDescrPersonHasSeen, titleView.getText());
}
@ -247,7 +264,7 @@ public class ReactedUserHolderView extends FrameLayout {
} else {
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
@ -282,4 +299,62 @@ public class ReactedUserHolderView extends FrameLayout {
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);
setWillNotDraw(false);
} 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));
CombinedDrawable combinedDrawable = new CombinedDrawable(circle, drawable);
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.RectF;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.Gravity;
import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.IMapsProvider;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.LocationController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
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.CombinedDrawable;
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 java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class SharingLiveLocationCell extends FrameLayout {
private BackupImageView avatarImageView;
@ -74,14 +88,16 @@ public class SharingLiveLocationCell extends FrameLayout {
avatarDrawable = new AvatarDrawable();
nameTextView = new SimpleTextView(context);
NotificationCenter.listenEmojiLoading(nameTextView);
nameTextView.setTextSize(16);
nameTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
nameTextView.setScrollNonFitText(true);
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(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.setTextSize(14);
@ -141,6 +157,66 @@ public class SharingLiveLocationCell extends FrameLayout {
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) {
long fromId = messageObject.getFromChatId();
if (messageObject.isForwarded()) {
@ -148,12 +224,49 @@ public class SharingLiveLocationCell extends FrameLayout {
}
currentAccount = messageObject.currentAccount;
String address = null;
String name;
CharSequence name = "";
if (!TextUtils.isEmpty(messageObject.messageOwner.media.address)) {
address = messageObject.messageOwner.media.address;
}
if (!TextUtils.isEmpty(messageObject.messageOwner.media.title)) {
name = messageObject.messageOwner.media.title;
boolean noTitle = TextUtils.isEmpty(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.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.setIconSize(AndroidUtilities.dp(24), AndroidUtilities.dp(24));
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);

View file

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

View file

@ -2131,7 +2131,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
dialog_id = -chatId;
if (ChatObject.isChannel(currentChat)) {
if (ChatObject.isNotInChat(currentChat)) {
if (ChatObject.isNotInChat(currentChat) && !isThreadChat() && !isInScheduleMode()) {
waitingForGetDifference = true;
getMessagesController().startShortPoll(currentChat, classGuid, false, isGettingDifference -> {
waitingForGetDifference = isGettingDifference;
@ -7212,7 +7212,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
private void createTopPanel() {
if (topChatPanelView != null || getContext() == null) {
if (contentView == null || topChatPanelView != null || getContext() == null) {
return;
}
@ -7395,6 +7395,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
args.putBoolean("addContact", true);
ContactAddActivity activity = new ContactAddActivity(args);
activity.setDelegate(() -> {
if (undoView != null || getContext() == null) {
return;
}
createUndoView();
undoView.showWithAction(dialog_id, UndoView.ACTION_CONTACT_ADDED, currentUser);
});
@ -10452,13 +10455,21 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
FileLog.e(e);
}
} else if (which == attach_gallery) {
if (Build.VERSION.SDK_INT >= 23 && getParentActivity().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) {
final Activity activity = getParentActivity();
if (Build.VERSION.SDK_INT >= 33) {
if (activity.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
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;
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);
}
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;
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<>();
messArr.add(obj);
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) {
chatAdapter.updateRowWithMessageObject(obj, false, false);
@ -17558,7 +17569,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
boolean updated = false;
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++) {
Integer mid = ids.get(a);
@ -17651,7 +17662,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
loadingPinnedMessages.remove(message.getId());
}
getMediaDataController().loadReplyMessagesForMessages(arrayList, dialog_id, false, 0, null);
getMediaDataController().loadReplyMessagesForMessages(arrayList, dialog_id, false, 0, null, classGuid);
updateMessagesVisiblePart(false);
} else {
pinnedMessageIds.clear();
@ -17997,7 +18008,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
totalPinnedMessagesCount = (Integer) args[3];
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) {
getMediaDataController().loadPinnedMessages(dialog_id, 0, fallbackId);
@ -20231,6 +20242,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
flagSecure.detach();
super.onBecomeFullyHidden();
}
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) {
if (messageObject == null) {
return null;
}
String restrictionReason = MessagesController.getRestrictionReason(messageObject.messageOwner.restriction_reason);
if (!TextUtils.isEmpty(restrictionReason)) {
return restrictionReason;
@ -26683,6 +26699,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
private void runCloseInstantCameraAnimation() {
if (instantCameraView == null) {
return;
}
instantCameraView.cancelBlur();
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.showDate(false);
flickerLoadingView.setUseHeaderOffset(true);
flickerLoadingView.setColors(Theme.key_actionBarDefaultSubmenuBackground, Theme.key_listSelector, Theme.key_listSelector);
progressLayout.addView(flickerLoadingView);
progressBar = new RadialProgressView(context);

View file

@ -17,14 +17,17 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -34,6 +37,7 @@ import android.text.Editable;
import android.text.Html;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
@ -55,10 +59,12 @@ import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.RawRes;
import androidx.annotation.RequiresApi;
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.LaunchActivity;
import org.telegram.ui.LoginActivity;
import org.telegram.ui.NotificationPermissionDialog;
import org.telegram.ui.NotificationsCustomSettingsActivity;
import org.telegram.ui.NotificationsSettingsActivity;
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) {
path = file;
PRERENDER_FRAME = SharedConfig.deviceIsAboveAverage() && limitFps;
PRERENDER_FRAME = SharedConfig.deviceIsAboveAverage();
streamFileSize = streamSize;
this.streamLoadingPriority = streamLoadingPriority;
currentAccount = account;
@ -518,8 +518,8 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public void setIsWebmSticker(boolean b) {
isWebmSticker = b;
PRERENDER_FRAME = false;
if (isWebmSticker) {
PRERENDER_FRAME = false;
useSharedQueue = true;
}
}
@ -723,6 +723,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
@Override
protected void finalize() throws Throwable {
try {
secondParentViews.clear();
recycle();
} finally {
super.finalize();

View file

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

View file

@ -39,7 +39,7 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
private float shadowAlpha = 1f;
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) {

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) {
this.duration = duration;
return this;
@ -1745,32 +1751,20 @@ public class Bulletin {
// to make bulletin above everything
// use as BulletinFactory.of(BulletinWindow.make(context), resourcesProvider)...
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;
private BulletinWindow(Context context) {
public static BulletinWindowLayout make(Context context) {
return new BulletinWindow(context, null).container;
}
private final BulletinWindowLayout container;
private BulletinWindow(Context context, Delegate delegate) {
super(context);
setContentView(
container = new FrameLayout(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);
}
},
container = new BulletinWindowLayout(context),
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
);
if (Build.VERSION.SDK_INT >= 21) {
@ -1794,12 +1788,17 @@ public class Bulletin {
addDelegate(container, new Delegate() {
@Override
public int getBottomOffset(int tag) {
return 0;
return delegate == null ? 0 : delegate.getBottomOffset(tag);
}
@Override
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.setWindowAnimations(R.style.DialogNoAnimation);
window.setBackgroundDrawable(null);
WindowManager.LayoutParams params = window.getAttributes();
params = window.getAttributes();
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.TOP | Gravity.LEFT;
params.dimAmount = 0;
params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
@ -1823,7 +1823,6 @@ public class Bulletin {
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
}
params.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
if (Build.VERSION.SDK_INT >= 28) {
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) {

View file

@ -171,6 +171,17 @@ public final class BulletinFactory {
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) {
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider);
layout.setAnimation(iconRawId, 36, 36);
@ -1032,6 +1043,21 @@ public final class BulletinFactory {
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
public static Bulletin createCopyLinkBulletin(BaseFragment fragment) {
return of(fragment).createCopyLinkBulletin();

View file

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

View file

@ -108,7 +108,9 @@ public class CacheChart extends View {
private static long particlesStart = -1;
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;
float angleCenter, angleSize;

View file

@ -180,6 +180,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private Runnable animationEndRunnable;
private float attachLayoutTranslationX;
private float attachLayoutPaddingTranslationX;
private float attachLayoutAlpha = 1f;
private float attachLayoutPaddingAlpha = 1f;
private float messageTextTranslationX;
private float messageTextPaddingTranslationX;
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") {
@Override
public Float get(View object) {
@ -2089,7 +2104,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
attachLayout.addView(attachButton, LayoutHelper.createLinear(48, 48));
attachButton.setOnClickListener(v -> {
if (adjustPanLayoutHelper != null && adjustPanLayoutHelper.animationInProgress()) {
if (adjustPanLayoutHelper != null && adjustPanLayoutHelper.animationInProgress() || attachLayoutPaddingAlpha == 0f) {
return;
}
delegate.didPressAttachButton();
@ -3624,7 +3639,12 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
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));
if (!self && dialog_id > 0) {
@ -3635,7 +3655,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (sendPopupWindow != null && sendPopupWindow.isShowing()) {
sendPopupWindow.dismiss();
}
sendMessageInternal(true, 0x7FFFFFFE);
sendMessageInternal(true, 0x7FFFFFFE, true);
});
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()) {
sendPopupWindow.dismiss();
}
sendMessageInternal(false, 0);
sendMessageInternal(false, 0, true);
});
sendPopupLayout.addView(sendWithoutSoundButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
}
@ -5486,14 +5506,19 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private void sendMessage() {
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 {
sendMessageInternal(true, 0);
sendMessageInternal(true, 0, 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 (delegate != null) {
delegate.scrollToSendingMessage();
@ -5514,6 +5539,11 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
emojiView.hideSearchKeyboard();
}
}
if (allowConfirm && showConfirmAlert(() -> {
sendMessageInternal(notify, scheduleDate, false);
})) {
return;
}
if (videoToSendMessageObject != null) {
delegate.needStartRecordVideo(4, notify, scheduleDate);
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) {
if (message == null || parentFragment == null) {
return false;
@ -5850,7 +5884,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) {
runningAnimation2 = new AnimatorSet();
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));
scheduleButtonHidden = false;
boolean hasScheduled = delegate != null && delegate.hasScheduledMessages();
@ -6034,7 +6068,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) {
runningAnimation2 = new AnimatorSet();
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));
boolean hasScheduled = delegate != null && delegate.hasScheduledMessages();
scheduleButtonHidden = true;
@ -6226,7 +6260,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
attachLayout.setVisibility(VISIBLE);
runningAnimation2 = new AnimatorSet();
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));
boolean hasScheduled = delegate != null && delegate.hasScheduledMessages();
scheduleButtonHidden = false;
@ -6386,12 +6420,13 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) {
if (attachLayout.getVisibility() != View.VISIBLE) {
attachLayout.setVisibility(VISIBLE);
attachLayout.setAlpha(0f);
attachLayoutAlpha = 0f;
updateAttachLayoutParams();
attachLayout.setScaleX(0f);
}
runningAnimation2 = new AnimatorSet();
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));
boolean hasScheduled = delegate != null && delegate.hasScheduledMessages();
scheduleButtonHidden = false;
@ -6524,7 +6559,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (getVisibility() == VISIBLE) {
delegate.onAttachButtonShow();
}
attachLayout.setAlpha(1.0f);
attachLayoutAlpha = 1.0f;
updateAttachLayoutParams();
attachLayout.setScaleX(1.0f);
attachLayout.setVisibility(VISIBLE);
updateFieldRight(1);
@ -6715,7 +6751,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) {
viewTransition.playTogether(
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) {
runningAnimationAudio.playTogether(
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) {
iconsAnimator.playTogether(
ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 1f),
ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 1f),
ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_TRANSLATION_X, 0)
);
}
@ -7108,7 +7144,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (attachLayout != null) {
icons2.playTogether(
ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_TRANSLATION_X, 0),
ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 1f)
ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 1f)
);
}
if (scheduledButton != null) {
@ -7198,7 +7234,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
attachLayoutTranslationX = 0;
updateAttachLayoutParams();
iconsAnimator.playTogether(
ObjectAnimator.ofFloat(attachLayout, View.ALPHA, 1f)
ObjectAnimator.ofFloat(attachLayout, ATTACH_LAYOUT_ALPHA, 1f)
);
}
if (scheduledButton != null) {
@ -7546,7 +7582,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
setSlowModeButtonVisible(true);
}
attachLayout.setScaleX(0.01f);
attachLayout.setAlpha(0.0f);
attachLayoutAlpha = 0f;
updateAttachLayoutParams();
attachLayout.setVisibility(GONE);
audioVideoButtonContainer.setScaleX(0.1f);
audioVideoButtonContainer.setScaleY(0.1f);
@ -7562,7 +7599,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
slowModeButton.setAlpha(0.0f);
setSlowModeButtonVisible(false);
attachLayout.setScaleX(1.0f);
attachLayout.setAlpha(1.0f);
attachLayoutAlpha = 1.0f;
updateAttachLayoutParams();
attachLayout.setVisibility(VISIBLE);
audioVideoButtonContainer.setScaleX(1.0f);
audioVideoButtonContainer.setScaleY(1.0f);
@ -8642,50 +8680,56 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
return;
}
if (stickersExpanded) {
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;
Runnable runnable = () -> {
if (result.document != null) {
MediaDataController.getInstance(currentAccount).addRecentGif(result.document, (int) (System.currentTimeMillis() / 1000), false);
if (stickersExpanded) {
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, 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();
}
}
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 (delegate != null) {
delegate.onMessageSend(null, notify, scheduleDate);
}
if (searchingType != 0) {
setSearchingTypeInternal(0, true);
emojiView.closeSearch(true);
emojiView.hideSearchKeyboard();
}
}
if (delegate != null) {
delegate.onMessageSend(null, notify, scheduleDate);
};
if (!showConfirmAlert(runnable)) {
runnable.run();
}
}
}
@ -8911,27 +8955,32 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (isInScheduleMode() && scheduleDate == 0) {
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (n, s) -> onStickerSelected(sticker, query, parent, sendAnimationData, clearsInputField, n, s), resourcesProvider);
} else {
if (slowModeTimer > 0 && !isInScheduleMode()) {
if (delegate != null) {
delegate.onUpdateSlowModeButton(slowModeButton, true, slowModeButton.getText());
Runnable runnable = () -> {
if (slowModeTimer > 0 && !isInScheduleMode()) {
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);
if (cancelToProgress != 1) {
int slideDelta = (int) (-getMeasuredWidth() / 4 * (1f - slideProgress));
int slideDelta = (int) (-getMeasuredWidth() / 4 * (1f - slideProgress) + recordCircle.getTranslationX() * 0.3f);
canvas.save();
canvas.clipRect((recordTimerView == null ? 0 : recordTimerView.getLeftProperty()) + AndroidUtilities.dp(4), 0, getMeasuredWidth(), getMeasuredHeight());
canvas.save();
@ -10774,29 +10823,34 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
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;
emojiButtonPaddingScale = s;
emojiButtonPaddingAlpha = progress;
updateEmojiButtonParams();
emojiButton.setTranslationX(-v);
messageTextPaddingTranslationX = -v - AndroidUtilities.dp(31) * (1f - progress);
emojiButton.setTranslationX(-leftPadding);
messageTextPaddingTranslationX = -leftPadding - AndroidUtilities.dp(31) * (1f - progress);
if (recordDeleteImageView != null) {
recordDeleteImageView.setTranslationX(-v);
recordDeleteImageView.setTranslationX(-leftPadding);
}
if (recordCircle != null) {
recordCircle.setTranslationX(rightPadding);
}
if (recordTimeContainer != null) {
recordTimeContainer.setTranslationX(-v);
recordTimeContainer.setTranslationX(-leftPadding);
}
if (recordedAudioPlayButton != null) {
recordedAudioPlayButton.setTranslationX(-v);
recordedAudioPlayButton.setTranslationX(-leftPadding);
}
if (recordedAudioTimeTextView != null) {
recordedAudioTimeTextView.setTranslationX(v);
recordedAudioTimeTextView.setTranslationX(leftPadding);
}
sendButtonContainer.setTranslationX(v);
sendButtonContainer.setTranslationX(rightPadding);
sendButtonContainer.setAlpha(allowShare ? progress : 1f);
sendButtonEnabled = allowShare ? progress == 1f : true;
attachLayoutPaddingTranslationX = v;
attachLayoutPaddingTranslationX = rightPadding;
attachLayoutPaddingAlpha = progress;
updateAttachLayoutParams();
updateMessageTextParams();
float newPadding = padding * (1f - progress);
@ -10823,6 +10877,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private void updateAttachLayoutParams() {
if (attachLayout != null) {
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) {
setOverrideHint(overrideHint, false);
}
public void setOverrideHint(CharSequence overrideHint, boolean animated) {
this.overrideHint = overrideHint;
updateFieldHint(false);
updateFieldHint(animated);
}
public void setOverrideKeyboardAnimation(boolean overrideKeyboardAnimation) {

View file

@ -15,6 +15,7 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
@ -109,6 +110,7 @@ import org.telegram.ui.PhotoPickerActivity;
import org.telegram.ui.PhotoPickerSearchActivity;
import org.telegram.ui.PremiumPreviewFragment;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -127,6 +129,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
public boolean canOpenPreview = false;
private boolean isSoundPicker = false;
public boolean isStoryLocationPicker = false;
private ImageUpdater.AvatarFor setAvatarFor;
public boolean pinnedToTop;
@ -1514,6 +1517,38 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
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) {
if (child instanceof AttachAlertLayout) {
canvas.save();
@ -1522,7 +1557,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
AttachAlertLayout layout = (AttachAlertLayout) child;
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;
if (currentSheetAnimationType == 1 || viewChangeAnimator != null) {
top += child.getTranslationY();
@ -1537,7 +1572,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (top < h) {
rad = Math.max(0, 1.0f - (h - top) / (float) backgroundPaddingTop);
}
} else if (top + backgroundPaddingTop < h) {
} else {
float toMove = offset;
if (layout == locationLayout) {
toMove += AndroidUtilities.dp(11);
@ -1546,8 +1581,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
} else {
toMove += AndroidUtilities.dp(4);
}
float moveProgress = Math.min(1.0f, (h - top - backgroundPaddingTop) / toMove);
float availableToMove = h - toMove;
float moveProgress = actionBar.getAlpha();
float availableToMove = h - toMove + AndroidUtilities.statusBarHeight;
int diff = (int) (availableToMove * moveProgress);
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());
if (clip) {
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());
}
canvas.save();
canvas.clipRect(backgroundPaddingLeft, actionBar.getY() + actionBar.getMeasuredHeight() - currentPanTranslationY, getMeasuredWidth() - backgroundPaddingLeft, getMeasuredHeight());
boolean result = super.drawChild(canvas, child, drawingTime);
if (clip) {
canvas.restore();
}
canvas.restore();
if (drawBackground) {
if (rad != 1.0f && actionBarType != 2) {
@ -1723,6 +1744,19 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
}
canvas.restore();
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);
}
@ -1732,10 +1766,10 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (inBubbleMode) {
return;
}
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));
Theme.dialogs_onlineCirclePaint.setColor(finalColor);
canvas.drawRect(backgroundPaddingLeft, currentPanTranslationY, getMeasuredWidth() - backgroundPaddingLeft, AndroidUtilities.statusBarHeight + currentPanTranslationY, Theme.dialogs_onlineCirclePaint);
// 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));
// Theme.dialogs_onlineCirclePaint.setColor(finalColor);
// canvas.drawRect(backgroundPaddingLeft, currentPanTranslationY, getMeasuredWidth() - backgroundPaddingLeft, AndroidUtilities.statusBarHeight + currentPanTranslationY, Theme.dialogs_onlineCirclePaint);
}
private int getCurrentTop() {
@ -1749,7 +1783,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
@Override
protected void dispatchDraw(Canvas canvas) {
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)) {
drawChildBackground(canvas, currentAttachLayout);
}
@ -2083,6 +2117,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
return;
}
if (view instanceof AttachButton) {
final Activity activity = baseFragment.getParentActivity();
int num = (Integer) view.getTag();
if (num == 1) {
if (!photosEnabled && !videosEnabled) {
@ -2090,13 +2125,24 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
}
showLayout(photoLayout);
} 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);
return;
}
openAudioLayout(true);
} 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);
return;
}
@ -3771,6 +3817,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
actionBarAnimation = null;
}
});
actionBarAnimation.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
actionBarAnimation.setDuration(380);
actionBarAnimation.start();
} else {
if (show) {
@ -3813,7 +3861,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
animated = false;
}
if (layout == currentAttachLayout) {
updateActionBarVisibility(show, animated);
updateActionBarVisibility(show, true);
}
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) layout.getLayoutParams();
newOffset += (layoutParams == null ? 0 : layoutParams.topMargin) - AndroidUtilities.dp(11);
@ -3969,7 +4017,14 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
enterCommentEventSent = false;
setFocusable(false);
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);
layoutToSet = documentLayout;
selectedId = 4;
@ -4106,6 +4161,29 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
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) {
if (editingMessageObject != null) {
return;

View file

@ -29,6 +29,8 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationManager;
import android.media.ExifInterface;
import android.media.MediaMetadataRetriever;
import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
@ -44,6 +46,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
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.Adapters.LocationActivityAdapter;
import org.telegram.ui.Adapters.LocationActivitySearchAdapter;
import org.telegram.ui.BasePermissionsActivity;
import org.telegram.ui.Cells.HeaderCell;
import org.telegram.ui.Cells.LocationCell;
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.ChatActivity;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLayout implements NotificationCenter.NotificationCenterDelegate {
@ -119,6 +126,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
private boolean currentMapStyleDark;
private boolean checkGpsEnabled = true;
private boolean askedForLocation = false;
private boolean locationDenied = false;
private boolean isFirstLocation = true;
@ -151,6 +159,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
private Location userLocation;
private int markerTop;
private boolean ignoreIdleCamera;
private boolean userLocationMoved;
private boolean searchedForCustomLocations;
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_WITH_LIVE = 1;
public final static int LOCATION_TYPE_STORY = 7;
public static class VenueLocation {
public int num;
@ -362,7 +372,9 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
AndroidUtilities.fixGoogleMapsBug();
ChatActivity chatActivity = (ChatActivity) parentAlert.baseFragment;
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;
} else {
locationType = LOCATION_TYPE_SEND;
@ -443,7 +455,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
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.setContentDescription(LocaleController.getString("Search", R.string.Search));
EditTextBoldCursor editText = searchItem.getSearchField();
@ -676,9 +688,15 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
}
};
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.setMyLocationDenied(locationDenied);
adapter.setMyLocationDenied(locationDenied, askedForLocation);
listView.setVerticalScrollBarEnabled(false);
listView.setLayoutManager(layoutManager = new FillLastLinearLayoutManager(context, LinearLayoutManager.VERTICAL, false, 0, listView) {
@Override
@ -732,7 +750,17 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
}
});
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 (lastPressedMarkerView != null) {
lastPressedMarkerView.callOnClick();
@ -754,6 +782,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
} else if (locationDenied) {
AlertsCreator.createLocationRequiredDialog(getParentActivity(), true).show();
}
return;
} else if (position == 2 && locationType == LOCATION_TYPE_SEND_WITH_LIVE) {
if (getLocationController().isSharingLocation(dialogId)) {
getLocationController().removeSharingLocation(dialogId);
@ -765,22 +794,23 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
openShareLiveLocation();
}
}
} else {
Object object = adapter.getItem(position);
if (object instanceof TLRPC.TL_messageMediaVenue) {
if (chatActivity.isInScheduleMode()) {
AlertsCreator.createScheduleDatePickerDialog(getParentActivity(), chatActivity.getDialogId(), (notify, scheduleDate) -> {
delegate.didSelectLocation((TLRPC.TL_messageMediaVenue) object, locationType, notify, scheduleDate);
parentAlert.dismiss(true);
}, resourcesProvider);
} else {
delegate.didSelectLocation((TLRPC.TL_messageMediaVenue) object, locationType, true, 0);
return;
}
Object object = adapter.getItem(position);
if (object instanceof TLRPC.TL_messageMediaVenue) {
if (chatActivity.isInScheduleMode()) {
AlertsCreator.createScheduleDatePickerDialog(getParentActivity(), chatActivity.getDialogId(), (notify, scheduleDate) -> {
delegate.didSelectLocation((TLRPC.TL_messageMediaVenue) object, locationType, notify, scheduleDate);
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));
}, resourcesProvider);
} else {
delegate.didSelectLocation((TLRPC.TL_messageMediaVenue) object, locationType, true, 0);
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);
@ -819,7 +849,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
animatorSet.setDuration(200);
animatorSet.playTogether(ObjectAnimator.ofFloat(markerImageView, View.TRANSLATION_Y, markerTop));
animatorSet.start();
adapter.fetchLocationAddress();
// adapter.fetchLocationAddress();
}
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
if (!userLocationMoved) {
@ -880,7 +910,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
searchListView = new RecyclerListView(context, resourcesProvider);
searchListView.setVisibility(GONE);
searchListView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
searchAdapter = new LocationActivitySearchAdapter(context) {
searchAdapter = new LocationActivitySearchAdapter(context, resourcesProvider, parentAlert.isStoryLocationPicker) {
@Override
public void notifyDataSetChanged() {
if (searchItem != null) {
@ -892,6 +922,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
super.notifyDataSetChanged();
}
};
searchAdapter.setMyLocationDenied(locationDenied);
searchAdapter.setDelegate(0, places -> {
searchInProgress = false;
updateEmptyView();
@ -1109,6 +1140,9 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
}
private void showSearchPlacesButton(boolean show) {
if (locationDenied) {
show = false;
}
if (show && searchAreaButton != null && searchAreaButton.getTag() == null) {
if (myLocation == null || userLocation == null || userLocation.distanceTo(myLocation) < 300) {
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 -> {
if (parentAlert == null || parentAlert.baseFragment == null) {
return;
}
positionMarker(location);
if (adapter != null && locationType == LOCATION_TYPE_STORY && !userLocationMoved) {
adapter.setCustomLocation(userLocation);
}
getLocationController().setMapLocation(location, isFirstLocation);
isFirstLocation = false;
});
@ -1288,12 +1339,12 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
overlayView.updatePositions();
}
});
positionMarker();
AndroidUtilities.runOnUIThread(() -> {
if (loadingMapView.getTag() == null) {
loadingMapView.animate().alpha(0.0f).setDuration(180).start();
}
}, 200);
positionMarker(myLocation = getLastLocation());
if (checkGpsEnabled && getParentActivity() != null) {
checkGpsEnabled = false;
@ -1306,7 +1357,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
LocationManager lm = (LocationManager) ApplicationLoader.applicationContext.getSystemService(Context.LOCATION_SERVICE);
if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
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.setPositiveButton(LocaleController.getString("ConnectingToProxyEnable", R.string.ConnectingToProxyEnable), (dialog, id) -> {
if (getParentActivity() == null) {
@ -1328,6 +1379,48 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
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() {
if (lastPressedMarker != null) {
markerImageView.setVisibility(VISIBLE);
@ -1418,7 +1511,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
IMapsProvider.LatLng location;
if (lastPressedMarker != null) {
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());
} else if (myLocation != null) {
location = new IMapsProvider.LatLng(myLocation.getLatitude(), myLocation.getLongitude());
@ -1450,7 +1543,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
private int buttonsHeight() {
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);
return buttonsHeight;
}
@ -1513,6 +1606,55 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
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) {
if (location == null) {
return;
@ -1547,8 +1689,13 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.locationPermissionGranted) {
locationDenied = false;
askedForLocation = false;
positionMarker();
if (adapter != null) {
adapter.setMyLocationDenied(locationDenied);
adapter.setMyLocationDenied(locationDenied, askedForLocation);
}
if (searchAdapter != null) {
searchAdapter.setMyLocationDenied(locationDenied);
}
if (map != null) {
try {
@ -1559,12 +1706,16 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
}
} else if (id == NotificationCenter.locationPermissionDenied) {
locationDenied = true;
askedForLocation = false;
if (adapter != null) {
adapter.setMyLocationDenied(locationDenied);
adapter.setMyLocationDenied(locationDenied, askedForLocation);
}
if (searchAdapter != null) {
searchAdapter.setMyLocationDenied(locationDenied);
}
}
fixLayoutInternal(true);
searchItem.setVisibility(locationDenied ? View.GONE : View.VISIBLE);
searchItem.setVisibility(locationDenied && !parentAlert.isStoryLocationPicker ? View.GONE : View.VISIBLE);
}
@Override
@ -1612,7 +1763,20 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
if (activity != null) {
checkPermission = false;
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;
}
@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.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@ -738,10 +739,14 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
}
return;
} else if (noGalleryPermissions) {
try {
fragment.getParentActivity().requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, BasePermissionsActivity.REQUEST_CODE_EXTERNAL_STORAGE);
} catch (Exception ignore) {
if (Build.VERSION.SDK_INT >= 33) {
try {
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;
}
@ -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() {
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) {
loadGalleryPhotos();
}
@ -3255,7 +3277,7 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
}
}
if (Build.VERSION.SDK_INT >= 23) {
noGalleryPermissions = parentAlert.getContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
noGalleryPermissions = isNoGalleryPermissions();
}
if (galleryAlbumEntry != null) {
for (int a = 0; a < Math.min(100, galleryAlbumEntry.photos.size()); a++) {
@ -4014,7 +4036,7 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
return 1;
}
int count = 0;
if (needCamera && selectedAlbumEntry != null && galleryAlbumEntry != null && selectedAlbumEntry.bucketId == galleryAlbumEntry.bucketId) {
if (needCamera && selectedAlbumEntry == galleryAlbumEntry) {
count++;
}
if (showAvatarConstructor) {

View file

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

View file

@ -26,6 +26,7 @@ import android.os.Build;
import android.os.SystemClock;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
@ -99,6 +100,7 @@ public class EditTextBoldCursor extends EditTextEffects {
private float lineSpacingExtra;
private Rect rect = new Rect();
private StaticLayout hintLayout;
private AnimatedTextView.AnimatedTextDrawable hintAnimatedDrawable;
private CharSequence hint;
private StaticLayout errorLayout;
private CharSequence errorText;
@ -193,6 +195,17 @@ public class EditTextBoldCursor extends EditTextEffects {
init();
}
public void useAnimatedTextDrawable() {
hintAnimatedDrawable = new AnimatedTextView.AnimatedTextDrawable() {
@Override
public void invalidateSelf() {
invalidate();
}
};
hintAnimatedDrawable.setTextColor(hintColor);
hintAnimatedDrawable.setTextSize(getPaint().getTextSize());
}
@Override
public void addTextChangedListener(TextWatcher watcher) {
registeredTextWatchers.add(watcher);
@ -462,6 +475,9 @@ public class EditTextBoldCursor extends EditTextEffects {
public void setHintColor(int value) {
hintColor = value;
if (hintAnimatedDrawable != null) {
hintAnimatedDrawable.setTextColor(hintColor);
}
invalidate();
}
@ -470,6 +486,14 @@ public class EditTextBoldCursor extends EditTextEffects {
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) {
nextSetTextAnimated = value;
}
@ -521,7 +545,10 @@ public class EditTextBoldCursor extends EditTextEffects {
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
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) {
setHintText(hint);
}
@ -537,30 +564,34 @@ public class EditTextBoldCursor extends EditTextEffects {
}
public void setHintText(CharSequence text, boolean animated) {
if (text == null) {
text = "";
}
if (getMeasuredWidth() == 0) {
animated = false;
}
if (animated) {
if (hintAnimator == null) {
hintAnimator = new SubstringLayoutAnimator(this);
}
hintAnimator.create(hintLayout, hint, text, getPaint());
if (hintAnimatedDrawable != null) {
hintAnimatedDrawable.setText(text, true);
} else {
if (hintAnimator != null) {
hintAnimator.cancel();
if (text == null) {
text = "";
}
}
hint = text;
if (getMeasuredWidth() != 0) {
text = TextUtils.ellipsize(text, getPaint(), getMeasuredWidth(), TextUtils.TruncateAt.END);
if (hintLayout != null && TextUtils.equals(hintLayout.getText(), text)) {
return;
if (getMeasuredWidth() == 0) {
animated = false;
}
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() {
@ -665,7 +696,7 @@ public class EditTextBoldCursor extends EditTextEffects {
@Override
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) {
long newTime = System.currentTimeMillis();
long dt = newTime - hintLastUpdateTime;
@ -686,46 +717,51 @@ public class EditTextBoldCursor extends EditTextEffects {
}
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.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
hintAnimator.draw(canvas, getPaint());
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.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
hintAnimator.draw(canvas, getPaint());
canvas.restore();
} else {
hintLayout.draw(canvas);
}
getPaint().setColor(oldColor);
canvas.restore();
} else {
hintLayout.draw(canvas);
}
getPaint().setColor(oldColor);
canvas.restore();
}
int topPadding = getExtendedPaddingTop();
@ -999,6 +1035,7 @@ public class EditTextBoldCursor extends EditTextEffects {
}
cleanupFloatingActionModeViews();
floatingToolbar = new FloatingToolbar(getContext(), windowView != null ? windowView : attachedToWindow, getActionModeStyle(), getResourcesProvider());
floatingToolbar.setOnPremiumLockClick(onPremiumMenuLockClickListener);
floatingActionMode = new FloatingActionMode(getContext(), new ActionModeCallback2Wrapper(callback), this, floatingToolbar);
floatingToolbarPreDrawListener = () -> {
if (floatingActionMode != null) {
@ -1091,4 +1128,9 @@ public class EditTextBoldCursor extends EditTextEffects {
setTextSelectHandleRight(right);
} 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 {
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);
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);
}
if (currentPackButton == null) {
@ -610,6 +610,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
} else if (currentPackButton.getDrawable() != drawable) {
currentPackButton.setDrawable(drawable);
}
currentPackButton.updateSelect(selected == i, false);
if (currentType == SelectAnimatedEmojiDialog.TYPE_AVATAR_CONSTRUCTOR) {
currentPackButton.setLock(null);
} else if (!isPremium && !free) {
@ -1065,14 +1066,14 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (lottieDrawable != null && wasVisible) {
if (lottieDrawable != null && isVisible) {
lottieDrawable.draw(canvas);
}
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (!wasVisible) {
if (!isVisible) {
return true;
}
return super.drawChild(canvas, child, drawingTime);
@ -1080,7 +1081,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
@Override
protected void onDraw(Canvas canvas) {
if (!wasVisible) {
if (!isVisible) {
return;
}
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) {
if (!wasVisible && visible) {
if (!isVisible && visible) {
if (lottieDrawable != null && !lottieDrawable.isRunning() && !ignore) {
lottieDrawable.setProgress(0);
lottieDrawable.start();
}
}
if (wasVisible != visible) {
wasVisible = visible;
if (isVisible != visible) {
isVisible = visible;
if (visible) {
invalidate();
if (lockView != null) {
@ -1254,14 +1255,14 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
newEmoji = (DelayedAnimatedEmojiDrawable) drawable;
}
if (animatedEmoji != newEmoji) {
if (animatedEmoji != null && attached && wasVisible) {
if (animatedEmoji != null) {
animatedEmoji.removeView();
}
animatedEmoji = newEmoji;
if (animatedEmoji != null && attached && wasVisible) {
if (animatedEmoji != null && attached && isVisible) {
animatedEmoji.updateView(imageView);
}
if (wasVisible && animatedEmoji != null) {
if (isVisible && animatedEmoji != null) {
animatedEmoji.load();
}
initLock();
@ -1287,7 +1288,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
private void updateAttachState() {
if (animatedEmoji != null) {
if ((keepAttached || attached) && wasVisible) {
if ((keepAttached || attached) && isVisible) {
animatedEmoji.updateView(imageView);
} else {
animatedEmoji.removeView();

View file

@ -20,6 +20,7 @@ public class FillLastLinearLayoutManager extends LinearLayoutManager {
private boolean canScrollVertically = true;
boolean fixedLastItemHeight;
private int minimumHeight;
private boolean setMeassuredHeightToLastItem = true;
public FillLastLinearLayoutManager(Context context, int h, RecyclerView recyclerView) {
super(context);
@ -163,11 +164,13 @@ public class FillLastLinearLayoutManager extends LinearLayoutManager {
@Override
public void measureChildWithMargins(View child, int widthUsed, int heightUsed) {
RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child);
int pos = holder.getAdapterPosition();
if (pos == getItemCount() - 1) {
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
layoutParams.height = Math.max(lastItemHeight, 0);
if (setMeassuredHeightToLastItem) {
RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child);
int pos = holder.getAdapterPosition();
if (pos == getItemCount() - 1) {
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
layoutParams.height = Math.max(lastItemHeight, 0);
}
}
super.measureChildWithMargins(child, 0, 0);
}
@ -179,4 +182,12 @@ public class FillLastLinearLayoutManager extends LinearLayoutManager {
public void setMinimumLastViewHeight(int 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 colorKey2 = Theme.key_listSelector;
private int colorKey3;
private int colorKey3 = -1;
private int itemsCount = 1;
private final Theme.ResourcesProvider resourcesProvider;

View file

@ -33,9 +33,10 @@ public class GradientTools {
Bitmap gradientBitmap = null;
int[] colors = new int[4];
public boolean isLinear;
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) {
@ -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));
}
} else {
if (gradientBitmap == null) {
gradientBitmap = Bitmap.createBitmap(INTERNAL_WIDTH, INTERNAL_HEIGHT, Bitmap.Config.ARGB_8888);
if (isLinear) {
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();
}

View file

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

View file

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

View file

@ -28,6 +28,7 @@ import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.util.Consumer;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BotWebViewVibrationEffect;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
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.Cells.UserCell;
import org.telegram.ui.ProfileActivity;
import org.telegram.ui.Stories.recorder.HintView2;
public class ItemOptions {
@ -59,6 +61,7 @@ public class ItemOptions {
private View scrimView;
private Drawable scrimViewBackground;
private int gravity = Gravity.RIGHT;
private boolean ignoreX;
private ActionBarPopupWindow actionBarPopupWindow;
private final float[] point = new float[2];
@ -84,10 +87,6 @@ public class ItemOptions {
this.scrimView = scrimView;
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();
}
@ -115,11 +114,9 @@ public class ItemOptions {
layout = lastLayout;
}
public ItemOptions addIf(boolean condition, int iconResId, CharSequence text, Runnable onClickListener) {
if (!condition) {
return this;
}
return add(iconResId, text, onClickListener);
public ItemOptions ignoreX() {
ignoreX = true;
return this;
}
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);
}
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) {
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) {
@ -141,14 +138,14 @@ public class ItemOptions {
}
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) {
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) {
return this;
}
@ -170,16 +167,43 @@ public class ItemOptions {
});
if (minWidthDp > 0) {
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;
}
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) {
if (onLockClick == null || context == null || lastLayout.getItemsCount() <= 0) {
return this;
@ -193,6 +217,8 @@ public class ItemOptions {
lastSubItem.getRightIcon().setAlpha(.4f);
lastSubItem.setOnClickListener(view1 -> {
if (onLockClick != null) {
AndroidUtilities.shakeViewSpring(view1, shiftDp = -shiftDp);
BotWebViewVibrationEffect.APP_ERROR.vibrate();
onLockClick.run();
}
});
@ -223,7 +249,12 @@ public class ItemOptions {
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;
}
@ -333,6 +364,9 @@ public class ItemOptions {
getPointOnScreen(scrimView, container, point);
y = point[1];
}
if (ignoreX) {
point[0] = 0;
}
final Bitmap cachedBitmap;
final Paint cachedBitmapPaint;
@ -449,6 +483,14 @@ public class ItemOptions {
} else {
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(
container,
0,

View file

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

View file

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

View file

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

View file

@ -7,6 +7,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Build;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
@ -26,19 +27,29 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.VideoEditedInfo;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Adapters.MentionsAdapter;
import org.telegram.ui.Adapters.PaddedListAdapter;
import org.telegram.ui.Cells.ContextLinkCell;
import org.telegram.ui.Cells.StickerCell;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.ContentPreviewViewer;
import org.telegram.ui.PhotoViewer;
import java.util.ArrayList;
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 boolean allowBlur;
private RecyclerListView.OnItemClickListener mentionsOnItemClickListener;
private Delegate delegate;
public MentionsContainerView(@NonNull Context context, long dialogId, int threadMessageId, BaseFragment baseFragment, SizeNotifierFrameLayout container, Theme.ResourcesProvider resourcesProvider) {
super(context, container);
@ -418,7 +430,7 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
if (listViewTranslationAnimator != null) {
listViewTranslationAnimator.cancel();
}
AndroidUtilities.runOnUIThread(updateVisibilityRunnable, baseFragment.getFragmentBeginToShow() ? 0 : 100);
AndroidUtilities.runOnUIThread(updateVisibilityRunnable, (baseFragment != null && baseFragment.getFragmentBeginToShow()) ? 0 : 100);
if (show) {
onOpen();
} else {
@ -529,7 +541,54 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
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) {
this.delegate = delegate;
getListView().setOnItemClickListener(mentionsOnItemClickListener = (view, position) -> {
if (position == 0 || getAdapter().isBannedInline()) {
return;
@ -596,10 +655,20 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
delegate.replaceText(start, len, code, true);
}
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));
}
public class MentionsListView extends RecyclerListView {
@ -784,6 +853,9 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
default void addEmojiToRecent(String code) {
}
default void sendBotInlineResult(TLRPC.BotInlineResult botInlineResult, boolean notify, int scheduleDate) {}
}
@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 REACTIONS_TYPE = 1;
public final static int EMOJI_STICKER_TYPE = 2;
public final static int SINGLE_REACTION_TYPE = 3;
int type;
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);
this.currentAccount = currentAccount;
this.type = type;
@ -77,28 +79,6 @@ public class MessageContainsEmojiButton extends FrameLayout implements Notificat
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(AndroidUtilities.dp(13));
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) {
String string;
@ -120,6 +100,8 @@ public class MessageContainsEmojiButton extends FrameLayout implements Notificat
String string;
if (type == EMOJI_TYPE) {
string = LocaleController.getString("MessageContainsEmojiPack", R.string.MessageContainsEmojiPack);
} else if (type == SINGLE_REACTION_TYPE) {
string = LocaleController.getString("MessageContainsReactionPack", R.string.MessageContainsReactionPack);
} else {
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_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_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 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 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(
"Google Sans",

View file

@ -20,8 +20,6 @@ import android.text.TextPaint;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.Components.EditTextBoldCursor;
import java.util.Arrays;
public class EditTextOutline extends EditTextBoldCursor {
private Canvas mCanvas = new Canvas();
@ -37,6 +35,7 @@ public class EditTextOutline extends EditTextBoldCursor {
public boolean betterFraming;
private RectF[] lines;
public RectF framePadding;
private boolean isFrameDirty;
public EditTextOutline(Context context) {
@ -201,6 +200,21 @@ public class EditTextOutline extends EditTextBoldCursor {
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();
float h = getHeight();
@ -251,6 +265,8 @@ public class EditTextOutline extends EditTextBoldCursor {
setFrameRoundRadius(r);
canvas.drawPath(path, paint);
canvas.restore();
} else {
framePadding = null;
}
super.onDraw(canvas);
}

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