update to 10.1.0 (3919)

This commit is contained in:
xaxtix 2023-09-22 18:40:36 +04:00
parent 6b4602c20a
commit 750eedfc96
137 changed files with 9539 additions and 2271 deletions

View file

@ -17,12 +17,14 @@ configurations.all {
} }
dependencies { dependencies {
implementation 'androidx.fragment:fragment:1.2.0'
implementation 'androidx.core:core:1.10.1' implementation 'androidx.core:core:1.10.1'
implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.palette:palette:1.0.0'
implementation 'androidx.exifinterface:exifinterface:1.3.3' implementation 'androidx.exifinterface:exifinterface:1.3.6'
implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0' implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
implementation "androidx.sharetarget:sharetarget:1.2.0" implementation "androidx.sharetarget:sharetarget:1.2.0"
implementation 'androidx.interpolator:interpolator:1.0.0'
compileOnly 'org.checkerframework:checker-qual:2.5.2' compileOnly 'org.checkerframework:checker-qual:2.5.2'
compileOnly 'org.checkerframework:checker-compat-qual:2.5.0' compileOnly 'org.checkerframework:checker-compat-qual:2.5.0'
@ -138,6 +140,19 @@ android {
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
} }
HA_hardcore {
debuggable false
jniDebuggable false
minifyEnabled true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_HARDCORE") + "\""
buildConfigField "boolean", "DEBUG_VERSION", "true"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
}
standalone { standalone {
debuggable false debuggable false
jniDebuggable false jniDebuggable false

View file

@ -236,7 +236,11 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
.setInterpolator(getRemoveInterpolator()) .setInterpolator(getRemoveInterpolator())
.alpha(0) .alpha(0)
.scaleX(1f - animateByScale(view)) .scaleX(1f - animateByScale(view))
.scaleY(1f - animateByScale(view)) .scaleY(1f - animateByScale(view));
if (Build.VERSION.SDK_INT >= 19) {
animation.setUpdateListener(animation1 -> onRemoveAnimationUpdate(holder));
}
animation
.setListener( .setListener(
new AnimatorListenerAdapter() { new AnimatorListenerAdapter() {
@Override @Override
@ -284,7 +288,11 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
.scaleY(1f) .scaleY(1f)
.setDuration(getAddDuration()) .setDuration(getAddDuration())
.setStartDelay(getAddDelay()) .setStartDelay(getAddDelay())
.setInterpolator(getAddInterpolator()) .setInterpolator(getAddInterpolator());
if (Build.VERSION.SDK_INT >= 19) {
animation.setUpdateListener(animation1 -> onAddAnimationUpdate(holder));
}
animation
.setListener(new AnimatorListenerAdapter() { .setListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationStart(Animator animator) { public void onAnimationStart(Animator animator) {
@ -342,6 +350,14 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
} }
protected void onAddAnimationUpdate(RecyclerView.ViewHolder holder) {
}
protected void onRemoveAnimationUpdate(RecyclerView.ViewHolder holder) {
}
protected void beforeAnimateMoveImpl(final RecyclerView.ViewHolder holder) { protected void beforeAnimateMoveImpl(final RecyclerView.ViewHolder holder) {
} }

View file

@ -785,6 +785,16 @@ public class AndroidUtilities {
return new float[] {xOffset, yOffset}; return new float[] {xOffset, yOffset};
} }
public static void doOnLayout(View view, Runnable runnable) {
view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
view.removeOnLayoutChangeListener(this);
runnable.run();
}
});
}
private static class LinkSpec { private static class LinkSpec {
String url; String url;
int start; int start;

View file

@ -44,7 +44,7 @@ import java.io.File;
public class ApplicationLoader extends Application { public class ApplicationLoader extends Application {
private static ApplicationLoader applicationLoaderInstance; public static ApplicationLoader applicationLoaderInstance;
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
public static volatile Context applicationContext; public static volatile Context applicationContext;
@ -555,4 +555,11 @@ public class ApplicationLoader extends Application {
} }
public boolean checkApkInstallPermissions(final Context context) {
return false;
}
public boolean openApkInstall(Activity activity, TLRPC.Document document) {
return false;
}
} }

View file

@ -24,8 +24,8 @@ public class BuildVars {
public static boolean USE_CLOUD_STRINGS = true; public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true; public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29; public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 3872; public static int BUILD_VERSION = 3919;
public static String BUILD_VERSION_STRING = "10.0.9"; public static String BUILD_VERSION_STRING = "10.1.0";
public static int APP_ID = 4; public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
@ -33,6 +33,7 @@ public class BuildVars {
public static String SAFETYNET_KEY = "AIzaSyDqt8P-7F7CPCseMkOiVRgb1LY8RN1bvH8"; public static String SAFETYNET_KEY = "AIzaSyDqt8P-7F7CPCseMkOiVRgb1LY8RN1bvH8";
public static String SMS_HASH = isStandaloneApp() ? "w0lkcmTZkKh" : (DEBUG_VERSION ? "O2P2z+/jBpJ" : "oLeq9AcOZkT"); public static String SMS_HASH = isStandaloneApp() ? "w0lkcmTZkKh" : (DEBUG_VERSION ? "O2P2z+/jBpJ" : "oLeq9AcOZkT");
public static String PLAYSTORE_APP_URL = "https://play.google.com/store/apps/details?id=org.telegram.messenger"; public static String PLAYSTORE_APP_URL = "https://play.google.com/store/apps/details?id=org.telegram.messenger";
public static String HUAWEI_STORE_URL = "https://appgallery.huawei.com/app/C101184875";
public static String GOOGLE_AUTH_CLIENT_ID = "760348033671-81kmi3pi84p11ub8hp9a1funsv0rn2p9.apps.googleusercontent.com"; public static String GOOGLE_AUTH_CLIENT_ID = "760348033671-81kmi3pi84p11ub8hp9a1funsv0rn2p9.apps.googleusercontent.com";
public static String HUAWEI_APP_ID = "101184875"; public static String HUAWEI_APP_ID = "101184875";

View file

@ -0,0 +1,108 @@
package org.telegram.messenger;
import com.google.android.exoplayer2.util.Consumer;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.BulletinFactory;
public class ChannelBoostsController {
private final int currentAccount;
private final MessagesController messagesController;
private final ConnectionsManager connectionsManager;
public final static int BOOSTS_FOR_LEVEL_1 = 1;
public final static int BOOSTS_FOR_LEVEL_2 = 1;
public ChannelBoostsController(int currentAccount) {
this.currentAccount = currentAccount;
messagesController = MessagesController.getInstance(currentAccount);
connectionsManager = ConnectionsManager.getInstance(currentAccount);
}
public void getBoostsStats(long dialogId, Consumer<TLRPC.TL_stories_boostsStatus> consumer) {
TLRPC.TL_stories_getBoostsStatus req = new TLRPC.TL_stories_getBoostsStatus();
req.peer = messagesController.getInputPeer(dialogId);
connectionsManager.sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response != null) {
consumer.accept((TLRPC.TL_stories_boostsStatus) response);
} else {
BulletinFactory.showForError(error);
consumer.accept(null);
}
}));
}
public void userCanBoostChannel(long dialogId, Consumer<CanApplyBoost> consumer) {
TLRPC.TL_stories_canApplyBoost req = new TLRPC.TL_stories_canApplyBoost();
req.peer = messagesController.getInputPeer(dialogId);
connectionsManager.sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
CanApplyBoost canApplyBoost = new CanApplyBoost();
if (response != null) {
canApplyBoost.canApply = true;
if (response instanceof TLRPC.TL_stories_canApplyBoostReplace) {
TLRPC.TL_stories_canApplyBoostReplace canApplyBoostReplace = (TLRPC.TL_stories_canApplyBoostReplace) response;
messagesController.putChats(canApplyBoostReplace.chats, false);
canApplyBoost.replaceDialogId = DialogObject.getPeerDialogId(canApplyBoostReplace.current_boost);
if (canApplyBoost.replaceDialogId == 0 && canApplyBoostReplace.chats.size() > 0) {
canApplyBoost.replaceDialogId = -canApplyBoostReplace.chats.get(0).id;
}
}
} else {
if (error != null) {
if (error.text.equals("SAME_BOOST_ALREADY_ACTIVE") || error.text.equals("BOOST_NOT_MODIFIED")) {
canApplyBoost.alreadyActive = true;
} else if (error.text.equals("PREMIUM_GIFTED_NOT_ALLOWED")) {
canApplyBoost.giftedPremium = true;
} else if (error.text.startsWith("FLOOD_WAIT")) {
canApplyBoost.floodWait = Utilities.parseInt(error.text);
canApplyBoost.lastCheckTime = System.currentTimeMillis();
}
}
}
consumer.accept(canApplyBoost);
}), ConnectionsManager.RequestFlagDoNotWaitFloodWait);
}
public void applyBoost(long dialogId) {
TLRPC.TL_stories_applyBoost req = new TLRPC.TL_stories_applyBoost();
req.peer = messagesController.getInputPeer(dialogId);
connectionsManager.sendRequest(req, (response, error) -> {
});
}
public int getTotalBooststToLevel(int level) {
int count = 0;
if (level >= 1) {
count += BOOSTS_FOR_LEVEL_1;
}
if (level >= 2) {
count += BOOSTS_FOR_LEVEL_2;
}
return count;
}
public static class CanApplyBoost {
public boolean canApply;
public long replaceDialogId;
public boolean alreadyActive;
public int floodWait;
public boolean giftedPremium;
private long lastCheckTime;
public void checkTime() {
floodWait -= (System.currentTimeMillis() - lastCheckTime) / 1000;
lastCheckTime = System.currentTimeMillis();
if (floodWait < 0) {
floodWait = 0;
canApply = true;
}
}
}
}

View file

@ -87,7 +87,7 @@ public class ChatMessagesMetadataController {
continue; continue;
} }
long storyDialogId = storyItem.dialogId; long storyDialogId = storyItem.dialogId;
req.user_id = chatActivity.getMessagesController().getInputUser(storyDialogId); req.peer = chatActivity.getMessagesController().getInputPeer(storyDialogId);
req.id.add(storyItem.id); req.id.add(storyItem.id);
int storyId = storyItem.id; int storyId = storyItem.id;
int reqId = chatActivity.getConnectionsManager().sendRequest(req, (response, error) -> { int reqId = chatActivity.getConnectionsManager().sendRequest(req, (response, error) -> {

View file

@ -2864,6 +2864,9 @@ public class ContactsController extends BaseController {
} }
public static String formatName(TLRPC.User user) { public static String formatName(TLRPC.User user) {
if (user == null) {
return "";
}
return formatName(user.first_name, user.last_name, 0); return formatName(user.first_name, user.last_name, 0);
} }

View file

@ -1370,6 +1370,12 @@ public class DatabaseMigrationHelper {
version = 133; version = 133;
} }
if (version == 133) {
database.executeFast("ALTER TABLE unread_push_messages ADD COLUMN topicId INTEGER default 0").stepThis().dispose();
database.executeFast("PRAGMA user_version = 134").stepThis().dispose();
version = 134;
}
return version; return version;
} }

View file

@ -1169,6 +1169,10 @@ public class FileLoader extends BaseController {
} }
public File getPathToMessage(TLRPC.Message message, boolean useFileDatabaseQueue) { public File getPathToMessage(TLRPC.Message message, boolean useFileDatabaseQueue) {
return getPathToMessage(message, useFileDatabaseQueue, false);
}
public File getPathToMessage(TLRPC.Message message, boolean useFileDatabaseQueue, boolean saveAsFile) {
if (message == null) { if (message == null) {
return new File(""); return new File("");
} }
@ -1184,7 +1188,7 @@ public class FileLoader extends BaseController {
} }
} else { } else {
if (MessageObject.getMedia(message) instanceof TLRPC.TL_messageMediaDocument) { if (MessageObject.getMedia(message) instanceof TLRPC.TL_messageMediaDocument) {
return getPathToAttach(MessageObject.getMedia(message).document, null, MessageObject.getMedia(message).ttl_seconds != 0, useFileDatabaseQueue); return getPathToAttach(MessageObject.getMedia(message).document, null,null, MessageObject.getMedia(message).ttl_seconds != 0, useFileDatabaseQueue, saveAsFile);
} else if (MessageObject.getMedia(message) instanceof TLRPC.TL_messageMediaPhoto) { } else if (MessageObject.getMedia(message) instanceof TLRPC.TL_messageMediaPhoto) {
ArrayList<TLRPC.PhotoSize> sizes = MessageObject.getMedia(message).photo.sizes; ArrayList<TLRPC.PhotoSize> sizes = MessageObject.getMedia(message).photo.sizes;
if (sizes.size() > 0) { if (sizes.size() > 0) {
@ -1221,21 +1225,22 @@ public class FileLoader extends BaseController {
} }
public File getPathToAttach(TLObject attach, String ext, boolean forceCache) { public File getPathToAttach(TLObject attach, String ext, boolean forceCache) {
return getPathToAttach(attach, null, ext, forceCache, true); return getPathToAttach(attach, null, ext, forceCache, true, false);
} }
public File getPathToAttach(TLObject attach, String ext, boolean forceCache, boolean useFileDatabaseQueue) { public File getPathToAttach(TLObject attach, String ext, boolean forceCache, boolean useFileDatabaseQueue) {
return getPathToAttach(attach, null, ext, forceCache, useFileDatabaseQueue); return getPathToAttach(attach, null, ext, forceCache, useFileDatabaseQueue, false);
} }
/** /**
* Return real file name. Used before file.exist() * Return real file name. Used before file.exist()
*/ */
public File getPathToAttach(TLObject attach, String size, String ext, boolean forceCache, boolean useFileDatabaseQueue) { public File getPathToAttach(TLObject attach, String size, String ext, boolean forceCache, boolean useFileDatabaseQueue, boolean saveAsFile) {
File dir = null; File dir = null;
long documentId = 0; long documentId = 0;
int dcId = 0; int dcId = 0;
int type = 0; int type = 0;
String fileName = null;
if (forceCache) { if (forceCache) {
dir = getDirectory(MEDIA_DIR_CACHE); dir = getDirectory(MEDIA_DIR_CACHE);
} else { } else {
@ -1252,7 +1257,13 @@ public class FileLoader extends BaseController {
} else if (MessageObject.isVideoDocument(document)) { } else if (MessageObject.isVideoDocument(document)) {
type = MEDIA_DIR_VIDEO; type = MEDIA_DIR_VIDEO;
} else { } else {
type = MEDIA_DIR_DOCUMENT; String documentFileName = getDocumentFileName(document);
if (saveAsFile && !TextUtils.isEmpty(documentFileName)) {
fileName = documentFileName;
type = MEDIA_DIR_FILES;
} else {
type = MEDIA_DIR_DOCUMENT;
}
} }
} }
documentId = document.id; documentId = document.id;
@ -1323,7 +1334,10 @@ public class FileLoader extends BaseController {
return new File(path); return new File(path);
} }
} }
return new File(dir, getAttachFileName(attach, ext)); if (fileName == null) {
fileName = getAttachFileName(attach, ext);
}
return new File(dir, fileName);
} }
public FilePathDatabase getFileDatabase() { public FilePathDatabase getFileDatabase() {

View file

@ -352,7 +352,7 @@ public class FileRefController extends BaseController {
if (parentObject instanceof TLRPC.StoryItem) { if (parentObject instanceof TLRPC.StoryItem) {
TLRPC.StoryItem storyItem = (TLRPC.StoryItem) parentObject; TLRPC.StoryItem storyItem = (TLRPC.StoryItem) parentObject;
TLRPC.TL_stories_getStoriesByID req = new TLRPC.TL_stories_getStoriesByID(); TLRPC.TL_stories_getStoriesByID req = new TLRPC.TL_stories_getStoriesByID();
req.user_id = getMessagesController().getInputUser(storyItem.dialogId); req.peer = getMessagesController().getInputPeer(storyItem.dialogId);
req.id.add(storyItem.id); req.id.add(storyItem.id);
getConnectionsManager().sendRequest(req, (response, error) -> { getConnectionsManager().sendRequest(req, (response, error) -> {
onRequestComplete(locationKey, parentKey, response, error, true, false); onRequestComplete(locationKey, parentKey, response, error, true, false);
@ -911,35 +911,7 @@ public class FileRefController extends BaseController {
} }
} else if (response instanceof TLRPC.TL_help_appUpdate) { } else if (response instanceof TLRPC.TL_help_appUpdate) {
TLRPC.TL_help_appUpdate appUpdate = (TLRPC.TL_help_appUpdate) response; TLRPC.TL_help_appUpdate appUpdate = (TLRPC.TL_help_appUpdate) response;
try { result = getFileReference(appUpdate.document, requester.location, needReplacement, locationReplacement);
SharedConfig.pendingAppUpdate = appUpdate;
SharedConfig.saveConfig();
} catch (Exception e) {
FileLog.e(e);
}
try {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.appUpdateAvailable);
} catch (Exception e) {
FileLog.e(e);
}
try {
if (appUpdate.document != null) {
result = appUpdate.document.file_reference;
TLRPC.TL_inputDocumentFileLocation location = new TLRPC.TL_inputDocumentFileLocation();
location.id = appUpdate.document.id;
location.access_hash = appUpdate.document.access_hash;
location.file_reference = appUpdate.document.file_reference;
location.thumb_size = "";
locationReplacement = new TLRPC.InputFileLocation[1];
locationReplacement[0] = location;
}
} catch (Exception e) {
result = null;
FileLog.e(e);
}
if (result == null) {
result = getFileReference(appUpdate.document, requester.location, needReplacement, locationReplacement);
}
if (result == null) { if (result == null) {
result = getFileReference(appUpdate.sticker, requester.location, needReplacement, locationReplacement); result = getFileReference(appUpdate.sticker, requester.location, needReplacement, locationReplacement);
} }
@ -1091,7 +1063,7 @@ public class FileRefController extends BaseController {
TLRPC.StoryItem storyItem = (TLRPC.StoryItem) operation.parentObject; TLRPC.StoryItem storyItem = (TLRPC.StoryItem) operation.parentObject;
if (newStoryItem == null) { if (newStoryItem == null) {
TLRPC.TL_updateStory story = new TLRPC.TL_updateStory(); TLRPC.TL_updateStory story = new TLRPC.TL_updateStory();
story.user_id = storyItem.dialogId; story.peer = getMessagesController().getPeer(storyItem.dialogId);
story.story = new TLRPC.TL_storyItemDeleted(); story.story = new TLRPC.TL_storyItemDeleted();
story.story.id = storyItem.id; story.story.id = storyItem.id;
ArrayList<TLRPC.Update> updates = new ArrayList<>(); ArrayList<TLRPC.Update> updates = new ArrayList<>();

View file

@ -54,6 +54,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
List<ImageReceiver> preloadReceivers; List<ImageReceiver> preloadReceivers;
private boolean allowCrossfadeWithImage = true; private boolean allowCrossfadeWithImage = true;
private boolean allowDrawWhileCacheGenerating; private boolean allowDrawWhileCacheGenerating;
private ArrayList<Decorator> decorators;
public boolean updateThumbShaderMatrix() { public boolean updateThumbShaderMatrix() {
if (currentThumbDrawable != null && thumbShader != null) { if (currentThumbDrawable != null && thumbShader != null) {
@ -1080,6 +1081,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (lottieDrawable != null) { if (lottieDrawable != null) {
lottieDrawable.removeParentView(this); lottieDrawable.removeParentView(this);
} }
if (decorators != null) {
for (int i = 0; i < decorators.size(); i++) {
decorators.get(i).onDetachedFromWidnow();
}
}
} }
public boolean setBackupImage() { public boolean setBackupImage() {
@ -1163,6 +1169,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (staticThumbDrawable instanceof AttachableDrawable) { if (staticThumbDrawable instanceof AttachableDrawable) {
((AttachableDrawable) staticThumbDrawable).onAttachedToWindow(this); ((AttachableDrawable) staticThumbDrawable).onAttachedToWindow(this);
} }
if (decorators != null) {
for (int i = 0; i < decorators.size(); i++) {
decorators.get(i).onAttachedToWindow(this);
}
}
return false; return false;
} }
@ -2028,6 +2039,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (gradientBitmap != null && currentImageKey != null) { if (gradientBitmap != null && currentImageKey != null) {
canvas.restore(); canvas.restore();
} }
if (result && isVisible && decorators != null) {
for (int i = 0; i < decorators.size(); i++) {
decorators.get(i).onDraw(canvas, this);
}
}
return result; return result;
} }
@ -3142,6 +3158,26 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return holder; return holder;
} }
public void clearDecorators() {
if (decorators != null) {
if (attachedToWindow) {
for (int i = 0; i < decorators.size(); i++) {
decorators.get(i).onDetachedFromWidnow();
}
}
decorators.clear();
}
}
public void addDecorator(Decorator decorator) {
if (decorators == null) {
decorators = new ArrayList<>();
}
decorators.add(decorator);
if (attachedToWindow) {
decorator.onAttachedToWindow(this);
}
}
public static class BackgroundThreadDrawHolder { public static class BackgroundThreadDrawHolder {
public boolean animationNotReady; public boolean animationNotReady;
public float overrideAlpha; public float overrideAlpha;
@ -3224,4 +3260,14 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
super(bitmap); super(bitmap);
} }
} }
public static abstract class Decorator {
protected abstract void onDraw(Canvas canvas, ImageReceiver imageReceiver);
public void onAttachedToWindow(ImageReceiver imageReceiver) {
}
public void onDetachedFromWidnow() {
}
}
} }

View file

@ -2040,14 +2040,14 @@ public class LocaleController {
public static String stringForMessageListDate(long date) { public static String stringForMessageListDate(long date) {
try { try {
date *= 1000; date *= 1000;
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
rightNow.setTimeInMillis(date);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
if (Math.abs(System.currentTimeMillis() - date) >= 31536000000L) { if (Math.abs(System.currentTimeMillis() - date) >= 31536000000L) {
return getInstance().formatterYear.format(new Date(date)); return getInstance().formatterYear.format(new Date(date));
} else { } else {
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
rightNow.setTimeInMillis(date);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dayDiff = dateDay - day; int dayDiff = dateDay - day;
if (dayDiff == 0 || dayDiff == -1 && System.currentTimeMillis() - date < 60 * 60 * 8 * 1000) { if (dayDiff == 0 || dayDiff == -1 && System.currentTimeMillis() - date < 60 * 60 * 8 * 1000) {
return getInstance().formatterDay.format(new Date(date)); return getInstance().formatterDay.format(new Date(date));

View file

@ -4068,7 +4068,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
} }
} }
if (path == null || path.length() == 0) { if (path == null || path.length() == 0) {
path = FileLoader.getInstance(currentAccount.getCurrentAccount()).getPathToMessage(message.messageOwner).toString(); path = FileLoader.getInstance(currentAccount.getCurrentAccount()).getPathToMessage(message.messageOwner, true, !isMusic).toString();
} }
File sourceFile = new File(path); File sourceFile = new File(path);
if (!sourceFile.exists()) { if (!sourceFile.exists()) {
@ -4122,7 +4122,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
} }
} }
if (path == null || path.length() == 0) { if (path == null || path.length() == 0) {
path = FileLoader.getInstance(currentAccount.getCurrentAccount()).getPathToMessage(message.messageOwner).toString(); path = FileLoader.getInstance(currentAccount.getCurrentAccount()).getPathToMessage(message.messageOwner, true, !isMusic).toString();
} }
File sourceFile = new File(path); File sourceFile = new File(path);
if (!sourceFile.exists()) { if (!sourceFile.exists()) {

View file

@ -94,6 +94,7 @@ import java.util.regex.Pattern;
public class MediaDataController extends BaseController { public class MediaDataController extends BaseController {
public final static String ATTACH_MENU_BOT_ANIMATED_ICON_KEY = "android_animated", public final static String ATTACH_MENU_BOT_ANIMATED_ICON_KEY = "android_animated",
ATTACH_MENU_BOT_STATIC_ICON_KEY = "default_static", ATTACH_MENU_BOT_STATIC_ICON_KEY = "default_static",
ATTACH_MENU_BOT_SIDE_MENU_ICON_KEY = "android_side_menu_static",
ATTACH_MENU_BOT_PLACEHOLDER_STATIC_KEY = "placeholder_static", ATTACH_MENU_BOT_PLACEHOLDER_STATIC_KEY = "placeholder_static",
ATTACH_MENU_BOT_COLOR_LIGHT_ICON = "light_icon", ATTACH_MENU_BOT_COLOR_LIGHT_ICON = "light_icon",
ATTACH_MENU_BOT_COLOR_LIGHT_TEXT = "light_text", ATTACH_MENU_BOT_COLOR_LIGHT_TEXT = "light_text",
@ -1568,6 +1569,16 @@ public class MediaDataController extends BaseController {
return null; return null;
} }
@Nullable
public static TLRPC.TL_attachMenuBotIcon getSideAttachMenuBotIcon(@NonNull TLRPC.TL_attachMenuBot bot) {
for (TLRPC.TL_attachMenuBotIcon icon : bot.icons) {
if (icon.name.equals(ATTACH_MENU_BOT_SIDE_MENU_ICON_KEY)) {
return icon;
}
}
return null;
}
@Nullable @Nullable
public static TLRPC.TL_attachMenuBotIcon getPlaceholderStaticAttachMenuBotIcon(@NonNull TLRPC.TL_attachMenuBot bot) { public static TLRPC.TL_attachMenuBotIcon getPlaceholderStaticAttachMenuBotIcon(@NonNull TLRPC.TL_attachMenuBot bot) {
for (TLRPC.TL_attachMenuBotIcon icon : bot.icons) { for (TLRPC.TL_attachMenuBotIcon icon : bot.icons) {
@ -5469,7 +5480,7 @@ public class MediaDataController extends BaseController {
} }
if (messageObject.type == MessageObject.TYPE_STORY || messageObject.type == MessageObject.TYPE_STORY_MENTION) { if (messageObject.type == MessageObject.TYPE_STORY || messageObject.type == MessageObject.TYPE_STORY_MENTION) {
if (messageObject.messageOwner.media.storyItem == null) { if (messageObject.messageOwner.media.storyItem == null) {
long storyDialogId = messageObject.messageOwner.media.user_id; long storyDialogId = DialogObject.getPeerDialogId(messageObject.messageOwner.media.peer);
if (messagesWithUnknownStories == null) { if (messagesWithUnknownStories == null) {
messagesWithUnknownStories = new LongSparseArray<>(); messagesWithUnknownStories = new LongSparseArray<>();
} }
@ -5480,7 +5491,7 @@ public class MediaDataController extends BaseController {
} }
array.add(messageObject); array.add(messageObject);
} else { } else {
long storyDialogId = messageObject.messageOwner.media.user_id; long storyDialogId = DialogObject.getPeerDialogId(messageObject.messageOwner.media.peer);
messageObject.messageOwner.media.storyItem = StoriesStorage.checkExpiredStateLocal(currentAccount, storyDialogId, messageObject.messageOwner.media.storyItem); messageObject.messageOwner.media.storyItem = StoriesStorage.checkExpiredStateLocal(currentAccount, storyDialogId, messageObject.messageOwner.media.storyItem);
} }
} else if (messageObject.getId() > 0 && messageObject.isReplyToStory()) { } else if (messageObject.getId() > 0 && messageObject.isReplyToStory()) {
@ -5554,7 +5565,7 @@ public class MediaDataController extends BaseController {
if (attr instanceof TLRPC.TL_webPageAttributeStory) { if (attr instanceof TLRPC.TL_webPageAttributeStory) {
TLRPC.TL_webPageAttributeStory attrStory = (TLRPC.TL_webPageAttributeStory) attr; TLRPC.TL_webPageAttributeStory attrStory = (TLRPC.TL_webPageAttributeStory) attr;
if (attrStory.storyItem == null) { if (attrStory.storyItem == null) {
long storyDialogId = attrStory.user_id; long storyDialogId = DialogObject.getPeerDialogId(attrStory.peer);
if (messagesWithUnknownStories == null) { if (messagesWithUnknownStories == null) {
messagesWithUnknownStories = new LongSparseArray<>(); messagesWithUnknownStories = new LongSparseArray<>();
} }
@ -5565,7 +5576,7 @@ public class MediaDataController extends BaseController {
} }
array.add(messageObject); array.add(messageObject);
} else { } else {
long storyDialogId = attrStory.user_id; long storyDialogId = DialogObject.getPeerDialogId(attrStory.peer);
attrStory.storyItem = StoriesStorage.checkExpiredStateLocal(currentAccount, storyDialogId, attrStory.storyItem); attrStory.storyItem = StoriesStorage.checkExpiredStateLocal(currentAccount, storyDialogId, attrStory.storyItem);
} }
} }
@ -7235,6 +7246,7 @@ public class MediaDataController extends BaseController {
public void applyAttachMenuBot(TLRPC.TL_attachMenuBotsBot attachMenuBot) { public void applyAttachMenuBot(TLRPC.TL_attachMenuBotsBot attachMenuBot) {
attachMenuBots.bots.add(attachMenuBot.bot); attachMenuBots.bots.add(attachMenuBot.bot);
loadAttachMenuBots(false, true);
} }
public boolean botInAttachMenu(long id) { public boolean botInAttachMenu(long id) {

View file

@ -233,7 +233,6 @@ public class MessageObject {
public int lastLineWidth; public int lastLineWidth;
public int textWidth; public int textWidth;
public int textHeight; public int textHeight;
public int captionHeight;
public boolean hasRtl; public boolean hasRtl;
public float textXOffset; public float textXOffset;
@ -1647,6 +1646,18 @@ public class MessageObject {
rights.append('\n').append(n.edit_messages ? '+' : '-').append(' '); rights.append('\n').append(n.edit_messages ? '+' : '-').append(' ');
rights.append(LocaleController.getString("EventLogPromotedEditMessages", R.string.EventLogPromotedEditMessages)); rights.append(LocaleController.getString("EventLogPromotedEditMessages", R.string.EventLogPromotedEditMessages));
} }
if (o.post_stories != n.post_stories) {
rights.append('\n').append(n.post_stories ? '+' : '-').append(' ');
rights.append(LocaleController.getString("EventLogPromotedPostStories", R.string.EventLogPromotedPostStories));
}
if (o.edit_stories != n.edit_stories) {
rights.append('\n').append(n.edit_messages ? '+' : '-').append(' ');
rights.append(LocaleController.getString("EventLogPromotedEditStories", R.string.EventLogPromotedEditStories));
}
if (o.delete_stories != n.delete_stories) {
rights.append('\n').append(n.delete_stories ? '+' : '-').append(' ');
rights.append(LocaleController.getString("EventLogPromotedDeleteStories", R.string.EventLogPromotedDeleteStories));
}
} }
if (o.delete_messages != n.delete_messages) { if (o.delete_messages != n.delete_messages) {
rights.append('\n').append(n.delete_messages ? '+' : '-').append(' '); rights.append('\n').append(n.delete_messages ? '+' : '-').append(' ');
@ -4295,8 +4306,8 @@ public class MessageObject {
public static boolean canPreviewDocument(TLRPC.Document document) { public static boolean canPreviewDocument(TLRPC.Document document) {
if (document != null && document.mime_type != null) { if (document != null && document.mime_type != null) {
String mime = document.mime_type.toLowerCase(); String mime = document.mime_type;
if (isDocumentHasThumb(document) && (mime.equals("image/png") || mime.equals("image/jpg") || mime.equals("image/jpeg")) || (Build.VERSION.SDK_INT >= 26 && (mime.equals("image/heic")))) { if (isDocumentHasThumb(document) && (mime.equalsIgnoreCase("image/png") || mime.equalsIgnoreCase("image/jpg") || mime.equalsIgnoreCase("image/jpeg")) || (Build.VERSION.SDK_INT >= 26 && (mime.equalsIgnoreCase("image/heic")))) {
for (int a = 0; a < document.attributes.size(); a++) { for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a); TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeImageSize) { if (attribute instanceof TLRPC.TL_documentAttributeImageSize) {
@ -4872,28 +4883,6 @@ public class MessageObject {
caption = Emoji.replaceEmoji(text, Theme.chat_msgTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false); caption = Emoji.replaceEmoji(text, Theme.chat_msgTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
caption = replaceAnimatedEmoji(caption, entities, Theme.chat_msgTextPaint.getFontMetricsInt(), false); caption = replaceAnimatedEmoji(caption, entities, Theme.chat_msgTextPaint.getFontMetricsInt(), false);
int maxWidth = getMaxMessageTextWidth();
final float lineSpacing = 1f;
final float lineAdd = 0;
Layout.Alignment align = Layout.Alignment.ALIGN_NORMAL;
StaticLayout captionLayout = null;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(caption, 0, caption.length(), Theme.chat_msgTextPaint, maxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
captionLayout = builder.build();
} else {
captionLayout = new StaticLayout(caption, Theme.chat_msgTextPaint, maxWidth, align, lineSpacing, lineAdd, false);
}
} catch (Exception e) {
FileLog.e(e);
}
captionHeight = captionLayout == null ? 0 : captionLayout.getHeight();
boolean hasEntities; boolean hasEntities;
if (messageOwner.send_state != MESSAGE_SEND_STATE_SENT) { if (messageOwner.send_state != MESSAGE_SEND_STATE_SENT) {
hasEntities = false; hasEntities = false;
@ -6900,10 +6889,6 @@ public class MessageObject {
photoHeight = h; photoHeight = h;
} }
if (caption != null && !TextUtils.isEmpty(caption)) {
photoHeight += captionHeight;
}
return photoHeight + AndroidUtilities.dp(14); return photoHeight + AndroidUtilities.dp(14);
} }
} }
@ -8080,7 +8065,7 @@ public class MessageObject {
webpage.type = "telegram_story"; webpage.type = "telegram_story";
TLRPC.TL_webPageAttributeStory attr = new TLRPC.TL_webPageAttributeStory(); TLRPC.TL_webPageAttributeStory attr = new TLRPC.TL_webPageAttributeStory();
attr.id = messageOwner.media.id; attr.id = messageOwner.media.id;
attr.user_id = messageOwner.media.user_id; attr.peer = MessagesController.getInstance(currentAccount).getPeer(messageOwner.media.user_id);
if (messageOwner.media.storyItem != null) { if (messageOwner.media.storyItem != null) {
attr.flags |= 1; attr.flags |= 1;
attr.storyItem = messageOwner.media.storyItem; attr.storyItem = messageOwner.media.storyItem;

View file

@ -146,6 +146,7 @@ public class MessagesController extends BaseController implements NotificationCe
private boolean hasArchivedChats; private boolean hasArchivedChats;
private boolean hasStories; private boolean hasStories;
public long storiesChangelogUserId = 777000; public long storiesChangelogUserId = 777000;
private ChannelBoostsController channelBoostsControler;
public static TLRPC.Peer getPeerFromInputPeer(TLRPC.InputPeer peer) { public static TLRPC.Peer getPeerFromInputPeer(TLRPC.InputPeer peer) {
if (peer.chat_id != 0) { if (peer.chat_id != 0) {
@ -163,6 +164,19 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
public ChannelBoostsController getBoostsController() {
if (channelBoostsControler != null) {
return channelBoostsControler;
}
synchronized (lockObjects[currentAccount]) {
if (channelBoostsControler != null) {
return channelBoostsControler;
}
channelBoostsControler = new ChannelBoostsController(currentAccount);
}
return channelBoostsControler;
}
class ChatlistUpdatesStat { class ChatlistUpdatesStat {
public ChatlistUpdatesStat() { public ChatlistUpdatesStat() {
this.loading = true; this.loading = true;
@ -4708,6 +4722,9 @@ public class MessagesController extends BaseController implements NotificationCe
} else { } else {
oldChat.flags |= 16384; oldChat.flags |= 16384;
} }
if (!chat.stories_hidden_min) {
chat.stories_hidden = oldChat.stories_hidden;
}
if (oldFlags != newFlags || oldFlags2 != newFlags2) { if (oldFlags != newFlags || oldFlags2 != newFlags2) {
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.channelRightsUpdated, chat)); AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.channelRightsUpdated, chat));
} }
@ -14788,7 +14805,8 @@ public class MessagesController extends BaseController implements NotificationCe
updatesOnMainThread.add(baseUpdate); updatesOnMainThread.add(baseUpdate);
} else if (baseUpdate instanceof TLRPC.TL_updateReadStories) { } else if (baseUpdate instanceof TLRPC.TL_updateReadStories) {
TLRPC.TL_updateReadStories updateReadStories = (TLRPC.TL_updateReadStories) baseUpdate; TLRPC.TL_updateReadStories updateReadStories = (TLRPC.TL_updateReadStories) baseUpdate;
getStoriesController().markStoriesAsReadFromServer(updateReadStories.user_id, updateReadStories.max_id); long dialogId = DialogObject.getPeerDialogId(updateReadStories.peer);
getStoriesController().markStoriesAsReadFromServer(dialogId, updateReadStories.max_id);
} else if (baseUpdate instanceof TLRPC.TL_updatePeerSettings) { } else if (baseUpdate instanceof TLRPC.TL_updatePeerSettings) {
TLRPC.TL_updatePeerSettings update = (TLRPC.TL_updatePeerSettings) baseUpdate; TLRPC.TL_updatePeerSettings update = (TLRPC.TL_updatePeerSettings) baseUpdate;
if (contactsIds == null) { if (contactsIds == null) {
@ -16308,7 +16326,9 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} else if (baseUpdate instanceof TLRPC.TL_updateSentStoryReaction) { } else if (baseUpdate instanceof TLRPC.TL_updateSentStoryReaction) {
getStoriesController().updateStoryReaction(((TLRPC.TL_updateSentStoryReaction) baseUpdate).user_id, ((TLRPC.TL_updateSentStoryReaction) baseUpdate).story_id, ((TLRPC.TL_updateSentStoryReaction) baseUpdate).reaction); TLRPC.TL_updateSentStoryReaction updateReaction = (TLRPC.TL_updateSentStoryReaction) baseUpdate;
long dialogId = DialogObject.getPeerDialogId(updateReaction.peer);
getStoriesController().updateStoryReaction(dialogId, updateReaction.story_id, updateReaction.reaction);
} }
} }
if (editor != null) { if (editor != null) {

View file

@ -96,7 +96,7 @@ public class MessagesStorage extends BaseController {
} }
} }
public final static int LAST_DB_VERSION = 133; public final static int LAST_DB_VERSION = 134;
private boolean databaseMigrationInProgress; private boolean databaseMigrationInProgress;
public boolean showClearDatabaseAlert; public boolean showClearDatabaseAlert;
private LongSparseIntArray dialogIsForum = new LongSparseIntArray(); private LongSparseIntArray dialogIsForum = new LongSparseIntArray();
@ -619,7 +619,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE wallpapers2(uid INTEGER PRIMARY KEY, data BLOB, num INTEGER)").stepThis().dispose(); database.executeFast("CREATE TABLE wallpapers2(uid INTEGER PRIMARY KEY, data BLOB, num INTEGER)").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS wallpapers_num ON wallpapers2(num);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS wallpapers_num ON wallpapers2(num);").stepThis().dispose();
database.executeFast("CREATE TABLE unread_push_messages(uid INTEGER, mid INTEGER, random INTEGER, date INTEGER, data BLOB, fm TEXT, name TEXT, uname TEXT, flags INTEGER, PRIMARY KEY(uid, mid))").stepThis().dispose(); database.executeFast("CREATE TABLE unread_push_messages(uid INTEGER, mid INTEGER, random INTEGER, date INTEGER, data BLOB, fm TEXT, name TEXT, uname TEXT, flags INTEGER, topicId INTEGER, PRIMARY KEY(uid, mid))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS unread_push_messages_idx_date ON unread_push_messages(date);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS unread_push_messages_idx_date ON unread_push_messages(date);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS unread_push_messages_idx_random ON unread_push_messages(random);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS unread_push_messages_idx_random ON unread_push_messages(random);").stepThis().dispose();
@ -1273,7 +1273,7 @@ public class MessagesStorage extends BaseController {
flags |= 2; flags |= 2;
} }
SQLitePreparedStatement state = database.executeFast("REPLACE INTO unread_push_messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"); SQLitePreparedStatement state = database.executeFast("REPLACE INTO unread_push_messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
state.requery(); state.requery();
state.bindLong(1, message.getDialogId()); state.bindLong(1, message.getDialogId());
state.bindInteger(2, message.getId()); state.bindInteger(2, message.getId());
@ -1296,6 +1296,7 @@ public class MessagesStorage extends BaseController {
state.bindString(8, message.localUserName); state.bindString(8, message.localUserName);
} }
state.bindInteger(9, flags); state.bindInteger(9, flags);
state.bindInteger(10, MessageObject.getTopicId(message.messageOwner, false));
state.step(); state.step();
data.reuse(); data.reuse();
@ -3510,7 +3511,7 @@ public class MessagesStorage extends BaseController {
cursor = null; cursor = null;
database.executeFast("DELETE FROM unread_push_messages WHERE date <= " + maxDate).stepThis().dispose(); database.executeFast("DELETE FROM unread_push_messages WHERE date <= " + maxDate).stepThis().dispose();
cursor = database.queryFinalized("SELECT data, mid, date, uid, random, fm, name, uname, flags FROM unread_push_messages WHERE 1 ORDER BY date DESC LIMIT 50"); cursor = database.queryFinalized("SELECT data, mid, date, uid, random, fm, name, uname, flags, topicId FROM unread_push_messages WHERE 1 ORDER BY date DESC LIMIT 50");
while (cursor.next()) { while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0); NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) { if (data != null) {
@ -3524,6 +3525,7 @@ public class MessagesStorage extends BaseController {
String name = cursor.isNull(6) ? null : cursor.stringValue(6); String name = cursor.isNull(6) ? null : cursor.stringValue(6);
String userName = cursor.isNull(7) ? null : cursor.stringValue(7); String userName = cursor.isNull(7) ? null : cursor.stringValue(7);
int flags = cursor.intValue(8); int flags = cursor.intValue(8);
int topicId = cursor.intValue(9);
if (MessageObject.getFromChatId(message) == 0) { if (MessageObject.getFromChatId(message) == 0) {
if (DialogObject.isUserDialog(message.dialog_id)) { if (DialogObject.isUserDialog(message.dialog_id)) {
message.from_id = new TLRPC.TL_peerUser(); message.from_id = new TLRPC.TL_peerUser();
@ -3539,6 +3541,11 @@ public class MessagesStorage extends BaseController {
chatsToLoad.add(-message.dialog_id); chatsToLoad.add(-message.dialog_id);
} }
} }
if (topicId != 0) {
message.reply_to = new TLRPC.TL_messageReplyHeader();
message.reply_to.forum_topic = true;
message.reply_to.reply_to_top_id = topicId;
}
pushMessages.add(new MessageObject(currentAccount, message, messageText, name, userName, (flags & 1) != 0, (flags & 2) != 0, (message.flags & 0x80000000) != 0, false)); pushMessages.add(new MessageObject(currentAccount, message, messageText, name, userName, (flags & 1) != 0, (flags & 2) != 0, (message.flags & 0x80000000) != 0, false));
addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad, null); addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad, null);
@ -14230,6 +14237,15 @@ public class MessagesStorage extends BaseController {
} }
} }
} }
if (message.media.peer != null) {
long dialogId = DialogObject.getPeerDialogId(message.media.peer);
if (dialogId > 0) {
usersToLoad.add(dialogId);
}
if (dialogId < 0) {
chatsToLoad.add(-dialogId);
}
}
} }
if (message.replies != null) { if (message.replies != null) {
for (int a = 0, N = message.replies.recent_repliers.size(); a < N; a++) { for (int a = 0, N = message.replies.recent_repliers.size(); a < N; a++) {

View file

@ -3692,6 +3692,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.TL_messageMediaStory mediaStory = new MessageMediaStoryFull(); TLRPC.TL_messageMediaStory mediaStory = new MessageMediaStoryFull();
mediaStory.id = sendingStory.id; mediaStory.id = sendingStory.id;
mediaStory.user_id = sendingStory.dialogId; mediaStory.user_id = sendingStory.dialogId;
mediaStory.peer = getMessagesController().getPeer(sendingStory.dialogId);
mediaStory.storyItem = sendingStory; mediaStory.storyItem = sendingStory;
newMsg.media = mediaStory; newMsg.media = mediaStory;
type = MEDIA_TYPE_STORY; type = MEDIA_TYPE_STORY;
@ -4278,7 +4279,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
} else if (type == MEDIA_TYPE_STORY) { } else if (type == MEDIA_TYPE_STORY) {
TLRPC.TL_inputMediaStory inputMediaStory = new TLRPC.TL_inputMediaStory(); TLRPC.TL_inputMediaStory inputMediaStory = new TLRPC.TL_inputMediaStory();
inputMediaStory.id = sendingStory.id; inputMediaStory.id = sendingStory.id;
inputMediaStory.user_id = MessagesController.getInstance(currentAccount).getInputUser(sendingStory.dialogId); inputMediaStory.peer = MessagesController.getInstance(currentAccount).getInputPeer(sendingStory.dialogId);
inputMedia = inputMediaStory; inputMedia = inputMediaStory;
} }

View file

@ -234,6 +234,9 @@ public class SharedConfig {
public static int searchMessagesAsListHintShows; public static int searchMessagesAsListHintShows;
public static int textSelectionHintShows; public static int textSelectionHintShows;
public static int scheduledOrNoSoundHintShows; public static int scheduledOrNoSoundHintShows;
public static long scheduledOrNoSoundHintSeenAt;
public static int scheduledHintShows;
public static long scheduledHintSeenAt;
public static int lockRecordAudioVideoHint; public static int lockRecordAudioVideoHint;
public static boolean forwardingOptionsHintShown; public static boolean forwardingOptionsHintShown;
public static boolean searchMessagesAsListUsed; public static boolean searchMessagesAsListUsed;
@ -430,6 +433,9 @@ public class SharedConfig {
editor.putBoolean("sortFilesByName", sortFilesByName); editor.putBoolean("sortFilesByName", sortFilesByName);
editor.putInt("textSelectionHintShows", textSelectionHintShows); editor.putInt("textSelectionHintShows", textSelectionHintShows);
editor.putInt("scheduledOrNoSoundHintShows", scheduledOrNoSoundHintShows); editor.putInt("scheduledOrNoSoundHintShows", scheduledOrNoSoundHintShows);
editor.putLong("scheduledOrNoSoundHintSeenAt", scheduledOrNoSoundHintSeenAt);
editor.putInt("scheduledHintShows", scheduledHintShows);
editor.putLong("scheduledHintSeenAt", scheduledHintSeenAt);
editor.putBoolean("forwardingOptionsHintShown", forwardingOptionsHintShown); editor.putBoolean("forwardingOptionsHintShown", forwardingOptionsHintShown);
editor.putInt("lockRecordAudioVideoHint", lockRecordAudioVideoHint); editor.putInt("lockRecordAudioVideoHint", lockRecordAudioVideoHint);
editor.putString("storageCacheDir", !TextUtils.isEmpty(storageCacheDir) ? storageCacheDir : ""); editor.putString("storageCacheDir", !TextUtils.isEmpty(storageCacheDir) ? storageCacheDir : "");
@ -605,6 +611,9 @@ public class SharedConfig {
storyReactionsLongPressHint = preferences.getBoolean("storyReactionsLongPressHint", false); storyReactionsLongPressHint = preferences.getBoolean("storyReactionsLongPressHint", false);
textSelectionHintShows = preferences.getInt("textSelectionHintShows", 0); textSelectionHintShows = preferences.getInt("textSelectionHintShows", 0);
scheduledOrNoSoundHintShows = preferences.getInt("scheduledOrNoSoundHintShows", 0); scheduledOrNoSoundHintShows = preferences.getInt("scheduledOrNoSoundHintShows", 0);
scheduledOrNoSoundHintSeenAt = preferences.getLong("scheduledOrNoSoundHintSeenAt", 0);
scheduledHintShows = preferences.getInt("scheduledHintShows", 0);
scheduledHintSeenAt = preferences.getLong("scheduledHintSeenAt", 0);
forwardingOptionsHintShown = preferences.getBoolean("forwardingOptionsHintShown", false); forwardingOptionsHintShown = preferences.getBoolean("forwardingOptionsHintShown", false);
lockRecordAudioVideoHint = preferences.getInt("lockRecordAudioVideoHint", 0); lockRecordAudioVideoHint = preferences.getInt("lockRecordAudioVideoHint", 0);
disableVoiceAudioEffects = preferences.getBoolean("disableVoiceAudioEffects", false); disableVoiceAudioEffects = preferences.getBoolean("disableVoiceAudioEffects", false);
@ -824,6 +833,9 @@ public class SharedConfig {
lastUpdateVersion = BuildVars.BUILD_VERSION_STRING; lastUpdateVersion = BuildVars.BUILD_VERSION_STRING;
textSelectionHintShows = 0; textSelectionHintShows = 0;
scheduledOrNoSoundHintShows = 0; scheduledOrNoSoundHintShows = 0;
scheduledOrNoSoundHintSeenAt = 0;
scheduledHintShows = 0;
scheduledHintSeenAt = 0;
lockRecordAudioVideoHint = 0; lockRecordAudioVideoHint = 0;
forwardingOptionsHintShown = false; forwardingOptionsHintShown = false;
messageSeenHintCount = 3; messageSeenHintCount = 3;
@ -887,10 +899,21 @@ public class SharedConfig {
editor.apply(); editor.apply();
} }
public static void increaseScheduledOrNoSuoundHintShowed() { public static void increaseScheduledOrNoSoundHintShowed() {
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit(); SharedPreferences.Editor editor = preferences.edit();
scheduledOrNoSoundHintSeenAt = System.currentTimeMillis();
editor.putInt("scheduledOrNoSoundHintShows", ++scheduledOrNoSoundHintShows); editor.putInt("scheduledOrNoSoundHintShows", ++scheduledOrNoSoundHintShows);
editor.putLong("scheduledOrNoSoundHintSeenAt", scheduledOrNoSoundHintSeenAt);
editor.apply();
}
public static void increaseScheduledHintShowed() {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
scheduledHintSeenAt = System.currentTimeMillis();
editor.putInt("scheduledHintShows", ++scheduledHintShows);
editor.putLong("scheduledHintSeenAt", scheduledHintSeenAt);
editor.apply(); editor.apply();
} }
@ -909,6 +932,13 @@ public class SharedConfig {
editor.apply(); editor.apply();
} }
public static void removeScheduledHint() {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("scheduledHintShows", 3);
editor.apply();
}
public static void increaseLockRecordAudioVideoHintShowed() { public static void increaseLockRecordAudioVideoHintShowed() {
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit(); SharedPreferences.Editor editor = preferences.edit();

View file

@ -284,19 +284,42 @@ public class VideoEditedInfo {
entity.rotation = rotation; entity.rotation = rotation;
entity.width = width; entity.width = width;
entity.height = height; entity.height = height;
entity.additionalHeight = additionalHeight;
entity.text = text; entity.text = text;
entity.entities.addAll(entities); if (entities != null) {
entity.entities = new ArrayList<>();
entity.entities.addAll(entities);
}
entity.color = color; entity.color = color;
entity.fontSize = fontSize; entity.fontSize = fontSize;
entity.textTypeface = textTypeface;
entity.textTypefaceKey = textTypefaceKey;
entity.textAlign = textAlign;
entity.viewWidth = viewWidth; entity.viewWidth = viewWidth;
entity.viewHeight = viewHeight; entity.viewHeight = viewHeight;
entity.roundRadius = roundRadius;
entity.scale = scale; entity.scale = scale;
entity.textViewWidth = textViewWidth; entity.textViewWidth = textViewWidth;
entity.textViewHeight = textViewHeight; entity.textViewHeight = textViewHeight;
entity.textViewX = textViewX; entity.textViewX = textViewX;
entity.textViewY = textViewY; entity.textViewY = textViewY;
entity.textAlign = textAlign; entity.document = document;
entity.textTypeface = textTypeface; entity.parentObject = parentObject;
entity.metadata = metadata;
entity.ptr = ptr;
entity.currentFrame = currentFrame;
entity.framesPerDraw = framesPerDraw;
entity.bitmap = bitmap;
entity.view = view;
entity.canvas = canvas;
entity.animatedFileDrawable = animatedFileDrawable;
entity.roundRadiusCanvas = roundRadiusCanvas;
entity.mediaArea = mediaArea;
entity.mediaGeo = mediaGeo;
entity.density = density;
entity.W = W;
entity.H = H;
entity.visibleReaction = visibleReaction;
return entity; return entity;
} }
} }

View file

@ -68,7 +68,9 @@ public class AudioBufferConverter {
} }
private void checkChannels(int inputChannelCount, int outputChannelCount){ private void checkChannels(int inputChannelCount, int outputChannelCount){
// Check channel count. if (inputChannelCount == 6 && outputChannelCount == 2) {
return;
}
if (inputChannelCount != 1 && inputChannelCount != 2) { if (inputChannelCount != 1 && inputChannelCount != 2) {
throw new UnsupportedOperationException("Input channel count (" + inputChannelCount + ") not supported."); throw new UnsupportedOperationException("Input channel count (" + inputChannelCount + ") not supported.");
} }

View file

@ -1,6 +1,7 @@
package org.telegram.messenger.video; package org.telegram.messenger.video;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.SurfaceTexture; import android.graphics.SurfaceTexture;
import android.net.Uri; import android.net.Uri;
@ -251,6 +252,15 @@ public class VideoPlayerHolderBase {
return; return;
} }
paused = true; paused = true;
prepareStub();
dispatchQueue.postRunnable(() -> {
if (videoPlayer != null) {
videoPlayer.pause();
}
});
}
public void prepareStub() {
if (surfaceView != null && firstFrameRendered && surfaceView.getHolder().getSurface().isValid()) { if (surfaceView != null && firstFrameRendered && surfaceView.getHolder().getSurface().isValid()) {
stubAvailable = true; stubAvailable = true;
if (playerStubBitmap == null) { if (playerStubBitmap == null) {
@ -259,13 +269,11 @@ public class VideoPlayerHolderBase {
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
AndroidUtilities.getBitmapFromSurface(surfaceView, playerStubBitmap); AndroidUtilities.getBitmapFromSurface(surfaceView, playerStubBitmap);
if (playerStubBitmap.getPixel(0, 0) == Color.TRANSPARENT) {
stubAvailable = false;
}
} }
} }
dispatchQueue.postRunnable(() -> {
if (videoPlayer != null) {
videoPlayer.pause();
}
});
} }
public void play() { public void play() {

View file

@ -9,7 +9,9 @@ public class DefaultAudioRemixer implements AudioRemixer {
@Override @Override
public void remix(@NonNull ShortBuffer inputBuffer, int inputChannelCount, @NonNull ShortBuffer outputBuffer, int outputChannelCount) { public void remix(@NonNull ShortBuffer inputBuffer, int inputChannelCount, @NonNull ShortBuffer outputBuffer, int outputChannelCount) {
AudioRemixer remixer; AudioRemixer remixer;
if (inputChannelCount > outputChannelCount) { if (inputChannelCount == 6 && outputChannelCount == 2) {
remixer = AudioRemixer.PASSTHROUGH;
} else if (inputChannelCount > outputChannelCount) {
remixer = DOWNMIX; remixer = DOWNMIX;
} else if (inputChannelCount < outputChannelCount) { } else if (inputChannelCount < outputChannelCount) {
remixer = AudioRemixer.UPMIX; remixer = AudioRemixer.UPMIX;
@ -22,7 +24,9 @@ public class DefaultAudioRemixer implements AudioRemixer {
@Override @Override
public int getRemixedSize(int inputSize, int inputChannelCount, int outputChannelCount) { public int getRemixedSize(int inputSize, int inputChannelCount, int outputChannelCount) {
AudioRemixer remixer; AudioRemixer remixer;
if (inputChannelCount > outputChannelCount) { if (inputChannelCount == 6 && outputChannelCount == 2) {
remixer = AudioRemixer.PASSTHROUGH;
} else if (inputChannelCount > outputChannelCount) {
remixer = DOWNMIX; remixer = DOWNMIX;
} else if (inputChannelCount < outputChannelCount) { } else if (inputChannelCount < outputChannelCount) {
remixer = AudioRemixer.UPMIX; remixer = AudioRemixer.UPMIX;

View file

@ -14,31 +14,12 @@ public class DownMixAudioRemixer implements AudioRemixer {
@Override @Override
public void remix(@NonNull ShortBuffer inputBuffer, int inputChannelCount, @NonNull ShortBuffer outputBuffer, int outputChannelCount) { public void remix(@NonNull ShortBuffer inputBuffer, int inputChannelCount, @NonNull ShortBuffer outputBuffer, int outputChannelCount) {
// Down-mix stereo to mono
// Viktor Toth's algorithm -
// See: http://www.vttoth.com/CMS/index.php/technical-notes/68
// http://stackoverflow.com/a/25102339
final int inRemaining = inputBuffer.remaining() / 2; final int inRemaining = inputBuffer.remaining() / 2;
final int outSpace = outputBuffer.remaining(); final int outSpace = outputBuffer.remaining();
final int samplesToBeProcessed = Math.min(inRemaining, outSpace); final int samplesToBeProcessed = Math.min(inRemaining, outSpace);
for (int i = 0; i < samplesToBeProcessed; ++i) { for (int i = 0; i < samplesToBeProcessed; ++i) {
// Convert to unsigned outputBuffer.put(mix(inputBuffer.get(), inputBuffer.get()));
final int a = inputBuffer.get() + SIGNED_SHORT_LIMIT;
final int b = inputBuffer.get() + SIGNED_SHORT_LIMIT;
int m;
// Pick the equation
if ((a < SIGNED_SHORT_LIMIT) || (b < SIGNED_SHORT_LIMIT)) {
// Viktor's first equation when both sources are "quiet"
// (i.e. less than middle of the dynamic range)
m = a * b / SIGNED_SHORT_LIMIT;
} else {
// Viktor's second equation when one or both sources are loud
m = 2 * (a + b) - (a * b) / SIGNED_SHORT_LIMIT - UNSIGNED_SHORT_MAX;
}
// Convert output back to signed short
if (m == UNSIGNED_SHORT_MAX + 1) m = UNSIGNED_SHORT_MAX;
outputBuffer.put((short) (m - SIGNED_SHORT_LIMIT));
} }
} }
@ -46,4 +27,28 @@ public class DownMixAudioRemixer implements AudioRemixer {
public int getRemixedSize(int inputSize, int inputChannelCount, int outputChannelCount) { public int getRemixedSize(int inputSize, int inputChannelCount, int outputChannelCount) {
return inputSize / 2; return inputSize / 2;
} }
private short mix(short input1, short input2) {
// Down-mix stereo to mono
// Viktor Toth's algorithm -
// See: http://www.vttoth.com/CMS/index.php/technical-notes/68
// http://stackoverflow.com/a/25102339
// Convert to unsigned
final int a = input1 + SIGNED_SHORT_LIMIT;
final int b = input2 + SIGNED_SHORT_LIMIT;
int m;
// Pick the equation
if ((a < SIGNED_SHORT_LIMIT) || (b < SIGNED_SHORT_LIMIT)) {
// Viktor's first equation when both sources are "quiet"
// (i.e. less than middle of the dynamic range)
m = a * b / SIGNED_SHORT_LIMIT;
} else {
// Viktor's second equation when one or both sources are loud
m = 2 * (a + b) - (a * b) / SIGNED_SHORT_LIMIT - UNSIGNED_SHORT_MAX;
}
// Convert output back to signed short
if (m == UNSIGNED_SHORT_MAX + 1) m = UNSIGNED_SHORT_MAX;
return (short) (m - SIGNED_SHORT_LIMIT);
}
} }

View file

@ -12,7 +12,9 @@ public class DefaultAudioResampler implements AudioResampler {
@Override @Override
public void resample(@NonNull ShortBuffer inputBuffer, int inputSampleRate, @NonNull ShortBuffer outputBuffer, int outputSampleRate, int channels) { public void resample(@NonNull ShortBuffer inputBuffer, int inputSampleRate, @NonNull ShortBuffer outputBuffer, int outputSampleRate, int channels) {
if (inputSampleRate < outputSampleRate) { if (inputSampleRate == 6 && outputSampleRate == 2) {
PASSTHROUGH.resample(inputBuffer, inputSampleRate, outputBuffer, outputSampleRate, channels);
} else if (inputSampleRate < outputSampleRate) {
UPSAMPLE.resample(inputBuffer, inputSampleRate, outputBuffer, outputSampleRate, channels); UPSAMPLE.resample(inputBuffer, inputSampleRate, outputBuffer, outputSampleRate, channels);
} else if (inputSampleRate > outputSampleRate) { } else if (inputSampleRate > outputSampleRate) {
DOWNSAMPLE.resample(inputBuffer, inputSampleRate, outputBuffer, outputSampleRate, channels); DOWNSAMPLE.resample(inputBuffer, inputSampleRate, outputBuffer, outputSampleRate, channels);

File diff suppressed because it is too large Load diff

View file

@ -69,6 +69,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
public boolean highlightActionButtons = false; public boolean highlightActionButtons = false;
private boolean attached; private boolean attached;
private boolean isSheet;
@Override @Override
public void setHighlightActionButtons(boolean highlightActionButtons) { public void setHighlightActionButtons(boolean highlightActionButtons) {
@ -440,6 +441,16 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
} }
} }
@Override
public void setIsSheet(boolean isSheet) {
this.isSheet = isSheet;
}
@Override
public boolean isSheet() {
return isSheet;
}
@Override @Override
public void onConfigurationChanged(android.content.res.Configuration newConfig) { public void onConfigurationChanged(android.content.res.Configuration newConfig) {
super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig);
@ -1213,7 +1224,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
return false; return false;
} }
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("present fragment " + fragment.getClass().getSimpleName()); FileLog.d("present fragment " + fragment.getClass().getSimpleName() + " args=" + fragment.getArguments());
} }
StoryViewer.closeGlobalInstances(); StoryViewer.closeGlobalInstances();
if (inPreviewMode && transitionAnimationPreviewMode) { if (inPreviewMode && transitionAnimationPreviewMode) {

View file

@ -393,6 +393,7 @@ public abstract class BaseFragment {
actionBar.onResume(); actionBar.onResume();
} }
if (storyViewer != null) { if (storyViewer != null) {
storyViewer.onResume();
storyViewer.updatePlayingMode(); storyViewer.updatePlayingMode();
} }
if (overlayStoryViewer != null) { if (overlayStoryViewer != null) {
@ -814,11 +815,13 @@ public abstract class BaseFragment {
} }
BottomSheet[] bottomSheet = new BottomSheet[1]; BottomSheet[] bottomSheet = new BottomSheet[1];
INavigationLayout[] actionBarLayout = new INavigationLayout[]{INavigationLayout.newLayout(getParentActivity(), () -> bottomSheet[0])}; INavigationLayout[] actionBarLayout = new INavigationLayout[]{INavigationLayout.newLayout(getParentActivity(), () -> bottomSheet[0])};
LaunchActivity.instance.sheetFragmentsStack.add(actionBarLayout[0]);
bottomSheet[0] = new BottomSheet(getParentActivity(), true, fragment.getResourceProvider()) { bottomSheet[0] = new BottomSheet(getParentActivity(), true, fragment.getResourceProvider()) {
{ {
drawNavigationBar = true; drawNavigationBar = true;
actionBarLayout[0].setFragmentStack(new ArrayList<>()); actionBarLayout[0].setFragmentStack(new ArrayList<>());
actionBarLayout[0].addFragmentToStack(fragment); actionBarLayout[0].addFragmentToStack(fragment);
actionBarLayout[0].setIsSheet(true);
actionBarLayout[0].showLastFragment(); actionBarLayout[0].showLastFragment();
actionBarLayout[0].getView().setPadding(backgroundPaddingLeft, 0, backgroundPaddingLeft, 0); actionBarLayout[0].getView().setPadding(backgroundPaddingLeft, 0, backgroundPaddingLeft, 0);
containerView = actionBarLayout[0].getView(); containerView = actionBarLayout[0].getView();
@ -836,6 +839,7 @@ public abstract class BaseFragment {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
fixNavigationBar(Theme.getColor(Theme.key_dialogBackgroundGray, fragment.getResourceProvider())); fixNavigationBar(Theme.getColor(Theme.key_dialogBackgroundGray, fragment.getResourceProvider()));
AndroidUtilities.setLightStatusBar(getWindow(), fragment.isLightStatusBar());
} }
@Override @Override
@ -860,6 +864,7 @@ public abstract class BaseFragment {
} }
} }
super.dismiss(); super.dismiss();
LaunchActivity.instance.sheetFragmentsStack.remove(actionBarLayout[0]);
actionBarLayout[0] = null; actionBarLayout[0] = null;
} }
@ -1052,6 +1057,9 @@ public abstract class BaseFragment {
public StoryViewer getOrCreateStoryViewer() { public StoryViewer getOrCreateStoryViewer() {
if (storyViewer == null) { if (storyViewer == null) {
storyViewer = new StoryViewer(this); storyViewer = new StoryViewer(this);
if (parentLayout.isSheet()) {
storyViewer.fromBottomSheet = true;
}
} }
return storyViewer; return storyViewer;
} }

View file

@ -277,6 +277,10 @@ public interface INavigationLayout {
return null; return null;
} }
void setIsSheet(boolean isSheet);
boolean isSheet();
interface INavigationLayoutDelegate { interface INavigationLayoutDelegate {
default boolean needPresentFragment(INavigationLayout layout, NavigationParams params) { default boolean needPresentFragment(INavigationLayout layout, NavigationParams params) {
return needPresentFragment(params.fragment, params.removeLast, params.noAnimation, layout); return needPresentFragment(params.fragment, params.removeLast, params.noAnimation, layout);

View file

@ -68,7 +68,7 @@ public class ContactsAdapter extends RecyclerListView.SectionsAdapter {
private boolean hasGps; private boolean hasGps;
private boolean isEmpty; private boolean isEmpty;
public boolean hasStories; public boolean hasStories;
public ArrayList<TLRPC.TL_userStories> userStories = new ArrayList<>(); public ArrayList<TLRPC.PeerStories> userStories = new ArrayList<>();
DialogStoriesCell dialogStoriesCell; DialogStoriesCell dialogStoriesCell;
BaseFragment fragment; BaseFragment fragment;
@ -84,7 +84,7 @@ public class ContactsAdapter extends RecyclerListView.SectionsAdapter {
this.fragment = fragment; this.fragment = fragment;
} }
public void setStories(ArrayList<TLRPC.TL_userStories> stories, boolean animated) { public void setStories(ArrayList<TLRPC.PeerStories> stories, boolean animated) {
// boolean hasStories = !stories.isEmpty(); // boolean hasStories = !stories.isEmpty();
// userStories.clear(); // userStories.clear();
// userStories.addAll(stories); // userStories.addAll(stories);
@ -194,7 +194,7 @@ public class ContactsAdapter extends RecyclerListView.SectionsAdapter {
if (position == userStories.size()) { if (position == userStories.size()) {
return "Header"; return "Header";
} else { } else {
return userStories.get(position).user_id; return DialogObject.getPeerDialogId(userStories.get(position).peer);
} }
} else if (hasStories && section > 1) { } else if (hasStories && section > 1) {
section--; section--;
@ -517,7 +517,7 @@ public class ContactsAdapter extends RecyclerListView.SectionsAdapter {
userCell.setAvatarPadding(6); userCell.setAvatarPadding(6);
userCell.storyParams.drawSegments = true; userCell.storyParams.drawSegments = true;
StoriesController storiesController = MessagesController.getInstance(currentAccount).getStoriesController(); StoriesController storiesController = MessagesController.getInstance(currentAccount).getStoriesController();
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(userStories.get(position).user_id); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(DialogObject.getPeerDialogId(userStories.get(position).peer));
if (storiesController.hasUnreadStories(user.id)) { if (storiesController.hasUnreadStories(user.id)) {
int newStories = storiesController.getUnreadStoriesCount(user.id); int newStories = storiesController.getUnreadStoriesCount(user.id);
userCell.setData(user, ContactsController.formatName(user), LocaleController.formatPluralString("NewStories", newStories, newStories).toLowerCase(), 0); userCell.setData(user, ContactsController.formatName(user), LocaleController.formatPluralString("NewStories", newStories, newStories).toLowerCase(), 0);
@ -703,7 +703,7 @@ public class ContactsAdapter extends RecyclerListView.SectionsAdapter {
public void removeStory(long dialogId) { public void removeStory(long dialogId) {
for (int i = 0; i < userStories.size(); i++) { for (int i = 0; i < userStories.size(); i++) {
if (userStories.get(i).user_id == dialogId) { if (DialogObject.getPeerDialogId(userStories.get(i).peer) == dialogId) {
userStories.remove(i); userStories.remove(i);
if (userStories.isEmpty()) { if (userStories.isEmpty()) {

View file

@ -1100,11 +1100,12 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
if (storiesController.getHiddenList().isEmpty()) { if (storiesController.getHiddenList().isEmpty()) {
return; return;
} }
boolean unreadOnly = storiesController.getUnreadState(storiesController.getHiddenList().get(0).user_id) != StoriesController.STATE_READ; boolean unreadOnly = storiesController.getUnreadState(DialogObject.getPeerDialogId(storiesController.getHiddenList().get(0).peer)) != StoriesController.STATE_READ;
ArrayList<Long> peerIds = new ArrayList<>(); ArrayList<Long> peerIds = new ArrayList<>();
for (int i = 0; i < storiesController.getHiddenList().size(); i++) { for (int i = 0; i < storiesController.getHiddenList().size(); i++) {
if (!unreadOnly || storiesController.getUnreadState(storiesController.getHiddenList().get(i).user_id) != StoriesController.STATE_READ) { long dialogId = DialogObject.getPeerDialogId(storiesController.getHiddenList().get(i).peer);
peerIds.add(storiesController.getHiddenList().get(i).user_id); if (!unreadOnly || storiesController.getUnreadState(dialogId) != StoriesController.STATE_READ) {
peerIds.add(dialogId);
} }
} }
@ -1323,6 +1324,10 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
height -= AndroidUtilities.statusBarHeight; height -= AndroidUtilities.statusBarHeight;
if (parentFragment.hasStories && !collapsedView && !isTransitionSupport) { if (parentFragment.hasStories && !collapsedView && !isTransitionSupport) {
height -= ActionBar.getCurrentActionBarHeight(); height -= ActionBar.getCurrentActionBarHeight();
if (getParent() instanceof DialogsActivity.DialogsRecyclerView) {
DialogsActivity.DialogsRecyclerView dialogsRecyclerView = (DialogsActivity.DialogsRecyclerView) getParent();
height -= dialogsRecyclerView.additionalPadding;
}
} else if (collapsedView) { } else if (collapsedView) {
height -= paddingTop; height -= paddingTop;
} }
@ -1333,6 +1338,10 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
height -= AndroidUtilities.statusBarHeight; height -= AndroidUtilities.statusBarHeight;
if (parentFragment.hasStories && !collapsedView && !isTransitionSupport) { if (parentFragment.hasStories && !collapsedView && !isTransitionSupport) {
height -= ActionBar.getCurrentActionBarHeight(); height -= ActionBar.getCurrentActionBarHeight();
if (getParent() instanceof DialogsActivity.DialogsRecyclerView) {
DialogsActivity.DialogsRecyclerView dialogsRecyclerView = (DialogsActivity.DialogsRecyclerView) getParent();
height -= dialogsRecyclerView.additionalPadding;
}
} else if (collapsedView) { } else if (collapsedView) {
height -= paddingTop; height -= paddingTop;
} }

View file

@ -319,7 +319,6 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
} }
showDivider = true; showDivider = true;
} }
boolean needDivider = false;
if (MessagesController.getInstance(UserConfig.selectedAccount).storiesEnabled()) { if (MessagesController.getInstance(UserConfig.selectedAccount).storiesEnabled()) {
items.add(new Item(16, LocaleController.getString("ProfileMyStories", R.string.ProfileMyStories), R.drawable.msg_menu_stories)); items.add(new Item(16, LocaleController.getString("ProfileMyStories", R.string.ProfileMyStories), R.drawable.msg_menu_stories));
showDivider = true; showDivider = true;

View file

@ -420,6 +420,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this); DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
previousWidth = 0; previousWidth = 0;
imageReceiver.setAutoRepeatCount(0); imageReceiver.setAutoRepeatCount(0);
imageReceiver.clearDecorators();
if (messageObject.isStoryMention()) { if (messageObject.isStoryMention()) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(messageObject.messageOwner.media.user_id); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(messageObject.messageOwner.media.user_id);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(user);

View file

@ -4317,6 +4317,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoImage.setCrossfadeDuration(ImageReceiver.DEFAULT_CROSSFADE_DURATION); photoImage.setCrossfadeDuration(ImageReceiver.DEFAULT_CROSSFADE_DURATION);
photoImage.setCrossfadeByScale(0); photoImage.setCrossfadeByScale(0);
photoImage.setGradientBitmap(null); photoImage.setGradientBitmap(null);
photoImage.clearDecorators();
lastTranslated = messageObject.translated; lastTranslated = messageObject.translated;
lastSendState = messageObject.messageOwner.send_state; lastSendState = messageObject.messageOwner.send_state;
lastDeleteDate = messageObject.messageOwner.destroyTime; lastDeleteDate = messageObject.messageOwner.destroyTime;
@ -4688,7 +4689,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
TLRPC.StoryItem storyItem = null; TLRPC.StoryItem storyItem = null;
TLRPC.ThemeSettings androidThemeSettings = null; TLRPC.ThemeSettings androidThemeSettings = null;
if (!drawInstantView) { if (!drawInstantView) {
if ("telegram_livestream".equals(webpageType)) { if ("telegram_channel_boost".equals(webpageType)) {
drawInstantView = true;
drawInstantViewType = 18;
} else if ("telegram_livestream".equals(webpageType)) {
drawInstantView = true; drawInstantView = true;
drawInstantViewType = 11; drawInstantViewType = 11;
} else if ("telegram_voicechat".equals(webpageType)) { } else if ("telegram_voicechat".equals(webpageType)) {
@ -4751,7 +4755,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
storyItem = attribute.storyItem; storyItem = attribute.storyItem;
if (storyItem != null) { if (storyItem != null) {
storyItem.messageId = messageObject.getId(); storyItem.messageId = messageObject.getId();
storyItem.dialogId = attribute.user_id; storyItem.dialogId = DialogObject.getPeerDialogId(attribute.peer);
if (storyItem instanceof TLRPC.TL_storyItemDeleted) { if (storyItem instanceof TLRPC.TL_storyItemDeleted) {
drawInstantView = false; drawInstantView = false;
hasLinkPreview = false; hasLinkPreview = false;
@ -4977,8 +4981,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
"article".equals(type) || "telegram_bot".equals(type) || "article".equals(type) || "telegram_bot".equals(type) ||
"telegram_user".equals(type) || "telegram_channel".equals(type) || "telegram_user".equals(type) || "telegram_channel".equals(type) ||
"telegram_megagroup".equals(type) || "telegram_voicechat".equals(type) || "telegram_megagroup".equals(type) || "telegram_voicechat".equals(type) ||
"telegram_livestream".equals(type); "telegram_livestream".equals(type) || "telegram_channel_boost".equals(type);
smallImage = !slideshow && (!drawInstantView || drawInstantViewType == 1 || drawInstantViewType == 2 || drawInstantViewType == 9 || drawInstantViewType == 11 || drawInstantViewType == 13) && document == null && isSmallImageType; smallImage = !slideshow && (!drawInstantView || drawInstantViewType == 1 || drawInstantViewType == 2 || drawInstantViewType == 9 || drawInstantViewType == 11 || drawInstantViewType == 13 || drawInstantViewType == 18) && document == null && isSmallImageType;
isSmallImage = smallImage && type != null && currentMessageObject.photoThumbs != null; isSmallImage = smallImage && type != null && currentMessageObject.photoThumbs != null;
} else if (hasInvoicePreview) { } else if (hasInvoicePreview) {
TLRPC.TL_messageMediaInvoice invoice = (TLRPC.TL_messageMediaInvoice) MessageObject.getMedia(messageObject.messageOwner); TLRPC.TL_messageMediaInvoice invoice = (TLRPC.TL_messageMediaInvoice) MessageObject.getMedia(messageObject.messageOwner);
@ -5011,7 +5015,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
isSmallImage = false; isSmallImage = false;
smallImage = false; smallImage = false;
} }
if (drawInstantViewType == 11) { if (drawInstantViewType == 18) {
site_name = LocaleController.getString("BoostChannel", R.string.BoostChannel);
} else if (drawInstantViewType == 11) {
site_name = LocaleController.getString("VoipChannelVoiceChat", R.string.VoipChannelVoiceChat); site_name = LocaleController.getString("VoipChannelVoiceChat", R.string.VoipChannelVoiceChat);
} else if (drawInstantViewType == 9) { } else if (drawInstantViewType == 9) {
site_name = LocaleController.getString("VoipGroupVoiceChat", R.string.VoipGroupVoiceChat); site_name = LocaleController.getString("VoipGroupVoiceChat", R.string.VoipGroupVoiceChat);
@ -9060,6 +9066,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
str = LocaleController.getString("OpenLink").toUpperCase(); str = LocaleController.getString("OpenLink").toUpperCase();
} else if (drawInstantViewType == 17) { } else if (drawInstantViewType == 17) {
str = LocaleController.getString("ViewStory").toUpperCase(); str = LocaleController.getString("ViewStory").toUpperCase();
} else if (drawInstantViewType == 18) {
str = LocaleController.getString("BoostLinkButton", R.string.BoostLinkButton);
} else { } else {
str = LocaleController.getString("InstantView", R.string.InstantView); str = LocaleController.getString("InstantView", R.string.InstantView);
} }
@ -10610,7 +10618,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
linkPreviewY += currentMessageObject.textHeight + AndroidUtilities.dp(4); linkPreviewY += currentMessageObject.textHeight + AndroidUtilities.dp(4);
} }
if (drawPhotoImage && drawInstantView && drawInstantViewType != 9 && drawInstantViewType != 2 && drawInstantViewType != 13 && drawInstantViewType != 11 && drawInstantViewType != 1 || drawInstantViewType == 6 && imageBackgroundColor != 0) { if (drawPhotoImage && drawInstantView && drawInstantViewType != 9 && drawInstantViewType != 2 && drawInstantViewType != 13 && drawInstantViewType != 11 && drawInstantViewType != 1 && drawInstantViewType != 18 || drawInstantViewType == 6 && imageBackgroundColor != 0) {
if (linkPreviewY != startY) { if (linkPreviewY != startY) {
linkPreviewY += AndroidUtilities.dp(2); linkPreviewY += AndroidUtilities.dp(2);
} }
@ -10791,7 +10799,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
linkPreviewY += descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1); linkPreviewY += descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1);
} }
if (drawPhotoImage && (!drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 2 || drawInstantViewType == 11 || drawInstantViewType == 13 || drawInstantViewType == 1)) { if (drawPhotoImage && (!drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 2 || drawInstantViewType == 11 || drawInstantViewType == 13 || drawInstantViewType == 1 || drawInstantViewType == 18)) {
if (linkPreviewY != startY) { if (linkPreviewY != startY) {
linkPreviewY += AndroidUtilities.dp(2); linkPreviewY += AndroidUtilities.dp(2);
} }
@ -12897,7 +12905,17 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
CharSequence lastLine; CharSequence lastLine;
if (messageObject.type == MessageObject.TYPE_STORY) { if (messageObject.type == MessageObject.TYPE_STORY) {
currentForwardNameString = forwardedString = LocaleController.getString("ForwardedStory", R.string.ForwardedStory); currentForwardNameString = forwardedString = LocaleController.getString("ForwardedStory", R.string.ForwardedStory);
lastLine = AndroidUtilities.replaceTags(LocaleController.formatString("ForwardedStoryFrom", R.string.ForwardedStoryFrom, getNameFromDialogId(messageObject.messageOwner.media.user_id))); long storyDialogId = DialogObject.getPeerDialogId(messageObject.messageOwner.media.peer);
if (storyDialogId > 0) {
currentForwardUser = MessagesController.getInstance(currentAccount).getUser(storyDialogId);
} else {
currentForwardChannel = MessagesController.getInstance(currentAccount).getChat(-storyDialogId);
}
String name = getNameFromDialogId(storyDialogId);
if (storyDialogId < 0 && currentForwardChannel == null) {
name = LocaleController.getString("ChannelPrivate", R.string.ChannelPrivate);
}
lastLine = AndroidUtilities.replaceTags(LocaleController.formatString("ForwardedStoryFrom", R.string.ForwardedStoryFrom, name));
forwardedNameWidth = getMaxNameWidth(); forwardedNameWidth = getMaxNameWidth();
} else { } else {
if (currentForwardChannel != null) { if (currentForwardChannel != null) {
@ -15399,6 +15417,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
invalidate(); invalidate();
} }
public boolean isCheckBoxVisible() {
return checkBoxVisible || checkBoxAnimationInProgress;
}
public void setChecked(boolean checked, boolean allChecked, boolean animated) { public void setChecked(boolean checked, boolean allChecked, boolean animated) {
if (checkBox != null) { if (checkBox != null) {
checkBox.setChecked(allChecked, animated); checkBox.setChecked(allChecked, animated);

View file

@ -143,7 +143,7 @@ public class DrawerActionCell extends FrameLayout {
} else { } else {
textView.setText(bot.short_name); textView.setText(bot.short_name);
} }
TLRPC.TL_attachMenuBotIcon botIcon = MediaDataController.getSideMenuBotIcon(bot); TLRPC.TL_attachMenuBotIcon botIcon = MediaDataController.getSideAttachMenuBotIcon(bot);
if (botIcon != null) { if (botIcon != null) {
imageView.setImage(ImageLocation.getForDocument(botIcon.icon), "24_24", (Drawable) null, bot); imageView.setImage(ImageLocation.getForDocument(botIcon.icon), "24_24", (Drawable) null, bot);
} else { } else {

View file

@ -53,6 +53,7 @@ import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.spoilers.SpoilerEffect; import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.Components.spoilers.SpoilerEffect2; import org.telegram.ui.Components.spoilers.SpoilerEffect2;
import org.telegram.ui.PhotoViewer; import org.telegram.ui.PhotoViewer;
import org.telegram.ui.Stories.StoryWidgetsImageDecorator;
import org.telegram.ui.Stories.recorder.DominantColors; import org.telegram.ui.Stories.recorder.DominantColors;
public class SharedPhotoVideoCell2 extends FrameLayout { public class SharedPhotoVideoCell2 extends FrameLayout {
@ -192,6 +193,7 @@ public class SharedPhotoVideoCell2 extends FrameLayout {
videoText = null; videoText = null;
videoInfoLayot = null; videoInfoLayot = null;
showVideoLayout = false; showVideoLayout = false;
imageReceiver.clearDecorators();
if (!TextUtils.isEmpty(restrictionReason)) { if (!TextUtils.isEmpty(restrictionReason)) {
showImageStub = true; showImageStub = true;
} else if (messageObject.storyItem != null && messageObject.storyItem.media instanceof TLRPC.TL_messageMediaUnsupported) { } else if (messageObject.storyItem != null && messageObject.storyItem.media instanceof TLRPC.TL_messageMediaUnsupported) {
@ -270,6 +272,9 @@ public class SharedPhotoVideoCell2 extends FrameLayout {
if (imageReceiver.getBitmap() != null && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealed) { if (imageReceiver.getBitmap() != null && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealed) {
blurImageReceiver.setImageBitmap(Utilities.stackBlurBitmapMax(imageReceiver.getBitmap())); blurImageReceiver.setImageBitmap(Utilities.stackBlurBitmapMax(imageReceiver.getBitmap()));
} }
if (messageObject != null && messageObject.storyItem != null) {
imageReceiver.addDecorator(new StoryWidgetsImageDecorator(messageObject.storyItem));
}
invalidate(); invalidate();
} }

View file

@ -66,6 +66,8 @@ public class UnconfirmedAuthHintCell extends FrameLayout {
public UnconfirmedAuthHintCell(Context context) { public UnconfirmedAuthHintCell(Context context) {
super(context); super(context);
setClickable(true);
linearLayout = new LinearLayout(context); linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.setOrientation(LinearLayout.VERTICAL);

View file

@ -0,0 +1,383 @@
package org.telegram.ui;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.FixedHeightEmptyCell;
import org.telegram.ui.Cells.ManageChatTextCell;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.Cells.UserCell;
import org.telegram.ui.Charts.view_data.ChartHeaderView;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LinkActionView;
import org.telegram.ui.Components.ListView.AdapterWithDiffUtils;
import org.telegram.ui.Components.Premium.LimitPreviewView;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Stories.ChannelBoostUtilities;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Objects;
public class ChannelBoostLayout extends FrameLayout {
private final static int OVERVIEW_TYPE = 0;
private final static int HEADER_VIEW_TYPE = 1;
private final static int DIVIDER_VIEW_TYPE = 2;
private final static int LINK_VIEW_TYPE = 3;
private final static int BOOST_VIEW = 4;
private final static int USER_VIEW_TYPE = 5;
private final static int DIVIDER_TEXT_VIEW_TYPE = 6;
private final static int EMPTY_VIEW_8DP = 7;
private final static int NO_USERS_HINT = 8;
private final static int SHOW_MORE_VIEW_TYPE = 9;
private final long dialogId;
int currentAccount = UserConfig.selectedAccount;
BaseFragment fragment;
TLRPC.TL_stories_boostsStatus boostsStatus;
private final Theme.ResourcesProvider resourcesProvider;
ArrayList<TLRPC.TL_booster> boosters = new ArrayList<>();
boolean hasNext;
int nextRemaining;
ArrayList<ItemInternal> items = new ArrayList<>();
AdapterWithDiffUtils adapter = new AdapterWithDiffUtils() {
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
return items.get(holder.getAdapterPosition()).selectable;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case BOOST_VIEW:
LimitPreviewView limitPreviewView = new LimitPreviewView(getContext(), R.drawable.filled_limit_boost, 10, 0, resourcesProvider);
limitPreviewView.isStatistic = true;
view = limitPreviewView;
Drawable shadowDrawable = Theme.getThemedDrawable(getContext(), R.drawable.greydivider, Theme.getColor(Theme.key_windowBackgroundGrayShadow, resourcesProvider));
Drawable background = new ColorDrawable(Theme.getColor(Theme.key_windowBackgroundGray));
CombinedDrawable combinedDrawable = new CombinedDrawable(background, shadowDrawable, 0, 0);
combinedDrawable.setFullsize(true);
view.setPadding(0, dp(20), 0, AndroidUtilities.dp(20));
view.setBackground(combinedDrawable);
limitPreviewView.setBoosts(boostsStatus, false);
break;
case DIVIDER_TEXT_VIEW_TYPE:
view = new TextInfoPrivacyCell(parent.getContext(), 12, resourcesProvider);
shadowDrawable = Theme.getThemedDrawable(getContext(), R.drawable.greydivider, Theme.getColor(Theme.key_windowBackgroundGrayShadow, resourcesProvider));
background = new ColorDrawable(Theme.getColor(Theme.key_windowBackgroundGray));
combinedDrawable = new CombinedDrawable(background, shadowDrawable, 0, 0);
combinedDrawable.setFullsize(true);
view.setBackground(combinedDrawable);
break;
case DIVIDER_VIEW_TYPE:
view = new ShadowSectionCell(parent.getContext(), 12, Theme.getColor(Theme.key_windowBackgroundGray));
break;
case OVERVIEW_TYPE:
view = new StatisticActivity.OverviewCell(getContext());
break;
case HEADER_VIEW_TYPE:
view = new ChartHeaderView(getContext());
view.setPadding(view.getPaddingLeft(), AndroidUtilities.dp(16), view.getRight(), AndroidUtilities.dp(16));
break;
case LINK_VIEW_TYPE:
LinkActionView linkActionView = new LinkActionView(getContext(), fragment, null, 0, false, false);
view = linkActionView;
linkActionView.hideOptions();
linkActionView.setLink(ChannelBoostUtilities.createLink(currentAccount, dialogId));
view.setPadding(AndroidUtilities.dp(11), 0, AndroidUtilities.dp(11), AndroidUtilities.dp(24));
break;
case USER_VIEW_TYPE:
view = new UserCell(getContext(), 0, 0, false);
break;
case EMPTY_VIEW_8DP:
view = new FixedHeightEmptyCell(getContext(), 8);
break;
case NO_USERS_HINT:
FrameLayout frameLayout = new FrameLayout(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(50), MeasureSpec.EXACTLY));
}
};
TextView textView = new TextView(getContext());
textView.setText(LocaleController.getString("NoBoostersHint", R.string.NoBoostersHint));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
textView.setGravity(Gravity.CENTER);
frameLayout.addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 7, 0, 0));
view = frameLayout;
break;
case SHOW_MORE_VIEW_TYPE:
ManageChatTextCell actionCell = new ManageChatTextCell(getContext());
actionCell.setColors(Theme.key_windowBackgroundWhiteBlueIcon, Theme.key_windowBackgroundWhiteBlueButton);
// actionCell.setText(LocaleController.getString("ShowMore", R.string.ShowMore), null, R.drawable.arrow_more, false);
view = actionCell;
break;
default:
throw new UnsupportedOperationException();
}
view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
return new RecyclerListView.Holder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder.getItemViewType() == BOOST_VIEW) {
} else if (holder.getItemViewType() == HEADER_VIEW_TYPE) {
ChartHeaderView headerCell = (ChartHeaderView) holder.itemView;
headerCell.setTitle(items.get(position).title);
headerCell.showDate(false);
} else if (holder.getItemViewType() == OVERVIEW_TYPE) {
StatisticActivity.OverviewCell overviewCell = (StatisticActivity.OverviewCell) holder.itemView;
overviewCell.setData(0, Integer.toString(boostsStatus.level), null, LocaleController.getString("BoostsLevel2", R.string.BoostsLevel2));
if (boostsStatus.premium_audience != null || boostsStatus.premium_audience.total == 0) {
overviewCell.setData(1, "~" + (int) boostsStatus.premium_audience.part, String.format(Locale.US, "%.1f", (float) boostsStatus.premium_audience.part / (float) boostsStatus.premium_audience.total) + "%", LocaleController.getString("PremiumSubscribers", R.string.PremiumSubscribers));
} else {
overviewCell.setData(1, "~0", "0%", LocaleController.getString("PremiumSubscribers", R.string.PremiumSubscribers));
}
overviewCell.setData(2, String.valueOf(boostsStatus.boosts), null, LocaleController.getString("BoostsExisting", R.string.BoostsExisting));
overviewCell.setData(3, String.valueOf(boostsStatus.next_level_boosts - boostsStatus.boosts), null, LocaleController.getString("BoostsToLevel", R.string.BoostsToLevel));
} else if (holder.getItemViewType() == USER_VIEW_TYPE) {
TLRPC.TL_booster booster = items.get(position).booster;
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(booster.user_id);
UserCell userCell = (UserCell) holder.itemView;
String str = LocaleController.formatString("BoostExpireOn", R.string.BoostExpireOn, LocaleController.formatDate(booster.expires));
userCell.setData(user, ContactsController.formatName(user), str, 0);
} else if (holder.getItemViewType() == DIVIDER_TEXT_VIEW_TYPE) {
TextInfoPrivacyCell privacyCell = (TextInfoPrivacyCell) holder.itemView;
privacyCell.setText(items.get(position).title);
} else if (holder.getItemViewType() == SHOW_MORE_VIEW_TYPE) {
ManageChatTextCell actionCell = (ManageChatTextCell) holder.itemView;
actionCell.setText(LocaleController.formatPluralString("ShowVotes", nextRemaining), null, R.drawable.arrow_more, false);
}
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public int getItemViewType(int position) {
return items.get(position).viewType;
}
};
RecyclerListView listView;
boolean usersLoading;
private LinearLayout progressLayout;
public ChannelBoostLayout(BaseFragment fragment, long dialogId, Theme.ResourcesProvider resourcesProvider) {
super(fragment.getContext());
this.fragment = fragment;
Context context = fragment.getContext();
this.resourcesProvider = resourcesProvider;
this.dialogId = dialogId;
listView = new RecyclerListView(context);
listView.setLayoutManager(new LinearLayoutManager(context));
DefaultItemAnimator defaultItemAnimator = new DefaultItemAnimator();
defaultItemAnimator.setSupportsChangeAnimations(false);
defaultItemAnimator.setDelayAnimations(false);
listView.setItemAnimator(defaultItemAnimator);
listView.setOnItemClickListener((view, position) -> {
if (view instanceof UserCell) {
UserCell cell = (UserCell) view;
fragment.presentFragment(ProfileActivity.of(cell.getDialogId()));
}
if (items.get(position).viewType == SHOW_MORE_VIEW_TYPE) {
loadUsers();
}
});
addView(listView);
loadStatistic();
listView.setAdapter(adapter);
updateRows(false);
createEmptyView(getContext());
progressLayout.setAlpha(0);
progressLayout.animate().alpha(1f).setDuration(200).setStartDelay(500).start();
}
private void updateRows(boolean animated) {
ArrayList<ItemInternal> oldItems = new ArrayList<>(items);
items.clear();
if (boostsStatus != null) {
items.add(new ItemInternal(BOOST_VIEW, false));
items.add(new ItemInternal(HEADER_VIEW_TYPE, LocaleController.getString("StatisticOverview", R.string.StatisticOverview)));
items.add(new ItemInternal(OVERVIEW_TYPE, true));
items.add(new ItemInternal(DIVIDER_VIEW_TYPE, false));
items.add(new ItemInternal(HEADER_VIEW_TYPE, LocaleController.getString("Boosters", R.string.Boosters)));
if (boosters.isEmpty()) {
items.add(new ItemInternal(NO_USERS_HINT, false));
items.add(new ItemInternal(DIVIDER_VIEW_TYPE, false));
} else {
for (int i = 0; i < boosters.size(); i++) {
items.add(new ItemInternal(USER_VIEW_TYPE, boosters.get(i)));
}
if (hasNext) {
items.add(new ItemInternal(SHOW_MORE_VIEW_TYPE, false));
} else {
items.add(new ItemInternal(EMPTY_VIEW_8DP, false));
}
items.add(new ItemInternal(DIVIDER_TEXT_VIEW_TYPE, LocaleController.getString("BoostersInfoDescription", R.string.BoostersInfoDescription)));
}
items.add(new ItemInternal(HEADER_VIEW_TYPE, LocaleController.getString("LinkForBoosting", R.string.LinkForBoosting)));
items.add(new ItemInternal(LINK_VIEW_TYPE, false));
}
if (animated) {
adapter.setItems(oldItems, items);
} else {
adapter.notifyDataSetChanged();
}
}
private void loadStatistic() {
MessagesController.getInstance(currentAccount).getBoostsController().getBoostsStats(dialogId, tl_stories_boostsStatus -> AndroidUtilities.runOnUIThread(() -> {
boostsStatus = tl_stories_boostsStatus;
progressLayout.animate().cancel();
progressLayout.animate().alpha(0).setDuration(100).setStartDelay(0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
progressLayout.setVisibility(View.GONE);
}
});
updateRows(true);
loadUsers();
}));
}
private void loadUsers() {
if (usersLoading) {
return;
}
usersLoading = true;
TLRPC.TL_stories_getBoostersList listReq = new TLRPC.TL_stories_getBoostersList();
listReq.limit = 25;
listReq.offset = "";
listReq.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId);
ConnectionsManager.getInstance(currentAccount).sendRequest(listReq, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
usersLoading = false;
if (response != null) {
TLRPC.TL_stories_boostersList list = (TLRPC.TL_stories_boostersList) response;
boosters.addAll(list.boosters);
hasNext = !TextUtils.isEmpty(list.next_offset) && boosters.size() < list.count;
nextRemaining = list.count - boosters.size();
updateRows(true);
}
}), ConnectionsManager.RequestFlagFailOnServerErrors);
}
private class ItemInternal extends AdapterWithDiffUtils.Item {
String title;
TLRPC.TL_booster booster;
public ItemInternal(int viewType, String title) {
super(viewType, false);
this.title = title;
}
public ItemInternal(int viewType, TLRPC.TL_booster booster) {
super(viewType, false);
this.booster = booster;
}
public ItemInternal(int viewType, boolean selectable) {
super(viewType, selectable);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ItemInternal that = (ItemInternal) o;
if (booster != null && that.booster != null) {
return booster.user_id == that.booster.user_id;
} else {
return true;
}
}
@Override
public int hashCode() {
return Objects.hash(title, booster);
}
}
public void createEmptyView(Context context) {
progressLayout = new LinearLayout(context);
progressLayout.setOrientation(LinearLayout.VERTICAL);
RLottieImageView imageView = new RLottieImageView(context);
imageView.setAutoRepeat(true);
imageView.setAnimation(R.raw.statistic_preload, 120, 120);
imageView.playAnimation();
TextView loadingTitle = new TextView(context);
loadingTitle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
loadingTitle.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
loadingTitle.setTextColor(Theme.getColor(Theme.key_player_actionBarTitle));
loadingTitle.setTag(Theme.key_player_actionBarTitle);
loadingTitle.setText(LocaleController.getString("LoadingStats", R.string.LoadingStats));
loadingTitle.setGravity(Gravity.CENTER_HORIZONTAL);
TextView loadingSubtitle = new TextView(context);
loadingSubtitle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
loadingSubtitle.setTextColor(Theme.getColor(Theme.key_player_actionBarSubtitle));
loadingSubtitle.setTag(Theme.key_player_actionBarSubtitle);
loadingSubtitle.setText(LocaleController.getString("LoadingStatsDescription", R.string.LoadingStatsDescription));
loadingSubtitle.setGravity(Gravity.CENTER_HORIZONTAL);
progressLayout.addView(imageView, LayoutHelper.createLinear(120, 120, Gravity.CENTER_HORIZONTAL, 0, 0, 0, 20));
progressLayout.addView(loadingTitle, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 0, 0, 0, 10));
progressLayout.addView(loadingSubtitle, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL));
addView(progressLayout, LayoutHelper.createFrame(240, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 0, 0, 0, 30));
}
}

View file

@ -316,6 +316,7 @@ import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -469,6 +470,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private HintView mediaBanTooltip; private HintView mediaBanTooltip;
private HintView searchAsListHint; private HintView searchAsListHint;
private HintView scheduledOrNoSoundHint; private HintView scheduledOrNoSoundHint;
private boolean scheduledOrNoSoundHintShown;
private HintView scheduledHint;
private boolean scheduledHintShown;
private boolean searchAsListHintShown; private boolean searchAsListHintShown;
private HintView fwdRestrictedTopHint; private HintView fwdRestrictedTopHint;
private HintView fwdRestrictedBottomHint; private HintView fwdRestrictedBottomHint;
@ -1811,6 +1815,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
emojiAnimationsOverlay.cancelAllAnimations(); emojiAnimationsOverlay.cancelAllAnimations();
} }
ReactionsEffectOverlay.dismissAll(); ReactionsEffectOverlay.dismissAll();
if (TextUtils.isEmpty(text)) {
hideSendButtonHints();
AndroidUtilities.cancelRunOnUIThread(showScheduledHintRunnable);
} else if (!bigChange){
showScheduledHint();
}
} }
@Override @Override
@ -2007,6 +2017,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (scheduledOrNoSoundHint != null) { if (scheduledOrNoSoundHint != null) {
scheduledOrNoSoundHint.hide(); scheduledOrNoSoundHint.hide();
} }
if (scheduledHint != null) {
scheduledHint.hide();
}
} }
@Override @Override
@ -2077,16 +2090,38 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (anchor == null || chatActivityEnterView.getEditField() == null || chatActivityEnterView.getEditField().getText().length() < 5) { if (anchor == null || chatActivityEnterView.getEditField() == null || chatActivityEnterView.getEditField().getText().length() < 5) {
return; return;
} }
SharedConfig.increaseScheduledOrNoSuoundHintShowed(); SharedConfig.increaseScheduledOrNoSoundHintShowed();
if (scheduledOrNoSoundHint == null) { if (scheduledOrNoSoundHint == null) {
scheduledOrNoSoundHint = new HintView(getParentActivity(), 4, themeDelegate); scheduledOrNoSoundHint = new HintView(getParentActivity(), 4, themeDelegate);
scheduledOrNoSoundHint.setShowingDuration(5000); scheduledOrNoSoundHint.createCloseButton();
scheduledOrNoSoundHint.setAlpha(0); scheduledOrNoSoundHint.setAlpha(0);
scheduledOrNoSoundHint.setVisibility(View.INVISIBLE); scheduledOrNoSoundHint.setVisibility(View.INVISIBLE);
scheduledOrNoSoundHint.setText(LocaleController.getString("ScheduledOrNoSoundHint", R.string.ScheduledOrNoSoundHint)); scheduledOrNoSoundHint.setText(LocaleController.getString("ScheduledOrNoSoundHint", R.string.ScheduledOrNoSoundHint));
contentView.addView(scheduledOrNoSoundHint, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 10, 0, 10, 0)); contentView.addView(scheduledOrNoSoundHint, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 10, 0, 10, 0));
} }
scheduledOrNoSoundHint.showForView(anchor, true); scheduledOrNoSoundHint.showForView(anchor, true);
scheduledOrNoSoundHintShown = true;
};
private final Runnable showScheduledHintRunnable = () -> {
if (getParentActivity() == null || fragmentView == null || chatActivityEnterView == null) {
return;
}
View anchor = chatActivityEnterView.getSendButton();
if (anchor == null || chatActivityEnterView.getEditField() == null || chatActivityEnterView.getEditField().getText().length() == 0) {
return;
}
SharedConfig.increaseScheduledHintShowed();
if (scheduledHint == null) {
scheduledHint = new HintView(getParentActivity(), 4, themeDelegate);
scheduledHint.createCloseButton();
scheduledHint.setAlpha(0);
scheduledHint.setVisibility(View.INVISIBLE);
scheduledHint.setText(LocaleController.getString("ScheduledHint", R.string.ScheduledHint));
contentView.addView(scheduledHint, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 10, 0, 10, 0));
}
scheduledHint.showForView(anchor, true);
scheduledHintShown = true;
}; };
public ChatActivity(Bundle args) { public ChatActivity(Bundle args) {
@ -2825,6 +2860,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
selectedMessagesCanStarIds[a].clear(); selectedMessagesCanStarIds[a].clear();
} }
scheduledOrNoSoundHint = null; scheduledOrNoSoundHint = null;
scheduledHint = null;
infoTopView = null; infoTopView = null;
aspectRatioFrameLayout = null; aspectRatioFrameLayout = null;
videoTextureView = null; videoTextureView = null;
@ -4931,9 +4967,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
} }
float tx = cell.getSlidingOffsetX() + cell.getCheckBoxTranslation(); float tx = cell.getSlidingOffsetX() + cell.getCheckBoxTranslation();
int y = (int) ((replaceAnimation ? child.getTop() : child.getY()) + cell.getLayoutHeight() + cell.getTransitionParams().deltaBottom); int y = (int) ((replaceAnimation ? child.getTop() : child.getY()) + cell.getLayoutHeight() + cell.getTransitionParams().deltaBottom);
int maxY = chatListView.getMeasuredHeight() - chatListView.getPaddingBottom(); int maxY = chatListView.getMeasuredHeight() - chatListView.getPaddingBottom();
boolean canUpdateTx = cell.isCheckBoxVisible() && tx == 0;
if (cell.isPlayingRound() || cell.getTransitionParams().animatePlayingRound) { if (cell.isPlayingRound() || cell.getTransitionParams().animatePlayingRound) {
if (cell.getTransitionParams().animatePlayingRound) { if (cell.getTransitionParams().animatePlayingRound) {
float progressLocal = cell.getTransitionParams().animateChangeProgress; float progressLocal = cell.getTransitionParams().animateChangeProgress;
@ -5000,6 +5036,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
top = view.getTop(); top = view.getTop();
if (view instanceof ChatMessageCell) { if (view instanceof ChatMessageCell) {
cell = (ChatMessageCell) view; cell = (ChatMessageCell) view;
float newTx = cell.getSlidingOffsetX() + cell.getCheckBoxTranslation();
if (canUpdateTx && newTx > 0) {
tx = newTx;
}
if (!cell.drawPinnedTop()) { if (!cell.drawPinnedTop()) {
break; break;
} else { } else {
@ -5017,6 +5057,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
top = holder.itemView.getTop(); top = holder.itemView.getTop();
if (holder.itemView instanceof ChatMessageCell) { if (holder.itemView instanceof ChatMessageCell) {
cell = (ChatMessageCell) holder.itemView; cell = (ChatMessageCell) holder.itemView;
float newTx = cell.getSlidingOffsetX() + cell.getCheckBoxTranslation();
if (canUpdateTx && newTx > 0) {
tx = newTx;
}
if (!cell.drawPinnedTop()) { if (!cell.drawPinnedTop()) {
break; break;
} else { } else {
@ -9398,11 +9442,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
} }
private boolean approved;
public void processInlineBotWebView(TLRPC.TL_inlineBotWebView object) { public void processInlineBotWebView(TLRPC.TL_inlineBotWebView object) {
BotWebViewSheet webViewSheet = new BotWebViewSheet(getContext(), getResourceProvider()); final Runnable open = () -> {
webViewSheet.setParentActivity(getParentActivity()); BotWebViewSheet webViewSheet = new BotWebViewSheet(getContext(), getResourceProvider());
webViewSheet.requestWebView(currentAccount, currentUser != null ? currentUser.id : currentChat.id, mentionContainer.getAdapter().getFoundContextBot().id, object.text, object.url, BotWebViewSheet.TYPE_SIMPLE_WEB_VIEW_BUTTON, 0, false, BotWebViewSheet.FLAG_FROM_INLINE_SWITCH); webViewSheet.setParentActivity(getParentActivity());
webViewSheet.show(); webViewSheet.requestWebView(currentAccount, currentUser != null ? currentUser.id : currentChat.id, mentionContainer.getAdapter().getFoundContextBot().id, object.text, object.url, BotWebViewSheet.TYPE_SIMPLE_WEB_VIEW_BUTTON, 0, false, BotWebViewSheet.FLAG_FROM_INLINE_SWITCH);
webViewSheet.show();
};
if (approved) {
open.run();
} else {
WebAppDisclaimerAlert.show(getContext(), ignored -> {
approved = true;
open.run();
}, null);
}
} }
public void processInlineBotContextPM(TLRPC.TL_inlineBotSwitchPM object) { public void processInlineBotContextPM(TLRPC.TL_inlineBotSwitchPM object) {
@ -9850,6 +9905,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (scheduledOrNoSoundHint != null) { if (scheduledOrNoSoundHint != null) {
scheduledOrNoSoundHint.hide(); scheduledOrNoSoundHint.hide();
} }
if (scheduledHint != null) {
scheduledHint.hide();
}
} }
if (fwdRestrictedBottomHint != null) { if (fwdRestrictedBottomHint != null) {
fwdRestrictedBottomHint.hide(); fwdRestrictedBottomHint.hide();
@ -9874,6 +9932,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
} }
private void hideSendButtonHints() {
if (scheduledOrNoSoundHint != null) {
scheduledOrNoSoundHint.hide();
}
if (scheduledHint != null) {
scheduledHint.hide();
}
}
private void showSlowModeHint(View view, boolean show, CharSequence time) { private void showSlowModeHint(View view, boolean show, CharSequence time) {
if (getParentActivity() == null || fragmentView == null || !show && (slowModeHint == null || slowModeHint.getVisibility() != View.VISIBLE)) { if (getParentActivity() == null || fragmentView == null || !show && (slowModeHint == null || slowModeHint.getVisibility() != View.VISIBLE)) {
return; return;
@ -9923,9 +9990,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
searchAsListHint.showForView(searchCountText, true); searchAsListHint.showForView(searchCountText, true);
} }
private void showScheduledHint() {
boolean disableNoSound = (UserObject.isUserSelf(currentUser) || (chatInfo != null && chatInfo.slowmode_next_send_date > 0) && chatMode == 0);
if (scheduledHintShown || scheduledOrNoSoundHintShown || disableNoSound || SharedConfig.scheduledHintShows >= 3) {
return;
}
AndroidUtilities.cancelRunOnUIThread(showScheduledHintRunnable);
AndroidUtilities.runOnUIThread(showScheduledHintRunnable, 4000);
}
private void showScheduledOrNoSoundHint() { private void showScheduledOrNoSoundHint() {
boolean disableNoSound = (UserObject.isUserSelf(currentUser) || (chatInfo != null && chatInfo.slowmode_next_send_date > 0) && chatMode == 0); boolean disableNoSound = (UserObject.isUserSelf(currentUser) || (chatInfo != null && chatInfo.slowmode_next_send_date > 0) && chatMode == 0);
if (SharedConfig.scheduledOrNoSoundHintShows >= 3 || System.currentTimeMillis() % 4 != 0 || disableNoSound) { long scheduledOrNoSoundHintTimeFromLastSeen = System.currentTimeMillis() - SharedConfig.scheduledOrNoSoundHintSeenAt;
long scheduledHintTimeFromLastSeen = System.currentTimeMillis() - SharedConfig.scheduledHintSeenAt;
if (disableNoSound || SharedConfig.scheduledOrNoSoundHintShows >= 3 || scheduledOrNoSoundHintTimeFromLastSeen < 86400000L || scheduledHintTimeFromLastSeen < 86400000L) {
return; return;
} }
AndroidUtilities.cancelRunOnUIThread(showScheduledOrNoSoundRunnable); AndroidUtilities.cancelRunOnUIThread(showScheduledOrNoSoundRunnable);
@ -13072,6 +13150,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
updateTextureViewPosition(false, false); updateTextureViewPosition(false, false);
updatePagedownButtonsPosition(); updatePagedownButtonsPosition();
if (scheduledOrNoSoundHint != null && scheduledOrNoSoundHint.isShowing()) {
scheduledOrNoSoundHint.updatePosition();
}
if (scheduledHint != null && scheduledHint.isShowing()) {
scheduledHint.updatePosition();
}
int restoreToCount = -1; int restoreToCount = -1;
if (switchingFromTopics) { if (switchingFromTopics) {
restoreToCount = canvas.saveLayerAlpha(0, actionBar.getBottom(), getMeasuredWidth(), getMeasuredHeight(), (int) (255 * switchingFromTopicsProgress), Canvas.ALL_SAVE_FLAG); restoreToCount = canvas.saveLayerAlpha(0, actionBar.getBottom(), getMeasuredWidth(), getMeasuredHeight(), (int) (255 * switchingFromTopicsProgress), Canvas.ALL_SAVE_FLAG);
@ -14978,6 +15062,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
} }
@Override
public void onApplyCaption(CharSequence caption) {
chatActivityEnterView.setFieldText(caption, true);
}
@Override @Override
public boolean closeKeyboard() { public boolean closeKeyboard() {
if (chatActivityEnterView != null && isKeyboardVisible()) { if (chatActivityEnterView != null && isKeyboardVisible()) {
@ -29049,6 +29138,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
AndroidUtilities.showKeyboard(searchItem.getSearchField()); AndroidUtilities.showKeyboard(searchItem.getSearchField());
removeKeyboardPositionBeforeTransition(); removeKeyboardPositionBeforeTransition();
}, 500); }, 500);
hideSendButtonHints();
} }
@Override @Override
@ -29891,7 +29981,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (message.type == MessageObject.TYPE_STORY) { if (message.type == MessageObject.TYPE_STORY) {
if (message.messageOwner.media.storyItem != null && !(message.messageOwner.media.storyItem instanceof TLRPC.TL_storyItemDeleted)) { if (message.messageOwner.media.storyItem != null && !(message.messageOwner.media.storyItem instanceof TLRPC.TL_storyItemDeleted)) {
TLRPC.StoryItem storyItem = message.messageOwner.media.storyItem; TLRPC.StoryItem storyItem = message.messageOwner.media.storyItem;
storyItem.dialogId = message.messageOwner.media.user_id; storyItem.dialogId = DialogObject.getPeerDialogId(message.messageOwner.media.peer);
storyItem.messageId = message.getId(); storyItem.messageId = message.getId();
storyItem.messageType = 2; storyItem.messageType = 2;
StoriesUtilities.applyViewedUser(storyItem, currentUser); StoriesUtilities.applyViewedUser(storyItem, currentUser);
@ -30079,7 +30169,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (webPage.attributes.get(i) instanceof TLRPC.TL_webPageAttributeStory) { if (webPage.attributes.get(i) instanceof TLRPC.TL_webPageAttributeStory) {
TLRPC.TL_webPageAttributeStory story = (TLRPC.TL_webPageAttributeStory) webPage.attributes.get(i); TLRPC.TL_webPageAttributeStory story = (TLRPC.TL_webPageAttributeStory) webPage.attributes.get(i);
if (story.storyItem != null) { if (story.storyItem != null) {
story.storyItem.dialogId = story.user_id; story.storyItem.dialogId = DialogObject.getPeerDialogId(story.peer);
story.storyItem.messageId = messageObject.getId(); story.storyItem.messageId = messageObject.getId();
story.storyItem.messageType = 1; story.storyItem.messageType = 1;
getOrCreateStoryViewer().open(getContext(), story.storyItem, StoriesListPlaceProvider.of(chatListView)); getOrCreateStoryViewer().open(getContext(), story.storyItem, StoriesListPlaceProvider.of(chatListView));

View file

@ -140,6 +140,7 @@ public class ChatRightsEditActivity extends BaseFragment {
private int sendMessagesRow; private int sendMessagesRow;
private int sendMediaRow; private int sendMediaRow;
private boolean sendMediaExpanded;
private int sendPhotosRow; private int sendPhotosRow;
private int sendVideosRow; private int sendVideosRow;
private int sendMusicRow; private int sendMusicRow;
@ -153,6 +154,17 @@ public class ChatRightsEditActivity extends BaseFragment {
private int untilSectionRow; private int untilSectionRow;
private int untilDateRow; private int untilDateRow;
private int channelMessagesRow;
private boolean channelMessagesExpanded;
private int channelPostMessagesRow;
private int channelEditMessagesRow;
private int channelDeleteMessagesRow;
private int channelStoriesRow;
private boolean channelStoriesExpanded;
private int channelPostStoriesRow;
private int channelEditStoriesRow;
private int channelDeleteStoriesRow;
private ChatRightsEditActivityDelegate delegate; private ChatRightsEditActivityDelegate delegate;
private String botHash; private String botHash;
@ -164,7 +176,6 @@ public class ChatRightsEditActivity extends BaseFragment {
public static final int TYPE_ADD_BOT = 2; public static final int TYPE_ADD_BOT = 2;
private boolean closingKeyboardAfterFinish = false; private boolean closingKeyboardAfterFinish = false;
private boolean sendMediaExpanded;
public interface ChatRightsEditActivityDelegate { public interface ChatRightsEditActivityDelegate {
void didSetRights(int rights, TLRPC.TL_chatAdminRights rightsAdmin, TLRPC.TL_chatBannedRights rightsBanned, String rank); void didSetRights(int rights, TLRPC.TL_chatAdminRights rightsAdmin, TLRPC.TL_chatBannedRights rightsBanned, String rank);
@ -181,6 +192,7 @@ public class ChatRightsEditActivity extends BaseFragment {
currentUser = MessagesController.getInstance(currentAccount).getUser(userId); currentUser = MessagesController.getInstance(currentAccount).getUser(userId);
currentType = type; currentType = type;
canEdit = edit; canEdit = edit;
channelMessagesExpanded = channelStoriesExpanded = !canEdit;
botHash = addingNewBotHash; botHash = addingNewBotHash;
currentChat = MessagesController.getInstance(currentAccount).getChat(chatId); currentChat = MessagesController.getInstance(currentAccount).getChat(chatId);
if (rank == null) { if (rank == null) {
@ -214,6 +226,9 @@ public class ChatRightsEditActivity extends BaseFragment {
rightsAdmin.edit_messages = rightsAdmin.edit_messages || botDefaultRights.edit_messages; rightsAdmin.edit_messages = rightsAdmin.edit_messages || botDefaultRights.edit_messages;
rightsAdmin.manage_call = rightsAdmin.manage_call || botDefaultRights.manage_call; rightsAdmin.manage_call = rightsAdmin.manage_call || botDefaultRights.manage_call;
rightsAdmin.manage_topics = rightsAdmin.manage_topics || botDefaultRights.manage_topics; rightsAdmin.manage_topics = rightsAdmin.manage_topics || botDefaultRights.manage_topics;
rightsAdmin.post_stories = rightsAdmin.post_stories || botDefaultRights.post_stories;
rightsAdmin.edit_stories = rightsAdmin.edit_stories || botDefaultRights.edit_stories;
rightsAdmin.delete_stories = rightsAdmin.delete_stories || botDefaultRights.delete_stories;
rightsAdmin.other = rightsAdmin.other || botDefaultRights.other; rightsAdmin.other = rightsAdmin.other || botDefaultRights.other;
} }
} }
@ -237,6 +252,9 @@ public class ChatRightsEditActivity extends BaseFragment {
adminRights.invite_users = myAdminRights.invite_users; adminRights.invite_users = myAdminRights.invite_users;
adminRights.pin_messages = myAdminRights.pin_messages; adminRights.pin_messages = myAdminRights.pin_messages;
adminRights.manage_topics = myAdminRights.manage_topics; adminRights.manage_topics = myAdminRights.manage_topics;
adminRights.post_stories = myAdminRights.post_stories;
adminRights.edit_stories = myAdminRights.edit_stories;
adminRights.delete_stories = myAdminRights.delete_stories;
adminRights.other = myAdminRights.other; adminRights.other = myAdminRights.other;
initialIsSet = false; initialIsSet = false;
} }
@ -252,6 +270,9 @@ public class ChatRightsEditActivity extends BaseFragment {
adminRights.invite_users = rightsAdmin.invite_users; adminRights.invite_users = rightsAdmin.invite_users;
adminRights.pin_messages = rightsAdmin.pin_messages; adminRights.pin_messages = rightsAdmin.pin_messages;
adminRights.manage_topics = rightsAdmin.manage_topics; adminRights.manage_topics = rightsAdmin.manage_topics;
adminRights.post_stories = rightsAdmin.post_stories;
adminRights.edit_stories = rightsAdmin.edit_stories;
adminRights.delete_stories = rightsAdmin.delete_stories;
adminRights.add_admins = rightsAdmin.add_admins; adminRights.add_admins = rightsAdmin.add_admins;
adminRights.anonymous = rightsAdmin.anonymous; adminRights.anonymous = rightsAdmin.anonymous;
adminRights.other = rightsAdmin.other; adminRights.other = rightsAdmin.other;
@ -410,6 +431,9 @@ public class ChatRightsEditActivity extends BaseFragment {
adminRights.add_admins = a.add_admins || b.add_admins; adminRights.add_admins = a.add_admins || b.add_admins;
adminRights.manage_call = a.manage_call || b.manage_call; adminRights.manage_call = a.manage_call || b.manage_call;
adminRights.manage_topics = a.manage_topics || b.manage_topics; adminRights.manage_topics = a.manage_topics || b.manage_topics;
adminRights.post_stories = a.post_stories || b.post_stories;
adminRights.edit_stories = a.edit_stories || b.edit_stories;
adminRights.delete_stories = a.delete_stories || b.delete_stories;
return adminRights; return adminRights;
} }
@ -418,7 +442,8 @@ public class ChatRightsEditActivity extends BaseFragment {
TLRPC.TL_chatAdminRights adminRights = new TLRPC.TL_chatAdminRights(); TLRPC.TL_chatAdminRights adminRights = new TLRPC.TL_chatAdminRights();
adminRights.change_info = adminRights.post_messages = adminRights.edit_messages = adminRights.change_info = adminRights.post_messages = adminRights.edit_messages =
adminRights.delete_messages = adminRights.ban_users = adminRights.invite_users = adminRights.delete_messages = adminRights.ban_users = adminRights.invite_users =
adminRights.pin_messages = adminRights.add_admins = adminRights.manage_call = adminRights.manage_topics = value; adminRights.pin_messages = adminRights.add_admins = adminRights.manage_call = adminRights.manage_topics =
adminRights.post_stories = adminRights.edit_stories = adminRights.delete_stories = value;
return adminRights; return adminRights;
} }
@ -527,15 +552,6 @@ public class ChatRightsEditActivity extends BaseFragment {
return; return;
} }
if (position == sendMediaRow) { if (position == sendMediaRow) {
// if (allDefaultMediaBanned()) {
// new AlertDialog.Builder(getParentActivity())
// .setTitle(LocaleController.getString("UserRestrictionsCantModify", R.string.UserRestrictionsCantModify))
// .setMessage(LocaleController.getString("UserRestrictionsCantModifyEnabled", R.string.UserRestrictionsCantModifyEnabled))
// .setPositiveButton(LocaleController.getString("OK", R.string.OK), null)
// .create()
// .show();
// return;
// }
sendMediaExpanded = !sendMediaExpanded; sendMediaExpanded = !sendMediaExpanded;
updateRows(false); updateRows(false);
if (sendMediaExpanded) { if (sendMediaExpanded) {
@ -544,6 +560,26 @@ public class ChatRightsEditActivity extends BaseFragment {
listViewAdapter.notifyItemRangeRemoved(sendMediaRow + 1, 9); listViewAdapter.notifyItemRangeRemoved(sendMediaRow + 1, 9);
} }
return; return;
} else if (position == channelMessagesRow) {
channelMessagesExpanded = !channelMessagesExpanded;
updateRows(false);
listViewAdapter.notifyItemChanged(channelMessagesRow);
if (channelMessagesExpanded) {
listViewAdapter.notifyItemRangeInserted(channelMessagesRow + 1, 3);
} else {
listViewAdapter.notifyItemRangeRemoved(channelMessagesRow + 1, 3);
}
return;
} else if (position == channelStoriesRow) {
channelStoriesExpanded = !channelStoriesExpanded;
updateRows(false);
listViewAdapter.notifyItemChanged(channelStoriesRow);
if (channelStoriesExpanded) {
listViewAdapter.notifyItemRangeInserted(channelStoriesRow + 1, 3);
} else {
listViewAdapter.notifyItemRangeRemoved(channelStoriesRow + 1, 3);
}
return;
} }
if (position == 0) { if (position == 0) {
Bundle args = new Bundle(); Bundle args = new Bundle();
@ -714,7 +750,29 @@ public class ChatRightsEditActivity extends BaseFragment {
showDialog(builder.create()); showDialog(builder.create());
} else if (view instanceof CheckBoxCell) { } else if (view instanceof CheckBoxCell) {
CheckBoxCell checkBoxCell = (CheckBoxCell) view; CheckBoxCell checkBoxCell = (CheckBoxCell) view;
if (currentType == TYPE_BANNED && bannedRights != null) { if (position == channelPostMessagesRow || position == channelEditMessagesRow || position == channelDeleteMessagesRow) {
boolean value;
if (position == channelPostMessagesRow) {
value = adminRights.post_messages = !adminRights.post_messages;
} else if (position == channelEditMessagesRow) {
value = adminRights.edit_messages = !adminRights.edit_messages;
} else {
value = adminRights.delete_messages = !adminRights.delete_messages;
}
listViewAdapter.notifyItemChanged(channelMessagesRow);
checkBoxCell.setChecked(value, true);
} else if (position == channelPostStoriesRow || position == channelEditStoriesRow || position == channelDeleteStoriesRow) {
boolean value;
if (position == channelPostStoriesRow) {
value = adminRights.post_stories = !adminRights.post_stories;
} else if (position == channelEditStoriesRow) {
value = adminRights.edit_stories = !adminRights.edit_stories;
} else {
value = adminRights.delete_stories = !adminRights.delete_stories;
}
listViewAdapter.notifyItemChanged(channelStoriesRow);
checkBoxCell.setChecked(value, true);
} else if (currentType == TYPE_BANNED && bannedRights != null) {
boolean disabled = !checkBoxCell.isChecked(); boolean disabled = !checkBoxCell.isChecked();
boolean value = false; boolean value = false;
@ -875,7 +933,7 @@ public class ChatRightsEditActivity extends BaseFragment {
private boolean hasAllAdminRights() { private boolean hasAllAdminRights() {
if (isChannel) { if (isChannel) {
return adminRights.change_info && adminRights.post_messages && adminRights.edit_messages && adminRights.delete_messages && adminRights.invite_users && adminRights.add_admins && adminRights.manage_call; return adminRights.change_info && adminRights.post_messages && adminRights.edit_messages && adminRights.delete_messages && adminRights.invite_users && adminRights.add_admins && adminRights.manage_call && adminRights.post_stories && adminRights.edit_stories && adminRights.delete_stories;
} else { } else {
return adminRights.change_info && adminRights.delete_messages && adminRights.ban_users && adminRights.invite_users && adminRights.pin_messages && adminRights.add_admins && adminRights.manage_call && (!isForum || adminRights.manage_topics); return adminRights.change_info && adminRights.delete_messages && adminRights.ban_users && adminRights.invite_users && adminRights.pin_messages && adminRights.add_admins && adminRights.manage_call && (!isForum || adminRights.manage_topics);
} }
@ -1020,7 +1078,7 @@ public class ChatRightsEditActivity extends BaseFragment {
}), ConnectionsManager.RequestFlagWithoutLogin); }), ConnectionsManager.RequestFlagWithoutLogin);
} else if (error.text.equals("CHANNELS_TOO_MUCH")) { } else if (error.text.equals("CHANNELS_TOO_MUCH")) {
if (getParentActivity() != null && !AccountInstance.getInstance(currentAccount).getUserConfig().isPremium()) { if (getParentActivity() != null && !AccountInstance.getInstance(currentAccount).getUserConfig().isPremium()) {
showDialog(new LimitReachedBottomSheet(this, getParentActivity(), LimitReachedBottomSheet.TYPE_TO0_MANY_COMMUNITIES, currentAccount, getResourceProvider())); showDialog(new LimitReachedBottomSheet(this, getParentActivity(), LimitReachedBottomSheet.TYPE_TO0_MANY_COMMUNITIES, currentAccount, null));
} else { } else {
presentFragment(new TooManyCommunitiesActivity(TooManyCommunitiesActivity.TYPE_EDIT)); presentFragment(new TooManyCommunitiesActivity(TooManyCommunitiesActivity.TYPE_EDIT));
} }
@ -1068,6 +1126,15 @@ public class ChatRightsEditActivity extends BaseFragment {
sendMessagesRow = -1; sendMessagesRow = -1;
sendMediaRow = -1; sendMediaRow = -1;
channelMessagesRow = -1;
channelPostMessagesRow = -1;
channelEditMessagesRow = -1;
channelDeleteMessagesRow = -1;
channelStoriesRow = -1;
channelPostStoriesRow = -1;
channelEditStoriesRow = -1;
channelDeleteStoriesRow = -1;
sendPhotosRow = -1; sendPhotosRow = -1;
sendVideosRow = -1; sendVideosRow = -1;
sendMusicRow = -1; sendMusicRow = -1;
@ -1088,9 +1155,18 @@ public class ChatRightsEditActivity extends BaseFragment {
if (currentType == TYPE_ADMIN || currentType == TYPE_ADD_BOT) { if (currentType == TYPE_ADMIN || currentType == TYPE_ADD_BOT) {
if (isChannel) { if (isChannel) {
changeInfoRow = rowCount++; changeInfoRow = rowCount++;
postMessagesRow = rowCount++; channelMessagesRow = rowCount++;
editMesagesRow = rowCount++; if (channelMessagesExpanded) {
deleteMessagesRow = rowCount++; channelPostMessagesRow = rowCount++;
channelEditMessagesRow = rowCount++;
channelDeleteMessagesRow = rowCount++;
}
channelStoriesRow = rowCount++;
if (channelStoriesExpanded) {
channelPostStoriesRow = rowCount++;
channelEditStoriesRow = rowCount++;
channelDeleteStoriesRow = rowCount++;
}
addUsersRow = rowCount++; addUsersRow = rowCount++;
startVoiceChatRow = rowCount++; startVoiceChatRow = rowCount++;
addAdminsRow = rowCount++; addAdminsRow = rowCount++;
@ -1224,7 +1300,7 @@ public class ChatRightsEditActivity extends BaseFragment {
} }
if (!adminRights.change_info && !adminRights.post_messages && !adminRights.edit_messages && if (!adminRights.change_info && !adminRights.post_messages && !adminRights.edit_messages &&
!adminRights.delete_messages && !adminRights.ban_users && !adminRights.invite_users && (!isForum || !adminRights.manage_topics) && !adminRights.delete_messages && !adminRights.ban_users && !adminRights.invite_users && (!isForum || !adminRights.manage_topics) &&
!adminRights.pin_messages && !adminRights.add_admins && !adminRights.anonymous && !adminRights.manage_call) { !adminRights.pin_messages && !adminRights.add_admins && !adminRights.anonymous && !adminRights.manage_call && (!isChannel || !adminRights.post_stories && !adminRights.edit_stories && !adminRights.delete_stories)) {
adminRights.other = true; adminRights.other = true;
} else { } else {
adminRights.other = false; adminRights.other = false;
@ -1240,6 +1316,7 @@ public class ChatRightsEditActivity extends BaseFragment {
adminRights.change_info || adminRights.post_messages || adminRights.edit_messages || adminRights.change_info || adminRights.post_messages || adminRights.edit_messages ||
adminRights.delete_messages || adminRights.ban_users || adminRights.invite_users || (isForum && adminRights.manage_topics) || adminRights.delete_messages || adminRights.ban_users || adminRights.invite_users || (isForum && adminRights.manage_topics) ||
adminRights.pin_messages || adminRights.add_admins || adminRights.anonymous || adminRights.manage_call || adminRights.pin_messages || adminRights.add_admins || adminRights.anonymous || adminRights.manage_call ||
isChannel && (adminRights.post_stories || adminRights.edit_stories || adminRights.delete_stories) ||
adminRights.other ? 1 : 0, adminRights, bannedRights, currentRank); adminRights.other ? 1 : 0, adminRights, bannedRights, currentRank);
finishFragment(); finishFragment();
} }
@ -1453,6 +1530,14 @@ public class ChatRightsEditActivity extends BaseFragment {
if (position == sendVoiceRow) return 33; if (position == sendVoiceRow) return 33;
if (position == sendRoundRow) return 34; if (position == sendRoundRow) return 34;
if (position == sendMediaRow) return 35; if (position == sendMediaRow) return 35;
if (position == channelMessagesRow) return 36;
if (position == channelPostMessagesRow) return 37;
if (position == channelEditMessagesRow) return 38;
if (position == channelDeleteMessagesRow) return 39;
if (position == channelStoriesRow) return 40;
if (position == channelPostStoriesRow) return 41;
if (position == channelEditStoriesRow) return 42;
if (position == channelDeleteStoriesRow) return 43;
return 0; return 0;
} else { } else {
return super.getItemId(position); return super.getItemId(position);
@ -1498,6 +1583,12 @@ public class ChatRightsEditActivity extends BaseFragment {
return myAdminRights.pin_messages && (defaultBannedRights == null || defaultBannedRights.pin_messages); return myAdminRights.pin_messages && (defaultBannedRights == null || defaultBannedRights.pin_messages);
} else if (position == manageTopicsRow) { } else if (position == manageTopicsRow) {
return myAdminRights.manage_topics; return myAdminRights.manage_topics;
} else if (position == channelPostStoriesRow) {
return myAdminRights.post_stories;
} else if (position == channelEditStoriesRow) {
return myAdminRights.edit_stories;
} else if (position == channelDeleteStoriesRow) {
return myAdminRights.delete_stories;
} }
} }
} }
@ -1594,6 +1685,7 @@ public class ChatRightsEditActivity extends BaseFragment {
break; break;
case VIEW_TYPE_INNER_CHECK: case VIEW_TYPE_INNER_CHECK:
CheckBoxCell checkBoxCell = new CheckBoxCell(mContext, 4, 21, getResourceProvider()); CheckBoxCell checkBoxCell = new CheckBoxCell(mContext, 4, 21, getResourceProvider());
checkBoxCell.setPad(1);
checkBoxCell.getCheckBoxRound().setDrawBackgroundAsArc(14); checkBoxCell.getCheckBoxRound().setDrawBackgroundAsArc(14);
checkBoxCell.getCheckBoxRound().setColor(Theme.key_switch2TrackChecked, Theme.key_radioBackground, Theme.key_checkboxCheck); checkBoxCell.getCheckBoxRound().setColor(Theme.key_switch2TrackChecked, Theme.key_radioBackground, Theme.key_checkboxCheck);
checkBoxCell.setEnabled(true); checkBoxCell.setEnabled(true);
@ -1638,6 +1730,18 @@ public class ChatRightsEditActivity extends BaseFragment {
} else if (position == sendRoundRow) { } else if (position == sendRoundRow) {
checkBoxCell.setText(LocaleController.getString("SendMediaPermissionRound", R.string.SendMediaPermissionRound), "", !bannedRights.send_roundvideos && !defaultBannedRights.send_roundvideos, true, animated); checkBoxCell.setText(LocaleController.getString("SendMediaPermissionRound", R.string.SendMediaPermissionRound), "", !bannedRights.send_roundvideos && !defaultBannedRights.send_roundvideos, true, animated);
checkBoxCell.setIcon(defaultBannedRights.send_roundvideos ? R.drawable.permission_locked : 0); checkBoxCell.setIcon(defaultBannedRights.send_roundvideos ? R.drawable.permission_locked : 0);
} else if (position == channelPostMessagesRow) {
checkBoxCell.setText(LocaleController.getString(R.string.EditAdminPostMessages), "", adminRights.post_messages, true, animated);
} else if (position == channelEditMessagesRow) {
checkBoxCell.setText(LocaleController.getString(R.string.EditAdminEditMessages), "", adminRights.edit_messages, true, animated);
} else if (position == channelDeleteMessagesRow) {
checkBoxCell.setText(LocaleController.getString(R.string.EditAdminDeleteMessages), "", adminRights.delete_messages, true, animated);
} else if (position == channelPostStoriesRow) {
checkBoxCell.setText(LocaleController.getString(R.string.EditAdminPostStories), "", adminRights.post_stories, true, animated);
} else if (position == channelEditStoriesRow) {
checkBoxCell.setText(LocaleController.getString(R.string.EditAdminEditStories), "", adminRights.edit_stories, true, animated);
} else if (position == channelDeleteStoriesRow) {
checkBoxCell.setText(LocaleController.getString(R.string.EditAdminDeleteStories), "", adminRights.delete_stories, true, animated);
} }
break; break;
case VIEW_TYPE_USER_CELL: case VIEW_TYPE_USER_CELL:
@ -1719,6 +1823,22 @@ public class ChatRightsEditActivity extends BaseFragment {
setSendMediaEnabled(checked); setSendMediaEnabled(checked);
}); });
checkCell.setIcon(allDefaultMediaBanned() ? R.drawable.permission_locked : 0); checkCell.setIcon(allDefaultMediaBanned() ? R.drawable.permission_locked : 0);
} else if (position == channelMessagesRow) {
int count = getChannelMessagesSelectedCount();
checkCell.setTextAndCheck(LocaleController.getString(R.string.ChannelManageMessages), count > 0, true, true);
checkCell.setCollapseArrow(String.format(Locale.US, "%d/3", count), !channelMessagesExpanded, () -> {
boolean checked = checkCell.isChecked();
checkCell.setChecked(checked);
setChannelMessagesEnabled(checked);
});
} else if (position == channelStoriesRow) {
int count = getChannelStoriesSelectedCount();
checkCell.setTextAndCheck(LocaleController.getString(R.string.ChannelManageStories), count > 0, true, true);
checkCell.setCollapseArrow(String.format(Locale.US, "%d/3", count), !channelStoriesExpanded, () -> {
boolean checked = checkCell.isChecked();
checkCell.setChecked(checked);
setChannelStoriesEnabled(checked);
});
} else if (position == manageRow) { } else if (position == manageRow) {
checkCell.setTextAndCheck(LocaleController.getString("ManageGroup", R.string.ManageGroup), asAdmin, true); checkCell.setTextAndCheck(LocaleController.getString("ManageGroup", R.string.ManageGroup), asAdmin, true);
checkCell.setIcon(myAdminRights.add_admins || isCreator ? 0 : R.drawable.permission_locked); checkCell.setIcon(myAdminRights.add_admins || isCreator ? 0 : R.drawable.permission_locked);
@ -1890,7 +2010,7 @@ public class ChatRightsEditActivity extends BaseFragment {
public int getItemViewType(int position) { public int getItemViewType(int position) {
if (isExpandableSendMediaRow(position)) { if (isExpandableSendMediaRow(position)) {
return VIEW_TYPE_INNER_CHECK; return VIEW_TYPE_INNER_CHECK;
} else if (position == sendMediaRow) { } else if (position == sendMediaRow || position == channelMessagesRow || position == channelStoriesRow) {
return VIEW_TYPE_EXPANDABLE_SWITCH; return VIEW_TYPE_EXPANDABLE_SWITCH;
} else if (position == 0) { } else if (position == 0) {
return VIEW_TYPE_USER_CELL; return VIEW_TYPE_USER_CELL;
@ -1900,7 +2020,8 @@ public class ChatRightsEditActivity extends BaseFragment {
return VIEW_TYPE_HEADER_CELL; return VIEW_TYPE_HEADER_CELL;
} else if (position == changeInfoRow || position == postMessagesRow || position == editMesagesRow || position == deleteMessagesRow || } else if (position == changeInfoRow || position == postMessagesRow || position == editMesagesRow || position == deleteMessagesRow ||
position == addAdminsRow || position == banUsersRow || position == addUsersRow || position == pinMessagesRow || position == addAdminsRow || position == banUsersRow || position == addUsersRow || position == pinMessagesRow ||
position == sendMessagesRow || position == anonymousRow || position == startVoiceChatRow || position == manageRow || position == manageTopicsRow) { position == sendMessagesRow || position == anonymousRow || position == startVoiceChatRow || position == manageRow || position == manageTopicsRow
) {
return VIEW_TYPE_SWITCH_CELL; return VIEW_TYPE_SWITCH_CELL;
} else if (position == cantEditInfoRow || position == rankInfoRow) { } else if (position == cantEditInfoRow || position == rankInfoRow) {
return VIEW_TYPE_INFO_CELL; return VIEW_TYPE_INFO_CELL;
@ -1962,6 +2083,48 @@ public class ChatRightsEditActivity extends BaseFragment {
return i; return i;
} }
private int getChannelMessagesSelectedCount() {
int i = 0;
if (adminRights.post_messages) {
i++;
}
if (adminRights.edit_messages) {
i++;
}
if (adminRights.delete_messages) {
i++;
}
return i;
}
private void setChannelMessagesEnabled(boolean enabled) {
adminRights.post_messages = !enabled;
adminRights.edit_messages = !enabled;
adminRights.delete_messages = !enabled;
AndroidUtilities.updateVisibleRows(listView);
}
private int getChannelStoriesSelectedCount() {
int i = 0;
if (adminRights.post_stories) {
i++;
}
if (adminRights.edit_stories) {
i++;
}
if (adminRights.delete_stories) {
i++;
}
return i;
}
private void setChannelStoriesEnabled(boolean enabled) {
adminRights.post_stories = !enabled;
adminRights.edit_stories = !enabled;
adminRights.delete_stories = !enabled;
AndroidUtilities.updateVisibleRows(listView);
}
private boolean allDefaultMediaBanned() { private boolean allDefaultMediaBanned() {
return defaultBannedRights.send_photos && defaultBannedRights.send_videos && defaultBannedRights.send_stickers return defaultBannedRights.send_photos && defaultBannedRights.send_videos && defaultBannedRights.send_stickers
&& defaultBannedRights.send_audios && defaultBannedRights.send_docs && defaultBannedRights.send_voices && && defaultBannedRights.send_audios && defaultBannedRights.send_docs && defaultBannedRights.send_voices &&
@ -1970,8 +2133,10 @@ public class ChatRightsEditActivity extends BaseFragment {
private boolean isExpandableSendMediaRow(int position) { private boolean isExpandableSendMediaRow(int position) {
if (position == sendStickersRow || position == embedLinksRow || position == sendPollsRow || if (position == sendStickersRow || position == embedLinksRow || position == sendPollsRow ||
position == sendPhotosRow || position == sendVideosRow || position == sendFilesRow || position == sendPhotosRow || position == sendVideosRow || position == sendFilesRow ||
position == sendMusicRow || position == sendRoundRow || position == sendVoiceRow) { position == sendMusicRow || position == sendRoundRow || position == sendVoiceRow ||
position == channelPostMessagesRow || position == channelEditMessagesRow || position == channelDeleteMessagesRow ||
position == channelPostStoriesRow || position == channelEditStoriesRow || position == channelDeleteStoriesRow) {
return true; return true;
} }
return false; return false;

View file

@ -4183,7 +4183,7 @@ public class AlertsCreator {
} }
if (storyId != 0) { if (storyId != 0) {
TLRPC.TL_stories_report request = new TLRPC.TL_stories_report(); TLRPC.TL_stories_report request = new TLRPC.TL_stories_report();
request.user_id = MessagesController.getInstance(UserConfig.selectedAccount).getInputUser(peer.user_id); request.peer = MessagesController.getInstance(UserConfig.selectedAccount).getInputPeer(peer.user_id);
request.id.add(storyId); request.id.add(storyId);
request.message = message; request.message = message;
request.reason = reason; request.reason = reason;
@ -4341,7 +4341,7 @@ public class AlertsCreator {
if (storyId != 0) { if (storyId != 0) {
TLRPC.TL_stories_report request = new TLRPC.TL_stories_report(); TLRPC.TL_stories_report request = new TLRPC.TL_stories_report();
request.id.add(storyId); request.id.add(storyId);
request.user_id = MessagesController.getInstance(UserConfig.selectedAccount).getInputUser(dialog_id); request.peer = MessagesController.getInstance(UserConfig.selectedAccount).getInputPeer(dialog_id);
request.message = ""; request.message = "";
if (type == REPORT_TYPE_SPAM) { if (type == REPORT_TYPE_SPAM) {
request.reason = new TLRPC.TL_inputReportReasonSpam(); request.reason = new TLRPC.TL_inputReportReasonSpam();

View file

@ -662,28 +662,6 @@ public class AnimatedEmojiDrawable extends Drawable {
imageReceiver.draw(canvas); imageReceiver.draw(canvas);
} }
public void drawRaw(Canvas canvas, boolean nextFrame, int fps) {
if (imageReceiver == null) {
return;
}
if (imageReceiver.getLottieAnimation() != null) {
RLottieDrawable rlottie = imageReceiver.getLottieAnimation();
if (nextFrame) {
int inc = (int) Math.round((float) rlottie.getFramesCount() / (rlottie.getDuration() / 1000f) / 30f);
rlottie.currentFrame = (rlottie.currentFrame + inc) % rlottie.getFramesCount();
}
rlottie.setBounds(getBounds());
rlottie.drawFrame(canvas, rlottie.currentFrame);
} else if (imageReceiver.getAnimation() != null) {
AnimatedFileDrawable webp = imageReceiver.getAnimation();
webp.drawFrame(canvas, nextFrame ? fps / 30 : 0);
} else {
imageReceiver.setImageCoords(getBounds());
imageReceiver.setAlpha(alpha);
imageReceiver.draw(canvas);
}
}
public void draw(Canvas canvas, Rect drawableBounds, float alpha) { public void draw(Canvas canvas, Rect drawableBounds, float alpha) {
if (imageReceiver == null) { if (imageReceiver == null) {
return; return;

View file

@ -220,40 +220,6 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
} }
} }
public static void drawRawAnimatedEmojis(Canvas canvas, Layout layout, EmojiGroupedSpans stack, float offset, List<SpoilerEffect> spoilers, float boundTop, float boundBottom, float drawingYOffset, float alpha, int fps) {
if (canvas == null || layout == null || stack == null) {
return;
}
boolean needRestore = false;
if (Emoji.emojiDrawingYOffset != 0 || offset != 0) {
needRestore = true;
canvas.save();
canvas.translate(0, Emoji.emojiDrawingYOffset + AndroidUtilities.dp(20 * offset));
}
stack.rawIndex++;
for (int k = 0; k < stack.holders.size(); ++k) {
AnimatedEmojiHolder holder = stack.holders.get(k);
float halfSide = holder.span.measuredSize / 2f;
float cx, cy;
cx = holder.span.lastDrawnCx;
cy = holder.span.lastDrawnCy;
holder.drawableBounds.set((int) (cx - halfSide), (int) (cy - halfSide), (int) (cx + halfSide), (int) (cy + halfSide));
holder.drawable.setBounds(holder.drawableBounds);
boolean nextFrame = false;
if (holder.drawable.rawDrawIndex < stack.rawIndex) {
holder.drawable.rawDrawIndex = stack.rawIndex;
nextFrame = true;
}
holder.drawable.drawRaw(canvas, nextFrame, fps);
}
if (needRestore) {
canvas.restore();
}
}
private static boolean isInsideSpoiler(Layout layout, int start, int end) { private static boolean isInsideSpoiler(Layout layout, int start, int end) {
if (layout == null || !(layout.getText() instanceof Spanned)) { if (layout == null || !(layout.getText() instanceof Spanned)) {
return false; return false;

View file

@ -6,12 +6,10 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.util.TypedValue; import android.util.TypedValue;
@ -23,25 +21,21 @@ import android.widget.ImageView;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import androidx.core.content.FileProvider;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.browser.Browser; import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.voip.CellFlickerDrawable; import org.telegram.ui.Components.voip.CellFlickerDrawable;
import java.io.File;
import java.util.Locale; import java.util.Locale;
public class BlockingUpdateView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate { public class BlockingUpdateView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
@ -145,16 +139,22 @@ public class BlockingUpdateView extends FrameLayout implements NotificationCente
acceptButton.setPadding(AndroidUtilities.dp(34), 0, AndroidUtilities.dp(34), 0); acceptButton.setPadding(AndroidUtilities.dp(34), 0, AndroidUtilities.dp(34), 0);
addView(acceptButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 46, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 45)); addView(acceptButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 46, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 45));
acceptButton.setOnClickListener(view1 -> { acceptButton.setOnClickListener(view1 -> {
if (!checkApkInstallPermissions(getContext())) { if (BuildVars.isStandaloneApp() || BuildVars.DEBUG_VERSION) {
return; if (!ApplicationLoader.applicationLoaderInstance.checkApkInstallPermissions(getContext())) {
} return;
if (appUpdate.document instanceof TLRPC.TL_document) {
if (!openApkInstall((Activity) getContext(), appUpdate.document)) {
FileLoader.getInstance(accountNum).loadFile(appUpdate.document, "update", FileLoader.PRIORITY_HIGH, 1);
showProgress(true);
} }
} else if (appUpdate.url != null) { if (appUpdate.document instanceof TLRPC.TL_document) {
Browser.openUrl(getContext(), appUpdate.url); if (!ApplicationLoader.applicationLoaderInstance.openApkInstall((Activity) getContext(), appUpdate.document)) {
FileLoader.getInstance(accountNum).loadFile(appUpdate.document, "update", FileLoader.PRIORITY_HIGH, 1);
showProgress(true);
}
} else if (appUpdate.url != null) {
Browser.openUrl(getContext(), appUpdate.url);
}
} else if (BuildVars.isHuaweiStoreApp()){
Browser.openUrl(context, BuildVars.HUAWEI_STORE_URL);
} else {
Browser.openUrl(context, BuildVars.PLAYSTORE_APP_URL);
} }
}); });
@ -209,7 +209,7 @@ public class BlockingUpdateView extends FrameLayout implements NotificationCente
String location = (String) args[0]; String location = (String) args[0];
if (fileName != null && fileName.equals(location)) { if (fileName != null && fileName.equals(location)) {
showProgress(false); showProgress(false);
openApkInstall((Activity) getContext(), appUpdate.document); ApplicationLoader.applicationLoaderInstance.openApkInstall((Activity) getContext(), appUpdate.document);
} }
} else if (id == NotificationCenter.fileLoadFailed) { } else if (id == NotificationCenter.fileLoadFailed) {
String location = (String) args[0]; String location = (String) args[0];
@ -227,39 +227,7 @@ public class BlockingUpdateView extends FrameLayout implements NotificationCente
} }
} }
public static boolean checkApkInstallPermissions(final Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !ApplicationLoader.applicationContext.getPackageManager().canRequestPackageInstalls()) {
AlertsCreator.createApkRestrictedDialog(context, null).show();
return false;
}
return true;
}
public static boolean openApkInstall(Activity activity, TLRPC.Document document) {
boolean exists = false;
try {
String fileName = FileLoader.getAttachFileName(document);
File f = FileLoader.getInstance(UserConfig.selectedAccount).getPathToAttach(document, true);
if (exists = f.exists()) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (Build.VERSION.SDK_INT >= 24) {
intent.setDataAndType(FileProvider.getUriForFile(activity, ApplicationLoader.getApplicationId() + ".provider", f), "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package-archive");
}
try {
activity.startActivityForResult(intent, 500);
} catch (Exception e) {
FileLog.e(e);
}
}
} catch (Exception e) {
FileLog.e(e);
}
return exists;
}
private void showProgress(final boolean show) { private void showProgress(final boolean show) {
if (progressAnimation != null) { if (progressAnimation != null) {
@ -332,7 +300,7 @@ public class BlockingUpdateView extends FrameLayout implements NotificationCente
NotificationCenter.getInstance(accountNum).addObserver(this, NotificationCenter.fileLoaded); NotificationCenter.getInstance(accountNum).addObserver(this, NotificationCenter.fileLoaded);
NotificationCenter.getInstance(accountNum).addObserver(this, NotificationCenter.fileLoadFailed); NotificationCenter.getInstance(accountNum).addObserver(this, NotificationCenter.fileLoadFailed);
NotificationCenter.getInstance(accountNum).addObserver(this, NotificationCenter.fileLoadProgressChanged); NotificationCenter.getInstance(accountNum).addObserver(this, NotificationCenter.fileLoadProgressChanged);
if (check) { if (check && BuildVars.isStandaloneApp()) {
TLRPC.TL_help_getAppUpdate req = new TLRPC.TL_help_getAppUpdate(); TLRPC.TL_help_getAppUpdate req = new TLRPC.TL_help_getAppUpdate();
try { try {
req.source = ApplicationLoader.applicationContext.getPackageManager().getInstallerPackageName(ApplicationLoader.applicationContext.getPackageName()); req.source = ApplicationLoader.applicationContext.getPackageManager().getInstallerPackageName(ApplicationLoader.applicationContext.getPackageName());

View file

@ -931,14 +931,11 @@ public class BlurringShader {
return true; return true;
} }
public Drawable makeDrawable(float offsetX, float offsetY, Drawable base) { public Drawable makeDrawable(float offsetX, float offsetY, Drawable base, float r) {
return new Drawable() { return new Drawable() {
float alpha = 1f; float alpha = 1f;
private final Paint dimPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint dimPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
{
dimPaint.setColor(0x52000000);
}
@Nullable @Nullable
private Paint getPaint() { private Paint getPaint() {
@ -971,22 +968,47 @@ public class BlurringShader {
Rect bounds = getBounds(); Rect bounds = getBounds();
if (paint != null) { if (paint != null) {
canvas.saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, 0xFF, Canvas.ALL_SAVE_FLAG); if (base != null) {
canvas.saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, 0xFF, Canvas.ALL_SAVE_FLAG);
base.setBounds(bounds);
base.draw(canvas);
canvas.drawRect(bounds, paint);
canvas.restore();
getPadding(AndroidUtilities.rectTmp2);
AndroidUtilities.rectTmp.set(
bounds.left + AndroidUtilities.rectTmp2.left,
bounds.top + AndroidUtilities.rectTmp2.top,
bounds.right - AndroidUtilities.rectTmp2.right,
bounds.bottom - AndroidUtilities.rectTmp2.bottom
);
dimPaint.setColor(0x66000000);
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, dimPaint);
} else {
if (r > 0) {
AndroidUtilities.rectTmp.set(bounds);
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, paint);
} else {
canvas.drawRect(bounds, paint);
}
dimPaint.setColor(0x66000000);
if (r > 0) {
AndroidUtilities.rectTmp.set(bounds);
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, dimPaint);
} else {
canvas.drawRect(bounds, dimPaint);
}
}
} else if (base != null) {
base.setBounds(bounds); base.setBounds(bounds);
base.draw(canvas); base.draw(canvas);
canvas.drawRect(bounds, paint);
canvas.restore();
getPadding(AndroidUtilities.rectTmp2);
AndroidUtilities.rectTmp.set(
bounds.left + AndroidUtilities.rectTmp2.left,
bounds.top + AndroidUtilities.rectTmp2.top,
bounds.right - AndroidUtilities.rectTmp2.right,
bounds.bottom - AndroidUtilities.rectTmp2.bottom
);
canvas.drawRoundRect(AndroidUtilities.rectTmp, dp(6), dp(6), dimPaint);
} else { } else {
base.setBounds(bounds); dimPaint.setColor(-14145495);
base.draw(canvas); if (r > 0) {
AndroidUtilities.rectTmp.set(bounds);
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, dimPaint);
} else {
canvas.drawRect(bounds, dimPaint);
}
} }
} }
@ -1005,7 +1027,12 @@ public class BlurringShader {
@Override @Override
public boolean getPadding(@NonNull Rect padding) { public boolean getPadding(@NonNull Rect padding) {
return base.getPadding(padding); if (base != null) {
return base.getPadding(padding);
} else {
padding.set(0, 0, 0, 0);
return true;
}
} }
}; };
} }

View file

@ -44,6 +44,8 @@ public class BottomPagerTabs extends View {
final RectF clickRect = new RectF(); final RectF clickRect = new RectF();
final AnimatedFloat nonscrollingT = new AnimatedFloat(BottomPagerTabs.this, 0, 200, CubicBezierInterpolator.EASE_OUT_QUINT); final AnimatedFloat nonscrollingT = new AnimatedFloat(BottomPagerTabs.this, 0, 200, CubicBezierInterpolator.EASE_OUT_QUINT);
public int customEndFrameMid;
public int customEndFrameEnd;
public Tab(int i, int resId, CharSequence text) { public Tab(int i, int resId, CharSequence text) {
this.i = i; this.i = i;
@ -70,29 +72,27 @@ public class BottomPagerTabs extends View {
return; return;
} }
if (i == 0) { if (tabs[i].customEndFrameMid != 0) {
// 0 - 20
// 20 - 40
if (active) { if (active) {
drawable.setCustomEndFrame(20); drawable.setCustomEndFrame(customEndFrameMid);
if (drawable.getCurrentFrame() >= 38) { if (drawable.getCurrentFrame() >= customEndFrameEnd - 2) {
drawable.setCurrentFrame(0, false); drawable.setCurrentFrame(0, false);
} }
if (drawable.getCurrentFrame() <= 20) { if (drawable.getCurrentFrame() <= customEndFrameMid) {
drawable.start(); drawable.start();
} else { } else {
drawable.setCurrentFrame(20); drawable.setCurrentFrame(customEndFrameMid);
} }
} else { } else {
if (drawable.getCurrentFrame() >= 19) { if (drawable.getCurrentFrame() >= customEndFrameMid - 1) {
drawable.setCustomEndFrame(39); drawable.setCustomEndFrame(customEndFrameEnd - 1);
drawable.start(); drawable.start();
} else { } else {
drawable.setCustomEndFrame(0); drawable.setCustomEndFrame(0);
drawable.setCurrentFrame(0); drawable.setCurrentFrame(0);
} }
} }
} else if (i == 1 && active) { } else if (active) {
drawable.setCurrentFrame(0); drawable.setCurrentFrame(0);
if (animated) { if (animated) {
drawable.start(); drawable.start();

View file

@ -22,6 +22,7 @@ import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatObject; import org.telegram.messenger.ChatObject;
import org.telegram.messenger.DialogObject; import org.telegram.messenger.DialogObject;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
@ -68,6 +69,18 @@ public final class BulletinFactory {
return BulletinFactory.of(baseFragment); return BulletinFactory.of(baseFragment);
} }
public static void showForError(TLRPC.TL_error error) {
BulletinFactory bulletinFactory = BulletinFactory.global();
if (bulletinFactory == null) {
return;
}
if (BuildVars.DEBUG_VERSION) {
bulletinFactory.createErrorBulletin(error.code + " " + error.text).show();
} else {
bulletinFactory.createErrorBulletin(LocaleController.getString("UnknownError", R.string.UnknownError)).show();
}
}
public enum FileType { public enum FileType {
PHOTO("PhotoSavedHint", R.string.PhotoSavedHint, Icon.SAVED_TO_GALLERY), PHOTO("PhotoSavedHint", R.string.PhotoSavedHint, Icon.SAVED_TO_GALLERY),

View file

@ -11,19 +11,27 @@ import android.view.animation.OvershootInterpolator;
public class ButtonBounce { public class ButtonBounce {
private View view; private View view;
private final float durationMultiplier; private final float durationPressMultiplier;
private final float durationReleaseMultiplier;
private final float overshoot; private final float overshoot;
private long releaseDelay = 0; private long releaseDelay = 0;
public ButtonBounce(View viewToInvalidate) { public ButtonBounce(View viewToInvalidate) {
view = viewToInvalidate; view = viewToInvalidate;
durationMultiplier = 1f; durationPressMultiplier = durationReleaseMultiplier = 1f;
overshoot = 5.0f; overshoot = 5.0f;
} }
public ButtonBounce(View viewToInvalidate, float durationMultiplier, float overshoot) { public ButtonBounce(View viewToInvalidate, float durationMultiplier, float overshoot) {
view = viewToInvalidate; view = viewToInvalidate;
this.durationMultiplier = durationMultiplier; this.durationPressMultiplier = this.durationReleaseMultiplier = durationMultiplier;
this.overshoot = overshoot;
}
public ButtonBounce(View viewToInvalidate, float durationPressMultiplier, float durationReleaseMultiplier, float overshoot) {
view = viewToInvalidate;
this.durationPressMultiplier = durationPressMultiplier;
this.durationReleaseMultiplier = durationReleaseMultiplier;
this.overshoot = overshoot; this.overshoot = overshoot;
} }
@ -65,11 +73,11 @@ public class ButtonBounce {
}); });
if (isPressed) { if (isPressed) {
animator.setInterpolator(CubicBezierInterpolator.DEFAULT); animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
animator.setDuration((long) (60 * durationMultiplier)); animator.setDuration((long) (60 * durationPressMultiplier));
animator.setStartDelay(0); animator.setStartDelay(0);
} else { } else {
animator.setInterpolator(new OvershootInterpolator(overshoot)); animator.setInterpolator(new OvershootInterpolator(overshoot));
animator.setDuration((long) (350 * durationMultiplier)); animator.setDuration((long) (350 * durationReleaseMultiplier));
animator.setStartDelay(releaseDelay); animator.setStartDelay(releaseDelay);
} }
animator.start(); animator.start();

View file

@ -3654,6 +3654,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}, resourcesProvider); }, resourcesProvider);
}); });
sendPopupLayout.addView(scheduleButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48)); sendPopupLayout.addView(scheduleButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
SharedConfig.removeScheduledHint();
if (!self && dialog_id > 0) { if (!self && dialog_id > 0) {
sendWhenOnlineButton = new ActionBarMenuSubItem(getContext(), true, !sendWithoutSoundButtonValue, resourcesProvider); sendWhenOnlineButton = new ActionBarMenuSubItem(getContext(), true, !sendWithoutSoundButtonValue, resourcesProvider);
sendWhenOnlineButton.setTextAndIcon(LocaleController.getString("SendWhenOnline", R.string.SendWhenOnline), R.drawable.msg_online); sendWhenOnlineButton.setTextAndIcon(LocaleController.getString("SendWhenOnline", R.string.SendWhenOnline), R.drawable.msg_online);

View file

@ -34,6 +34,7 @@ import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.text.TextPaint; import android.text.TextPaint;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -76,6 +77,7 @@ import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject; import org.telegram.messenger.DialogObject;
import org.telegram.messenger.DocumentObject; import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.Emoji; import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaController; import org.telegram.messenger.MediaController;
@ -110,6 +112,8 @@ import org.telegram.ui.PaymentFormActivity;
import org.telegram.ui.PhotoPickerActivity; import org.telegram.ui.PhotoPickerActivity;
import org.telegram.ui.PhotoPickerSearchActivity; import org.telegram.ui.PhotoPickerSearchActivity;
import org.telegram.ui.PremiumPreviewFragment; import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.Stories.DarkThemeResourceProvider;
import org.telegram.ui.Stories.recorder.CaptionContainerView;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -2463,6 +2467,12 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if ((count - before) >= 1) { if ((count - before) >= 1) {
processChange = true; processChange = true;
} }
if (mentionContainer == null) {
createMentionsContainer();
}
if (mentionContainer.getAdapter() != null) {
mentionContainer.getAdapter().searchUsernameOrHashtag(charSequence, commentTextView.getEditText().getSelectionStart(), null, false, false);
}
} }
@Override @Override
@ -2796,6 +2806,13 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
public void updateCommentTextViewPosition() { public void updateCommentTextViewPosition() {
commentTextView.getLocationOnScreen(commentTextViewLocation); commentTextView.getLocationOnScreen(commentTextViewLocation);
if (mentionContainer != null) {
float y = -commentTextView.getHeight();
if (mentionContainer.getY() != y) {
mentionContainer.setTranslationY(y);
mentionContainer.invalidate();
}
}
} }
public int getCommentTextViewTop() { public int getCommentTextViewTop() {
@ -4661,4 +4678,72 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
public void setDocumentsDelegate(ChatAttachAlertDocumentLayout.DocumentSelectActivityDelegate documentsDelegate) { public void setDocumentsDelegate(ChatAttachAlertDocumentLayout.DocumentSelectActivityDelegate documentsDelegate) {
this.documentsDelegate = documentsDelegate; this.documentsDelegate = documentsDelegate;
} }
private void replaceWithText(int start, int len, CharSequence text, boolean parseEmoji) {
if (commentTextView == null) {
return;
}
try {
SpannableStringBuilder builder = new SpannableStringBuilder(commentTextView.getText());
builder.replace(start, start + len, text);
if (parseEmoji) {
Emoji.replaceEmoji(builder, commentTextView.getEditText().getPaint().getFontMetricsInt(), AndroidUtilities.dp(20), false);
}
commentTextView.setText(builder);
commentTextView.setSelection(start + text.length());
} catch (Exception e) {
FileLog.e(e);
}
}
public MentionsContainerView mentionContainer;
private void createMentionsContainer() {
mentionContainer = new MentionsContainerView(getContext(), UserConfig.getInstance(currentAccount).getClientUserId(), 0, LaunchActivity.getLastFragment(), null, resourcesProvider) {
@Override
protected void onScrolled(boolean atTop, boolean atBottom) {
if (photoLayout != null) {
photoLayout.checkCameraViewPosition();
}
}
@Override
protected void onAnimationScroll() {
if (photoLayout != null) {
photoLayout.checkCameraViewPosition();
}
}
};
setupMentionContainer();
mentionContainer.withDelegate(new MentionsContainerView.Delegate() {
@Override
public void replaceText(int start, int len, CharSequence replacingString, boolean allowShort) {
replaceWithText(start, len, replacingString, allowShort);
}
@Override
public Paint.FontMetricsInt getFontMetrics() {
return commentTextView.getEditText().getPaint().getFontMetricsInt();
}
});
containerView.addView(mentionContainer, containerView.indexOfChild(frameLayout2), LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.BOTTOM));
mentionContainer.setTranslationY(-commentTextView.getHeight());
setupMentionContainer();
}
protected void setupMentionContainer() {
mentionContainer.getAdapter().setAllowStickers(false);
mentionContainer.getAdapter().setAllowBots(false);
mentionContainer.getAdapter().setAllowChats(false);
mentionContainer.getAdapter().setSearchInDailogs(true);
if (baseFragment instanceof ChatActivity) {
mentionContainer.getAdapter().setChatInfo(((ChatActivity) baseFragment).getCurrentChatInfo());
mentionContainer.getAdapter().setNeedUsernames(((ChatActivity) baseFragment).getCurrentChat() != null);
} else {
mentionContainer.getAdapter().setChatInfo(null);
mentionContainer.getAdapter().setNeedUsernames(false);
}
mentionContainer.getAdapter().setNeedBotContext(false);
}
} }

View file

@ -36,6 +36,7 @@ import android.os.Build;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
@ -2167,7 +2168,7 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
super.dispatchDraw(canvas); super.dispatchDraw(canvas);
} else { } else {
int maxY = (int) Math.min(parentAlert.getCommentTextViewTop() + currentPanTranslationY + parentAlert.getContainerView().getTranslationY() - cameraView.getTranslationY(), getMeasuredHeight()); int maxY = (int) Math.min(parentAlert.getCommentTextViewTop() + currentPanTranslationY + parentAlert.getContainerView().getTranslationY() - cameraView.getTranslationY() - (parentAlert.mentionContainer != null ? parentAlert.mentionContainer.clipBottom() + AndroidUtilities.dp(8) : 0), getMeasuredHeight());
if (cameraAnimationInProgress) { if (cameraAnimationInProgress) {
AndroidUtilities.rectTmp.set(animationClipLeft + cameraViewOffsetX * (1f - cameraOpenProgress), animationClipTop + cameraViewOffsetY * (1f - cameraOpenProgress), animationClipRight, Math.min(maxY, animationClipBottom)); AndroidUtilities.rectTmp.set(animationClipLeft + cameraViewOffsetX * (1f - cameraOpenProgress), animationClipTop + cameraViewOffsetY * (1f - cameraOpenProgress), animationClipRight, Math.min(maxY, animationClipBottom));
} else if (!cameraAnimationInProgress && !cameraOpened) { } else if (!cameraAnimationInProgress && !cameraOpened) {
@ -2204,7 +2205,7 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
cameraView.setOutlineProvider(new ViewOutlineProvider() { cameraView.setOutlineProvider(new ViewOutlineProvider() {
@Override @Override
public void getOutline(View view, Outline outline) { public void getOutline(View view, Outline outline) {
int maxY = (int) Math.min(parentAlert.getCommentTextViewTop() + currentPanTranslationY + parentAlert.getContainerView().getTranslationY() - cameraView.getTranslationY(), view.getMeasuredHeight()); int maxY = (int) Math.min(parentAlert.getCommentTextViewTop() - (parentAlert.mentionContainer != null ? parentAlert.mentionContainer.clipBottom() + AndroidUtilities.dp(8) : 0) + currentPanTranslationY + parentAlert.getContainerView().getTranslationY() - cameraView.getTranslationY(), view.getMeasuredHeight());
if (cameraOpened) { if (cameraOpened) {
maxY = view.getMeasuredHeight(); maxY = view.getMeasuredHeight();
} else if (cameraAnimationInProgress) { } else if (cameraAnimationInProgress) {
@ -2764,9 +2765,12 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
int containerHeight = parentAlert.getSheetContainer().getMeasuredHeight(); int containerHeight = parentAlert.getSheetContainer().getMeasuredHeight();
maxY = (int) (containerHeight - parentAlert.buttonsRecyclerView.getMeasuredHeight() + parentAlert.buttonsRecyclerView.getTranslationY()); maxY = (int) (containerHeight - parentAlert.buttonsRecyclerView.getMeasuredHeight() + parentAlert.buttonsRecyclerView.getTranslationY());
if (parentAlert.mentionContainer != null) {
maxY -= parentAlert.mentionContainer.clipBottom() - AndroidUtilities.dp(6);
}
if (topLocal + child.getMeasuredHeight() > maxY) { if (topLocal + child.getMeasuredHeight() > maxY) {
cameraViewOffsetBottomY = topLocal + child.getMeasuredHeight() - maxY; cameraViewOffsetBottomY = Math.min(-AndroidUtilities.dp(5), topLocal - maxY) + child.getMeasuredHeight();
} else { } else {
cameraViewOffsetBottomY = 0; cameraViewOffsetBottomY = 0;
} }

View file

@ -148,6 +148,9 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
final boolean avatarClickable = parentFragment != null && parentFragment.getChatMode() == 0 && !UserObject.isReplyUser(parentFragment.getCurrentUser()); final boolean avatarClickable = parentFragment != null && parentFragment.getChatMode() == 0 && !UserObject.isReplyUser(parentFragment.getCurrentUser());
avatarImageView = new BackupImageView(context) { avatarImageView = new BackupImageView(context) {
StoriesUtilities.AvatarStoryParams params = new StoriesUtilities.AvatarStoryParams(true);
@Override @Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info); super.onInitializeAccessibilityNodeInfo(info);
@ -160,6 +163,19 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
info.setVisibleToUser(false); info.setVisibleToUser(false);
} }
} }
@Override
protected void onDraw(Canvas canvas) {
if (allowDrawStories && animatedEmojiDrawable == null) {
params.originalAvatarRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
params.drawSegments = true;
params.drawInside = true;
params.resourcesProvider = resourcesProvider;
StoriesUtilities.drawAvatarWithStory(parentFragment.getDialogId(), canvas, imageReceiver, params);
} else {
super.onDraw(canvas);
}
}
}; };
if (baseFragment instanceof ChatActivity || baseFragment instanceof TopicsFragment) { if (baseFragment instanceof ChatActivity || baseFragment instanceof TopicsFragment) {
sharedMediaPreloader = new SharedMediaLayout.SharedMediaPreloader(baseFragment); sharedMediaPreloader = new SharedMediaLayout.SharedMediaPreloader(baseFragment);

View file

@ -13,6 +13,7 @@ import android.graphics.Paint;
import android.graphics.PointF; import android.graphics.PointF;
import android.graphics.RectF; import android.graphics.RectF;
import android.os.Build; import android.os.Build;
import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@ -993,54 +994,37 @@ public class CropView extends FrameLayout implements CropAreaView.AreaViewListen
if (entities != null && !entities.isEmpty()) { if (entities != null && !entities.isEmpty()) {
float[] point = new float[4]; float[] point = new float[4];
float newScale = 1.0f / sc * scale * stateScale;
float widthScale = b.getWidth() / (float) canvasBitmap.getWidth();
newScale *= widthScale;
TextPaintView textPaintView = null;
for (int a = 0, N = entities.size(); a < N; a++) { for (int a = 0, N = entities.size(); a < N; a++) {
VideoEditedInfo.MediaEntity entity = entities.get(a); VideoEditedInfo.MediaEntity entity = entities.get(a);
point[0] = entity.x * b.getWidth() + entity.viewWidth * entity.scale / 2; point[0] = (entity.x + entity.width / 2) * b.getWidth();
point[1] = entity.y * b.getHeight() + entity.viewHeight * entity.scale / 2; point[1] = (entity.y + entity.height / 2) * b.getHeight();
point[2] = entity.textViewX * b.getWidth(); point[2] = entity.textViewX * b.getWidth();
point[3] = entity.textViewY * b.getHeight(); point[3] = entity.textViewY * b.getHeight();
matrix.mapPoints(point); matrix.mapPoints(point);
if (entity.type == 0) { final int w = contentWidth, h = contentHeight;
entity.viewWidth = entity.viewHeight = canvasBitmap.getWidth() / 2; int bw = b.getWidth(), bh = b.getHeight();
} else if (entity.type == 1) { if (orientationOnly == 90 || orientationOnly == 270) {
entity.fontSize = canvasBitmap.getWidth() / 9; bw = b.getHeight();
if (textPaintView == null) { bh = b.getWidth();
textPaintView = new TextPaintView(context, new Point(0, 0), entity.fontSize, "", new Swatch(Color.BLACK, 0.85f, 0.1f), 0);
textPaintView.setMaxWidth(canvasBitmap.getWidth() - 20);
}
int type;
if ((entity.subType & 1) != 0) {
type = 0;
} else if ((entity.subType & 4) != 0) {
type = 2;
} else {
type = 1;
}
textPaintView.setType(type);
textPaintView.setText(entity.text);
textPaintView.measure(MeasureSpec.makeMeasureSpec(canvasBitmap.getWidth(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(canvasBitmap.getHeight(), MeasureSpec.AT_MOST));
entity.viewWidth = textPaintView.getMeasuredWidth();
entity.viewHeight = textPaintView.getMeasuredHeight();
} }
entity.scale *= newScale; if (entity.type == VideoEditedInfo.MediaEntity.TYPE_TEXT) {
entity.width = entity.width * w / canvasBitmap.getWidth() * scale * stateScale;
entity.height = entity.height * h / canvasBitmap.getHeight() * scale * stateScale;
} else {
entity.viewWidth = (int) (entity.viewWidth / (float) w * bw);
entity.viewHeight = (int) (entity.viewHeight / (float) h * bh);
entity.x = (point[0] - entity.viewWidth * entity.scale / 2) / canvasBitmap.getWidth(); entity.width = entity.width * w / bw * scale * stateScale;
entity.y = (point[1] - entity.viewHeight * entity.scale / 2) / canvasBitmap.getHeight(); entity.height = entity.height * h / bh * scale * stateScale;
}
entity.x = point[0] / canvasBitmap.getWidth() - entity.width / 2;
entity.y = point[1] / canvasBitmap.getHeight() - entity.height / 2;
entity.textViewX = point[2] / canvasBitmap.getWidth(); entity.textViewX = point[2] / canvasBitmap.getWidth();
entity.textViewY = point[3] / canvasBitmap.getHeight(); entity.textViewY = point[3] / canvasBitmap.getHeight();
entity.width = entity.viewWidth * entity.scale / canvasBitmap.getWidth();
entity.height = entity.viewHeight * entity.scale / canvasBitmap.getHeight();
entity.textViewWidth = entity.viewWidth / (float) canvasBitmap.getWidth();
entity.textViewHeight = entity.viewHeight / (float) canvasBitmap.getHeight();
entity.rotation -= (rotation + orientationOnly) * (Math.PI / 180); entity.rotation -= (rotation + orientationOnly) * (Math.PI / 180);
} }
} }

View file

@ -137,8 +137,9 @@ public class HintView extends FrameLayout {
imageView.setImageResource(R.drawable.msg_mini_close_tooltip); imageView.setImageResource(R.drawable.msg_mini_close_tooltip);
imageView.setScaleType(ImageView.ScaleType.CENTER); imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setColorFilter(new PorterDuffColorFilter(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_chat_gifSaveHintText), 125), PorterDuff.Mode.MULTIPLY)); imageView.setColorFilter(new PorterDuffColorFilter(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_chat_gifSaveHintText), 125), PorterDuff.Mode.MULTIPLY));
imageView.setOnClickListener(v -> hide(true));
addView(imageView, LayoutHelper.createFrame(34, 34, Gravity.RIGHT | Gravity.CENTER_VERTICAL, 0, isTopArrow ? 3 : 0, 0, isTopArrow ? 0 : 3)); addView(imageView, LayoutHelper.createFrame(34, 34, Gravity.RIGHT | Gravity.CENTER_VERTICAL, 0, isTopArrow ? 3 : 0, 0, isTopArrow ? 0 : 3));
setOnClickListener(v -> hide(true));
} }
public void setBackgroundColor(int background, int text) { public void setBackgroundColor(int background, int text) {

View file

@ -1,5 +1,7 @@
package org.telegram.ui.Components; package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.content.Context; import android.content.Context;
@ -150,7 +152,7 @@ public class ItemOptions {
} }
ActionBarMenuSubItem subItem = new ActionBarMenuSubItem(context, false, false, resourcesProvider); ActionBarMenuSubItem subItem = new ActionBarMenuSubItem(context, false, false, resourcesProvider);
subItem.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18 + (LocaleController.isRTL ? 0 : 8)), 0); subItem.setPadding(dp(18), 0, dp(18 + (LocaleController.isRTL ? 0 : 8)), 0);
subItem.setTextAndIcon(text, iconResId); subItem.setTextAndIcon(text, iconResId);
subItem.setColors(Theme.getColor(textColorKey, resourcesProvider), Theme.getColor(iconColorKey, resourcesProvider)); subItem.setColors(Theme.getColor(textColorKey, resourcesProvider), Theme.getColor(iconColorKey, resourcesProvider));
@ -165,7 +167,7 @@ public class ItemOptions {
} }
}); });
if (minWidthDp > 0) { if (minWidthDp > 0) {
subItem.setMinimumWidth(AndroidUtilities.dp(minWidthDp)); subItem.setMinimumWidth(dp(minWidthDp));
lastLayout.addView(subItem, LayoutHelper.createLinear(minWidthDp, LayoutHelper.WRAP_CONTENT)); lastLayout.addView(subItem, LayoutHelper.createLinear(minWidthDp, LayoutHelper.WRAP_CONTENT));
} else { } else {
lastLayout.addView(subItem, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); lastLayout.addView(subItem, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
@ -276,10 +278,10 @@ public class ItemOptions {
final TextView textView = new TextView(context); final TextView textView = new TextView(context);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSizeDp); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSizeDp);
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider)); textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
textView.setPadding(AndroidUtilities.dp(13), AndroidUtilities.dp(8), AndroidUtilities.dp(13), AndroidUtilities.dp(8)); textView.setPadding(dp(13), dp(8), dp(13), dp(8));
textView.setText(text); textView.setText(text);
textView.setTag(R.id.fit_width_tag, 1); textView.setTag(R.id.fit_width_tag, 1);
textView.setMaxWidth(AndroidUtilities.dp(200)); textView.setMaxWidth(dp(200));
lastLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); lastLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
return this; return this;
} }
@ -323,7 +325,7 @@ public class ItemOptions {
if (layout instanceof ActionBarPopupWindow.ActionBarPopupWindowLayout) { if (layout instanceof ActionBarPopupWindow.ActionBarPopupWindowLayout) {
layout.setBackgroundDrawable( layout.setBackgroundDrawable(
new BlurringShader.StoryBlurDrawer(blurManager, layout, BlurringShader.StoryBlurDrawer.BLUR_TYPE_MENU_BACKGROUND) new BlurringShader.StoryBlurDrawer(blurManager, layout, BlurringShader.StoryBlurDrawer.BLUR_TYPE_MENU_BACKGROUND)
.makeDrawable(offsetX + ox + layout.getX(), offsetY + oy + layout.getY(), baseDrawable) .makeDrawable(offsetX + ox + layout.getX(), offsetY + oy + layout.getY(), baseDrawable, dp(6))
); );
} else { } else {
for (int i = 0; i < layout.getChildCount(); ++i) { for (int i = 0; i < layout.getChildCount(); ++i) {
@ -331,7 +333,7 @@ public class ItemOptions {
if (child instanceof ActionBarPopupWindow.ActionBarPopupWindowLayout) { if (child instanceof ActionBarPopupWindow.ActionBarPopupWindowLayout) {
child.setBackgroundDrawable( child.setBackgroundDrawable(
new BlurringShader.StoryBlurDrawer(blurManager, child, BlurringShader.StoryBlurDrawer.BLUR_TYPE_MENU_BACKGROUND) new BlurringShader.StoryBlurDrawer(blurManager, child, BlurringShader.StoryBlurDrawer.BLUR_TYPE_MENU_BACKGROUND)
.makeDrawable(offsetX + ox + layout.getX() + child.getX(), offsetY + oy + layout.getY() + child.getY(), baseDrawable) .makeDrawable(offsetX + ox + layout.getX() + child.getX(), offsetY + oy + layout.getY() + child.getY(), baseDrawable, dp(6))
); );
} }
} }
@ -388,7 +390,7 @@ public class ItemOptions {
if (child instanceof ActionBarPopupWindow.ActionBarPopupWindowLayout) { if (child instanceof ActionBarPopupWindow.ActionBarPopupWindowLayout) {
ActionBarPopupWindow.ActionBarPopupWindowLayout popupLayout = (ActionBarPopupWindow.ActionBarPopupWindowLayout) child; ActionBarPopupWindow.ActionBarPopupWindowLayout popupLayout = (ActionBarPopupWindow.ActionBarPopupWindowLayout) child;
for (int i = 0; i < popupLayout.getItemsCount(); ++i) { for (int i = 0; i < popupLayout.getItemsCount(); ++i) {
popupLayout.getItemAt(i).setMinimumWidth(AndroidUtilities.dp(minWidthDp)); popupLayout.getItemAt(i).setMinimumWidth(dp(minWidthDp));
} }
} }
} }
@ -460,7 +462,7 @@ public class ItemOptions {
} }
int Y; int Y;
if (scrimView != null) { if (scrimView != null) {
if (forceTop || y + layout.getMeasuredHeight() + AndroidUtilities.dp(16) > AndroidUtilities.displaySize.y) { if (forceTop || y + layout.getMeasuredHeight() + dp(16) > AndroidUtilities.displaySize.y) {
// put above scrimView // put above scrimView
y -= scrimView.getMeasuredHeight(); y -= scrimView.getMeasuredHeight();
y -= layout.getMeasuredHeight(); y -= layout.getMeasuredHeight();

View file

@ -435,6 +435,13 @@ public class LinkActionView extends LinearLayout {
} }
} }
public void hideOptions() {
optionsView.setVisibility(View.GONE);
linkView.setGravity(Gravity.CENTER);
removeView.setVisibility(View.GONE);
avatarsContainer.setVisibility(View.GONE);
}
private class AvatarsContainer extends FrameLayout { private class AvatarsContainer extends FrameLayout {
TextView countTextView; TextView countTextView;

View file

@ -467,7 +467,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
getMessagesController().getStoriesController().updateStoriesInLists(dialogId, storyItems); getMessagesController().getStoriesController().updateStoriesInLists(dialogId, storyItems);
final boolean[] undone = new boolean[] { false }; final boolean[] undone = new boolean[] { false };
applyBulletin = () -> { applyBulletin = () -> {
getMessagesController().getStoriesController().updateStoriesPinned(storyItems, pin, null); getMessagesController().getStoriesController().updateStoriesPinned(dialogId, storyItems, pin, null);
}; };
final Runnable undo = () -> { final Runnable undo = () -> {
undone[0] = true; undone[0] = true;
@ -1159,10 +1159,13 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
@Override @Override
public Tab[] createTabs() { public Tab[] createTabs() {
return new Tab[] { Tab[] tabs = new Tab[] {
new Tab(0, R.raw.msg_stories_saved, LocaleController.getString("ProfileMyStoriesTab", R.string.ProfileMyStoriesTab)), new Tab(0, R.raw.msg_stories_saved, LocaleController.getString("ProfileMyStoriesTab", R.string.ProfileMyStoriesTab)),
new Tab(1, R.raw.msg_stories_archive, LocaleController.getString("ProfileStoriesArchiveTab", R.string.ProfileStoriesArchiveTab)) new Tab(1, R.raw.msg_stories_archive, LocaleController.getString("ProfileStoriesArchiveTab", R.string.ProfileStoriesArchiveTab))
}; };
tabs[0].customEndFrameMid = 20;
tabs[0].customEndFrameEnd = 40;
return tabs;
} }
} }

View file

@ -270,6 +270,10 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
} }
protected void onAnimationScroll() {
}
public MentionsListView getListView() { public MentionsListView getListView() {
return listView; return listView;
} }
@ -321,6 +325,7 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
containerPadding = AndroidUtilities.dp(2 + (topPadding ? 2 : 0)); containerPadding = AndroidUtilities.dp(2 + (topPadding ? 2 : 0));
float r = AndroidUtilities.dp(6); float r = AndroidUtilities.dp(6);
float wasContainerTop = containerTop;
if (reversed) { if (reversed) {
int paddingViewTop = paddedAdapter.paddingViewAttached ? paddedAdapter.paddingView.getTop() : getHeight(); int paddingViewTop = paddedAdapter.paddingViewAttached ? paddedAdapter.paddingView.getTop() : getHeight();
float top = Math.max(0, paddingViewTop + listView.getTranslationY()) + containerPadding; float top = Math.max(0, paddingViewTop + listView.getTranslationY()) + containerPadding;
@ -344,6 +349,9 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
rect.bottom += (int) r; rect.bottom += (int) r;
} }
} }
if (Math.abs(wasContainerTop - containerTop) > 0.1f) {
onAnimationScroll();
}
if (paint == null) { if (paint == null) {
paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint = new Paint(Paint.ANTI_ALIAS_FLAG);
@ -504,6 +512,7 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
); );
listViewTranslationAnimator.addUpdateListener((anm, val, vel) -> { listViewTranslationAnimator.addUpdateListener((anm, val, vel) -> {
listView.setTranslationY(val); listView.setTranslationY(val);
onAnimationScroll();
hideT = AndroidUtilities.lerp(fromHideT, toHideT, (val - fromTranslation) / (toTranslation - fromTranslation)); hideT = AndroidUtilities.lerp(fromHideT, toHideT, (val - fromTranslation) / (toTranslation - fromTranslation));
}); });
if (forceZeroHeight) { if (forceZeroHeight) {

View file

@ -1,6 +1,7 @@
package org.telegram.ui.Components.Paint.Views; package org.telegram.ui.Components.Paint.Views;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.ScaleGestureDetector; import android.view.ScaleGestureDetector;
import android.view.View; import android.view.View;
@ -12,6 +13,8 @@ import org.telegram.messenger.AndroidUtilities;
public class EntitiesContainerView extends FrameLayout { public class EntitiesContainerView extends FrameLayout {
public boolean drawForThumb;
public interface EntitiesContainerViewDelegate { public interface EntitiesContainerViewDelegate {
boolean shouldReceiveTouches(); boolean shouldReceiveTouches();
void onEntityDeselect(); void onEntityDeselect();
@ -98,4 +101,12 @@ public class EntitiesContainerView extends FrameLayout {
super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed); super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);
} }
} }
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (drawForThumb && child instanceof ReactionWidgetEntityView) {
return true;
}
return super.drawChild(canvas, child, drawingTime);
}
} }

View file

@ -10,6 +10,7 @@ import android.graphics.Canvas;
import android.graphics.DashPathEffect; import android.graphics.DashPathEffect;
import android.graphics.Paint; import android.graphics.Paint;
import android.os.Build; import android.os.Build;
import android.util.Log;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
@ -485,7 +486,7 @@ public class EntityView extends FrameLayout {
if (parent != null) { if (parent != null) {
int newStickyX = STICKY_NONE; int newStickyX = STICKY_NONE;
if (!lastIsMultitouch) { if (!lastIsMultitouch) {
if (Math.abs(position.x - parent.getMeasuredWidth() / 2f) <= dp(STICKY_TRIGGER_DP) && position.y < parent.getMeasuredHeight() - dp(112 + 64)) { if (Math.abs(position.x - parent.getMeasuredWidth() / 2f) <= dp(STICKY_TRIGGER_DP) && position.y < parent.getMeasuredHeight() - dp(112)) {
newStickyX = STICKY_CENTER; newStickyX = STICKY_CENTER;
} else if (Math.abs(position.x - (width() / 2f + getStickyPaddingLeft()) * getScaleX() - dp(STICKY_PADDING_X_DP)) <= dp(STICKY_TRIGGER_DP)) { } else if (Math.abs(position.x - (width() / 2f + getStickyPaddingLeft()) * getScaleX() - dp(STICKY_PADDING_X_DP)) <= dp(STICKY_TRIGGER_DP)) {
newStickyX = STICKY_START; newStickyX = STICKY_START;
@ -773,6 +774,10 @@ public class EntityView extends FrameLayout {
} }
} }
public boolean isSelectedProgress() {
return isSelected() || selectT > 0;
}
private ViewGroup lastSelectionContainer; private ViewGroup lastSelectionContainer;
public void select(ViewGroup selectionContainer) { public void select(ViewGroup selectionContainer) {
updateSelect(lastSelectionContainer = selectionContainer, true); updateSelect(lastSelectionContainer = selectionContainer, true);

View file

@ -234,8 +234,8 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
return -9539985; return -9539985;
} else if (key == Theme.key_chat_emojiPanelIcon) { } else if (key == Theme.key_chat_emojiPanelIcon) {
return -9539985; return -9539985;
} else if (key == Theme.key_chat_emojiPanelIconSelected) { // } else if (key == Theme.key_chat_emojiPanelIconSelected) {
return 0xffffffff; // return -10177041;
} else if (key == Theme.key_windowBackgroundWhiteBlackText) { } else if (key == Theme.key_windowBackgroundWhiteBlackText) {
return -1; return -1;
} else if (key == Theme.key_featuredStickers_addedIcon) { } else if (key == Theme.key_featuredStickers_addedIcon) {
@ -459,6 +459,14 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
} }
CharSequence charSequence = text; CharSequence charSequence = text;
charSequence = Emoji.replaceEmoji(charSequence, textPaintView.getFontMetricsInt(), (int) (textPaintView.getFontSize() * .8f), false); charSequence = Emoji.replaceEmoji(charSequence, textPaintView.getFontMetricsInt(), (int) (textPaintView.getFontSize() * .8f), false);
if (charSequence instanceof Spanned) {
Emoji.EmojiSpan[] spans = ((Spanned) charSequence).getSpans(0, charSequence.length(), Emoji.EmojiSpan.class);
if (spans != null) {
for (int i = 0; i < spans.length; ++i) {
spans[i].scale = .85f;
}
}
}
textPaintView.setText(charSequence); textPaintView.setText(charSequence);
setTextAlignment(textPaintView, entity.textAlign); setTextAlignment(textPaintView, entity.textAlign);
Swatch swatch = textPaintView.getSwatch(); Swatch swatch = textPaintView.getSwatch();
@ -471,8 +479,7 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
view.setX(entity.x * paintingSize.width - entity.viewWidth * (1 - entity.scale) / 2); view.setX(entity.x * paintingSize.width - entity.viewWidth * (1 - entity.scale) / 2);
view.setY(entity.y * paintingSize.height - entity.viewHeight * (1 - entity.scale) / 2); view.setY(entity.y * paintingSize.height - entity.viewHeight * (1 - entity.scale) / 2);
view.setPosition(new Point(view.getX() + entity.viewWidth / 2f, view.getY() + entity.viewHeight / 2f)); view.setPosition(new Point(view.getX() + entity.viewWidth / 2f, view.getY() + entity.viewHeight / 2f));
view.setScaleX(entity.scale); view.setScale(entity.scale);
view.setScaleY(entity.scale);
view.setRotation((float) (-entity.rotation / Math.PI * 180)); view.setRotation((float) (-entity.rotation / Math.PI * 180));
} }
} }
@ -934,11 +941,13 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
return currentEntityView instanceof TextPaintView; return currentEntityView instanceof TextPaintView;
} }
public float getSelectedEntityCenterY() { public float getSelectedEntityBottom() {
if (currentEntityView == null) { if (currentEntityView == null) {
return getY() + entitiesView.getTop() + entitiesView.getMeasuredHeight() / 2f; return getY() + entitiesView.getMeasuredHeight();
} }
return getY() + entitiesView.getTop() + currentEntityView.getPositionY(); int[] loc = new int[2];
currentEntityView.getLocationInWindow(loc);
return loc[1] + currentEntityView.getHeight() * entitiesView.getScaleY();
} }
private TextPaintView createText(boolean select) { private TextPaintView createText(boolean select) {
@ -1148,7 +1157,7 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
int w = (int) (vw * currentCropState.cropPw * child.getScaleX() / currentCropState.cropScale); int w = (int) (vw * currentCropState.cropPw * child.getScaleX() / currentCropState.cropScale);
int h = (int) (vh * currentCropState.cropPh * child.getScaleY() / currentCropState.cropScale); int h = (int) (vh * currentCropState.cropPh * child.getScaleY() / currentCropState.cropScale);
float x = (float) Math.ceil((getMeasuredWidth() - w) / 2f) + transformX; float x = (float) Math.ceil((getMeasuredWidth() - w) / 2f) + transformX;
float y = (getMeasuredHeight() - actionBarHeight2 - AndroidUtilities.dp(48) + getAdditionalBottom() - h) / 2f + AndroidUtilities.dp(8) + status + transformY; float y = (getMeasuredHeight() - emojiPadding - actionBarHeight2 - AndroidUtilities.dp(48) + getAdditionalBottom() - h) / 2f + AndroidUtilities.dp(8) + status + transformY;
canvas.clipRect(Math.max(0, x), Math.max(0, y), Math.min(x + w, getMeasuredWidth()), Math.min(getMeasuredHeight(), y + h)); canvas.clipRect(Math.max(0, x), Math.max(0, y), Math.min(x + w, getMeasuredWidth()), Math.min(getMeasuredHeight(), y + h));
restore = true; restore = true;
@ -1403,9 +1412,7 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
entitiesView.setScaleX(baseScale); entitiesView.setScaleX(baseScale);
entitiesView.setScaleY(baseScale); entitiesView.setScaleY(baseScale);
entitiesView.measure(MeasureSpec.makeMeasureSpec((int) paintingSize.width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) paintingSize.height, MeasureSpec.EXACTLY)); entitiesView.measure(MeasureSpec.makeMeasureSpec((int) paintingSize.width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) paintingSize.height, MeasureSpec.EXACTLY));
if (currentEntityView != null) { updateEntitiesSelections();
currentEntityView.updateSelectionView();
}
selectionContainerView.measure(MeasureSpec.makeMeasureSpec((int) renderWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) renderHeight, MeasureSpec.EXACTLY)); selectionContainerView.measure(MeasureSpec.makeMeasureSpec((int) renderWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) renderHeight, MeasureSpec.EXACTLY));
measureChild(bottomLayout, widthMeasureSpec, heightMeasureSpec); measureChild(bottomLayout, widthMeasureSpec, heightMeasureSpec);
measureChild(weightChooserView, widthMeasureSpec, heightMeasureSpec); measureChild(weightChooserView, widthMeasureSpec, heightMeasureSpec);
@ -1939,9 +1946,19 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
view.setRotation(rotation); view.setRotation(rotation);
view.invalidate(); view.invalidate();
} }
updateEntitiesSelections();
invalidate(); invalidate();
} }
public void updateEntitiesSelections() {
for (int i = 0; i < entitiesView.getChildCount(); ++i) {
View child = entitiesView.getChildAt(i);
if (child == currentEntityView || child instanceof EntityView && ((EntityView) child).isSelectedProgress()) {
((EntityView) child).updateSelectionView();
}
}
}
@Override @Override
public List<TLRPC.InputDocument> getMasks() { public List<TLRPC.InputDocument> getMasks() {
ArrayList<TLRPC.InputDocument> result = null; ArrayList<TLRPC.InputDocument> result = null;
@ -2479,6 +2496,26 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
parent.addView(editView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 48)); parent.addView(editView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 48));
} }
if (entityView instanceof StickerView) {
TextView flipView = new TextView(getContext());
flipView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
flipView.setBackgroundDrawable(Theme.getSelectorDrawable(false));
flipView.setGravity(Gravity.CENTER_VERTICAL);
flipView.setEllipsize(TextUtils.TruncateAt.END);
flipView.setPadding(AndroidUtilities.dp(14), 0, AndroidUtilities.dp(16), 0);
flipView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
flipView.setTag(2);
flipView.setText(LocaleController.getString("Flip", R.string.Flip));
flipView.setOnClickListener(v -> {
((StickerView) entityView).mirror(true);
if (popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss(true);
}
});
parent.addView(flipView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 48));
}
TextView duplicateView = new TextView(getContext()); TextView duplicateView = new TextView(getContext());
duplicateView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem)); duplicateView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
duplicateView.setBackgroundDrawable(Theme.getSelectorDrawable(false)); duplicateView.setBackgroundDrawable(Theme.getSelectorDrawable(false));

View file

@ -0,0 +1,377 @@
package org.telegram.ui.Components.Paint.Views;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.RectF;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.Point;
import org.telegram.ui.Components.Reactions.ReactionImageHolder;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.Rect;
import org.telegram.ui.Components.Size;
import org.telegram.ui.Stories.StoryReactionWidgetBackground;
import java.util.List;
import java.util.Objects;
public class ReactionWidgetEntityView extends EntityView {
Size baseSize;
StoryReactionWidgetBackground storyReactionWidgetBackground = new StoryReactionWidgetBackground(this);
StoryReactionWidgetBackground outBackground = new StoryReactionWidgetBackground(this);
ReactionImageHolder reactionHolder = new ReactionImageHolder(this);
ReactionImageHolder nextReactionHolder = new ReactionImageHolder(this);
ReactionsLayoutInBubble.VisibleReaction currentReaction;
AnimatedFloat progressToNext = new AnimatedFloat(this);
AnimatedFloat crossfadeBackgrounds = new AnimatedFloat(this);
boolean mirror;
private float drawScale = 1f;
int filterColor;
public ReactionWidgetEntityView(Context context, Point pos, Size baseSize) {
super(context, pos);
this.baseSize = baseSize;
crossfadeBackgrounds.set(1f, true);
progressToNext.set(1f, true);
List<TLRPC.TL_availableReaction> availableReactions = MediaDataController.getInstance(UserConfig.selectedAccount).getReactionsList();
reactionHolder.setVisibleReaction(currentReaction = ReactionsLayoutInBubble.VisibleReaction.fromEmojicon(findHeartReaction(availableReactions)));
updatePosition();
}
private String findHeartReaction(List<TLRPC.TL_availableReaction> availableReactions) {
for (int i = 0; i < availableReactions.size(); i++) {
if (availableReactions.get(i).title.equals("Red Heart")) {
return availableReactions.get(i).reaction;
}
}
return availableReactions.get(0).reaction;
}
protected void updatePosition() {
float halfWidth = baseSize.width / 2.0f;
float halfHeight = baseSize.height / 2.0f;
setX(getPositionX() - halfWidth);
setY(getPositionY() - halfHeight);
updateSelectionView();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec((int) baseSize.width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) baseSize.height, MeasureSpec.EXACTLY));
}
@Override
protected void dispatchDraw(Canvas canvas) {
int padding = getPadding();
float crossfade = crossfadeBackgrounds.set(1f);
if (crossfade == 1f) {
outBackground = null;
}
canvas.save();
canvas.scale(drawScale, drawScale, getMeasuredWidth() / 2f, getMeasuredHeight() / 2f);
if (outBackground != null) {
outBackground.setAlpha((int) (255 * (1f - crossfade)));
outBackground.setBounds(padding, padding, (int) baseSize.width - padding, (int) baseSize.height - padding);
outBackground.draw(canvas);
}
storyReactionWidgetBackground.setAlpha((int) (255 * crossfade));
storyReactionWidgetBackground.setBounds(padding, padding, (int) baseSize.width - padding, (int) baseSize.height - padding);
storyReactionWidgetBackground.draw(canvas);
float imageSize = storyReactionWidgetBackground.getBounds().width() * 0.61f;
AndroidUtilities.rectTmp2.set(
(int) (storyReactionWidgetBackground.getBounds().centerX() - imageSize / 2f),
(int) (storyReactionWidgetBackground.getBounds().centerY() - imageSize / 2f),
(int) (storyReactionWidgetBackground.getBounds().centerX() + imageSize / 2f),
(int) (storyReactionWidgetBackground.getBounds().centerY() + imageSize / 2f)
);
float progress = progressToNext.set(1);
reactionHolder.setBounds(AndroidUtilities.rectTmp2);
nextReactionHolder.setBounds(AndroidUtilities.rectTmp2);
reactionHolder.setColor(storyReactionWidgetBackground.isDarkStyle() ? Color.WHITE : Color.BLACK);
if (progress == 1) {
reactionHolder.draw(canvas);
} else {
canvas.save();
canvas.scale(1f - progress, 1f - progress, AndroidUtilities.rectTmp2.centerX(), AndroidUtilities.rectTmp2.top);
nextReactionHolder.setAlpha(1f - progress);
nextReactionHolder.draw(canvas);
canvas.restore();
canvas.save();
canvas.scale(progress, progress, AndroidUtilities.rectTmp2.centerX(), AndroidUtilities.rectTmp2.bottom);
reactionHolder.setAlpha(progress);
reactionHolder.draw(canvas);
canvas.restore();
}
canvas.restore();
}
public int getPadding() {
return (int) ((baseSize.height - AndroidUtilities.dp(84)) / 2f);
}
@Override
protected Rect getSelectionBounds() {
ViewGroup parentView = (ViewGroup) getParent();
if (parentView == null) {
return new Rect();
}
float scale = parentView.getScaleX();
float side = getMeasuredWidth() * (getScale() + 0.4f);
return new Rect((getPositionX() - side / 2.0f) * scale, (getPositionY() - side / 2.0f) * scale, side * scale, side * scale);
}
@Override
protected SelectionView createSelectionView() {
return new StickerViewSelectionView(getContext());
}
public void setCurrentReaction(ReactionsLayoutInBubble.VisibleReaction visibleReaction, boolean animated) {
if (Objects.equals(currentReaction, visibleReaction)) {
return;
}
if (!animated) {
currentReaction = visibleReaction;
reactionHolder.setVisibleReaction(currentReaction);
invalidate();
} else {
currentReaction = visibleReaction;
nextReactionHolder.setVisibleReaction(currentReaction);
ReactionImageHolder k = reactionHolder;
reactionHolder = nextReactionHolder;
nextReactionHolder = k;
progressToNext.set(0, true);
invalidate();
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
reactionHolder.onAttachedToWindow(true);
nextReactionHolder.onAttachedToWindow(true);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
reactionHolder.onAttachedToWindow(false);
nextReactionHolder.onAttachedToWindow(false);
}
public ReactionsLayoutInBubble.VisibleReaction getCurrentReaction() {
return currentReaction;
}
public void mirror(boolean animate) {
mirror = !mirror;
if (!animate) {
storyReactionWidgetBackground.setMirror(mirror, animate);
} else {
boolean[] mirrored = new boolean[] {false};
ValueAnimator animator = ValueAnimator.ofFloat(0, 1f);
animator.addUpdateListener(animation -> {
float progress = (float) animation.getAnimatedValue();
if (progress < 0.5f) {
setRotationY(90 * (progress / 0.5f));
drawScale = 0.7f + 0.3f * (1f - (progress / 0.5f));
invalidate();
} else {
if (!mirrored[0]) {
mirrored[0] = true;
storyReactionWidgetBackground.setMirror(mirror, false);
}
progress -= 0.5f;
setRotationY(-90 * (1f - progress / 0.5f));
drawScale = 0.7f + 0.3f * (progress / 0.5f);
invalidate();
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (!mirrored[0]) {
mirrored[0] = true;
storyReactionWidgetBackground.setMirror(mirror, false);
}
setRotationY(0);
drawScale = 1f;
}
});
animator.setInterpolator(CubicBezierInterpolator.EASE_OUT);
animator.setDuration(350);
animator.start();
}
}
public void changeStyle(boolean animated) {
if (!animated) {
storyReactionWidgetBackground.nextStyle();
} else {
outBackground = storyReactionWidgetBackground;
storyReactionWidgetBackground = new StoryReactionWidgetBackground(this);
if (!outBackground.isDarkStyle()) {
storyReactionWidgetBackground.nextStyle();
}
storyReactionWidgetBackground.setMirror(mirror, false);
storyReactionWidgetBackground.updateShadowLayer(getScaleX());
crossfadeBackgrounds.set(0, true);
}
invalidate();
}
public boolean isMirrored() {
return mirror;
}
public boolean isDark() {
return storyReactionWidgetBackground.isDarkStyle();
}
// private void animateBounce() {
// AnimatorSet animatorSet = new AnimatorSet();
// ValueAnimator inAnimator = ValueAnimator.ofFloat(1, 1.05f);
// inAnimator.setDuration(100);
// inAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT);
//
// ValueAnimator outAnimator = ValueAnimator.ofFloat(1.05f, 1f);
// outAnimator.setDuration(250);
// outAnimator.setInterpolator(new OvershootInterpolator());
//
// ValueAnimator.AnimatorUpdateListener updater = animation -> {
// bounceScale = (float) animation.getAnimatedValue();
// invalidate();
// };
// setClipInParent(false);
// inAnimator.addUpdateListener(updater);
// outAnimator.addUpdateListener(updater);
// animatorSet.playSequentially(inAnimator, outAnimator);
// animatorSet.addListener(new AnimatorListenerAdapter() {
// @Override
// public void onAnimationEnd(Animator animation) {
// bounceScale = 1f;
// invalidate();
// setClipInParent(true);
// }
// });
// animatorSet.start();
//
// if (animationRunnable != null) {
// AndroidUtilities.cancelRunOnUIThread(animationRunnable);
// animationRunnable.run();
// animationRunnable = null;
// }
// }
public class StickerViewSelectionView extends SelectionView {
private RectF arcRect = new RectF();
public StickerViewSelectionView(Context context) {
super(context);
}
@Override
protected int pointInsideHandle(float x, float y) {
float thickness = AndroidUtilities.dp(1.0f);
float radius = AndroidUtilities.dp(19.5f);
float inset = radius + thickness;
float middle = inset + (getMeasuredHeight() - inset * 2) / 2.0f;
if (x > inset - radius && y > middle - radius && x < inset + radius && y < middle + radius) {
return SELECTION_LEFT_HANDLE;
} else if (x > inset + (getMeasuredWidth() - inset * 2) - radius && y > middle - radius && x < inset + (getMeasuredWidth() - inset * 2) + radius && y < middle + radius) {
return SELECTION_RIGHT_HANDLE;
}
float selectionRadius = getMeasuredWidth() / 2.0f;
if (Math.pow(x - selectionRadius, 2) + Math.pow(y - selectionRadius, 2) < Math.pow(selectionRadius, 2)) {
return SELECTION_WHOLE_HANDLE;
}
return 0;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int count = canvas.getSaveCount();
float alpha = getShowAlpha();
if (alpha <= 0) {
return;
} else if (alpha < 1) {
canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), (int) (0xFF * alpha), Canvas.ALL_SAVE_FLAG);
}
float thickness = AndroidUtilities.dp(1.0f);
float radius = AndroidUtilities.dpf2(5.66f);
float inset = radius + thickness + AndroidUtilities.dp(15);
float mainRadius = getMeasuredWidth() / 2 - inset;
arcRect.set(inset, inset, inset + mainRadius * 2, inset + mainRadius * 2);
canvas.drawArc(arcRect, 0, 180, false, paint);
canvas.drawArc(arcRect, 180, 180, false, paint);
canvas.drawCircle(inset, inset + mainRadius, radius, dotStrokePaint);
canvas.drawCircle(inset, inset + mainRadius, radius - AndroidUtilities.dp(1), dotPaint);
canvas.drawCircle(inset + mainRadius * 2, inset + mainRadius, radius, dotStrokePaint);
canvas.drawCircle(inset + mainRadius * 2, inset + mainRadius, radius - AndroidUtilities.dp(1), dotPaint);
canvas.restoreToCount(count);
}
}
@Override
public boolean allowLongPressOnSelected() {
return true;
}
@Override
public void setScaleX(float scaleX) {
if (getScaleX() != scaleX) {
super.setScaleX(scaleX);
storyReactionWidgetBackground.updateShadowLayer(scaleX);
invalidate();
}
}
@Override
protected float getMaxScale() {
return 1.8f;
}
@Override
protected float getMinScale() {
return 0.5f;
}
@Override
protected boolean allowHaptic() {
return false;
}
}

View file

@ -3,6 +3,7 @@ package org.telegram.ui.Components.Paint.Views;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.RectF; import android.graphics.RectF;
import android.util.Log;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;

View file

@ -34,6 +34,7 @@ import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.ColoredImageSpan; import org.telegram.ui.Components.ColoredImageSpan;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
@ -44,6 +45,9 @@ import java.util.ArrayList;
public class LimitPreviewView extends LinearLayout { public class LimitPreviewView extends LinearLayout {
private float percent;
private final int premiumLimit;
private int currentValue;
public int gradientTotalHeight; public int gradientTotalHeight;
boolean wasAnimation; boolean wasAnimation;
CounterView limitIcon; CounterView limitIcon;
@ -69,6 +73,10 @@ public class LimitPreviewView extends LinearLayout {
private boolean isBoostsStyle; private boolean isBoostsStyle;
Theme.ResourcesProvider resourcesProvider; Theme.ResourcesProvider resourcesProvider;
private boolean animateIncrease;
private int animateIncreaseWidth;
float limitIconRotation;
public boolean isStatistic;
public LimitPreviewView(@NonNull Context context, int icon, int currentValue, int premiumLimit, Theme.ResourcesProvider resourcesProvider) { public LimitPreviewView(@NonNull Context context, int icon, int currentValue, int premiumLimit, Theme.ResourcesProvider resourcesProvider) {
@ -79,8 +87,10 @@ public class LimitPreviewView extends LinearLayout {
public LimitPreviewView(@NonNull Context context, int icon, int currentValue, int premiumLimit, float inputPercent, Theme.ResourcesProvider resourcesProvider) { public LimitPreviewView(@NonNull Context context, int icon, int currentValue, int premiumLimit, float inputPercent, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
final float percent = MathUtils.clamp(inputPercent, 0.1f, 0.9f); this.percent = MathUtils.clamp(inputPercent, 0.1f, 0.9f);
this.icon = icon; this.icon = icon;
this.currentValue = currentValue;
this.premiumLimit = premiumLimit;
setOrientation(VERTICAL); setOrientation(VERTICAL);
setClipChildren(false); setClipChildren(false);
setClipToPadding(false); setClipToPadding(false);
@ -88,7 +98,7 @@ public class LimitPreviewView extends LinearLayout {
setPadding(0, dp(16), 0, 0); setPadding(0, dp(16), 0, 0);
limitIcon = new CounterView(context); limitIcon = new CounterView(context);
setIconValue(currentValue); setIconValue(currentValue, false);
limitIcon.setPadding(dp(24), dp(6), dp(24), dp(14)); limitIcon.setPadding(dp(24), dp(6), dp(24), dp(14));
addView(limitIcon, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 0, Gravity.LEFT)); addView(limitIcon, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 0, Gravity.LEFT));
@ -145,7 +155,11 @@ public class LimitPreviewView extends LinearLayout {
@Override @Override
protected void dispatchDraw(Canvas canvas) { protected void dispatchDraw(Canvas canvas) {
if (isBoostsStyle) { if (isBoostsStyle) {
grayPaint.setColor(Theme.getColor(Theme.key_graySection, resourcesProvider)); if (isStatistic) {
grayPaint.setColor(Theme.getColor(Theme.key_listSelector, resourcesProvider));
} else {
grayPaint.setColor(Theme.getColor(Theme.key_graySection, resourcesProvider));
}
} else { } else {
grayPaint.setColor(Theme.getColor(Theme.key_windowBackgroundGray, resourcesProvider)); grayPaint.setColor(Theme.getColor(Theme.key_windowBackgroundGray, resourcesProvider));
} }
@ -200,16 +214,35 @@ public class LimitPreviewView extends LinearLayout {
MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
); );
final int minWidth2 = Math.max(premiumLayout.getMeasuredWidth(), dp(24) + premiumText.getMeasuredWidth() + (premiumCount.getVisibility() == View.VISIBLE ? dp(24) + premiumCount.getMeasuredWidth() : 0)); if (isBoostsStyle) {
width1 = (int) Utilities.clamp(width * percent, width - minWidth2, minWidth1); if (percent == 0) {
defaultLayout.measure( width1 = 0;
MeasureSpec.makeMeasureSpec(width1, MeasureSpec.EXACTLY), premiumCount.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) defaultText.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
); } else if (percent < 1f) {
premiumLayout.measure( float leftWidth = defaultLayout.getMeasuredWidth() - AndroidUtilities.dp(8);
MeasureSpec.makeMeasureSpec(width - width1, MeasureSpec.EXACTLY), float rightWidth = premiumLayout.getMeasuredWidth() - AndroidUtilities.dp(8);
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) float availableWidth = width - leftWidth - rightWidth;
); width1 = (int) (leftWidth + availableWidth * percent);
premiumCount.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
defaultText.setTextColor(Color.WHITE);
} else {
width1 = width;
premiumCount.setTextColor(Color.WHITE);
defaultText.setTextColor(Color.WHITE);
}
} else {
final int minWidth2 = Math.max(premiumLayout.getMeasuredWidth(), dp(24) + premiumText.getMeasuredWidth() + (premiumCount.getVisibility() == View.VISIBLE ? dp(24) + premiumCount.getMeasuredWidth() : 0));
width1 = (int) Utilities.clamp(width * percent, width - minWidth2, minWidth1);
defaultLayout.measure(
MeasureSpec.makeMeasureSpec(width1, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
);
premiumLayout.measure(
MeasureSpec.makeMeasureSpec(width - width1, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
);
}
setMeasuredDimension(width, height); setMeasuredDimension(width, height);
} else { } else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@ -234,11 +267,12 @@ public class LimitPreviewView extends LinearLayout {
addView(limitsContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 30, 0, 0, 14, icon == 0 ? 0 : 12, 14, 0)); addView(limitsContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 30, 0, 0, 14, icon == 0 ? 0 : 12, 14, 0));
} }
public void setIconValue(int currentValue) { public void setIconValue(int currentValue, boolean animated) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append("d ").setSpan(new ColoredImageSpan(icon), 0, 1, 0); spannableStringBuilder.append("d ").setSpan(new ColoredImageSpan(icon), 0, 1, 0);
spannableStringBuilder.append(Integer.toString(currentValue)); spannableStringBuilder.append(Integer.toString(currentValue));
limitIcon.setText(spannableStringBuilder); limitIcon.setText(spannableStringBuilder, animated);
limitIcon.requestLayout();
} }
private float getGlobalXOffset() { private float getGlobalXOffset() {
@ -267,12 +301,18 @@ public class LimitPreviewView extends LinearLayout {
@Override @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) { protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b); super.onLayout(changed, l, t, r, b);
if (!wasAnimation && limitIcon != null && animationCanPlay && !premiumLocked) { if (animateIncrease || (!wasAnimation && limitIcon != null && animationCanPlay && !premiumLocked)) {
int padding = dp(14); int padding = dp(14);
float fromX = 0; boolean animateIncreaseFinal = animateIncrease;
animateIncrease = false;
float fromX = animateIncreaseFinal ? limitIcon.getTranslationX() : 0;
float toX = padding + Math.max(width1, (getMeasuredWidth() - padding * 2) * position) - limitIcon.getMeasuredWidth() / 2f; float toX = padding + Math.max(width1, (getMeasuredWidth() - padding * 2) * position) - limitIcon.getMeasuredWidth() / 2f;
float fromProgressCenter = 0.5f; float fromProgressCenter = 0.5f;
float toProgressCenter = 0.5f; float toProgressCenter = 0.5f;
if (toX < padding) {
toX = padding;
fromProgressCenter = toProgressCenter = 0f;
}
if (toX > getMeasuredWidth() - padding - limitIcon.getMeasuredWidth()) { if (toX > getMeasuredWidth() - padding - limitIcon.getMeasuredWidth()) {
toX = getMeasuredWidth() - padding - limitIcon.getMeasuredWidth(); toX = getMeasuredWidth() - padding - limitIcon.getMeasuredWidth();
toProgressCenter = 1f; toProgressCenter = 1f;
@ -281,13 +321,20 @@ public class LimitPreviewView extends LinearLayout {
limitIcon.setTranslationX(fromX); limitIcon.setTranslationX(fromX);
limitIcon.setPivotX(limitIcon.getMeasuredWidth() / 2f); limitIcon.setPivotX(limitIcon.getMeasuredWidth() / 2f);
limitIcon.setPivotY(limitIcon.getMeasuredHeight()); limitIcon.setPivotY(limitIcon.getMeasuredHeight());
limitIcon.setScaleX(0); if (!animateIncreaseFinal) {
limitIcon.setScaleY(0); limitIcon.setScaleX(0);
limitIcon.createAnimationLayouts(); limitIcon.setScaleY(0);
limitIcon.createAnimationLayouts();
}
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f); ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f);
float finalToX = toX; float finalToX = toX;
float finalToProgressCenter = toProgressCenter; float finalToProgressCenter = toProgressCenter;
float toWidth = width1;
if (animateIncreaseFinal) {
width1 = animateIncreaseWidth;
}
float finalFromProgressCenter = fromProgressCenter;
valueAnimator.addUpdateListener(animation -> { valueAnimator.addUpdateListener(animation -> {
float v = (float) animation.getAnimatedValue(); float v = (float) animation.getAnimatedValue();
float moveValue = Math.min(1f, v); float moveValue = Math.min(1f, v);
@ -296,25 +343,47 @@ public class LimitPreviewView extends LinearLayout {
wasHaptic = true; wasHaptic = true;
limitIcon.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); limitIcon.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
} }
limitIcon.setRotation((v - 1f) * 60); limitIcon.setRotation(limitIconRotation + (v - 1f) * 60);
} else { } else {
limitIcon.setRotation(0); limitIcon.setRotation(limitIconRotation);
} }
limitIcon.setTranslationX(fromX * (1f - moveValue) + finalToX * moveValue); limitIcon.setTranslationX(fromX * (1f - moveValue) + finalToX * moveValue);
float arrowCenter = fromProgressCenter * (1f - moveValue) + finalToProgressCenter * moveValue; float arrowCenter = finalFromProgressCenter * (1f - moveValue) + finalToProgressCenter * moveValue;
limitIcon.setArrowCenter(arrowCenter); limitIcon.setArrowCenter(arrowCenter);
float scale = Math.min(1, moveValue * 2f); float scale = Math.min(1, moveValue * 2f);
limitIcon.setScaleX(scale); if (!animateIncreaseFinal) {
limitIcon.setScaleY(scale); limitIcon.setScaleX(scale);
limitIcon.setScaleY(scale);
} else {
width1 = (int) AndroidUtilities.lerp(animateIncreaseWidth, toWidth, moveValue);
limitsContainer.invalidate();
}
limitIcon.setPivotX(limitIcon.getMeasuredWidth() * arrowCenter); limitIcon.setPivotX(limitIcon.getMeasuredWidth() * arrowCenter);
}); });
valueAnimator.setInterpolator(new OvershootInterpolator()); valueAnimator.setInterpolator(new OvershootInterpolator());
valueAnimator.setDuration(1000); if (animateIncreaseFinal) {
valueAnimator.setStartDelay(200); ValueAnimator valueAnimator1 = ValueAnimator.ofFloat(0, 1f);
valueAnimator1.addUpdateListener(animation -> {
float p = (float) animation.getAnimatedValue();
float k = 0.5f;
float angle = -7;
limitIconRotation = p < k ? p / k * angle : angle * (1f - (p - k) / (1f - k));
});
valueAnimator1.setDuration(500);
valueAnimator1.start();
valueAnimator.setDuration(600);
} else {
valueAnimator.setDuration(1000);
valueAnimator.setStartDelay(200);
}
valueAnimator.start(); valueAnimator.start();
wasAnimation = true; wasAnimation = true;
} else if (isBoostsStyle) {
limitIcon.setAlpha(1f);
limitIcon.setScaleX(1f);
limitIcon.setScaleY(1f);
} else if (premiumLocked) { } else if (premiumLocked) {
int padding = dp(14); int padding = dp(14);
float toX = padding + (getMeasuredWidth() - padding * 2) * 0.5f - limitIcon.getMeasuredWidth() / 2f; float toX = padding + (getMeasuredWidth() - padding * 2) * 0.5f - limitIcon.getMeasuredWidth() / 2f;
@ -331,7 +400,7 @@ public class LimitPreviewView extends LinearLayout {
limitIcon.setScaleY(1f); limitIcon.setScaleY(1f);
} }
limitIcon.setTranslationX(toX); limitIcon.setTranslationX(toX);
} else if (limitIcon != null){ } else if (limitIcon != null) {
limitIcon.setAlpha(0); limitIcon.setAlpha(0);
} }
} }
@ -342,14 +411,14 @@ public class LimitPreviewView extends LinearLayout {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append("d ").setSpan(new ColoredImageSpan(icon), 0, 1, 0); spannableStringBuilder.append("d ").setSpan(new ColoredImageSpan(icon), 0, 1, 0);
spannableStringBuilder.append(UserConfig.getInstance(UserConfig.selectedAccount).isPremium() ? "4 GB" : "2 GB"); spannableStringBuilder.append(UserConfig.getInstance(UserConfig.selectedAccount).isPremium() ? "4 GB" : "2 GB");
limitIcon.setText(spannableStringBuilder); limitIcon.setText(spannableStringBuilder, false);
} }
premiumCount.setText("4 GB"); premiumCount.setText("4 GB");
} else if (type == LimitReachedBottomSheet.TYPE_ADD_MEMBERS_RESTRICTED) { } else if (type == LimitReachedBottomSheet.TYPE_ADD_MEMBERS_RESTRICTED) {
if (limitIcon != null) { if (limitIcon != null) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append("d").setSpan(new ColoredImageSpan(icon), 0, 1, 0); spannableStringBuilder.append("d").setSpan(new ColoredImageSpan(icon), 0, 1, 0);
limitIcon.setText(spannableStringBuilder); limitIcon.setText(spannableStringBuilder, false);
} }
premiumCount.setText(""); premiumCount.setText("");
} }
@ -382,6 +451,41 @@ public class LimitPreviewView extends LinearLayout {
premiumLocked = true; premiumLocked = true;
} }
public void setBoosts(TLRPC.TL_stories_boostsStatus boosts, boolean boosted) {
int k = boosts.current_level_boosts;
boolean isZeroLevelBoosts = boosts.current_level_boosts == boosts.boosts;
if ((isZeroLevelBoosts && boosted) || boosts.next_level_boosts == 0) {
percent = 1f;
defaultText.setText(LocaleController.formatString("BoostsLevel", R.string.BoostsLevel, boosts.level - 1));
premiumCount.setText(LocaleController.formatString("BoostsLevel", R.string.BoostsLevel, boosts.level));
} else {
percent = MathUtils.clamp((boosts.boosts - k) / (float) (boosts.next_level_boosts - k), 0, 1f);
defaultText.setText(LocaleController.formatString("BoostsLevel", R.string.BoostsLevel, boosts.level));
premiumCount.setText(LocaleController.formatString("BoostsLevel", R.string.BoostsLevel, boosts.level + 1));
}
setType(LimitReachedBottomSheet.TYPE_BOOSTS);
defaultCount.setVisibility(View.GONE);
premiumText.setVisibility(View.GONE);
premiumCount.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
defaultText.setTextColor(Color.WHITE);
setIconValue(boosts.boosts, false);
isBoostsStyle = true;
}
public void increaseCurrentValue(int value, int maxValue) {
currentValue++;
percent = MathUtils.clamp(value / (float) maxValue, 0f, 1f);
animateIncrease = true;
animateIncreaseWidth = width1;
setIconValue(currentValue, true);
limitsContainer.requestLayout();
requestLayout();
}
private class CounterView extends View { private class CounterView extends View {
Path path = new Path(); Path path = new Path();
@ -418,12 +522,14 @@ public class LimitPreviewView extends LinearLayout {
int h = getMeasuredHeight() - dp(8); int h = getMeasuredHeight() - dp(8);
float widthHalf = getMeasuredWidth() * arrowCenter; float widthHalf = getMeasuredWidth() * arrowCenter;
float x2 = Utilities.clamp(widthHalf + dp(8), getMeasuredWidth(), 0); float x2 = Utilities.clamp(widthHalf + dp(8), getMeasuredWidth(), 0);
float x3 = Utilities.clamp(widthHalf + dp(10), getMeasuredWidth(), 0); float x3 = Utilities.clamp(widthHalf + dp(10), getMeasuredWidth(), AndroidUtilities.dp(24));
float x4 = Utilities.clamp(widthHalf - dp(24), getMeasuredWidth(), 0);
float x5 = Utilities.clamp(widthHalf - dp(8), getMeasuredWidth(), 0);
path.rewind(); path.rewind();
path.moveTo(widthHalf - dp(24), h - h / 2f - dp(2)); path.moveTo(x4, h - h / 2f - dp(2));
path.lineTo(widthHalf - dp(24), h); path.lineTo(x4, h);
path.lineTo(widthHalf - dp(8), h); path.lineTo(x5, h);
path.lineTo(widthHalf, h + dp(8)); path.lineTo(widthHalf, h + dp(8));
if (arrowCenter < 0.7f) { if (arrowCenter < 0.7f) {
path.lineTo(x2, h); path.lineTo(x2, h);
@ -476,7 +582,13 @@ public class LimitPreviewView extends LinearLayout {
for (int i = 0; i < animatedLayouts.size(); i++) { for (int i = 0; i < animatedLayouts.size(); i++) {
AnimatedLayout animatedLayout = animatedLayouts.get(i); AnimatedLayout animatedLayout = animatedLayouts.get(i);
canvas.save(); canvas.save();
if (animatedLayout.direction) { if (animatedLayout.replace) {
canvas.translate(x + animatedLayout.x, y + h * (animatedLayout.progress) - h * (1 - animatedLayout.staticLayouts.size()));
for (int j = 0; j < animatedLayout.staticLayouts.size(); j++) {
canvas.translate(0, -h);
animatedLayout.staticLayouts.get(j).draw(canvas);
}
} else if (animatedLayout.direction) {
canvas.translate(x + animatedLayout.x, y - h * 10 * animatedLayout.progress + h * (10 - animatedLayout.staticLayouts.size())); canvas.translate(x + animatedLayout.x, y - h * 10 * animatedLayout.progress + h * (10 - animatedLayout.staticLayouts.size()));
for (int j = 0; j < animatedLayout.staticLayouts.size(); j++) { for (int j = 0; j < animatedLayout.staticLayouts.size(); j++) {
canvas.translate(0, h); canvas.translate(0, h);
@ -506,6 +618,9 @@ public class LimitPreviewView extends LinearLayout {
void createAnimationLayouts() { void createAnimationLayouts() {
animatedLayouts.clear(); animatedLayouts.clear();
if (isBoostsStyle && currentValue == 0) {
return;
}
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
boolean direction = true; boolean direction = true;
@ -561,6 +676,55 @@ public class LimitPreviewView extends LinearLayout {
} }
} }
void createAnimationLayoutsDiff(CharSequence oldText) {
animatedLayouts.clear();
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
int directionCount = 0;
for (int i = text.length() - 1; i >= 0; i--) {
char oldChar = i < oldText.length() ? oldText.charAt(i) : ' ';
if (oldChar != text.charAt(i) && Character.isDigit(text.charAt(i))) {
AnimatedLayout animatedLayout = new AnimatedLayout();
animatedLayouts.add(animatedLayout);
animatedLayout.x = textLayout.getSecondaryHorizontal(i);
animatedLayout.replace = true;
if (directionCount >= 1) {
directionCount = 0;
}
directionCount++;
StaticLayout staticLayoutOld = new StaticLayout("" + oldChar, textPaint, (int) textWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
animatedLayout.staticLayouts.add(staticLayoutOld);
StaticLayout staticLayout = new StaticLayout("" + text.charAt(i), textPaint, (int) textWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
animatedLayout.staticLayouts.add(staticLayout);
spannableStringBuilder.setSpan(new EmptyStubSpan(), i, i + 1, 0);
}
}
animatedStableLayout = new StaticLayout(spannableStringBuilder, textPaint, (int) textWidth + dp(12), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
for (int i = 0; i < animatedLayouts.size(); i++) {
animationInProgress = true;
AnimatedLayout layout = animatedLayouts.get(i);
layout.valueAnimator = ValueAnimator.ofFloat(0, 1f);
layout.valueAnimator.addUpdateListener(animation -> {
layout.progress = (float) animation.getAnimatedValue();
invalidate();
});
layout.valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
layout.valueAnimator = null;
checkAnimationComplete();
}
});
layout.valueAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT);
layout.valueAnimator.setDuration(250);
layout.valueAnimator.setStartDelay((animatedLayouts.size() - 1 - i) * 60L);
layout.valueAnimator.start();
}
}
private void checkAnimationComplete() { private void checkAnimationComplete() {
for (int i = 0; i < animatedLayouts.size(); i++) { for (int i = 0; i < animatedLayouts.size(); i++) {
if (animatedLayouts.get(i).valueAnimator != null) { if (animatedLayouts.get(i).valueAnimator != null) {
@ -572,8 +736,14 @@ public class LimitPreviewView extends LinearLayout {
invalidate(); invalidate();
} }
public void setText(CharSequence text) { public void setText(CharSequence text, boolean animated) {
this.text = text; if (!animated) {
this.text = text;
} else {
CharSequence oldText = this.text;
this.text = text;
createAnimationLayoutsDiff(oldText);
}
} }
public void setArrowCenter(float v) { public void setArrowCenter(float v) {
@ -585,6 +755,7 @@ public class LimitPreviewView extends LinearLayout {
} }
private class AnimatedLayout { private class AnimatedLayout {
public boolean replace;
ArrayList<StaticLayout> staticLayouts = new ArrayList<>(); ArrayList<StaticLayout> staticLayouts = new ArrayList<>();
float progress; float progress;
public boolean direction; public boolean direction;

View file

@ -1,26 +1,41 @@
package org.telegram.ui.Components.Premium; package org.telegram.ui.Components.Premium;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.TextUtils; import android.text.TextUtils;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.transition.TransitionValues;
import android.transition.Visibility;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.checkerframework.checker.units.qual.A;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChannelBoostsController;
import org.telegram.messenger.ChatObject; import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController; import org.telegram.messenger.ContactsController;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
@ -37,14 +52,22 @@ import org.telegram.ui.Cells.AdminedChannelCell;
import org.telegram.ui.Cells.GroupCreateUserCell; import org.telegram.ui.Cells.GroupCreateUserCell;
import org.telegram.ui.Cells.HeaderCell; import org.telegram.ui.Cells.HeaderCell;
import org.telegram.ui.Cells.ShadowSectionCell; import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.BottomSheetWithRecyclerListView; import org.telegram.ui.Components.BottomSheetWithRecyclerListView;
import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.ColoredImageSpan; import org.telegram.ui.Components.ColoredImageSpan;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.FireworksOverlay;
import org.telegram.ui.Components.FlickerLoadingView; import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RecyclerItemsEnterAnimator; import org.telegram.ui.Components.RecyclerItemsEnterAnimator;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.ScaleStateListAnimator;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PremiumPreviewFragment; import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.Stories.ChannelBoostUtilities;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -71,10 +94,16 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
public static final int TYPE_STORIES_WEEK = 15; public static final int TYPE_STORIES_WEEK = 15;
public static final int TYPE_STORIES_MONTH = 16; public static final int TYPE_STORIES_MONTH = 16;
public static final int TYPE_BOOSTS = 17; public static final int TYPE_BOOSTS = 17;
public static final int TYPE_BOOSTS_FOR_POSTING = 18;
public static final int TYPE_BOOSTS_FOR_USERS = 19;
private boolean canSendLink; private boolean canSendLink;
private int linkRow = -1; private int linkRow = -1;
private long dialogId; private long dialogId;
private TLRPC.TL_stories_boostsStatus boostsStatus;
private ChannelBoostsController.CanApplyBoost canApplyBoost;
private HeaderView headerView;
private boolean isCurrentChat;
public static String limitTypeToServerString(int type) { public static String limitTypeToServerString(int type) {
switch (type) { switch (type) {
@ -135,6 +164,8 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
LimitParams limitParams; LimitParams limitParams;
private boolean isVeryLargeFile; private boolean isVeryLargeFile;
private TLRPC.Chat fromChat; private TLRPC.Chat fromChat;
FireworksOverlay fireworksOverlay;
Runnable statisticClickRunnable;
public LimitReachedBottomSheet(BaseFragment fragment, Context context, int type, int currentAccount, Theme.ResourcesProvider resourcesProvider) { public LimitReachedBottomSheet(BaseFragment fragment, Context context, int type, int currentAccount, Theme.ResourcesProvider resourcesProvider) {
super(fragment, false, hasFixedSize(type), false, resourcesProvider); super(fragment, false, hasFixedSize(type), false, resourcesProvider);
@ -150,6 +181,10 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
loadInactiveChannels(); loadInactiveChannels();
} }
updatePremiumButtonText(); updatePremiumButtonText();
if (type == TYPE_BOOSTS_FOR_USERS) {
fireworksOverlay = new FireworksOverlay(getContext());
container.addView(fireworksOverlay, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
} }
@Override @Override
@ -209,6 +244,125 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
if (type == TYPE_ADD_MEMBERS_RESTRICTED) { if (type == TYPE_ADD_MEMBERS_RESTRICTED) {
return; return;
} }
if (type == TYPE_BOOSTS_FOR_USERS) {
canApplyBoost.checkTime();
if (!UserConfig.getInstance(currentAccount).isPremium()) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(LocaleController.getString("PremiumNeeded", R.string.PremiumNeeded));
builder.setSubtitle(AndroidUtilities.replaceTags(LocaleController.getString("PremiumNeededForBoosting", R.string.PremiumNeededForBoosting)));
builder.setPositiveButton(LocaleController.getString("CheckPhoneNumberYes", R.string.CheckPhoneNumberYes), (dialog, which) -> {
PremiumFeatureBottomSheet featureBottomSheet = new PremiumFeatureBottomSheet(parentFragment, PremiumPreviewFragment.PREMIUM_FEATURE_STORIES, false);
parentFragment.showDialog(featureBottomSheet);
LimitReachedBottomSheet.this.dismiss();
dialog.dismiss();
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), (dialog, which) -> dialog.dismiss());
builder.show();
} else if (canApplyBoost.canApply && canApplyBoost.replaceDialogId == 0) {
boostChannel();
} else if (canApplyBoost.giftedPremium) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(LocaleController.getString("CantBoostWithGiftedPremium", R.string.CantBoostWithGiftedPremium));
builder.setSubtitle(AndroidUtilities.replaceTags(LocaleController.formatString("CantBoostWithGiftedPremiumDescription ", R.string.CantBoostWithGiftedPremiumDescription)));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialog, which) -> {
dialog.dismiss();
});
builder.show();
} else if (canApplyBoost.canApply) {
FrameLayout frameLayout = new FrameLayout(getContext());
BackupImageView fromAvatar = new BackupImageView(getContext());
fromAvatar.setRoundRadius(AndroidUtilities.dp(30));
frameLayout.addView(fromAvatar, LayoutHelper.createFrame(60, 60));
frameLayout.setClipChildren(false);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Theme.getColor(Theme.key_dialogBackground));
Drawable boostDrawable = ContextCompat.getDrawable(getContext(), R.drawable.filled_limit_boost);
View boostIcon = new View(getContext()) {
@Override
protected void onDraw(Canvas canvas) {
float cx = getMeasuredWidth() / 2f;
float cy = getMeasuredHeight() / 2f;
canvas.drawCircle(cx, cy, getMeasuredWidth() / 2f, paint);
PremiumGradient.getInstance().updateMainGradientMatrix(0, 0, getMeasuredWidth(), getMeasuredHeight(), -AndroidUtilities.dp(10), 0);
canvas.drawCircle(cx, cy, getMeasuredWidth() / 2f - AndroidUtilities.dp(2), PremiumGradient.getInstance().getMainGradientPaint());
float iconSizeHalf = AndroidUtilities.dp(18) / 2f;
boostDrawable.setBounds(
(int) (cx - iconSizeHalf),
(int) (cy - iconSizeHalf),
(int) (cx + iconSizeHalf),
(int) (cy + iconSizeHalf)
);
boostDrawable.draw(canvas);
}
};
frameLayout.addView(boostIcon, LayoutHelper.createFrame(28, 28, 0, 34, 34, 0, 0));
ImageView imageView = new ImageView(getContext());
imageView.setImageResource(R.drawable.msg_arrow_avatar);
imageView.setColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon));
frameLayout.addView(imageView, LayoutHelper.createFrame(24, 24, Gravity.CENTER));
BackupImageView toAvatar = new BackupImageView(getContext());
toAvatar.setRoundRadius(AndroidUtilities.dp(30));
frameLayout.addView(toAvatar, LayoutHelper.createFrame(60, 60, 0, 60 + 36, 0, 0, 0));
FrameLayout containerLayout = new FrameLayout(getContext());
containerLayout.addView(frameLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 60, Gravity.CENTER_HORIZONTAL));
containerLayout.setClipChildren(false);
TextView textView = new TextView(context);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
textView.setLetterSpacing(0.025f);
}
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
containerLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 24, 80, 24, 0));
AvatarDrawable fromAvatarDrawable = new AvatarDrawable();
TLRPC.Chat fromChat = MessagesController.getInstance(currentAccount).getChat(-canApplyBoost.replaceDialogId);
fromAvatarDrawable.setInfo(fromChat);
fromAvatar.setForUserOrChat(fromChat, fromAvatarDrawable);
AvatarDrawable toAvatarDrawable = new AvatarDrawable();
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
toAvatarDrawable.setInfo(chat);
toAvatar.setForUserOrChat(chat, toAvatarDrawable);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setView(containerLayout);
textView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("ReplaceBoostChannelDescription", R.string.ReplaceBoostChannelDescription,fromChat.title, chat.title)));
builder.setPositiveButton(LocaleController.getString("Replace", R.string.Replace), (dialog, which) -> {
dialog.dismiss();
boostChannel();
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), (dialog, which) -> dialog.dismiss());
builder.show();
} else if (canApplyBoost.floodWait != 0) {
String timeString;
int time = canApplyBoost.floodWait;
if (time < 60) {
timeString = LocaleController.formatPluralString("Seconds", time);
} else if (time < 60 * 60){
timeString = LocaleController.formatPluralString("Minutes", time / 60);
} else if (time / 60 / 60 > 2) {
timeString = LocaleController.formatPluralString("Hours", time / 60 / 60);
} else {
timeString = LocaleController.formatPluralString("Hours", time / 60 / 60) + " " + LocaleController.formatPluralString("Minutes", time % 60);
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(LocaleController.getString("CantBoostTooOften", R.string.CantBoostTooOften));
builder.setSubtitle(AndroidUtilities.replaceTags(LocaleController.formatString("CantBoostTooOftenDescription", R.string.CantBoostTooOftenDescription, timeString)));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialog, which) -> {
dialog.dismiss();
});
builder.show();
}
return;
}
if (type == TYPE_BOOSTS_FOR_POSTING) {
AndroidUtilities.addToClipboard(getBoostLink());
dismiss();
return;
}
if (UserConfig.getInstance(currentAccount).isPremium() || MessagesController.getInstance(currentAccount).premiumLocked || isVeryLargeFile) { if (UserConfig.getInstance(currentAccount).isPremium() || MessagesController.getInstance(currentAccount).premiumLocked || isVeryLargeFile) {
dismiss(); dismiss();
return; return;
@ -226,6 +380,10 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
dismiss(); dismiss();
}); });
premiumButtonView.overlayTextView.setOnClickListener(v -> { premiumButtonView.overlayTextView.setOnClickListener(v -> {
if (type == TYPE_BOOSTS_FOR_USERS) {
dismiss();
return;
}
if (type == TYPE_ADD_MEMBERS_RESTRICTED) { if (type == TYPE_ADD_MEMBERS_RESTRICTED) {
if (selectedChats.isEmpty()) { if (selectedChats.isEmpty()) {
dismiss(); dismiss();
@ -246,6 +404,49 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
enterAnimator = new RecyclerItemsEnterAnimator(recyclerListView, true); enterAnimator = new RecyclerItemsEnterAnimator(recyclerListView, true);
} }
private void boostChannel() {
TransitionSet transitionSet = new TransitionSet();
transitionSet.addTransition(new Visibility() {
@Override
public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) {
AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1f),
ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, AndroidUtilities.dp(20), 0)
);
set.setInterpolator(CubicBezierInterpolator.DEFAULT);
return set;
}
@Override
public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) {
AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), 0f),
ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, 0, -AndroidUtilities.dp(20))
);
set.setInterpolator(CubicBezierInterpolator.DEFAULT);
return set;
}
});
transitionSet.setOrdering(TransitionSet.ORDERING_TOGETHER);
TransitionManager.beginDelayedTransition(headerView, transitionSet);
MessagesController.getInstance(currentAccount).getBoostsController().applyBoost(dialogId);
limitPreviewView.increaseCurrentValue((boostsStatus.boosts + 1) - boostsStatus.next_level_boosts * boostsStatus.level, boostsStatus.next_level_boosts - boostsStatus.next_level_boosts * boostsStatus.level);
boostsStatus.boosts++;
if (boostsStatus.next_level_boosts == boostsStatus.boosts) {
boostsStatus.level += 1;
boostsStatus.current_level_boosts = boostsStatus.boosts;
}
canApplyBoost.alreadyActive = true;
headerView.recreateTitleAndDescription();
headerView.title.setText(getBoostsTitleString());
headerView.description.setText(AndroidUtilities.replaceTags(getBoostsDescriptionString()));
updateButton();
fireworksOverlay.start();
fireworksOverlay.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
}
private void sendInviteMessages() { private void sendInviteMessages() {
String link = null; String link = null;
TLRPC.ChatFull chatFull = MessagesController.getInstance(currentAccount).getChatFull(fromChat.id); TLRPC.ChatFull chatFull = MessagesController.getInstance(currentAccount).getChatFull(fromChat.id);
@ -267,7 +468,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
} }
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
BulletinFactory factory = BulletinFactory.global(); BulletinFactory factory = BulletinFactory.global();
if (factory != null) { if (factory != null) {
if (selectedChats.size() == 1) { if (selectedChats.size() == 1) {
TLRPC.User user = (TLRPC.User) selectedChats.iterator().next(); TLRPC.User user = (TLRPC.User) selectedChats.iterator().next();
factory.createSimpleBulletin(R.raw.voip_invite, factory.createSimpleBulletin(R.raw.voip_invite,
@ -284,7 +485,14 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
} }
public void updatePremiumButtonText() { public void updatePremiumButtonText() {
if (UserConfig.getInstance(currentAccount).isPremium() || MessagesController.getInstance(currentAccount).premiumLocked || isVeryLargeFile) { if (type == TYPE_BOOSTS_FOR_USERS) {
premiumButtonView.buttonTextView.setText(LocaleController.getString("BoostChannel", R.string.BoostChannel));
} else if (type == TYPE_BOOSTS_FOR_POSTING) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("d ");
spannableStringBuilder.setSpan(new ColoredImageSpan(R.drawable.msg_copy_filled), 0, 1, 0);
spannableStringBuilder.append(LocaleController.getString("CopyLink", R.string.CopyLink));
premiumButtonView.buttonTextView.setText(spannableStringBuilder);
} else if (UserConfig.getInstance(currentAccount).isPremium() || MessagesController.getInstance(currentAccount).premiumLocked || isVeryLargeFile) {
premiumButtonView.buttonTextView.setText(LocaleController.getString("OK", R.string.OK)); premiumButtonView.buttonTextView.setText(LocaleController.getString("OK", R.string.OK));
premiumButtonView.hideIcon(); premiumButtonView.hideIcon();
} else { } else {
@ -293,9 +501,9 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
if (limitParams.defaultLimit + 1 == limitParams.premiumLimit) { if (limitParams.defaultLimit + 1 == limitParams.premiumLimit) {
premiumButtonView.setIcon(R.raw.addone_icon); premiumButtonView.setIcon(R.raw.addone_icon);
} else if ( } else if (
limitParams.defaultLimit != 0 && limitParams.premiumLimit != 0 && limitParams.defaultLimit != 0 && limitParams.premiumLimit != 0 &&
limitParams.premiumLimit / (float) limitParams.defaultLimit >= 1.6f && limitParams.premiumLimit / (float) limitParams.defaultLimit >= 1.6f &&
limitParams.premiumLimit / (float) limitParams.defaultLimit <= 2.5f limitParams.premiumLimit / (float) limitParams.defaultLimit <= 2.5f
) { ) {
premiumButtonView.setIcon(R.raw.double_icon); premiumButtonView.setIcon(R.raw.double_icon);
} else { } else {
@ -339,7 +547,13 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
} }
private void updateButton() { private void updateButton() {
if (type == TYPE_ADD_MEMBERS_RESTRICTED) { if (type == TYPE_BOOSTS_FOR_USERS) {
if (canApplyBoost.alreadyActive) {
premiumButtonView.setOverlayText(LocaleController.getString("OK", R.string.OK), true, true);
} else {
premiumButtonView.clearOverlayText();
}
} else if (type == TYPE_ADD_MEMBERS_RESTRICTED) {
premiumButtonView.checkCounterView(); premiumButtonView.checkCounterView();
if (!canSendLink) { if (!canSendLink) {
premiumButtonView.setOverlayText(LocaleController.getString("Close", R.string.Close), true, true); premiumButtonView.setOverlayText(LocaleController.getString("Close", R.string.Close), true, true);
@ -369,7 +583,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
if (type == TYPE_PIN_DIALOGS || type == TYPE_FOLDERS || type == TYPE_CHATS_IN_FOLDER || if (type == TYPE_PIN_DIALOGS || type == TYPE_FOLDERS || type == TYPE_CHATS_IN_FOLDER ||
type == TYPE_LARGE_FILE || type == TYPE_ACCOUNTS || type == TYPE_FOLDER_INVITES || type == TYPE_LARGE_FILE || type == TYPE_ACCOUNTS || type == TYPE_FOLDER_INVITES ||
type == TYPE_SHARED_FOLDERS || type == TYPE_STORIES_COUNT || type == TYPE_STORIES_WEEK || type == TYPE_SHARED_FOLDERS || type == TYPE_STORIES_COUNT || type == TYPE_STORIES_WEEK ||
type == TYPE_STORIES_MONTH) { type == TYPE_STORIES_MONTH || type == TYPE_BOOSTS_FOR_POSTING || type == TYPE_BOOSTS_FOR_USERS) {
return true; return true;
} }
return false; return false;
@ -403,21 +617,35 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
case 7: case 7:
FrameLayout frameLayout = new FrameLayout(getContext()); FrameLayout frameLayout = new FrameLayout(getContext());
TextView linkView = new TextView(context); TextView linkView = new TextView(context);
linkView.setPadding(AndroidUtilities.dp(18), AndroidUtilities.dp(13), AndroidUtilities.dp(40), AndroidUtilities.dp(13)); linkView.setPadding(AndroidUtilities.dp(18), AndroidUtilities.dp(13), AndroidUtilities.dp(50), AndroidUtilities.dp(13));
linkView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); linkView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
linkView.setEllipsize(TextUtils.TruncateAt.MIDDLE); linkView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
linkView.setSingleLine(true); linkView.setSingleLine(true);
frameLayout.addView(linkView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 11, 0, 11, 0)); frameLayout.addView(linkView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 11, 0, 11, 0));
linkView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(8), Theme.getColor(Theme.key_graySection, resourcesProvider), ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_listSelector, resourcesProvider), (int) (255 * 0.3f)))); linkView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(8), Theme.getColor(Theme.key_graySection, resourcesProvider), ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_listSelector, resourcesProvider), (int) (255 * 0.3f))));
linkView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider)); linkView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
linkView.setOnClickListener(v -> {
AndroidUtilities.addToClipboard(getBoostLink());
});
if (statisticClickRunnable != null) {
ImageView imageView = new ImageView(getContext());
imageView.setImageResource(R.drawable.msg_stats);
imageView.setColorFilter(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
imageView.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8));
imageView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(20), 0, ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_listSelector, resourcesProvider), (int) (255 * 0.3f))));
frameLayout.addView(imageView, LayoutHelper.createFrame(40, 40 ,Gravity.RIGHT | Gravity.CENTER_VERTICAL, 15, 0, 15, 0));
imageView.setOnClickListener(v -> {
statisticClickRunnable.run();
dismiss();
});
}
linkView.setText(getBoostLink()); linkView.setText(getBoostLink());
linkView.setGravity(Gravity.CENTER); linkView.setGravity(Gravity.CENTER);
view = frameLayout; view = frameLayout;
break; break;
default: default:
case 0: case 0:
view = new HeaderView(context); view = headerView = new HeaderView(context);
break; break;
case 1: case 1:
view = new AdminedChannelCell(context, new View.OnClickListener() { view = new AdminedChannelCell(context, new View.OnClickListener() {
@ -532,8 +760,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
} }
private String getBoostLink() { private String getBoostLink() {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId); return ChannelBoostUtilities.createLink(currentAccount, dialogId);
return "https://" + ChatObject.getPublicUsername(chat) +"?boost";
} }
public void setCurrentValue(int currentValue) { public void setCurrentValue(int currentValue) {
@ -561,8 +788,25 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
this.dialogId = dialogId; this.dialogId = dialogId;
} }
public void setBoostsStats(TLRPC.TL_stories_boostsStatus boostsStatus, boolean isCurrentChat) {
this.boostsStatus = boostsStatus;
this.isCurrentChat = isCurrentChat;
}
public void setCanApplyBoost(ChannelBoostsController.CanApplyBoost canApplyBoost) {
this.canApplyBoost = canApplyBoost;
updateButton();
}
public void showStatisticButtonInLink(Runnable runnable) {
this.statisticClickRunnable = runnable;
}
private class HeaderView extends LinearLayout { private class HeaderView extends LinearLayout {
TextView title;
TextView description;
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
public HeaderView(Context context) { public HeaderView(Context context) {
super(context); super(context);
@ -573,7 +817,14 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
int icon = limitParams.icon; int icon = limitParams.icon;
String descriptionStr; String descriptionStr;
boolean premiumLocked = MessagesController.getInstance(currentAccount).premiumLocked; boolean premiumLocked = MessagesController.getInstance(currentAccount).premiumLocked;
if (type == TYPE_ADD_MEMBERS_RESTRICTED) { if (type == TYPE_BOOSTS_FOR_USERS) {
descriptionStr = getBoostsDescriptionString();
} else if (type == TYPE_BOOSTS_FOR_POSTING) {
descriptionStr = LocaleController.formatString(
"ChannelNeedBoostsDescription", R.string.ChannelNeedBoostsDescription,
LocaleController.formatPluralString("MoreBoosts", boostsStatus.next_level_boosts, boostsStatus.next_level_boosts)
);
} else if (type == TYPE_ADD_MEMBERS_RESTRICTED) {
premiumLocked = true; premiumLocked = true;
if (!canSendLink) { if (!canSendLink) {
if (ChatObject.isChannelAndNotMegaGroup(fromChat)) { if (ChatObject.isChannelAndNotMegaGroup(fromChat)) {
@ -654,21 +905,31 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
percent = defaultLimit / (float) premiumLimit; percent = defaultLimit / (float) premiumLimit;
if (type == TYPE_BOOSTS_FOR_POSTING || type == TYPE_BOOSTS_FOR_USERS) {
currentValue = 0;
}
limitPreviewView = new LimitPreviewView(context, icon, currentValue, premiumLimit, percent, resourcesProvider); limitPreviewView = new LimitPreviewView(context, icon, currentValue, premiumLimit, percent, resourcesProvider);
limitPreviewView.setBagePosition(position); if (type == TYPE_BOOSTS_FOR_POSTING || type == TYPE_BOOSTS_FOR_USERS) {
limitPreviewView.setType(type); if (boostsStatus != null) {
limitPreviewView.defaultCount.setVisibility(View.GONE); limitPreviewView.setBoosts(boostsStatus, canApplyBoost != null && canApplyBoost.alreadyActive);
if (premiumLocked) { }
limitPreviewView.setPremiumLocked();
} else { } else {
if (UserConfig.getInstance(currentAccount).isPremium() || isVeryLargeFile) { limitPreviewView.setBagePosition(position);
limitPreviewView.premiumCount.setVisibility(View.GONE); limitPreviewView.setType(type);
if (type == TYPE_LARGE_FILE) { limitPreviewView.defaultCount.setVisibility(View.GONE);
limitPreviewView.defaultCount.setText("2 GB"); if (premiumLocked) {
} else { limitPreviewView.setPremiumLocked();
limitPreviewView.defaultCount.setText(Integer.toString(defaultLimit)); } else {
if (UserConfig.getInstance(currentAccount).isPremium() || isVeryLargeFile) {
limitPreviewView.premiumCount.setVisibility(View.GONE);
if (type == TYPE_LARGE_FILE) {
limitPreviewView.defaultCount.setText("2 GB");
} else {
limitPreviewView.defaultCount.setText(Integer.toString(defaultLimit));
}
limitPreviewView.defaultCount.setVisibility(View.VISIBLE);
} }
limitPreviewView.defaultCount.setVisibility(View.VISIBLE);
} }
} }
@ -676,12 +937,15 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
limitPreviewView.setDelayedAnimation(); limitPreviewView.setDelayedAnimation();
} }
addView(limitPreviewView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, 0, 0, 0)); addView(limitPreviewView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, 0, 0, 0));
TextView title = new TextView(context); title = new TextView(context);
title.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); title.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
if (type == TYPE_ADD_MEMBERS_RESTRICTED) { if (type == TYPE_BOOSTS_FOR_USERS) {
title.setText(getBoostsTitleString());
} else if (type == TYPE_BOOSTS_FOR_POSTING) {
title.setText(LocaleController.getString("BoostingEnableStories", R.string.BoostingEnableStories));
} else if (type == TYPE_ADD_MEMBERS_RESTRICTED) {
if (canSendLink) { if (canSendLink) {
title.setText(LocaleController.getString("ChannelInviteViaLink", R.string.ChannelInviteViaLink)); title.setText(LocaleController.getString("ChannelInviteViaLink", R.string.ChannelInviteViaLink));
} else { } else {
@ -694,9 +958,35 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
} }
title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
title.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider)); title.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
title.setGravity(Gravity.CENTER);
addView(title, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 0, premiumLocked ? 8 : 22, 0, 10)); addView(title, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 0, premiumLocked ? 8 : 22, 0, 10));
TextView description = new TextView(context); if (type == TYPE_BOOSTS_FOR_USERS && !isCurrentChat) {
FrameLayout frameLayout = new FrameLayout(getContext());
frameLayout.setBackground(Theme.createRoundRectDrawable(AndroidUtilities.dp(14), Theme.getColor(Theme.key_windowBackgroundGray)));
BackupImageView backupImageView = new BackupImageView(getContext());
backupImageView.setRoundRadius(AndroidUtilities.dp(14));
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
AvatarDrawable avatarDrawable = new AvatarDrawable();
avatarDrawable.setInfo(chat);
backupImageView.setForUserOrChat(chat, avatarDrawable);
frameLayout.addView(backupImageView, LayoutHelper.createFrame(28, 28));
TextView textView = new TextView(getContext());
textView.setText(chat.title);
textView.setSingleLine(true);
textView.setMaxLines(1);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
frameLayout.addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 36, 0, 8, 0));
addView(frameLayout, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 28, Gravity.CENTER_HORIZONTAL, 0, 0, 0, 12));
ScaleStateListAnimator.apply(frameLayout);
frameLayout.setOnClickListener(v -> {
getBaseFragment().presentFragment(ChatActivity.of(dialogId));
dismiss();
});
}
description = new TextView(context);
description.setText(AndroidUtilities.replaceTags(descriptionStr)); description.setText(AndroidUtilities.replaceTags(descriptionStr));
description.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); description.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
description.setGravity(Gravity.CENTER_HORIZONTAL); description.setGravity(Gravity.CENTER_HORIZONTAL);
@ -705,6 +995,86 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
updatePremiumButtonText(); updatePremiumButtonText();
} }
public void recreateTitleAndDescription() {
int titleIndex = indexOfChild(title);
int descriptionIndex = indexOfChild(description);
removeView(title);
title = new TextView(getContext());
title.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
title.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
title.setGravity(Gravity.CENTER);
addView(title, titleIndex, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 0, 22, 0, 10));
removeView(description);
description = new TextView(getContext());
description.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
description.setGravity(Gravity.CENTER_HORIZONTAL);
description.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
addView(description, descriptionIndex, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 24, 0, 24, 24));
}
}
private String getBoostsTitleString() {
if (boostsStatus.level > 0 && !canApplyBoost.alreadyActive) {
return LocaleController.getString("HelpUpgradeChannel", R.string.HelpUpgradeChannel);
} else if (boostsStatus.next_level_boosts == 0) {
return LocaleController.formatString("BoostsMaxLevelReached", R.string.BoostsMaxLevelReached);
} else if (isCurrentChat) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
if (canApplyBoost.alreadyActive) {
return LocaleController.formatString("YouBoostedChannel2", R.string.YouBoostedChannel2, chat.title);
} else {
return LocaleController.formatString("BoostingEnableStoriesForChannel2", R.string.BoostingEnableStoriesForChannel2, chat.title);
}
} else {
if (canApplyBoost.alreadyActive) {
return LocaleController.getString("YouBoostedChannel", R.string.YouBoostedChannel);
} else {
return LocaleController.getString("BoostingEnableStoriesForChannel", R.string.BoostingEnableStoriesForChannel);
}
}
}
private String getBoostsDescriptionString() {
boolean isZeroBoostsForNextLevel = boostsStatus.boosts == boostsStatus.current_level_boosts;
if (isZeroBoostsForNextLevel && canApplyBoost.alreadyActive) {
if (boostsStatus.level == 1) {
return LocaleController.formatString("ChannelBoostsJustReachedLevel1", R.string.ChannelBoostsJustReachedLevel1);
} else {
return LocaleController.formatString("ChannelBoostsJustReachedLevelNext", R.string.ChannelBoostsJustReachedLevelNext,
boostsStatus.level,
LocaleController.formatPluralString("BoostStories", boostsStatus.level));
}
} else {
if (canApplyBoost.alreadyActive) {
if (boostsStatus.level == 0) {
return LocaleController.formatString(
"ChannelNeedBoostsAlreadyBoostedDescriptionLevel1", R.string.ChannelNeedBoostsAlreadyBoostedDescriptionLevel1,
LocaleController.formatPluralString("MoreBoosts", boostsStatus.next_level_boosts - boostsStatus.boosts, boostsStatus.next_level_boosts - boostsStatus.boosts)
);
} else {
return LocaleController.formatString("ChannelNeedBoostsDescriptionLevelNext", R.string.ChannelNeedBoostsDescriptionLevelNext,
LocaleController.formatPluralString("MoreBoosts", boostsStatus.next_level_boosts - boostsStatus.boosts, boostsStatus.next_level_boosts - boostsStatus.boosts),
LocaleController.formatPluralString("BoostStories", boostsStatus.level)
);
}
} else {
if (boostsStatus.level == 0) {
return LocaleController.formatString(
"ChannelNeedBoostsDescriptionLevel1", R.string.ChannelNeedBoostsDescriptionLevel1,
LocaleController.formatPluralString("MoreBoosts", boostsStatus.next_level_boosts - boostsStatus.boosts, boostsStatus.next_level_boosts - boostsStatus.boosts)
);
} else {
return LocaleController.formatString("ChannelNeedBoostsDescriptionLevelNext", R.string.ChannelNeedBoostsDescriptionLevelNext,
LocaleController.formatPluralString("MoreBoosts", boostsStatus.next_level_boosts - boostsStatus.boosts, boostsStatus.next_level_boosts - boostsStatus.boosts),
LocaleController.formatPluralString("BoostStories", boostsStatus.level)
);
}
}
}
} }
private static LimitParams getLimitParams(int type, int currentAccount) { private static LimitParams getLimitParams(int type, int currentAccount) {
@ -800,6 +1170,13 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
limitParams.descriptionStr = LocaleController.formatString("LimitReachedStoriesMonthly", R.string.LimitReachedStoriesMonthly, limitParams.defaultLimit, limitParams.premiumLimit); limitParams.descriptionStr = LocaleController.formatString("LimitReachedStoriesMonthly", R.string.LimitReachedStoriesMonthly, limitParams.defaultLimit, limitParams.premiumLimit);
limitParams.descriptionStrPremium = LocaleController.formatString("LimitReachedStoriesMonthlyPremium", R.string.LimitReachedStoriesMonthlyPremium, limitParams.premiumLimit); limitParams.descriptionStrPremium = LocaleController.formatString("LimitReachedStoriesMonthlyPremium", R.string.LimitReachedStoriesMonthlyPremium, limitParams.premiumLimit);
limitParams.descriptionStrLocked = LocaleController.formatString("LimitReachedStoriesMonthlyPremium", R.string.LimitReachedStoriesMonthlyPremium, limitParams.defaultLimit); limitParams.descriptionStrLocked = LocaleController.formatString("LimitReachedStoriesMonthlyPremium", R.string.LimitReachedStoriesMonthlyPremium, limitParams.defaultLimit);
} else if (type == TYPE_BOOSTS_FOR_POSTING || type == TYPE_BOOSTS_FOR_USERS) {
limitParams.defaultLimit = MessagesController.getInstance(currentAccount).storiesSentMonthlyLimitDefault;
limitParams.premiumLimit = MessagesController.getInstance(currentAccount).storiesSentMonthlyLimitPremium;
limitParams.icon = R.drawable.filled_limit_boost;
limitParams.descriptionStr = LocaleController.formatString("LimitReachedStoriesMonthly", R.string.LimitReachedStoriesMonthly, limitParams.defaultLimit, limitParams.premiumLimit);
limitParams.descriptionStrPremium = LocaleController.formatString("LimitReachedStoriesMonthlyPremium", R.string.LimitReachedStoriesMonthlyPremium, limitParams.premiumLimit);
limitParams.descriptionStrLocked = LocaleController.formatString("LimitReachedStoriesMonthlyPremium", R.string.LimitReachedStoriesMonthlyPremium, limitParams.defaultLimit);
} }
return limitParams; return limitParams;
} }
@ -833,7 +1210,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
} }
int currentValue = Math.max(chats.size(), limitParams.defaultLimit); int currentValue = Math.max(chats.size(), limitParams.defaultLimit);
limitPreviewView.setIconValue(currentValue); limitPreviewView.setIconValue(currentValue, false);
limitPreviewView.setBagePosition(currentValue / (float) limitParams.premiumLimit); limitPreviewView.setBagePosition(currentValue / (float) limitParams.premiumLimit);
limitPreviewView.startDelayedAnimation(); limitPreviewView.startDelayedAnimation();
})); }));
@ -868,6 +1245,9 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
} }
} }
} }
if (type == TYPE_BOOSTS_FOR_POSTING) {
linkRow = rowCount++;
}
notifyDataSetChanged(); notifyDataSetChanged();
} }
@ -976,7 +1356,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
} }
int currentValue = Math.max(inactiveChats.size(), limitParams.defaultLimit); int currentValue = Math.max(inactiveChats.size(), limitParams.defaultLimit);
if (limitPreviewView != null) { if (limitPreviewView != null) {
limitPreviewView.setIconValue(currentValue); limitPreviewView.setIconValue(currentValue, false);
limitPreviewView.setBagePosition(currentValue / (float) limitParams.premiumLimit); limitPreviewView.setBagePosition(currentValue / (float) limitParams.premiumLimit);
limitPreviewView.startDelayedAnimation(); limitPreviewView.startDelayedAnimation();
} }

View file

@ -1365,15 +1365,23 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
} }
private int rawBackgroundBitmapFrame = -1; private int rawBackgroundBitmapFrame = -1;
public void drawFrame(Canvas canvas, int frame) { private Bitmap rawBackgroundBitmap;
if (rawBackgroundBitmapFrame != frame || backgroundBitmap == null) {
if (backgroundBitmap == null) { public void cacheFrame(int frame) {
backgroundBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); if (rawBackgroundBitmapFrame != frame || rawBackgroundBitmap == null) {
if (rawBackgroundBitmap == null) {
rawBackgroundBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
} }
int result = getFrame(nativePtr, rawBackgroundBitmapFrame = frame, backgroundBitmap, width, height, backgroundBitmap.getRowBytes(), true); int result = getFrame(nativePtr, rawBackgroundBitmapFrame = frame, rawBackgroundBitmap, width, height, rawBackgroundBitmap.getRowBytes(), true);
}
}
public void drawFrame(Canvas canvas, int frame) {
cacheFrame(frame);
if (rawBackgroundBitmap != null) {
AndroidUtilities.rectTmp2.set(0, 0, width, height);
canvas.drawBitmap(rawBackgroundBitmap, AndroidUtilities.rectTmp2, getBounds(), getPaint());
} }
AndroidUtilities.rectTmp2.set(0, 0, width, height);
canvas.drawBitmap(backgroundBitmap, AndroidUtilities.rectTmp2, getBounds(), getPaint());
} }
@Override @Override

View file

@ -342,19 +342,21 @@ public class ChatSelectionReactionMenuOverlay extends FrameLayout {
private void animateVisible(boolean visible) { private void animateVisible(boolean visible) {
if (visible) { if (visible) {
currentPrimaryObject = findPrimaryObject();
checkCreateReactionsLayout();
invalidatePosition(false);
setVisibility(VISIBLE); setVisibility(VISIBLE);
if (reactionsContainerLayout.isEnabled()) { post(() -> {
messageSet = true; currentPrimaryObject = findPrimaryObject();
reactionsContainerLayout.setMessage(currentPrimaryObject, parentFragment.getCurrentChatInfo()); checkCreateReactionsLayout();
reactionsContainerLayout.startEnterAnimation(false); invalidatePosition(false);
} else {
messageSet = false; if (reactionsContainerLayout.isEnabled()) {
reactionsContainerLayout.setTransitionProgress(1f); messageSet = true;
} reactionsContainerLayout.setMessage(currentPrimaryObject, parentFragment.getCurrentChatInfo());
reactionsContainerLayout.startEnterAnimation(false);
} else {
messageSet = false;
reactionsContainerLayout.setTransitionProgress(1f);
}
});
} else { } else {
messageSet = false; messageSet = false;
ValueAnimator animator = ValueAnimator.ofFloat(1, 0).setDuration(150); ValueAnimator animator = ValueAnimator.ofFloat(1, 0).setDuration(150);

View file

@ -258,10 +258,10 @@ public class CustomEmojiReactionsWindow {
containerView.addView(selectAnimatedEmojiDialog, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, 0, 0)); containerView.addView(selectAnimatedEmojiDialog, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, 0, 0));
windowView.addView(containerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP, 16, 16, 16, 16)); windowView.addView(containerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP, 16, 16, 16, 16));
windowView.setClipChildren(false); windowView.setClipChildren(false);
if (type == TYPE_STORY) { if (type == TYPE_STORY || (reactionsContainerLayout.getDelegate() != null && reactionsContainerLayout.getDelegate().drawBackground())) {
selectAnimatedEmojiDialog.setBackgroundDelegate((canvas, left, top, right, bottom, x, y) -> { selectAnimatedEmojiDialog.setBackgroundDelegate((canvas, left, top, right, bottom, x, y) -> {
AndroidUtilities.rectTmp.set(left, top, right, bottom); AndroidUtilities.rectTmp.set(left, top, right, bottom);
reactionsContainerLayout.getDelegate().drawRoundRect(canvas, AndroidUtilities.rectTmp, 0, containerView.getX() + x, containerView.getY() - AndroidUtilities.statusBarHeight + y); reactionsContainerLayout.getDelegate().drawRoundRect(canvas, AndroidUtilities.rectTmp, 0, containerView.getX() + x, getBlurOffset() + y, 255,true);
}); });
} }
if (attachToParent) { if (attachToParent) {
@ -715,7 +715,7 @@ public class CustomEmojiReactionsWindow {
@Override @Override
public void invalidate() { public void invalidate() {
super.invalidate(); super.invalidate();
if (type == TYPE_STORY) { if (type == TYPE_STORY || (reactionsContainerLayout != null && reactionsContainerLayout.getDelegate() != null && reactionsContainerLayout.getDelegate().drawBackground())) {
selectAnimatedEmojiDialog.invalidateSearchBox(); selectAnimatedEmojiDialog.invalidateSearchBox();
} }
} }
@ -759,8 +759,8 @@ public class CustomEmojiReactionsWindow {
transitionReactions.clear(); transitionReactions.clear();
if (type == TYPE_STORY) { if (type == TYPE_STORY || (reactionsContainerLayout.getDelegate() != null && reactionsContainerLayout.getDelegate().drawBackground())) {
reactionsContainerLayout.getDelegate().drawRoundRect(canvas, drawingRect, radius, getX(), getY() - AndroidUtilities.statusBarHeight); reactionsContainerLayout.getDelegate().drawRoundRect(canvas, drawingRect, radius, getX(), getBlurOffset(), 255, true);
} else { } else {
shadow.setAlpha((int) (Utilities.clamp(progressClpamped / 0.05f, 1f, 0f) * 255)); shadow.setAlpha((int) (Utilities.clamp(progressClpamped / 0.05f, 1f, 0f) * 255));
shadow.setBounds((int) drawingRect.left - shadowPad.left, (int) drawingRect.top - shadowPad.top, (int) drawingRect.right + shadowPad.right, (int) drawingRect.bottom + shadowPad.bottom); shadow.setBounds((int) drawingRect.left - shadowPad.left, (int) drawingRect.top - shadowPad.top, (int) drawingRect.right + shadowPad.right, (int) drawingRect.bottom + shadowPad.bottom);

View file

@ -31,9 +31,12 @@ public class ReactionImageHolder {
ReactionsLayoutInBubble.VisibleReaction reaction; ReactionsLayoutInBubble.VisibleReaction reaction;
private final int currentAccount = UserConfig.selectedAccount; private final int currentAccount = UserConfig.selectedAccount;
ReactionsLayoutInBubble.VisibleReaction currentReaction; ReactionsLayoutInBubble.VisibleReaction currentReaction;
private final View parent; private View parent;
private boolean attached; private boolean attached;
float alpha = 1f; float alpha = 1f;
private boolean isStatic;
int lastColorForFilter;
ColorFilter colorFilter;
public ReactionImageHolder(View parent) { public ReactionImageHolder(View parent) {
this.parent = parent; this.parent = parent;
@ -52,20 +55,28 @@ public class ReactionImageHolder {
} }
this.currentReaction = currentReaction; this.currentReaction = currentReaction;
String filter = "60_60";
if (isStatic) {
filter += "_firstframe";
}
if (currentReaction.emojicon != null) { if (currentReaction.emojicon != null) {
TLRPC.TL_availableReaction defaultReaction = MediaDataController.getInstance(currentAccount).getReactionsMap().get(currentReaction.emojicon); TLRPC.TL_availableReaction defaultReaction = MediaDataController.getInstance(currentAccount).getReactionsMap().get(currentReaction.emojicon);
if (defaultReaction != null) { if (defaultReaction != null) {
SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(defaultReaction.select_animation, Theme.key_windowBackgroundWhiteGrayIcon, 0.2f); SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(defaultReaction.select_animation, Theme.key_windowBackgroundWhiteGrayIcon, 0.2f);
imageReceiver.setImage(ImageLocation.getForDocument(defaultReaction.select_animation), "60_60", null, null, svgThumb, 0, "tgs", currentReaction, 0); imageReceiver.setImage(ImageLocation.getForDocument(defaultReaction.select_animation), filter, null, null, svgThumb, 0, "tgs", currentReaction, 0);
// imageReceiver.setAllowStartAnimation(false); // imageReceiver.setAllowStartAnimation(false);
// imageReceiver.setAutoRepeatCount(1); // imageReceiver.setAutoRepeatCount(1);
} }
} else { } else {
animatedEmojiDrawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES_LARGE, UserConfig.selectedAccount, currentReaction.documentId); int type = AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES_LARGE;
if (isStatic) {
type = AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW_STATIC;
}
animatedEmojiDrawable = new AnimatedEmojiDrawable(type, UserConfig.selectedAccount, currentReaction.documentId);
if (attached) { if (attached) {
animatedEmojiDrawable.addView(parent); animatedEmojiDrawable.addView(parent);
} }
animatedEmojiDrawable.setColorFilter(new PorterDuffColorFilter(Color.BLACK, PorterDuff.Mode.SRC_ATOP)); animatedEmojiDrawable.setColorFilter(colorFilter = new PorterDuffColorFilter(lastColorForFilter = Color.BLACK, PorterDuff.Mode.SRC_ATOP));
} }
} }
@ -74,6 +85,7 @@ public class ReactionImageHolder {
if (animatedEmojiDrawable.getImageReceiver() != null) { if (animatedEmojiDrawable.getImageReceiver() != null) {
animatedEmojiDrawable.getImageReceiver().setRoundRadius((int) (bounds.width() * 0.1f)); animatedEmojiDrawable.getImageReceiver().setRoundRadius((int) (bounds.width() * 0.1f));
} }
animatedEmojiDrawable.setColorFilter(colorFilter);
animatedEmojiDrawable.setBounds(bounds); animatedEmojiDrawable.setBounds(bounds);
animatedEmojiDrawable.setAlpha((int) (255 * alpha)); animatedEmojiDrawable.setAlpha((int) (255 * alpha));
animatedEmojiDrawable.draw(canvas); animatedEmojiDrawable.draw(canvas);
@ -110,4 +122,32 @@ public class ReactionImageHolder {
public void play() { public void play() {
imageReceiver.startAnimation(); imageReceiver.startAnimation();
} }
public void setParent(View parentView) {
if (this.parent == parentView) {
return;
}
if (attached) {
onAttachedToWindow(false);
this.parent = parentView;
onAttachedToWindow(true);
} else {
this.parent = parentView;
}
}
public void setStatic() {
isStatic = true;
}
public void setColor(int color) {
if (lastColorForFilter != color) {
lastColorForFilter = color;
colorFilter = new PorterDuffColorFilter(lastColorForFilter, PorterDuff.Mode.SRC_ATOP);
if (parent != null) {
parent.invalidate();
}
}
}
} }

View file

@ -56,4 +56,36 @@ public class ReactionsUtils {
} }
return ""; return "";
} }
public static void applyForStoryViews(TLRPC.Reaction oldReaction, TLRPC.Reaction newReaction, TLRPC.StoryViews views) {
boolean found = false;
if (views == null) {
return;
}
for (int i = 0; i < views.reactions.size(); i++) {
TLRPC.ReactionCount reactionCount = views.reactions.get(i);
if (oldReaction != null) {
if (compare(reactionCount.reaction, oldReaction)) {
reactionCount.count--;
if (reactionCount.count <= 0) {
views.reactions.remove(i);
i--;
continue;
}
}
}
if (newReaction != null) {
if (compare(reactionCount.reaction, newReaction)) {
reactionCount.count++;
found = true;
}
}
}
if (!found) {
TLRPC.ReactionCount reactionCount = new TLRPC.TL_reactionCount();
reactionCount.count = 1;
reactionCount.reaction = newReaction;
views.reactions.add(reactionCount);
}
}
} }

View file

@ -716,8 +716,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
float sc = transitionProgress; float sc = transitionProgress;
canvas.scale(sc, sc, pivotX, getHeight() / 2f); canvas.scale(sc, sc, pivotX, getHeight() / 2f);
} }
if (type == TYPE_STORY) { if (type == TYPE_STORY || delegate.drawBackground()) {
delegate.drawRoundRect(canvas, rect, radius, getX(), getY()); delegate.drawRoundRect(canvas, rect, radius, getX(), getY(), 255, false);
} else { } else {
canvas.drawRoundRect(rect, radius, radius, bgPaint); canvas.drawRoundRect(rect, radius, radius, bgPaint);
} }
@ -887,7 +887,12 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
bgPaint.setAlpha(alpha); bgPaint.setAlpha(alpha);
shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr)); shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr));
shadow.draw(canvas); shadow.draw(canvas);
canvas.drawCircle(cx, cy, br, bgPaint); if (delegate.drawBackground()) {
rectF.set(cx - br, cy - br, cx + br, cy + br);
delegate.drawRoundRect(canvas, rectF, br, getX(), getY(), alpha, false);
} else {
canvas.drawCircle(cx, cy, br, bgPaint);
}
cx = LocaleController.isRTL || mirrorX ? bigCircleOffset - bigCircleRadius : getWidth() - bigCircleOffset + bigCircleRadius; cx = LocaleController.isRTL || mirrorX ? bigCircleOffset - bigCircleRadius : getWidth() - bigCircleOffset + bigCircleRadius;
cx += bubblesOffset; cx += bubblesOffset;
@ -896,7 +901,12 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
sPad = -AndroidUtilities.dp(1); sPad = -AndroidUtilities.dp(1);
shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr)); shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr));
shadow.draw(canvas); shadow.draw(canvas);
canvas.drawCircle(cx, cy, sr, bgPaint); if (delegate.drawBackground()) {
rectF.set(cx - sr, cy - sr, cx + sr, cy + sr);
delegate.drawRoundRect(canvas, rectF, sr, getX(), getY(), alpha, false);
} else {
canvas.drawCircle(cx, cy, sr, bgPaint);
}
canvas.restore(); canvas.restore();
shadow.setAlpha(255); shadow.setAlpha(255);
@ -1868,7 +1878,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} }
default void drawRoundRect(Canvas canvas, RectF rect, float radius, float offsetX, float offsetY) { default void drawRoundRect(Canvas canvas, RectF rect, float radius, float offsetX, float offsetY, int alpha, boolean isWindow) {
} }
@ -1879,6 +1889,10 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
default void onEmojiWindowDismissed() { default void onEmojiWindowDismissed() {
} }
default boolean drawBackground() {
return false;
}
} }
@Override @Override

View file

@ -1263,7 +1263,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
int[] mediaCount = preloader.getLastMediaCount(); int[] mediaCount = preloader.getLastMediaCount();
topicId = sharedMediaPreloader.topicId; topicId = sharedMediaPreloader.topicId;
hasMedia = new int[]{mediaCount[0], mediaCount[1], mediaCount[2], mediaCount[3], mediaCount[4], mediaCount[5], topicId == 0 ? commonGroupsCount : 0}; hasMedia = new int[]{mediaCount[0], mediaCount[1], mediaCount[2], mediaCount[3], mediaCount[4], mediaCount[5], topicId == 0 ? commonGroupsCount : 0};
if (userInfo != null && userInfo.stories_pinned_available || isStoriesView()) { if (userInfo != null && userInfo.stories_pinned_available || chatInfo != null && chatInfo.stories_pinned_available || isStoriesView()) {
initialTab = getInitialTab(); initialTab = getInitialTab();
} else if (membersFirst && topicId == 0) { } else if (membersFirst && topicId == 0) {
initialTab = TAB_GROUPUSERS; initialTab = TAB_GROUPUSERS;
@ -1497,6 +1497,28 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
} }
}); });
if (info != null && !isStoriesView()) {
TLRPC.Chat chat = MessagesController.getInstance(profileActivity.getCurrentAccount()).getChat(info.id);
if (chat != null && chat.admin_rights != null && chat.admin_rights.edit_stories) {
ActionBarMenuSubItem openArchiveItem = new ActionBarMenuSubItem(context, false, true, resourcesProvider);
openArchiveItem.setTextAndIcon(LocaleController.getString(R.string.OpenChannelArchiveStories), R.drawable.msg_archive);
openArchiveItem.setOnClickListener(e -> {
Bundle args = new Bundle();
args.putInt("type", MediaActivity.TYPE_ARCHIVED_CHANNEL_STORIES);
args.putLong("dialog_id", -info.id);
MediaActivity fragment = new MediaActivity(args, null);
fragment.setChatInfo(info);
profileActivity.presentFragment(fragment);
if (optionsWindow != null) {
optionsWindow.dismiss();
}
});
popupLayout.addView(openArchiveItem);
}
}
if (hasDifferentTypes) { if (hasDifferentTypes) {
popupLayout.addView(dividerView); popupLayout.addView(dividerView);
ActionBarMenuSubItem showPhotosItem = new ActionBarMenuSubItem(context, true, false, false, resourcesProvider); ActionBarMenuSubItem showPhotosItem = new ActionBarMenuSubItem(context, true, false, false, resourcesProvider);
@ -4717,6 +4739,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
} }
public void setChatInfo(TLRPC.ChatFull chatInfo) { public void setChatInfo(TLRPC.ChatFull chatInfo) {
boolean stories_pinned_available = this.info != null && this.info.stories_pinned_available;
info = chatInfo; info = chatInfo;
if (info != null && info.migrated_from_chat_id != 0 && mergeDialogId == 0) { if (info != null && info.migrated_from_chat_id != 0 && mergeDialogId == 0) {
mergeDialogId = -info.migrated_from_chat_id; mergeDialogId = -info.migrated_from_chat_id;
@ -4725,6 +4748,13 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
sharedMediaData[a].endReached[1] = false; sharedMediaData[a].endReached[1] = false;
} }
} }
if (info != null && (stories_pinned_available != info.stories_pinned_available)) {
if (scrollSlidingTextTabStrip != null) {
scrollSlidingTextTabStrip.setInitialTabId(isArchivedOnlyStoriesView() ? TAB_ARCHIVED_STORIES : TAB_STORIES);
}
updateTabs(true);
switchToCurrentSelectedMode(false);
}
} }
public void setUserInfo(TLRPC.UserFull userInfo) { public void setUserInfo(TLRPC.UserFull userInfo) {
@ -4813,7 +4843,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
animated = false; animated = false;
} }
int changed = 0; int changed = 0;
if ((DialogObject.isUserDialog(dialog_id) && !DialogObject.isEncryptedDialog(dialog_id) && (userInfo != null && userInfo.stories_pinned_available || isStoriesView()) && includeStories()) != scrollSlidingTextTabStrip.hasTab(TAB_STORIES)) { if (((DialogObject.isUserDialog(dialog_id) || DialogObject.isChatDialog(dialog_id)) && !DialogObject.isEncryptedDialog(dialog_id) && (userInfo != null && userInfo.stories_pinned_available || info != null && info.stories_pinned_available || isStoriesView()) && includeStories()) != scrollSlidingTextTabStrip.hasTab(TAB_STORIES)) {
changed++; changed++;
} }
if (!isStoriesView()) { if (!isStoriesView()) {
@ -4887,15 +4917,22 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
if (changed > 3) { if (changed > 3) {
idToView = null; idToView = null;
} }
if (DialogObject.isUserDialog(dialog_id) && !DialogObject.isEncryptedDialog(dialog_id) && (userInfo != null && userInfo.stories_pinned_available || isStoriesView()) && includeStories()) { if ((DialogObject.isUserDialog(dialog_id) || DialogObject.isChatDialog(dialog_id)) && !DialogObject.isEncryptedDialog(dialog_id) && (userInfo != null && userInfo.stories_pinned_available || info != null && info.stories_pinned_available || isStoriesView()) && includeStories()) {
if (!scrollSlidingTextTabStrip.hasTab(TAB_STORIES)) { if (isArchivedOnlyStoriesView()) {
scrollSlidingTextTabStrip.addTextTab(TAB_STORIES, LocaleController.getString("ProfileStories", R.string.ProfileStories), idToView);
}
if (isStoriesView()) {
if (!scrollSlidingTextTabStrip.hasTab(TAB_ARCHIVED_STORIES)) { if (!scrollSlidingTextTabStrip.hasTab(TAB_ARCHIVED_STORIES)) {
scrollSlidingTextTabStrip.addTextTab(TAB_ARCHIVED_STORIES, LocaleController.getString("ProfileStories", R.string.ProfileStories), idToView); scrollSlidingTextTabStrip.addTextTab(TAB_ARCHIVED_STORIES, LocaleController.getString("ProfileStories", R.string.ProfileStories), idToView);
} }
scrollSlidingTextTabStrip.animationDuration = 420; scrollSlidingTextTabStrip.animationDuration = 420;
} else {
if (!scrollSlidingTextTabStrip.hasTab(TAB_STORIES)) {
scrollSlidingTextTabStrip.addTextTab(TAB_STORIES, LocaleController.getString("ProfileStories", R.string.ProfileStories), idToView);
}
if (isStoriesView()) {
if (!scrollSlidingTextTabStrip.hasTab(TAB_ARCHIVED_STORIES)) {
scrollSlidingTextTabStrip.addTextTab(TAB_ARCHIVED_STORIES, LocaleController.getString("ProfileStories", R.string.ProfileStories), idToView);
}
scrollSlidingTextTabStrip.animationDuration = 420;
}
} }
} }
if (!isStoriesView()) { if (!isStoriesView()) {

View file

@ -56,7 +56,7 @@ public class ViewPagerFixed extends FrameLayout {
private Theme.ResourcesProvider resourcesProvider; private Theme.ResourcesProvider resourcesProvider;
public int currentPosition; public int currentPosition;
public float currentProgress; public float currentProgress = 1f;
int nextPosition; int nextPosition;
protected View[] viewPages; protected View[] viewPages;
private int[] viewTypes; private int[] viewTypes;
@ -478,9 +478,9 @@ public class ViewPagerFixed extends FrameLayout {
viewPages[1].setTranslationX(animatingForward ? viewPages[0].getMeasuredWidth() : -viewPages[0].getMeasuredWidth()); viewPages[1].setTranslationX(animatingForward ? viewPages[0].getMeasuredWidth() : -viewPages[0].getMeasuredWidth());
} }
nextPosition = 0; nextPosition = 0;
currentProgress = 0; currentProgress = 1f;
if (tabsView != null) { if (tabsView != null) {
tabsView.selectTab(currentPosition, 0, 0); tabsView.selectTab(nextPosition, currentPosition, currentProgress);
} }
onTabAnimationUpdate(false); onTabAnimationUpdate(false);
} }
@ -708,6 +708,10 @@ public class ViewPagerFixed extends FrameLayout {
} }
public void setPosition(int position) { public void setPosition(int position) {
if (adapter == null) {
currentPosition = position;
onTabAnimationUpdate(false);
}
if (tabsAnimation != null) { if (tabsAnimation != null) {
tabsAnimation.cancel(); tabsAnimation.cancel();
} }

View file

@ -65,7 +65,7 @@ public class SpoilerEffect extends Drawable {
private Stack<Particle> particlesPool = new Stack<>(); private Stack<Particle> particlesPool = new Stack<>();
private int maxParticles; private int maxParticles;
float[][] particlePoints = new float[ALPHAS.length][MAX_PARTICLES_PER_ENTITY * 2]; float[][] particlePoints = new float[ALPHAS.length][MAX_PARTICLES_PER_ENTITY * 5];
private float[] particleRands = new float[RAND_REPEAT]; private float[] particleRands = new float[RAND_REPEAT];
private int[] renderCount = new int[ALPHAS.length]; private int[] renderCount = new int[ALPHAS.length];
@ -99,6 +99,7 @@ public class SpoilerEffect extends Drawable {
private int lastColor; private int lastColor;
public boolean drawPoints; public boolean drawPoints;
private static Paint xRefPaint; private static Paint xRefPaint;
private int bitmapSize;
private static int measureParticlesPerCharacter() { private static int measureParticlesPerCharacter() {
switch (SharedConfig.getDevicePerformanceClass()) { switch (SharedConfig.getDevicePerformanceClass()) {
@ -320,11 +321,6 @@ public class SpoilerEffect extends Drawable {
float hdt = particle.velocity * dt / 500f; float hdt = particle.velocity * dt / 500f;
particle.x += particle.vecX * hdt; particle.x += particle.vecX * hdt;
particle.y += particle.vecY * hdt; particle.y += particle.vecY * hdt;
int alphaIndex = particle.alpha;
particlePoints[alphaIndex][renderCount[alphaIndex] * 2] = particle.x;
particlePoints[alphaIndex][renderCount[alphaIndex] * 2 + 1] = particle.y;
renderCount[alphaIndex]++;
} }
if (particles.size() < maxParticles) { if (particles.size() < maxParticles) {
@ -358,27 +354,56 @@ public class SpoilerEffect extends Drawable {
newParticle.alpha = Utilities.fastRandom.nextInt(ALPHAS.length); newParticle.alpha = Utilities.fastRandom.nextInt(ALPHAS.length);
particles.add(newParticle); particles.add(newParticle);
int alphaIndex = newParticle.alpha;
particlePoints[alphaIndex][renderCount[alphaIndex] * 2] = newParticle.x;
particlePoints[alphaIndex][renderCount[alphaIndex] * 2 + 1] = newParticle.y;
renderCount[alphaIndex]++;
} }
} }
for (int a = enableAlpha ? 0 : ALPHAS.length - 1; a < ALPHAS.length; a++) { for (int a = enableAlpha ? 0 : ALPHAS.length - 1; a < ALPHAS.length; a++) {
int renderCount = 0; int renderCount = 0;
int off = 0; float paintW = particlePaints[a].getStrokeWidth() / 2f;
for (int i = 0; i < particles.size(); i++) { for (int i = 0; i < particles.size(); i++) {
Particle p = particles.get(i); Particle p = particles.get(i);
if (visibleRect != null && !visibleRect.contains(p.x, p.y) || p.alpha != a && enableAlpha) { if (visibleRect != null && !visibleRect.contains(p.x, p.y) || p.alpha != a && enableAlpha) {
off++;
continue; continue;
} }
particlePoints[a][(i - off) * 2] = p.x; particlePoints[a][renderCount] = p.x;
particlePoints[a][(i - off) * 2 + 1] = p.y; particlePoints[a][renderCount + 1] = p.y;
renderCount += 2; renderCount += 2;
if (p.x < paintW) {
if (renderCount >= particlePoints[a].length - 2) {
continue;
}
particlePoints[a][renderCount] = p.x + bitmapSize;
particlePoints[a][renderCount + 1] = p.y;
renderCount += 2;
}
if (p.x > bitmapSize - paintW) {
if (renderCount >= particlePoints[a].length - 2) {
continue;
}
particlePoints[a][renderCount] = p.x - bitmapSize;
particlePoints[a][renderCount + 1] = p.y;
renderCount += 2;
}
if (p.y < paintW) {
if (renderCount >= particlePoints[a].length - 2) {
continue;
}
particlePoints[a][renderCount] = p.x;
particlePoints[a][renderCount + 1] = p.y + bitmapSize;
renderCount += 2;
}
if (p.y > bitmapSize - paintW) {
if (renderCount >= particlePoints[a].length - 2) {
continue;
}
particlePoints[a][renderCount] = p.x;
particlePoints[a][renderCount + 1] = p.y - bitmapSize;
renderCount += 2;
}
} }
canvas.drawPoints(particlePoints[a], 0, renderCount, particlePaints[a]); canvas.drawPoints(particlePoints[a], 0, renderCount, particlePaints[a]);
} }
@ -756,6 +781,10 @@ public class SpoilerEffect extends Drawable {
} }
} }
public void setSize(int bitmapSize) {
this.bitmapSize = bitmapSize;
}
private static class Particle { private static class Particle {
private float x, y; private float x, y;
private float vecX, vecY; private float vecX, vecY;

View file

@ -540,28 +540,20 @@ public class SpoilerEffect2 {
} }
private void die() { private void die() {
try { if (particlesData != null) {
if (particlesData != null) { GLES31.glDeleteBuffers(2, particlesData, 0);
GLES31.glDeleteBuffers(2, particlesData, 0); particlesData = null;
particlesData = null;
}
if (drawProgram != 0) {
GLES31.glDeleteProgram(drawProgram);
drawProgram = 0;
}
if (egl != null) {
egl.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
egl.eglDestroySurface(eglDisplay, eglSurface);
egl.eglDestroyContext(eglDisplay, eglContext);
}
} catch (Exception e) {
FileLog.e(e);
} }
try { if (drawProgram != 0) {
surfaceTexture.release(); GLES31.glDeleteProgram(drawProgram);
} catch (Exception e) { drawProgram = 0;
FileLog.e(e);
} }
if (egl != null) {
egl.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
egl.eglDestroySurface(eglDisplay, eglSurface);
egl.eglDestroyContext(eglDisplay, eglContext);
}
surfaceTexture.release();
checkGlErrors(); checkGlErrors();
} }

View file

@ -59,6 +59,7 @@ public class SpoilerEffectBitmapFactory {
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) { for (int j = 0; j < 10; j++) {
SpoilerEffect shaderSpoilerEffect = new SpoilerEffect(); SpoilerEffect shaderSpoilerEffect = new SpoilerEffect();
shaderSpoilerEffect.setSize(size);
shaderSpoilerEffect.setBounds(step * i, step * j - AndroidUtilities.dp(5), step * i + step + AndroidUtilities.dp(3), step * j + step + AndroidUtilities.dp(5)); shaderSpoilerEffect.setBounds(step * i, step * j - AndroidUtilities.dp(5), step * i + step + AndroidUtilities.dp(3), step * j + step + AndroidUtilities.dp(5));
shaderSpoilerEffect.drawPoints = true; shaderSpoilerEffect.drawPoints = true;
shaderSpoilerEffect.particlePoints = new float[SpoilerEffect.ALPHAS.length][particleCount * 2]; shaderSpoilerEffect.particlePoints = new float[SpoilerEffect.ALPHAS.length][particleCount * 2];

View file

@ -83,6 +83,8 @@ import androidx.recyclerview.widget.LinearSmoothScrollerCustom;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AccountInstance; import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.AnimationNotificationsLocker; import org.telegram.messenger.AnimationNotificationsLocker;
@ -197,6 +199,7 @@ import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.RecyclerAnimationScrollHelper; import org.telegram.ui.Components.RecyclerAnimationScrollHelper;
import org.telegram.ui.Components.RecyclerItemsEnterAnimator; import org.telegram.ui.Components.RecyclerItemsEnterAnimator;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.ScaleStateListAnimator;
import org.telegram.ui.Components.SearchViewPager; import org.telegram.ui.Components.SearchViewPager;
import org.telegram.ui.Components.SharedMediaLayout; import org.telegram.ui.Components.SharedMediaLayout;
import org.telegram.ui.Components.SimpleThemeDescription; import org.telegram.ui.Components.SimpleThemeDescription;
@ -352,6 +355,8 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
private ActionBarMenuItem doneItem; private ActionBarMenuItem doneItem;
private ProxyDrawable proxyDrawable; private ProxyDrawable proxyDrawable;
private HintView2 storyHint; private HintView2 storyHint;
private boolean canShowStoryHint;
private boolean storyHintShown;
private RLottieImageView floatingButton; private RLottieImageView floatingButton;
private FrameLayout floatingButtonContainer; private FrameLayout floatingButtonContainer;
private RLottieImageView floatingButton2; private RLottieImageView floatingButton2;
@ -443,6 +448,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
private DialogsHintCell dialogsHintCell; private DialogsHintCell dialogsHintCell;
private UnconfirmedAuthHintCell authHintCell; private UnconfirmedAuthHintCell authHintCell;
private float authHintCellProgress; private float authHintCellProgress;
private boolean authHintCellAnimating;
private boolean dialogsHintCellVisible; private boolean dialogsHintCellVisible;
private boolean authHintCellVisible; private boolean authHintCellVisible;
private Long cacheSize, deviceSize; private Long cacheSize, deviceSize;
@ -1622,6 +1628,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
float animateFromSelectorPosition; float animateFromSelectorPosition;
boolean animateSwitchingSelector; boolean animateSwitchingSelector;
UserListPoller poller; UserListPoller poller;
public int additionalPadding;
public DialogsRecyclerView(Context context, ViewPage page) { public DialogsRecyclerView(Context context, ViewPage page) {
super(context); super(context);
@ -1959,15 +1966,24 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
if (hasStories && !actionModeFullyShowed) { if (hasStories && !actionModeFullyShowed) {
t += AndroidUtilities.dp(DialogStoriesCell.HEIGHT_IN_DP); t += AndroidUtilities.dp(DialogStoriesCell.HEIGHT_IN_DP);
} }
if (authHintCell != null && authHintCellProgress != 0) { additionalPadding = 0;
t += authHintCell.getMeasuredHeight() * authHintCellProgress; if (authHintCell != null && authHintCellProgress != 0 && !authHintCellAnimating) {
t += authHintCell.getMeasuredHeight();
additionalPadding += authHintCell.getMeasuredHeight();
} }
setTopGlowOffset(t); if (t != getPaddingTop()) {
setPadding(0, t, 0, 0); setTopGlowOffset(t);
if (hasStories) { setPadding(0, t, 0, 0);
parentPage.progressView.setPaddingTop(t - AndroidUtilities.dp(DialogStoriesCell.HEIGHT_IN_DP)); if (hasStories) {
} else { parentPage.progressView.setPaddingTop(t - AndroidUtilities.dp(DialogStoriesCell.HEIGHT_IN_DP));
parentPage.progressView.setPaddingTop(t); } else {
parentPage.progressView.setPaddingTop(t);
}
for (int i = 0; i < getChildCount(); i++) {
if (getChildAt(i) instanceof DialogsAdapter.LastEmptyView) {
getChildAt(i).requestLayout();
}
}
} }
ignoreLayout = false; ignoreLayout = false;
} }
@ -2220,17 +2236,11 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
if (anchorView != null) { if (anchorView != null) {
if (animationSupportListView != null) { if (animationSupportListView != null) {
int topPadding = this.topPadding; int topPadding = this.topPadding;
// if (hasStories) {
// topPadding -= AndroidUtilities.dp(DialogStoriesCell.HEIGHT_IN_DP);
// }
animationSupportListView.setPadding(getPaddingLeft(), topPadding, getPaddingLeft(), getPaddingBottom()); animationSupportListView.setPadding(getPaddingLeft(), topPadding, getPaddingLeft(), getPaddingBottom());
if (anchorView != null) { if (anchorView != null) {
DialogsAdapter adapter = (DialogsAdapter) animationSupportListView.getAdapter(); DialogsAdapter adapter = (DialogsAdapter) animationSupportListView.getAdapter();
int p = adapter.findDialogPosition(anchorView.getDialogId()); int p = adapter.findDialogPosition(anchorView.getDialogId());
int offset = (int) (anchorView.getTop() - anchorListView.getPaddingTop() + scrollOffset); int offset = (int) (anchorView.getTop() - anchorListView.getPaddingTop() + scrollOffset);
// if (hasStories) {
// offset += AndroidUtilities.dp(DialogStoriesCell.HEIGHT_IN_DP);
// }
if (p >= 0) { if (p >= 0) {
boolean hasArchive = parentPage.dialogsType == DIALOGS_TYPE_DEFAULT && parentPage.archivePullViewState == ARCHIVE_ITEM_STATE_HIDDEN && hasHiddenArchive(); boolean hasArchive = parentPage.dialogsType == DIALOGS_TYPE_DEFAULT && parentPage.archivePullViewState == ARCHIVE_ITEM_STATE_HIDDEN && hasHiddenArchive();
int fixedOffset = adapter.fixScrollGap(this, p, offset, hasArchive, hasStories, canShowFilterTabsView, opened); int fixedOffset = adapter.fixScrollGap(this, p, offset, hasArchive, hasStories, canShowFilterTabsView, opened);
@ -2701,7 +2711,13 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
Long emojiStatusId = UserObject.getEmojiStatusDocumentId(user); Long emojiStatusId = UserObject.getEmojiStatusDocumentId(user);
if (emojiStatusId != null) { if (emojiStatusId != null) {
statusDrawable.set(emojiStatusId, animated); statusDrawable.set(emojiStatusId, animated);
actionBar.setRightDrawableOnClick(e -> showSelectStatusDialog()); actionBar.setRightDrawableOnClick(e -> {
if (dialogStoriesCellVisible && dialogStoriesCell != null && !dialogStoriesCell.isExpanded()) {
scrollToTop(true, true);
return;
}
showSelectStatusDialog();
});
SelectAnimatedEmojiDialog.preload(currentAccount); SelectAnimatedEmojiDialog.preload(currentAccount);
} else if (user != null && MessagesController.getInstance(currentAccount).isPremiumUser(user)) { } else if (user != null && MessagesController.getInstance(currentAccount).isPremiumUser(user)) {
if (premiumStar == null) { if (premiumStar == null) {
@ -2718,7 +2734,13 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} }
premiumStar.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_profile_verifiedBackground), PorterDuff.Mode.MULTIPLY)); premiumStar.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_profile_verifiedBackground), PorterDuff.Mode.MULTIPLY));
statusDrawable.set(premiumStar, animated); statusDrawable.set(premiumStar, animated);
actionBar.setRightDrawableOnClick(e -> showSelectStatusDialog()); actionBar.setRightDrawableOnClick(e -> {
if (dialogStoriesCellVisible && dialogStoriesCell != null && !dialogStoriesCell.isExpanded()) {
scrollToTop(true, true);
return;
}
showSelectStatusDialog();
});
SelectAnimatedEmojiDialog.preload(currentAccount); SelectAnimatedEmojiDialog.preload(currentAccount);
} else { } else {
statusDrawable.set((Drawable) null, animated); statusDrawable.set((Drawable) null, animated);
@ -2877,6 +2899,8 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
authHintCellVisible = false; authHintCellVisible = false;
authHintCellProgress = 0f; authHintCellProgress = 0f;
authHintCell = null; authHintCell = null;
dialogsHintCell = null;
dialogsHintCellVisible = false;
ActionBarMenu menu = actionBar.createMenu(); ActionBarMenu menu = actionBar.createMenu();
if (!onlySelect && searchString == null && folderId == 0) { if (!onlySelect && searchString == null && folderId == 0) {
@ -4410,12 +4434,16 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
StoryRecorder.getInstance(getParentActivity(), currentAccount) StoryRecorder.getInstance(getParentActivity(), currentAccount)
.closeToWhenSent(new StoryRecorder.ClosingViewProvider() { .closeToWhenSent(new StoryRecorder.ClosingViewProvider() {
@Override @Override
public void preLayout(Runnable runnable) { public void preLayout(long dialogId, Runnable runnable) {
if (dialogStoriesCell != null) { if (dialogStoriesCell != null) {
scrollToTop(false, true); scrollToTop(false, true);
invalidateScrollY = true; invalidateScrollY = true;
fragmentView.invalidate(); fragmentView.invalidate();
dialogStoriesCell.scrollToFirstCell(); if (dialogId == 0 || dialogId == getUserConfig().getClientUserId()) {
dialogStoriesCell.scrollToFirstCell();
} else {
dialogStoriesCell.scrollTo(dialogId);
}
viewPages[0].listView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { viewPages[0].listView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override @Override
public boolean onPreDraw() { public boolean onPreDraw() {
@ -4430,20 +4458,19 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} }
@Override @Override
public StoryRecorder.SourceView getView() { public StoryRecorder.SourceView getView(long dialogId) {
return StoryRecorder.SourceView.fromStoryCell(dialogStoriesCell != null ? dialogStoriesCell.findSelfStoryCell() : null); return StoryRecorder.SourceView.fromStoryCell(dialogStoriesCell != null ? dialogStoriesCell.findStoryCell(dialogId) : null);
} }
}) })
.open(StoryRecorder.SourceView.fromFloatingButton(floatingButtonContainer), true); .open(StoryRecorder.SourceView.fromFloatingButton(floatingButtonContainer), true);
} }
}); });
boolean showStoryHint = false;
if (!isArchive() && initialDialogsType == DIALOGS_TYPE_DEFAULT) { if (!isArchive() && initialDialogsType == DIALOGS_TYPE_DEFAULT) {
if (MessagesController.getInstance(currentAccount).getMainSettings().getBoolean("storyhint", true)) { if (MessagesController.getInstance(currentAccount).getMainSettings().getBoolean("storyhint", true)) {
storyHint = new HintView2(context, HintView2.DIRECTION_RIGHT) storyHint = new HintView2(context, HintView2.DIRECTION_RIGHT)
.setRounding(8) .setRounding(8)
.setDuration(-1) .setDuration(8_000)
.setCloseButton(true) .setCloseButton(true)
.setMaxWidth(165) .setMaxWidth(165)
.setMultilineText(true) .setMultilineText(true)
@ -4452,7 +4479,6 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
.setBgColor(getThemedColor(Theme.key_undo_background)) .setBgColor(getThemedColor(Theme.key_undo_background))
.setOnHiddenListener(() -> MessagesController.getInstance(currentAccount).getMainSettings().edit().putBoolean("storyhint", false).commit()); .setOnHiddenListener(() -> MessagesController.getInstance(currentAccount).getMainSettings().edit().putBoolean("storyhint", false).commit());
contentView.addView(storyHint, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 160, Gravity.BOTTOM | Gravity.FILL_HORIZONTAL, 0, 0, 80, 0)); contentView.addView(storyHint, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 160, Gravity.BOTTOM | Gravity.FILL_HORIZONTAL, 0, 0, 80, 0));
showStoryHint = true;
} }
} }
@ -4483,9 +4509,6 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
floatingButtonContainer.addView(floatingButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); floatingButtonContainer.addView(floatingButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
updateFloatingButtonColor(); updateFloatingButtonColor();
updateStoriesPosting(); updateStoriesPosting();
if (showStoryHint && storyHint != null && storiesEnabled) {
storyHint.show();
}
searchTabsView = null; searchTabsView = null;
@ -5494,38 +5517,60 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
authHintCell.setVisibility(View.VISIBLE); authHintCell.setVisibility(View.VISIBLE);
} }
authHintCell.setAlpha(1f); authHintCell.setAlpha(1f);
viewPages[0].listView.requestLayout(); viewPages[0].listView.requestLayout();
if (fragmentView != null) { fragmentView.requestLayout();
fragmentView.requestLayout();
}
notificationsLocker.lock(); notificationsLocker.lock();
authHintCellAnimating = true;
ValueAnimator valueAnimator = ValueAnimator.ofFloat(authHintCellProgress, visible ? 1f : 0); ValueAnimator valueAnimator = ValueAnimator.ofFloat(authHintCellProgress, visible ? 1f : 0);
valueAnimator.addUpdateListener(animation -> {
authHintCellProgress = (float) animation.getAnimatedValue(); int pos = viewPages[0].layoutManager.findFirstVisibleItemPosition();
updateContextViewPosition(); int childTop = 0;
viewPages[0].listView.requestLayout(); if (pos != RecyclerView.NO_POSITION) {
}); childTop = viewPages[0].layoutManager.findViewByPosition(pos).getTop();
valueAnimator.addListener(new AnimatorListenerAdapter() { childTop += visible ? 0 : -authHintCell.getMeasuredHeight();
@Override }
public void onAnimationEnd(Animator animation) { int finalChildTop = childTop;
notificationsLocker.unlock(); AndroidUtilities.doOnLayout(fragmentView, () -> {
if (fragmentView != null) { float listDy = authHintCell.getMeasuredHeight();
fragmentView.requestLayout(); if (!visible) {
} View view = viewPages[0].layoutManager.findViewByPosition(pos);
authHintCellProgress = visible ? 1f : 0; //look at real visible views difference
if (!visible) { if (view != null) {
authHintCell.setVisibility(View.GONE); int newTop = view.getTop();
listDy += (finalChildTop - newTop);
} }
} }
float finalListDy = listDy;
viewPages[0].listView.setTranslationY(finalListDy * authHintCellProgress);
valueAnimator.addUpdateListener(animation -> {
authHintCellProgress = (float) animation.getAnimatedValue();
viewPages[0].listView.setTranslationY(finalListDy * authHintCellProgress);
updateContextViewPosition();
});
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
notificationsLocker.unlock();
authHintCellAnimating = false;
authHintCellProgress = visible ? 1f : 0;
fragmentView.requestLayout();
viewPages[0].listView.requestLayout();
viewPages[0].listView.setTranslationY(0);
if (!visible) {
authHintCell.setVisibility(View.GONE);
}
}
});
valueAnimator.setDuration(250);
valueAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
valueAnimator.start();
}); });
valueAnimator.setDuration(250);
valueAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
valueAnimator.start();
} }
} }
private void updateDialogsHint() { private void updateDialogsHint() {
if (dialogsHintCell == null || getContext() == null) { if (dialogsHintCell == null || fragmentView == null || getContext() == null) {
return; return;
} }
if (!getMessagesController().getUnconfirmedAuthController().auths.isEmpty() && folderId == 0 && initialDialogsType == DIALOGS_TYPE_DEFAULT) { if (!getMessagesController().getUnconfirmedAuthController().auths.isEmpty() && folderId == 0 && initialDialogsType == DIALOGS_TYPE_DEFAULT) {
@ -5533,9 +5578,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
dialogsHintCell.setVisibility(View.GONE); dialogsHintCell.setVisibility(View.GONE);
if (authHintCell == null) { if (authHintCell == null) {
authHintCell = new UnconfirmedAuthHintCell(getContext()); authHintCell = new UnconfirmedAuthHintCell(getContext());
if (fragmentView instanceof ContentView) { ((ContentView) fragmentView).addView(authHintCell);
((ContentView) fragmentView).addView(authHintCell);
}
} }
authHintCell.set(DialogsActivity.this, currentAccount); authHintCell.set(DialogsActivity.this, currentAccount);
updateAuthHintCellVisibility(true); updateAuthHintCellVisibility(true);
@ -6664,6 +6707,10 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} }
} }
} }
if (storyHint != null) {
storyHint.hide();
}
Bulletin.hideVisible();
return b; return b;
} }
@ -6760,6 +6807,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
undoView[0].hide(true, 0); undoView[0].hide(true, 0);
} }
super.onBecomeFullyHidden(); super.onBecomeFullyHidden();
canShowStoryHint = true;
} }
@Override @Override
@ -6785,6 +6833,12 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} }
} }
} }
updateFloatingButtonOffset();
if (canShowStoryHint && !storyHintShown && storyHint != null && storiesEnabled) {
storyHintShown = true;
canShowStoryHint = false;
storyHint.show();
}
} }
private void showArchiveHelp() { private void showArchiveHelp() {
@ -9724,9 +9778,15 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
permissons.add(Manifest.permission.GET_ACCOUNTS); permissons.add(Manifest.permission.GET_ACCOUNTS);
} }
if (Build.VERSION.SDK_INT >= 33) { if (Build.VERSION.SDK_INT >= 33) {
permissons.add(Manifest.permission.READ_MEDIA_IMAGES); if (activity.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
permissons.add(Manifest.permission.READ_MEDIA_VIDEO); permissons.add(Manifest.permission.READ_MEDIA_IMAGES);
permissons.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); }
if (activity.checkSelfPermission(Manifest.permission.READ_MEDIA_VIDEO) != PackageManager.PERMISSION_GRANTED) {
permissons.add(Manifest.permission.READ_MEDIA_VIDEO);
}
if (activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
permissons.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
} else if ((Build.VERSION.SDK_INT <= 28 || BuildVars.NO_SCOPED_STORAGE) && activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { } else if ((Build.VERSION.SDK_INT <= 28 || BuildVars.NO_SCOPED_STORAGE) && activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
permissons.add(Manifest.permission.READ_EXTERNAL_STORAGE); permissons.add(Manifest.permission.READ_EXTERNAL_STORAGE);
permissons.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); permissons.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);

View file

@ -38,6 +38,7 @@ import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.StickerSetBulletinLayout; import org.telegram.ui.Components.StickerSetBulletinLayout;
import org.telegram.ui.Components.StickersAlert; import org.telegram.ui.Components.StickersAlert;
import org.telegram.ui.Stories.StoryReactionWidgetView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -895,6 +896,82 @@ public class EmojiAnimationsOverlay implements NotificationCenter.NotificationCe
} }
} }
public boolean showAnimationForWidget(StoryReactionWidgetView widgetView) {
if (drawingObjects.size() > 12) {
return false;
}
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(widgetView.mediaArea.reaction);
String emoji = visibleReaction.emojicon;
if (emoji == null) {
TLRPC.Document document = AnimatedEmojiDrawable.findDocument(currentAccount, visibleReaction.documentId);
emoji = MessageObject.findAnimatedEmojiEmoticon(document);
}
MessageObject messageObject = null;
float imageH = widgetView.getMeasuredHeight();
float imageW = widgetView.getMeasuredWidth();
View parent = (View) widgetView.getParent();
if (imageW > parent.getWidth() * 0.5f) {
imageH = imageW = parent.getWidth() * 0.4f;
}
// if (imageH <= 0 || imageW <= 0) {
// return false;
// }
emoji = unwrapEmoji(emoji);
int viewId = widgetView.hashCode();
TLRPC.Document viewDocument = null;
boolean isOutOwner = widgetView.getTranslationX() > contentLayout.getMeasuredWidth() / 2f;//view.getMessageObject().isOutOwner();
if (visibleReaction.emojicon != null && createDrawingObject(emoji, viewId, viewDocument, messageObject, -1, false, false, imageW, imageH, isOutOwner)) {
if (!drawingObjects.isEmpty()) {
DrawingObject drawingObject = drawingObjects.get(drawingObjects.size() - 1);
drawingObject.isReaction = true;
drawingObject.lastH = imageH;
drawingObject.lastW = imageW;
drawingObject.lastX = widgetView.getTranslationX() - drawingObject.lastW / 2f;
drawingObject.lastY = widgetView.getTranslationY() - drawingObject.lastW * 1.5f;
if (drawingObject.isOut) {
drawingObject.lastX += -drawingObject.lastW * 1.8f;
} else {
drawingObject.lastX += -drawingObject.lastW * 0.2f;
}
}
return true;
} else if (visibleReaction.documentId != 0 && widgetView.getAnimatedEmojiDrawable() != null) {
int sameAnimationCount = 0;
for (int i = 0; i < drawingObjects.size(); i++) {
if (drawingObjects.get(i).documentId == visibleReaction.documentId) {
sameAnimationCount++;
}
}
if (sameAnimationCount >= 4) {
return false;
}
DrawingObject drawingObject = new DrawingObject();
drawingObject.genericEffect = AnimatedEmojiEffect.createFrom(widgetView.getAnimatedEmojiDrawable(), true, true);
drawingObject.randomOffsetX = imageW / 4 * ((random.nextInt() % 101) / 100f);
drawingObject.randomOffsetY = imageH / 4 * ((random.nextInt() % 101) / 100f);
drawingObject.messageId = viewId;
drawingObject.document = null;
drawingObject.documentId = visibleReaction.documentId;
drawingObject.isOut = isOutOwner;
drawingObject.isReaction = true;
drawingObject.lastH = imageH;
drawingObject.lastW = imageW;
drawingObject.lastX = widgetView.getTranslationX() - drawingObject.lastW / 2f;
drawingObject.lastY = widgetView.getTranslationY() - drawingObject.lastW * 1.5f;
drawingObject.lastX += -drawingObject.lastW * 1.8f;
if (attached) {
drawingObject.genericEffect.setView(contentLayout);
}
drawingObjects.add(drawingObject);
return true;
}
return false;
}
public void setAccount(int currentAccount) { public void setAccount(int currentAccount) {
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
} }

View file

@ -9,6 +9,7 @@
package org.telegram.ui; package org.telegram.ui;
import static org.telegram.ui.Components.Premium.LimitReachedBottomSheet.TYPE_ACCOUNTS; import static org.telegram.ui.Components.Premium.LimitReachedBottomSheet.TYPE_ACCOUNTS;
import static org.telegram.ui.Components.Premium.LimitReachedBottomSheet.TYPE_BOOSTS_FOR_USERS;
import android.Manifest; import android.Manifest;
import android.animation.Animator; import android.animation.Animator;
@ -97,6 +98,7 @@ import org.telegram.messenger.AutoDeleteMediaTask;
import org.telegram.messenger.BackupAgent; import org.telegram.messenger.BackupAgent;
import org.telegram.messenger.BotWebViewVibrationEffect; import org.telegram.messenger.BotWebViewVibrationEffect;
import org.telegram.messenger.BuildVars; import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChannelBoostsController;
import org.telegram.messenger.ChatObject; import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController; import org.telegram.messenger.ContactsController;
import org.telegram.messenger.ContactsLoadingObserver; import org.telegram.messenger.ContactsLoadingObserver;
@ -132,6 +134,8 @@ import org.telegram.messenger.voip.VoIPService;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBarLayout;
import org.telegram.ui.ActionBar.ActionBarMenu;
import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.DrawerLayoutContainer; import org.telegram.ui.ActionBar.DrawerLayoutContainer;
@ -219,6 +223,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
public static Runnable onResumeStaticCallback; public static Runnable onResumeStaticCallback;
private static final String EXTRA_ACTION_TOKEN = "actions.fulfillment.extra.ACTION_TOKEN"; private static final String EXTRA_ACTION_TOKEN = "actions.fulfillment.extra.ACTION_TOKEN";
public ArrayList<INavigationLayout> sheetFragmentsStack = new ArrayList<>();
private boolean finished; private boolean finished;
private String videoPath; private String videoPath;
@ -948,7 +953,6 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
webViewSheet.setParentActivity(this); webViewSheet.setParentActivity(this);
webViewSheet.requestWebView(currentAccount, attachMenuBot.bot_id, attachMenuBot.bot_id, attachMenuBot.short_name, null, BotWebViewSheet.TYPE_SIMPLE_WEB_VIEW_BUTTON, 0, false, BotWebViewSheet.FLAG_FROM_SIDE_MENU); webViewSheet.requestWebView(currentAccount, attachMenuBot.bot_id, attachMenuBot.bot_id, attachMenuBot.short_name, null, BotWebViewSheet.TYPE_SIMPLE_WEB_VIEW_BUTTON, 0, false, BotWebViewSheet.FLAG_FROM_SIDE_MENU);
webViewSheet.show(); webViewSheet.show();
drawerLayoutContainer.closeDrawer();
} }
@Override @Override
@ -2023,6 +2027,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
Integer messageId = null; Integer messageId = null;
Long channelId = null; Long channelId = null;
Integer threadId = null; Integer threadId = null;
boolean isBoost = false;
Integer commentId = null; Integer commentId = null;
int videoTimestamp = -1; int videoTimestamp = -1;
boolean hasUrl = false; boolean hasUrl = false;
@ -2201,6 +2206,10 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
messageId = Utilities.parseInt(segments.get(3)); messageId = Utilities.parseInt(segments.get(3));
} }
} }
if (data.getQuery() != null && segments.size() == 2) {
isBoost = data.getQuery().equals("boost");
channelId = Utilities.parseLong(segments.get(1));
}
} else if (path.startsWith("contact/")) { } else if (path.startsWith("contact/")) {
contactToken = path.substring(8); contactToken = path.substring(8);
} else if (path.startsWith("folder/")) { } else if (path.startsWith("folder/")) {
@ -2246,6 +2255,9 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
attachMenuBotChoose = data.getQueryParameter("choose"); attachMenuBotChoose = data.getQueryParameter("choose");
attachMenuBotToOpen = data.getQueryParameter("attach"); attachMenuBotToOpen = data.getQueryParameter("attach");
threadId = Utilities.parseInt(data.getQueryParameter("thread")); threadId = Utilities.parseInt(data.getQueryParameter("thread"));
if (data.getQuery() != null) {
isBoost = data.getQuery().equals("boost");
}
// storyId = Utilities.parseInt(data.getQueryParameter("story")); // storyId = Utilities.parseInt(data.getQueryParameter("story"));
if (threadId == 0) { if (threadId == 0) {
threadId = null; threadId = null;
@ -2674,7 +2686,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
if (message != null && message.startsWith("@")) { if (message != null && message.startsWith("@")) {
message = " " + message; message = " " + message;
} }
runLinkRequest(intentAccount[0], username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, login, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, 0, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, botAppMaybe, startApp, progress, forceNotInternalForApps, storyId); runLinkRequest(intentAccount[0], username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, login, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, 0, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, botAppMaybe, startApp, progress, forceNotInternalForApps, storyId, isBoost);
} else { } else {
try (Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null)) { try (Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null)) {
if (cursor != null) { if (cursor != null) {
@ -3491,9 +3503,10 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
final String botAppStartParam, final String botAppStartParam,
final Browser.Progress progress, final Browser.Progress progress,
final boolean forceNotInternalForApps, final boolean forceNotInternalForApps,
final int storyId) { final int storyId,
final boolean isBoost) {
if (state == 0 && ChatActivity.SCROLL_DEBUG_DELAY && progress != null) { if (state == 0 && ChatActivity.SCROLL_DEBUG_DELAY && progress != null) {
Runnable runnable = () -> runLinkRequest(intentAccount, username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, loginToken, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, 1, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, botAppMaybe, botAppStartParam, progress, forceNotInternalForApps, storyId); Runnable runnable = () -> runLinkRequest(intentAccount, username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, loginToken, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, 1, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, botAppMaybe, botAppStartParam, progress, forceNotInternalForApps, storyId, isBoost);
progress.init(); progress.init();
progress.onCancel(() -> AndroidUtilities.cancelRunOnUIThread(runnable)); progress.onCancel(() -> AndroidUtilities.cancelRunOnUIThread(runnable));
AndroidUtilities.runOnUIThread(runnable, 7500); AndroidUtilities.runOnUIThread(runnable, 7500);
@ -3503,7 +3516,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
if (account != intentAccount) { if (account != intentAccount) {
switchToAccount(account, true); switchToAccount(account, true);
} }
runLinkRequest(account, username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, loginToken, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, 1, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, botAppMaybe, botAppStartParam, progress, forceNotInternalForApps, storyId); runLinkRequest(account, username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, loginToken, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, 1, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, botAppMaybe, botAppStartParam, progress, forceNotInternalForApps, storyId, isBoost);
}).show(); }).show();
return; return;
} else if (code != null) { } else if (code != null) {
@ -3685,18 +3698,10 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
TLRPC.TL_messages_getAttachMenuBot getAttachMenuBot = new TLRPC.TL_messages_getAttachMenuBot(); TLRPC.TL_messages_getAttachMenuBot getAttachMenuBot = new TLRPC.TL_messages_getAttachMenuBot();
getAttachMenuBot.bot = MessagesController.getInstance(intentAccount).getInputUser(peerId); getAttachMenuBot.bot = MessagesController.getInstance(intentAccount).getInputUser(peerId);
ConnectionsManager.getInstance(intentAccount).sendRequest(getAttachMenuBot, (response1, error1) -> AndroidUtilities.runOnUIThread(() -> { ConnectionsManager.getInstance(intentAccount).sendRequest(getAttachMenuBot, (response1, error1) -> AndroidUtilities.runOnUIThread(() -> {
try {
if (dismissLoading != null) {
dismissLoading.run();
}
} catch (Exception e) {
FileLog.e(e);
}
if (response1 instanceof TLRPC.TL_attachMenuBotsBot) { if (response1 instanceof TLRPC.TL_attachMenuBotsBot) {
WebAppDisclaimerAlert.show(this, ignore -> { WebAppDisclaimerAlert.show(this, ignore -> {
user.inactive = false; user.inactive = false;
MediaDataController.getInstance(currentAccount).applyAttachMenuBot((TLRPC.TL_attachMenuBotsBot) response1); processWebAppBot(intentAccount, username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, loginToken, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, state, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, botAppMaybe, botAppStartParam, progress, false, storyId, isBoost, user, dismissLoading);
processWebAppBot(intentAccount, username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, loginToken, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, state, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, botAppMaybe, botAppStartParam, progress, false, storyId, true, user, dismissLoading);
TLRPC.TL_messages_toggleBotInAttachMenu botRequest = new TLRPC.TL_messages_toggleBotInAttachMenu(); TLRPC.TL_messages_toggleBotInAttachMenu botRequest = new TLRPC.TL_messages_toggleBotInAttachMenu();
botRequest.bot = MessagesController.getInstance(intentAccount).getInputUser(peerId); botRequest.bot = MessagesController.getInstance(intentAccount).getInputUser(peerId);
@ -3712,12 +3717,17 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
} }
})); }));
} else { } else {
processWebAppBot(intentAccount, username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, loginToken, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, state, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, botAppMaybe, botAppStartParam, progress, false, storyId, false, user, dismissLoading); processWebAppBot(intentAccount, username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, loginToken, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, state, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, botAppMaybe, botAppStartParam, progress, false, storyId, isBoost, user, dismissLoading);
} }
return; return;
} }
} }
if (isBoost) {
processBoostDialog(peerId, dismissLoading);
return;
}
if (setAsAttachBot != null && attachMenuBotToOpen == null) { if (setAsAttachBot != null && attachMenuBotToOpen == null) {
TLRPC.User user = MessagesController.getInstance(intentAccount).getUser(peerId); TLRPC.User user = MessagesController.getInstance(intentAccount).getUser(peerId);
if (user != null && user.bot) { if (user != null && user.bot) {
@ -3941,7 +3951,6 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
}); });
presentFragment(fragment); presentFragment(fragment);
} else { } else {
long dialog_id; long dialog_id;
boolean isBot = false; boolean isBot = false;
Bundle args = new Bundle(); Bundle args = new Bundle();
@ -4523,7 +4532,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
} }
} }
})); }));
} else if (channelId != null && messageId != null) { } else if (channelId != null && (messageId != null || isBoost)) {
if (threadId != null) { if (threadId != null) {
TLRPC.Chat chat = MessagesController.getInstance(intentAccount).getChat(channelId); TLRPC.Chat chat = MessagesController.getInstance(intentAccount).getChat(channelId);
if (chat != null) { if (chat != null) {
@ -4556,9 +4565,13 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
} else { } else {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putLong("chat_id", channelId); args.putLong("chat_id", channelId);
args.putInt("message_id", messageId); if (messageId != null) {
args.putInt("message_id", messageId);
}
TLRPC.Chat chatLocal = MessagesController.getInstance(currentAccount).getChat(channelId); TLRPC.Chat chatLocal = MessagesController.getInstance(currentAccount).getChat(channelId);
if (chatLocal != null && chatLocal.forum) { if (chatLocal != null && isBoost) {
processBoostDialog(-channelId, dismissLoading);
} else if (chatLocal != null && chatLocal.forum) {
openForumFromLink(-channelId, 0, messageId, () -> { openForumFromLink(-channelId, 0, messageId, () -> {
try { try {
dismissLoading.run(); dismissLoading.run();
@ -4588,7 +4601,9 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
notFound = false; notFound = false;
MessagesController.getInstance(currentAccount).putChats(res.chats, false); MessagesController.getInstance(currentAccount).putChats(res.chats, false);
TLRPC.Chat chat = res.chats.get(0); TLRPC.Chat chat = res.chats.get(0);
if (chat != null && chat.forum) { if (chat != null && isBoost) {
processBoostDialog(-channelId, null);
} else if (chat != null && chat.forum) {
if (threadId != null) { if (threadId != null) {
openForumFromLink(-channelId, threadId, messageId, null); openForumFromLink(-channelId, threadId, messageId, null);
} else { } else {
@ -4675,7 +4690,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
final Browser.Progress progress, final Browser.Progress progress,
final boolean forceNotInternalForApps, final boolean forceNotInternalForApps,
final int storyId, final int storyId,
boolean justAdded, final boolean isBoost,
TLRPC.User user, TLRPC.User user,
Runnable dismissLoading) { Runnable dismissLoading) {
@ -4689,7 +4704,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
progress.end(); progress.end();
} }
if (error1 != null) { if (error1 != null) {
AndroidUtilities.runOnUIThread(() -> runLinkRequest(intentAccount, username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, loginToken, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, state, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, null, null, progress, forceNotInternalForApps, storyId)); AndroidUtilities.runOnUIThread(() -> runLinkRequest(intentAccount, username, group, sticker, emoji, botUser, botChat, botChannel, botChatAdminParams, message, contactToken, folderSlug, hasUrl, messageId, channelId, threadId, commentId, game, auth, lang, unsupportedUrl, code, loginToken, wallPaper, inputInvoiceSlug, theme, voicechat, livestream, state, videoTimestamp, setAsAttachBot, attachMenuBotToOpen, attachMenuBotChoose, null, null, progress, forceNotInternalForApps, storyId, isBoost));
} else { } else {
TLRPC.TL_messages_botApp botApp = (TLRPC.TL_messages_botApp) response1; TLRPC.TL_messages_botApp botApp = (TLRPC.TL_messages_botApp) response1;
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
@ -4702,12 +4717,12 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
sheet.setParentActivity(LaunchActivity.this); sheet.setParentActivity(LaunchActivity.this);
sheet.requestWebView(intentAccount, user.id, user.id, null, null, BotWebViewSheet.TYPE_WEB_VIEW_BOT_APP, 0, false, lastFragment, botApp.app, allowWrite.get(), botAppStartParam, user); sheet.requestWebView(intentAccount, user.id, user.id, null, null, BotWebViewSheet.TYPE_WEB_VIEW_BOT_APP, 0, false, lastFragment, botApp.app, allowWrite.get(), botAppStartParam, user);
sheet.show(); sheet.show();
if (justAdded) { if (botApp.inactive || forceNotInternalForApps) {
sheet.showJustAddedBulletin(); sheet.showJustAddedBulletin();
} }
}; };
if (!user.bot_attach_menu && (botApp.inactive || forceNotInternalForApps)) { if (botApp.inactive || forceNotInternalForApps) {
AlertsCreator.createBotLaunchAlert(lastFragment, botApp, user, allowWrite, loadBotSheet); AlertsCreator.createBotLaunchAlert(lastFragment, botApp, user, allowWrite, loadBotSheet);
} else { } else {
loadBotSheet.run(); loadBotSheet.run();
@ -4718,6 +4733,36 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
} }
private void processBoostDialog(Long peerId, Runnable dismissLoading) {
ChannelBoostsController boostsController = MessagesController.getInstance(currentAccount).getBoostsController();
boostsController.getBoostsStats(peerId, boostsStatus -> {
if (boostsStatus == null) {
dismissLoading.run();
return;
}
boostsController.userCanBoostChannel(peerId, canApplyBoost -> {
LimitReachedBottomSheet limitReachedBottomSheet = new LimitReachedBottomSheet(getLastFragment(), this, TYPE_BOOSTS_FOR_USERS, currentAccount, null);
limitReachedBottomSheet.setCanApplyBoost(canApplyBoost);
BaseFragment lastFragment = getLastFragment();
boolean isCurrentChat = false;
if (lastFragment instanceof ChatActivity) {
isCurrentChat = ((ChatActivity) lastFragment).getDialogId() == peerId;
}
limitReachedBottomSheet.setBoostsStats(boostsStatus, isCurrentChat);
limitReachedBottomSheet.setDialogId(peerId);
limitReachedBottomSheet.show();
try {
if (dismissLoading != null) {
dismissLoading.run();
}
} catch (Exception e) {
FileLog.e(e);
}
});
});
}
private void processAttachMenuBot(int intentAccount, long peerId, String attachMenuBotChoose, TLRPC.User user, String setAsAttachBot) { private void processAttachMenuBot(int intentAccount, long peerId, String attachMenuBotChoose, TLRPC.User user, String setAsAttachBot) {
TLRPC.TL_messages_getAttachMenuBot getAttachMenuBot = new TLRPC.TL_messages_getAttachMenuBot(); TLRPC.TL_messages_getAttachMenuBot getAttachMenuBot = new TLRPC.TL_messages_getAttachMenuBot();
getAttachMenuBot.bot = MessagesController.getInstance(intentAccount).getInputUser(peerId); getAttachMenuBot.bot = MessagesController.getInstance(intentAccount).getInputUser(peerId);
@ -5124,6 +5169,9 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
} }
public void checkAppUpdate(boolean force) { public void checkAppUpdate(boolean force) {
if (!BuildVars.isStandaloneApp()) {
return;
}
if (!force && BuildVars.DEBUG_VERSION || !force && !BuildVars.CHECK_UPDATES) { if (!force && BuildVars.DEBUG_VERSION || !force && !BuildVars.CHECK_UPDATES) {
return; return;
} }
@ -7508,6 +7556,9 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
} }
public static BaseFragment getLastFragment() { public static BaseFragment getLastFragment() {
if (instance != null && !instance.sheetFragmentsStack.isEmpty()) {
return instance.sheetFragmentsStack.get(instance.sheetFragmentsStack.size() - 1).getLastFragment();
}
if (instance != null && instance.getActionBarLayout() != null) { if (instance != null && instance.getActionBarLayout() != null) {
return instance.getActionBarLayout().getLastFragment(); return instance.getActionBarLayout().getLastFragment();
} }
@ -7649,7 +7700,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
return; return;
} }
StoriesController storiesController = MessagesController.getInstance(currentAccount).getStoriesController(); StoriesController storiesController = MessagesController.getInstance(currentAccount).getStoriesController();
ArrayList<TLRPC.TL_userStories> stories = new ArrayList<>(onlyArchived ? storiesController.getHiddenList() : storiesController.getDialogListStories()); ArrayList<TLRPC.PeerStories> stories = new ArrayList<>(onlyArchived ? storiesController.getHiddenList() : storiesController.getDialogListStories());
ArrayList<Long> peerIds = new ArrayList<>(); ArrayList<Long> peerIds = new ArrayList<>();
ArrayList<Long> toLoadPeerIds = new ArrayList<>(); ArrayList<Long> toLoadPeerIds = new ArrayList<>();
final long[] finalDialogIds; final long[] finalDialogIds;
@ -7686,19 +7737,19 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
}; };
for (int i = 0; i < toLoadPeerIds.size(); ++i) { for (int i = 0; i < toLoadPeerIds.size(); ++i) {
long did = toLoadPeerIds.get(i); long did = toLoadPeerIds.get(i);
TLRPC.TL_stories_getUserStories req = new TLRPC.TL_stories_getUserStories(); TLRPC.TL_stories_getPeerStories req = new TLRPC.TL_stories_getPeerStories();
req.user_id = messagesController.getInputUser(did); req.peer = messagesController.getInputPeer(did);
if (req.user_id instanceof TLRPC.TL_inputUserEmpty) { if (req.peer instanceof TLRPC.TL_inputPeerEmpty) {
loaded[0]--; loaded[0]--;
continue; continue;
} }
if (req.user_id == null) { if (req.peer == null) {
loaded[0]--; loaded[0]--;
continue; continue;
} }
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> { ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (res instanceof TLRPC.TL_stories_userStories) { if (res instanceof TLRPC.TL_stories_peerStories) {
TLRPC.TL_stories_userStories r = (TLRPC.TL_stories_userStories) res; TLRPC.TL_stories_peerStories r = (TLRPC.TL_stories_peerStories) res;
messagesController.putUsers(r.users, false); messagesController.putUsers(r.users, false);
messagesController.getStoriesController().putStories(did, r.stories); messagesController.getStoriesController().putStories(did, r.stories);
whenDone.run(); whenDone.run();
@ -7710,9 +7761,10 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
} else { } else {
long me = UserConfig.getInstance(currentAccount).getClientUserId(); long me = UserConfig.getInstance(currentAccount).getClientUserId();
for (int i = 0; i < stories.size(); ++i) { for (int i = 0; i < stories.size(); ++i) {
TLRPC.TL_userStories userStories = stories.get(i); TLRPC.PeerStories userStories = stories.get(i);
if (userStories.user_id != me && !peerIds.contains(userStories.user_id) && storiesController.hasUnreadStories(userStories.user_id)) { long dialogId = DialogObject.getPeerDialogId(userStories.peer);
peerIds.add(userStories.user_id); if (dialogId != me && !peerIds.contains(dialogId) && storiesController.hasUnreadStories(dialogId)) {
peerIds.add(dialogId);
} }
} }
if (!peerIds.isEmpty()) { if (!peerIds.isEmpty()) {

View file

@ -4018,6 +4018,8 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No
if (currentType == AUTH_TYPE_MESSAGE) { if (currentType == AUTH_TYPE_MESSAGE) {
if (nextType == AUTH_TYPE_FLASH_CALL || nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_MISSED_CALL) { if (nextType == AUTH_TYPE_FLASH_CALL || nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_MISSED_CALL) {
problemText.setText(LocaleController.getString("DidNotGetTheCodePhone", R.string.DidNotGetTheCodePhone)); problemText.setText(LocaleController.getString("DidNotGetTheCodePhone", R.string.DidNotGetTheCodePhone));
} else if (nextType == AUTH_TYPE_FRAGMENT_SMS) {
problemText.setText(LocaleController.getString("DidNotGetTheCodeFragment", R.string.DidNotGetTheCodeFragment));
} else if (nextType == 0) { } else if (nextType == 0) {
problemText.setText(LocaleController.getString("DidNotGetTheCode", R.string.DidNotGetTheCode)); problemText.setText(LocaleController.getString("DidNotGetTheCode", R.string.DidNotGetTheCode));
} else { } else {

View file

@ -2398,7 +2398,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
} }
}); });
if (paymentForm.invoice.recurring) { if (paymentForm.invoice.terms_url != null) {
recurrentAcceptCell = new RecurrentPaymentsAcceptCell(context, getResourceProvider()); recurrentAcceptCell = new RecurrentPaymentsAcceptCell(context, getResourceProvider());
recurrentAcceptCell.setChecked(paymentForm.invoice.recurring && isAcceptTermsChecked); recurrentAcceptCell.setChecked(paymentForm.invoice.recurring && isAcceptTermsChecked);
String str = LocaleController.getString(R.string.PaymentCheckoutAcceptRecurrent); String str = LocaleController.getString(R.string.PaymentCheckoutAcceptRecurrent);
@ -2406,7 +2406,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
int firstIndex = str.indexOf('*'), lastIndex = str.lastIndexOf('*'); int firstIndex = str.indexOf('*'), lastIndex = str.lastIndexOf('*');
if (firstIndex != -1 && lastIndex != -1) { if (firstIndex != -1 && lastIndex != -1) {
SpannableString acceptTerms = new SpannableString(str.substring(firstIndex + 1, lastIndex)); SpannableString acceptTerms = new SpannableString(str.substring(firstIndex + 1, lastIndex));
acceptTerms.setSpan(new URLSpanNoUnderline(paymentForm.invoice.recurring_terms_url), 0, acceptTerms.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); acceptTerms.setSpan(new URLSpanNoUnderline(paymentForm.invoice.terms_url), 0, acceptTerms.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.replace(firstIndex, lastIndex + 1, acceptTerms); sb.replace(firstIndex, lastIndex + 1, acceptTerms);
str = str.substring(0, firstIndex) + acceptTerms + str.substring(lastIndex + 1); str = str.substring(0, firstIndex) + acceptTerms + str.substring(lastIndex + 1);
} }

View file

@ -1777,10 +1777,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
windowLayoutParams.flags = windowLayoutParams.flags =
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR |
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
} else {
windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
} }
windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
windowView.setFocusable(false); windowView.setFocusable(false);
@ -4607,7 +4604,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
navigationBarLayoutParams.bottomMargin = -navigationBarHeight / 2; navigationBarLayoutParams.bottomMargin = -navigationBarHeight / 2;
navigationBar.setLayoutParams(navigationBarLayoutParams); navigationBar.setLayoutParams(navigationBarLayoutParams);
} }
containerView.setPadding(insets.left, 0, insets.right, 0); containerView.setPadding(newInsets.getSystemWindowInsetLeft(), 0, newInsets.getSystemWindowInsetRight(), 0);
if (actionBar != null) { if (actionBar != null) {
AndroidUtilities.cancelRunOnUIThread(updateContainerFlagsRunnable); AndroidUtilities.cancelRunOnUIThread(updateContainerFlagsRunnable);
if (isVisible && animationInProgress == 0) { if (isVisible && animationInProgress == 0) {
@ -4636,10 +4633,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
windowLayoutParams.flags = windowLayoutParams.flags =
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR |
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
} else {
windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
} }
paintingOverlay = new PaintingOverlay(parentActivity); paintingOverlay = new PaintingOverlay(parentActivity);
@ -6045,6 +6039,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
@Override @Override
protected void setupMentionContainer() { protected void setupMentionContainer() {
if (parentChatActivity != null) {
return;
}
mentionContainer.getAdapter().setAllowStickers(false);
mentionContainer.getAdapter().setAllowBots(false);
mentionContainer.getAdapter().setAllowChats(false);
mentionContainer.getAdapter().setSearchInDailogs(true);
if (parentChatActivity != null) { if (parentChatActivity != null) {
mentionContainer.getAdapter().setChatInfo(parentChatActivity.chatInfo); mentionContainer.getAdapter().setChatInfo(parentChatActivity.chatInfo);
mentionContainer.getAdapter().setNeedUsernames(parentChatActivity.currentChat != null); mentionContainer.getAdapter().setNeedUsernames(parentChatActivity.currentChat != null);
@ -10534,7 +10535,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
photoPaintView.keyboardVisible = paintKeyboardNotifier.keyboardVisible(); photoPaintView.keyboardVisible = paintKeyboardNotifier.keyboardVisible();
containerView.invalidate(); containerView.invalidate();
height = Math.max(height, photoPaintView.getEmojiPadding(false)); height = Math.max(height, photoPaintView.getEmojiPadding(false));
translateY(photoPaintView.isCurrentText() && height > 0 ? ((AndroidUtilities.displaySize.y - height) / 2f - photoPaintView.getSelectedEntityCenterY()) / 2.5f : 0); translateY(photoPaintView.isCurrentText() && height > 0 ? (AndroidUtilities.displaySize.y - height - dp(80) - photoPaintView.getSelectedEntityBottom()) : 0);
if (paintKeyboardAnimator != null) { if (paintKeyboardAnimator != null) {
paintKeyboardAnimator.cancel(); paintKeyboardAnimator.cancel();
@ -14270,10 +14271,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
windowLayoutParams.flags = windowLayoutParams.flags =
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR |
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
} else {
windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
} }
if (chatActivity != null && chatActivity.getCurrentEncryptedChat() != null || if (chatActivity != null && chatActivity.getCurrentEncryptedChat() != null ||
avatarsDialogId != 0 && MessagesController.getInstance(currentAccount).isChatNoForwards(-avatarsDialogId) || avatarsDialogId != 0 && MessagesController.getInstance(currentAccount).isChatNoForwards(-avatarsDialogId) ||
@ -16991,100 +16989,6 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
return tempInt; return tempInt;
} }
private int[] applyCrop(Matrix matrix, int containerWidth, int containerHeight, int bitmapWidth, int bitmapHeight, float currentScale, CropTransform cropTransform, MediaController.CropState cropState) {
int originalWidth = bitmapWidth;
int originalHeight = bitmapHeight;
float scale = Math.min(containerWidth / (float) originalWidth, containerHeight / (float) originalHeight);
int rotatedWidth = originalWidth;
int rotatedHeight = originalHeight;
int orientation = cropTransform.getOrientation();
if (orientation == 90 || orientation == 270) {
int temp = bitmapWidth;
bitmapWidth = bitmapHeight;
bitmapHeight = temp;
temp = rotatedWidth;
rotatedWidth = rotatedHeight;
rotatedHeight = temp;
}
float cropAnimationValue;
if (sendPhotoType != SELECT_TYPE_AVATAR && (currentEditMode == EDIT_MODE_PAINT || switchingToMode == EDIT_MODE_PAINT)) {
cropAnimationValue = 1.0f;
} else if (imageMoveAnimation != null && switchingToMode != -1) {
if (currentEditMode == EDIT_MODE_CROP || switchingToMode == EDIT_MODE_CROP || (currentEditMode == EDIT_MODE_FILTER || currentEditMode == EDIT_MODE_PAINT) && switchingToMode == -1) {
cropAnimationValue = 1.0f;
} else if (switchingToMode == EDIT_MODE_NONE) {
cropAnimationValue = animationValue;
} else {
cropAnimationValue = 1.0f - animationValue;
}
} else {
cropAnimationValue = currentEditMode == EDIT_MODE_FILTER || currentEditMode == EDIT_MODE_PAINT ? 0.0f : 1.0f;
}
float cropPw = cropTransform.getCropPw();
float cropPh = cropTransform.getCropPh();
bitmapWidth *= cropPw + (1.0f - cropPw) * (1.0f - cropAnimationValue);
bitmapHeight *= cropPh + (1.0f - cropPh) * (1.0f - cropAnimationValue);
float scaleToFitX = containerWidth / (float) bitmapWidth;
if (scaleToFitX * bitmapHeight > containerHeight) {
scaleToFitX = containerHeight / (float) bitmapHeight;
}
// if (sendPhotoType != SELECT_TYPE_AVATAR && (currentEditMode != EDIT_MODE_CROP || switchingToMode == EDIT_MODE_NONE) && cropState != null) {
// float startW = bitmapWidth * scaleToFitX;
// float startH = bitmapHeight * scaleToFitX;
// float originalScaleToFitX = containerWidth / (float) originalWidth;
// if (originalScaleToFitX * originalHeight > containerHeight) {
// originalScaleToFitX = containerHeight / (float) originalHeight;
// }
// float finalW = originalWidth * originalScaleToFitX / currentScale;
// float finalH = originalHeight * originalScaleToFitX / currentScale;
//
// float w = startW + (finalW - startW) * (1.0f - cropAnimationValue);
// float h = startH + (finalH - startH) * (1.0f - cropAnimationValue);
//
// canvas.clipRect(-w / 2, -h / 2, w / 2, h / 2);
// }
if (sendPhotoType == SELECT_TYPE_AVATAR || cropTransform.hasViewTransform()) {
float cropScale;
if (currentEditMode == EDIT_MODE_CROP || sendPhotoType == SELECT_TYPE_AVATAR) {
float trueScale = 1.0f + (cropTransform.getTrueCropScale() - 1.0f) * (1.0f - cropAnimationValue);
cropScale = cropTransform.getScale() / trueScale;
float scaleToFit = containerWidth / (float) rotatedWidth;
if (scaleToFit * rotatedHeight > containerHeight) {
scaleToFit = containerHeight / (float) rotatedHeight;
}
cropScale *= scaleToFit / scale;
if (sendPhotoType == SELECT_TYPE_AVATAR) {
if (currentEditMode == EDIT_MODE_PAINT || switchingToMode == EDIT_MODE_PAINT) {
cropScale /= 1.0f + (cropTransform.getMinScale() - 1.0f) * (1.0f - cropAnimationValue);
} else if (switchingToMode == EDIT_MODE_NONE) {
cropScale /= cropTransform.getMinScale();
}
}
} else {
cropScale = cropState != null ? cropState.cropScale : 1.0f;
float trueScale = 1.0f + (cropScale - 1.0f) * (1.0f - cropAnimationValue);
cropScale *= scaleToFitX / scale / trueScale;
}
matrix.postTranslate(cropTransform.getCropAreaX() * cropAnimationValue, cropTransform.getCropAreaY() * cropAnimationValue);
matrix.postScale(cropScale, cropScale);
matrix.postTranslate(cropTransform.getCropPx() * rotatedWidth * scale * cropAnimationValue, cropTransform.getCropPy() * rotatedHeight * scale * cropAnimationValue);
float rotation = (cropTransform.getRotation() + orientation);
if (rotation > 180) {
rotation -= 360;
}
if (sendPhotoType == SELECT_TYPE_AVATAR && (currentEditMode == EDIT_MODE_PAINT || switchingToMode == EDIT_MODE_PAINT)) {
matrix.postRotate(rotation);
} else {
matrix.postRotate(rotation * cropAnimationValue);
}
}
tempInt[0] = bitmapWidth;
tempInt[1] = bitmapHeight;
return tempInt;
}
private void onActionClick(boolean download) { private void onActionClick(boolean download) {
if (currentMessageObject == null && currentBotInlineResult == null && (pageBlocksAdapter == null || currentFileNames[0] == null) && sendPhotoType != SELECT_TYPE_NO_SELECT) { if (currentMessageObject == null && currentBotInlineResult == null && (pageBlocksAdapter == null || currentFileNames[0] == null) && sendPhotoType != SELECT_TYPE_NO_SELECT) {
return; return;

View file

@ -99,6 +99,7 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio
private int paymentsClearRow; private int paymentsClearRow;
private int webSessionsRow; private int webSessionsRow;
private int botsDetailRow; private int botsDetailRow;
private int botsAndWebsitesShadowRow;
private int contactsSectionRow; private int contactsSectionRow;
private int contactsDeleteRow; private int contactsDeleteRow;
private int contactsSuggestRow; private int contactsSuggestRow;
@ -119,7 +120,8 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio
private boolean archiveChats; private boolean archiveChats;
private boolean[] clear = new boolean[2]; private boolean[] clear = new boolean[2];
SessionsActivity sessionsActivityPreload; private SessionsActivity devicesActivityPreload;
private SessionsActivity webSessionsActivityPreload;
@Override @Override
public boolean onFragmentCreate() { public boolean onFragmentCreate() {
@ -144,13 +146,24 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio
getUserConfig().loadGlobalTTl(); getUserConfig().loadGlobalTTl();
sessionsActivityPreload = new SessionsActivity(0); devicesActivityPreload = new SessionsActivity(SessionsActivity.TYPE_DEVICES);
sessionsActivityPreload.setDelegate(() -> { devicesActivityPreload.setDelegate(() -> {
if (listAdapter != null && sessionsRow >= 0) { if (listAdapter != null && sessionsRow >= 0) {
listAdapter.notifyItemChanged(sessionsRow); listAdapter.notifyItemChanged(sessionsRow);
} }
}); });
sessionsActivityPreload.loadSessions(false); devicesActivityPreload.loadSessions(false);
webSessionsActivityPreload = new SessionsActivity(SessionsActivity.TYPE_WEB_SESSIONS);
webSessionsActivityPreload.setDelegate(() -> {
if (listAdapter != null) {
int webSessionsCount = webSessionsActivityPreload.getSessionsCount();
if (webSessionsRow < 0 && webSessionsCount > 0) {
updateRows();
}
}
});
webSessionsActivityPreload.loadSessions(false);
return true; return true;
} }
@ -245,10 +258,11 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio
} if (position == blockedRow) { } if (position == blockedRow) {
presentFragment(new PrivacyUsersActivity()); presentFragment(new PrivacyUsersActivity());
} else if (position == sessionsRow) { } else if (position == sessionsRow) {
sessionsActivityPreload.resetFragment(); devicesActivityPreload.resetFragment();
presentFragment(sessionsActivityPreload); presentFragment(devicesActivityPreload);
} else if (position == webSessionsRow) { } else if (position == webSessionsRow) {
presentFragment(new SessionsActivity(1)); webSessionsActivityPreload.resetFragment();
presentFragment(webSessionsActivityPreload);
} else if (position == deleteAccountRow) { } else if (position == deleteAccountRow) {
if (getParentActivity() == null) { if (getParentActivity() == null) {
return; return;
@ -659,8 +673,15 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio
passportRow = -1; passportRow = -1;
} }
paymentsClearRow = rowCount++; paymentsClearRow = rowCount++;
webSessionsRow = rowCount++; if (webSessionsActivityPreload != null && webSessionsActivityPreload.getSessionsCount() > 0) {
botsDetailRow = rowCount++; webSessionsRow = rowCount++;
botsDetailRow = rowCount++;
botsAndWebsitesShadowRow = -1;
} else {
webSessionsRow = -1;
botsDetailRow = -1;
botsAndWebsitesShadowRow = rowCount++;
}
contactsSectionRow = rowCount++; contactsSectionRow = rowCount++;
contactsDeleteRow = rowCount++; contactsDeleteRow = rowCount++;
contactsSyncRow = rowCount++; contactsSyncRow = rowCount++;
@ -1107,16 +1128,16 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio
textCell2.setTextAndValueAndIcon(LocaleController.getString("AutoDeleteMessages", R.string.AutoDeleteMessages), value, true, R.drawable.msg2_autodelete, true); textCell2.setTextAndValueAndIcon(LocaleController.getString("AutoDeleteMessages", R.string.AutoDeleteMessages), value, true, R.drawable.msg2_autodelete, true);
} else if (position == sessionsRow) { } else if (position == sessionsRow) {
String count = ""; String count = "";
if (sessionsActivityPreload.getSessionsCount() == 0) { if (devicesActivityPreload.getSessionsCount() == 0) {
if (getMessagesController().lastKnownSessionsCount == 0) { if (getMessagesController().lastKnownSessionsCount == 0) {
showLoading = true; showLoading = true;
} else { } else {
count = String.format(LocaleController.getInstance().getCurrentLocale(), "%d", getMessagesController().lastKnownSessionsCount); count = String.format(LocaleController.getInstance().getCurrentLocale(), "%d", getMessagesController().lastKnownSessionsCount);
} }
} else { } else {
count = String.format(LocaleController.getInstance().getCurrentLocale(), "%d", sessionsActivityPreload.getSessionsCount()); count = String.format(LocaleController.getInstance().getCurrentLocale(), "%d", devicesActivityPreload.getSessionsCount());
} }
getMessagesController().lastKnownSessionsCount = sessionsActivityPreload.getSessionsCount(); getMessagesController().lastKnownSessionsCount = devicesActivityPreload.getSessionsCount();
textCell2.setTextAndValueAndIcon(LocaleController.getString("SessionsTitle", R.string.SessionsTitle), count, true, R.drawable.msg2_devices, false); textCell2.setTextAndValueAndIcon(LocaleController.getString("SessionsTitle", R.string.SessionsTitle), count, true, R.drawable.msg2_devices, false);
} else if (position == emailLoginRow) { } else if (position == emailLoginRow) {
CharSequence val = ""; CharSequence val = "";
@ -1186,7 +1207,7 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio
return 2; return 2;
} else if (position == secretWebpageRow || position == contactsSyncRow || position == contactsSuggestRow || position == newChatsRow) { } else if (position == secretWebpageRow || position == contactsSyncRow || position == contactsSuggestRow || position == newChatsRow) {
return 3; return 3;
} else if (position == privacyShadowRow) { } else if (position == privacyShadowRow || position == botsAndWebsitesShadowRow) {
return 4; return 4;
} else if (position == autoDeleteMesages || position == sessionsRow || position == emailLoginRow || position == passwordRow || position == passcodeRow || position == blockedRow) { } else if (position == autoDeleteMesages || position == sessionsRow || position == emailLoginRow || position == passwordRow || position == passcodeRow || position == blockedRow) {
return 5; return 5;

View file

@ -8,6 +8,7 @@
package org.telegram.ui; package org.telegram.ui;
import static androidx.core.view.ViewCompat.TYPE_TOUCH;
import static org.telegram.messenger.ContactsController.PRIVACY_RULES_TYPE_ADDED_BY_PHONE; import static org.telegram.messenger.ContactsController.PRIVACY_RULES_TYPE_ADDED_BY_PHONE;
import android.Manifest; import android.Manifest;
@ -15,7 +16,9 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.animation.StateListAnimator;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.Dialog; import android.app.Dialog;
@ -31,6 +34,7 @@ import android.content.res.Configuration;
import android.database.DataSetObserver; import android.database.DataSetObserver;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.Point; import android.graphics.Point;
@ -65,8 +69,10 @@ import android.view.MotionEvent;
import android.view.VelocityTracker; import android.view.VelocityTracker;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator; import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator;
import android.webkit.WebStorage; import android.webkit.WebStorage;
@ -194,6 +200,7 @@ import org.telegram.ui.Components.LinkSpanDrawable;
import org.telegram.ui.Components.MediaActivity; import org.telegram.ui.Components.MediaActivity;
import org.telegram.ui.Components.Paint.PersistColorPalette; import org.telegram.ui.Components.Paint.PersistColorPalette;
import org.telegram.ui.Components.Premium.GiftPremiumBottomSheet; import org.telegram.ui.Components.Premium.GiftPremiumBottomSheet;
import org.telegram.ui.Components.Premium.LimitReachedBottomSheet;
import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet; import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet;
import org.telegram.ui.Components.Premium.PremiumGradient; import org.telegram.ui.Components.Premium.PremiumGradient;
import org.telegram.ui.Components.Premium.PremiumPreviewBottomSheet; import org.telegram.ui.Components.Premium.PremiumPreviewBottomSheet;
@ -216,9 +223,11 @@ import org.telegram.ui.Components.UndoView;
import org.telegram.ui.Components.VectorAvatarThumbDrawable; import org.telegram.ui.Components.VectorAvatarThumbDrawable;
import org.telegram.ui.Components.voip.VoIPHelper; import org.telegram.ui.Components.voip.VoIPHelper;
import org.telegram.ui.Stories.ProfileStoriesView; import org.telegram.ui.Stories.ProfileStoriesView;
import org.telegram.ui.Stories.StoriesController;
import org.telegram.ui.Stories.StoriesListPlaceProvider; import org.telegram.ui.Stories.StoriesListPlaceProvider;
import org.telegram.ui.Stories.StoryViewer; import org.telegram.ui.Stories.StoryViewer;
import org.telegram.ui.Stories.recorder.DualCameraView; import org.telegram.ui.Stories.recorder.DualCameraView;
import org.telegram.ui.Stories.recorder.StoryRecorder;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
@ -630,6 +639,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
private boolean hasFallbackPhoto; private boolean hasFallbackPhoto;
private boolean hasCustomPhoto; private boolean hasCustomPhoto;
private ImageReceiver fallbackImage; private ImageReceiver fallbackImage;
private boolean loadingBoostsStats;
private boolean waitCanSendStoryRequest;
public static ProfileActivity of(long dialogId) { public static ProfileActivity of(long dialogId) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
@ -649,6 +660,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
private final RectF rect = new RectF(); private final RectF rect = new RectF();
private final Paint placeholderPaint; private final Paint placeholderPaint;
public boolean drawAvatar = true;
public float bounceScale = 1f;
private ImageReceiver foregroundImageReceiver; private ImageReceiver foregroundImageReceiver;
private float foregroundAlpha; private float foregroundAlpha;
@ -658,6 +671,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
ProfileGalleryView avatarsViewPager; ProfileGalleryView avatarsViewPager;
private boolean hasStories; private boolean hasStories;
private float progressToInsets = 1f;
public void setAvatarsViewPager(ProfileGalleryView avatarsViewPager) { public void setAvatarsViewPager(ProfileGalleryView avatarsViewPager) {
this.avatarsViewPager = avatarsViewPager; this.avatarsViewPager = avatarsViewPager;
@ -736,11 +750,16 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
ImageReceiver imageReceiver = animatedEmojiDrawable != null ? animatedEmojiDrawable.getImageReceiver() : this.imageReceiver; ImageReceiver imageReceiver = animatedEmojiDrawable != null ? animatedEmojiDrawable.getImageReceiver() : this.imageReceiver;
canvas.save();
canvas.scale(bounceScale, bounceScale, getMeasuredWidth() / 2f, getMeasuredHeight() / 2f);
if (imageReceiver != null && (foregroundAlpha < 1f || !drawForeground)) { if (imageReceiver != null && (foregroundAlpha < 1f || !drawForeground)) {
int inset = hasStories ? (int) AndroidUtilities.dpf2(3.5f) : 0; float inset = hasStories ? (int) AndroidUtilities.dpf2(3.5f) : 0;
inset *= (1f - progressToExpand); inset *= (1f - progressToExpand);
inset *= progressToInsets;
imageReceiver.setImageCoords(inset, inset, getMeasuredWidth() - inset * 2f, getMeasuredHeight() - inset * 2f); imageReceiver.setImageCoords(inset, inset, getMeasuredWidth() - inset * 2f, getMeasuredHeight() - inset * 2f);
imageReceiver.draw(canvas); if (drawAvatar) {
imageReceiver.draw(canvas);
}
} }
if (foregroundAlpha > 0f && drawForeground) { if (foregroundAlpha > 0f && drawForeground) {
if (foregroundImageReceiver.getDrawable() != null) { if (foregroundImageReceiver.getDrawable() != null) {
@ -754,6 +773,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
canvas.drawRoundRect(rect, radius, radius, placeholderPaint); canvas.drawRoundRect(rect, radius, radius, placeholderPaint);
} }
} }
canvas.restore();
} }
@Override @Override
@ -764,6 +784,16 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
} }
} }
public void setProgressToStoriesInsets(float progressToInsets) {
if (progressToInsets == this.progressToInsets) {
return;
}
this.progressToInsets = progressToInsets;
//if (hasStories) {
invalidate();
//}
}
public void drawForeground(boolean drawForeground) { public void drawForeground(boolean drawForeground) {
this.drawForeground = drawForeground; this.drawForeground = drawForeground;
} }
@ -1187,6 +1217,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
innerListView.scrollBy(0, dyUnconsumed); innerListView.scrollBy(0, dyUnconsumed);
} }
} }
if (dyConsumed != 0 && type == TYPE_TOUCH) {
hideFloatingButton(dyConsumed > 0);
}
} catch (Throwable e) { } catch (Throwable e) {
FileLog.e(e); FileLog.e(e);
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
@ -1640,6 +1673,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
getNotificationCenter().addObserver(this, NotificationCenter.topicsDidLoaded); getNotificationCenter().addObserver(this, NotificationCenter.topicsDidLoaded);
getNotificationCenter().addObserver(this, NotificationCenter.updateSearchSettings); getNotificationCenter().addObserver(this, NotificationCenter.updateSearchSettings);
getNotificationCenter().addObserver(this, NotificationCenter.reloadDialogPhotos); getNotificationCenter().addObserver(this, NotificationCenter.reloadDialogPhotos);
getNotificationCenter().addObserver(this, NotificationCenter.storiesUpdated);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded); NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
updateRowsIds(); updateRowsIds();
if (listAdapter != null) { if (listAdapter != null) {
@ -1709,6 +1743,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
getNotificationCenter().removeObserver(this, NotificationCenter.topicsDidLoaded); getNotificationCenter().removeObserver(this, NotificationCenter.topicsDidLoaded);
getNotificationCenter().removeObserver(this, NotificationCenter.updateSearchSettings); getNotificationCenter().removeObserver(this, NotificationCenter.updateSearchSettings);
getNotificationCenter().removeObserver(this, NotificationCenter.reloadDialogPhotos); getNotificationCenter().removeObserver(this, NotificationCenter.reloadDialogPhotos);
getNotificationCenter().removeObserver(this, NotificationCenter.storiesUpdated);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
if (avatarsViewPager != null) { if (avatarsViewPager != null) {
avatarsViewPager.onDestroy(); avatarsViewPager.onDestroy();
@ -2125,6 +2160,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putLong("chat_id", chatId); args.putLong("chat_id", chatId);
args.putBoolean("is_megagroup", chat.megagroup); args.putBoolean("is_megagroup", chat.megagroup);
if (!chatInfo.can_view_stats) {
args.putBoolean("only_boosts", chat.megagroup);
}
StatisticActivity fragment = new StatisticActivity(args); StatisticActivity fragment = new StatisticActivity(args);
presentFragment(fragment); presentFragment(fragment);
} else if (id == view_discussion) { } else if (id == view_discussion) {
@ -3475,7 +3513,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
getMessagesStorage().clearSentMedia(); getMessagesStorage().clearSentMedia();
SharedConfig.setNoSoundHintShowed(false); SharedConfig.setNoSoundHintShowed(false);
SharedPreferences.Editor editor = MessagesController.getGlobalMainSettings().edit(); SharedPreferences.Editor editor = MessagesController.getGlobalMainSettings().edit();
editor.remove("archivehint").remove("proximityhint").remove("archivehint_l").remove("speedhint").remove("gifhint").remove("reminderhint").remove("soundHint").remove("themehint").remove("bganimationhint").remove("filterhint").remove("n_0").remove("storyprvhint").remove("storyhint").remove("storyhint2").remove("storydualhint").remove("storysvddualhint").remove("stories_camera").remove("dualcam").remove("dualmatrix").remove("dual_available").remove("archivehint").remove("askNotificationsAfter").remove("askNotificationsDuration").remove("viewoncehint").commit(); editor.remove("archivehint").remove("proximityhint").remove("archivehint_l").remove("speedhint").remove("gifhint").remove("reminderhint").remove("soundHint").remove("themehint").remove("bganimationhint").remove("filterhint").remove("n_0").remove("storyprvhint").remove("storyhint").remove("storyhint2").remove("storydualhint").remove("storysvddualhint").remove("stories_camera").remove("dualcam").remove("dualmatrix").remove("dual_available").remove("archivehint").remove("askNotificationsAfter").remove("askNotificationsDuration").remove("viewoncehint").remove("taptostorysoundhint").commit();
MessagesController.getEmojiSettings(currentAccount).edit().remove("featured_hidden").remove("emoji_featured_hidden").commit(); MessagesController.getEmojiSettings(currentAccount).edit().remove("featured_hidden").remove("emoji_featured_hidden").commit();
SharedConfig.textSelectionHintShows = 0; SharedConfig.textSelectionHintShows = 0;
SharedConfig.lockRecordAudioVideoHint = 0; SharedConfig.lockRecordAudioVideoHint = 0;
@ -4184,21 +4222,31 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
}; };
mediaCounterTextView.setAlpha(0.0f); mediaCounterTextView.setAlpha(0.0f);
avatarContainer2.addView(mediaCounterTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, 0, 8, 0)); avatarContainer2.addView(mediaCounterTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, 0, 8, 0));
storyView = new ProfileStoriesView(context, currentAccount, userId == 0 ? chatId : userId, avatarContainer, avatarImage, resourcesProvider) { storyView = new ProfileStoriesView(context, currentAccount, getDialogId(), avatarContainer, avatarImage, resourcesProvider) {
@Override @Override
protected void onTap(StoryViewer.PlaceProvider provider) { protected void onTap(StoryViewer.PlaceProvider provider) {
long did = userId == 0 ? chatId : userId; long did = getDialogId();
if (getMessagesController().getStoriesController().hasStories(did)) { StoriesController storiesController = getMessagesController().getStoriesController();
if (storiesController.hasStories(did) || storiesController.hasUploadingStories(did) || storiesController.isLastUploadingFailed(did)) {
getOrCreateStoryViewer().open(context, did, provider); getOrCreateStoryViewer().open(context, did, provider);
} else if (userInfo != null && userInfo.stories != null && !userInfo.stories.stories.isEmpty() && userId != getUserConfig().clientUserId) { } else if (userInfo != null && userInfo.stories != null && !userInfo.stories.stories.isEmpty() && userId != getUserConfig().clientUserId) {
getOrCreateStoryViewer().open(context, userInfo.stories, provider); getOrCreateStoryViewer().open(context, userInfo.stories, provider);
} else if (chatInfo != null && chatInfo.stories != null && !chatInfo.stories.stories.isEmpty()) {
getOrCreateStoryViewer().open(context, chatInfo.stories, provider);
} else { } else {
expandAvatar(); expandAvatar();
} }
} }
}; };
updateStoriesViewBounds(false); updateStoriesViewBounds(false);
storyView.setUserFull(userInfo); if (userInfo != null) {
storyView.setStories(userInfo.stories);
} else if (chatInfo != null) {
storyView.setStories(chatInfo.stories);
}
if (avatarImage != null) {
avatarImage.setHasStories(needInsetForStories());
}
avatarContainer2.addView(storyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); avatarContainer2.addView(storyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
updateProfileData(true); updateProfileData(true);
@ -4386,9 +4434,171 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
actionBarBackgroundPaint.setColor(getThemedColor(Theme.key_listSelector)); actionBarBackgroundPaint.setColor(getThemedColor(Theme.key_listSelector));
contentView.blurBehindViews.add(sharedMediaLayout); contentView.blurBehindViews.add(sharedMediaLayout);
updateTtlIcon(); updateTtlIcon();
createFloatingActionButton(getContext());
return fragmentView; return fragmentView;
} }
FrameLayout floatingButtonContainer;
RLottieImageView floatingButton;
boolean floatingHidden;
float floatingButtonHideProgress;
boolean showBoostsAlert;
private final AccelerateDecelerateInterpolator floatingInterpolator = new AccelerateDecelerateInterpolator();
private void createFloatingActionButton(Context context) {
if (getDialogId() > 0L) {
return;
}
StoriesController storiesController = getMessagesController().getStoriesController();
if (!storiesController.canPostStories(getDialogId())) {
return;
} else {
waitCanSendStoryRequest = true;
storiesController.canSendStoryFor(getDialogId(), canSend -> {
waitCanSendStoryRequest = false;
showBoostsAlert = !canSend;
hideFloatingButton(false);
}, false, resourcesProvider);
}
long dialogId = getDialogId();
floatingButtonContainer = new FrameLayout(context);
floatingButtonContainer.setVisibility(View.VISIBLE);
contentView.addView(floatingButtonContainer, LayoutHelper.createFrame((Build.VERSION.SDK_INT >= 21 ? 56 : 60), (Build.VERSION.SDK_INT >= 21 ? 56 : 60), (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.BOTTOM, LocaleController.isRTL ? 14 : 0, 0, LocaleController.isRTL ? 0 : 14, 14));
floatingButtonContainer.setOnClickListener(v -> {
if (showBoostsAlert) {
if (loadingBoostsStats) {
return;
}
MessagesController messagesController = MessagesController.getInstance(currentAccount);
loadingBoostsStats = true;
messagesController.getBoostsController().getBoostsStats(dialogId, boostsStatus -> {
loadingBoostsStats = false;
if (boostsStatus == null) {
return;
}
BaseFragment lastFragment = LaunchActivity.getLastFragment();
LimitReachedBottomSheet limitReachedBottomSheet = new LimitReachedBottomSheet(lastFragment, lastFragment.getContext(), LimitReachedBottomSheet.TYPE_BOOSTS_FOR_POSTING, currentAccount, resourcesProvider);
limitReachedBottomSheet.setBoostsStats(boostsStatus, false);
limitReachedBottomSheet.setDialogId(dialogId);
limitReachedBottomSheet.showStatisticButtonInLink(() -> {
TLRPC.Chat chat = getMessagesController().getChat(chatId);
Bundle args = new Bundle();
args.putLong("chat_id", chatId);
args.putBoolean("is_megagroup", chat.megagroup);
args.putBoolean("start_from_boosts", true);
if (chatInfo == null || !chatInfo.can_view_stats) {
args.putBoolean("only_boosts", chat.megagroup);
};
StatisticActivity fragment = new StatisticActivity(args);
presentFragment(fragment);
});
limitReachedBottomSheet.show();
});
return;
}
StoryRecorder.getInstance(getParentActivity(), currentAccount)
.selectedPeerId(getDialogId())
.canChangePeer(false)
.closeToWhenSent(new StoryRecorder.ClosingViewProvider() {
@Override
public void preLayout(long dialogId, Runnable runnable) {
avatarImage.setHasStories(needInsetForStories());
if (dialogId == getDialogId()) {
collapseAvatarInstant();
}
AndroidUtilities.runOnUIThread(runnable, 30);
}
@Override
public StoryRecorder.SourceView getView(long dialogId) {
if (dialogId != getDialogId()) {
return null;
}
return StoryRecorder.SourceView.fromAvatarImage(avatarImage);
}
})
.open(StoryRecorder.SourceView.fromFloatingButton(floatingButtonContainer), true);
});
floatingButton = new RLottieImageView(context);
floatingButton.setScaleType(ImageView.ScaleType.CENTER);
floatingButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chats_actionIcon), PorterDuff.Mode.MULTIPLY));
if (Build.VERSION.SDK_INT >= 21) {
StateListAnimator animator = new StateListAnimator();
animator.addState(new int[]{android.R.attr.state_pressed}, ObjectAnimator.ofFloat(floatingButtonContainer, View.TRANSLATION_Z, AndroidUtilities.dp(2), AndroidUtilities.dp(4)).setDuration(200));
animator.addState(new int[]{}, ObjectAnimator.ofFloat(floatingButtonContainer, View.TRANSLATION_Z, AndroidUtilities.dp(4), AndroidUtilities.dp(2)).setDuration(200));
floatingButtonContainer.setStateListAnimator(animator);
floatingButtonContainer.setOutlineProvider(new ViewOutlineProvider() {
@SuppressLint("NewApi")
@Override
public void getOutline(View view, Outline outline) {
outline.setOval(0, 0, AndroidUtilities.dp(56), AndroidUtilities.dp(56));
}
});
}
floatingButtonContainer.addView(floatingButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
floatingButton.setAnimation(R.raw.write_contacts_fab_icon_camera, 56, 56);
floatingButtonContainer.setContentDescription(LocaleController.getString("AccDescrCaptureStory", R.string.AccDescrCaptureStory));
updateFloatingButtonColor();
}
private void collapseAvatarInstant() {
if (allowPullingDown && currentExpandAnimatorValue > 0) {
layoutManager.scrollToPositionWithOffset(0, AndroidUtilities.dp(88) - listView.getPaddingTop());
listView.post(() -> {
needLayout(true);
if (expandAnimator.isRunning()) {
expandAnimator.cancel();
}
setAvatarExpandProgress(1f);
});
}
}
private void updateFloatingButtonColor() {
if (getParentActivity() == null) {
return;
}
Drawable drawable;
if (floatingButtonContainer != null) {
drawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(56), Theme.getColor(Theme.key_chats_actionBackground), Theme.getColor(Theme.key_chats_actionPressedBackground));
if (Build.VERSION.SDK_INT < 21) {
Drawable shadowDrawable = ContextCompat.getDrawable(getParentActivity(), R.drawable.floating_shadow).mutate();
shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.MULTIPLY));
CombinedDrawable combinedDrawable = new CombinedDrawable(shadowDrawable, drawable, 0, 0);
combinedDrawable.setIconSize(AndroidUtilities.dp(56), AndroidUtilities.dp(56));
drawable = combinedDrawable;
}
floatingButtonContainer.setBackground(drawable);
}
}
private void hideFloatingButton(boolean hide) {
if (floatingHidden == hide || floatingButtonContainer == null || waitCanSendStoryRequest) {
return;
}
floatingHidden = hide;
AnimatorSet animatorSet = new AnimatorSet();
ValueAnimator valueAnimator = ValueAnimator.ofFloat(floatingButtonHideProgress, floatingHidden ? 1f : 0f);
valueAnimator.addUpdateListener(animation -> {
floatingButtonHideProgress = (float) animation.getAnimatedValue();
updateFloatingButtonOffset();
});
animatorSet.playTogether(valueAnimator);
animatorSet.setDuration(300);
animatorSet.setInterpolator(floatingInterpolator);
floatingButtonContainer.setClickable(!hide);
animatorSet.start();
}
private void updateFloatingButtonOffset() {
if (floatingButtonContainer != null) {
floatingButtonContainer.setTranslationY(AndroidUtilities.dp(100) * floatingButtonHideProgress);
}
}
private boolean expandAvatar() { private boolean expandAvatar() {
if (!AndroidUtilities.isTablet() && !isInLandscapeMode && avatarImage.getImageReceiver().hasNotThumb() && !AndroidUtilities.isAccessibilityScreenReaderEnabled()) { if (!AndroidUtilities.isTablet() && !isInLandscapeMode && avatarImage.getImageReceiver().hasNotThumb() && !AndroidUtilities.isAccessibilityScreenReaderEnabled()) {
openingAvatar = true; openingAvatar = true;
@ -6324,6 +6534,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (chatInfo != null && (chatInfo.call == null && !hasVoiceChatItem || chatInfo.call != null && hasVoiceChatItem)) { if (chatInfo != null && (chatInfo.call == null && !hasVoiceChatItem || chatInfo.call != null && hasVoiceChatItem)) {
createActionBarMenu(false); createActionBarMenu(false);
} }
if (storyView != null && chatInfo != null) {
storyView.setStories(chatInfo.stories);
}
if (avatarImage != null) {
avatarImage.setHasStories(needInsetForStories());
}
} }
} else if (id == NotificationCenter.chatInfoDidLoad) { } else if (id == NotificationCenter.chatInfoDidLoad) {
TLRPC.ChatFull chatFull = (TLRPC.ChatFull) args[0]; TLRPC.ChatFull chatFull = (TLRPC.ChatFull) args[0];
@ -6355,6 +6571,15 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
} }
updateAutoDeleteItem(); updateAutoDeleteItem();
updateTtlIcon(); updateTtlIcon();
if (storyView != null && chatInfo != null) {
storyView.setStories(chatInfo.stories);
}
if (avatarImage != null) {
avatarImage.setHasStories(needInsetForStories());
}
if (sharedMediaLayout != null) {
sharedMediaLayout.setChatInfo(chatInfo);
}
} }
} else if (id == NotificationCenter.closeChats) { } else if (id == NotificationCenter.closeChats) {
removeSelfFromStack(true); removeSelfFromStack(true);
@ -6369,7 +6594,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (uid == userId) { if (uid == userId) {
userInfo = (TLRPC.UserFull) args[1]; userInfo = (TLRPC.UserFull) args[1];
if (storyView != null) { if (storyView != null) {
storyView.setUserFull(userInfo); storyView.setStories(userInfo.stories);
}
if (avatarImage != null) {
avatarImage.setHasStories(needInsetForStories());
} }
if (sharedMediaLayout != null) { if (sharedMediaLayout != null) {
sharedMediaLayout.setUserInfo(userInfo); sharedMediaLayout.setUserInfo(userInfo);
@ -6447,6 +6675,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
} }
} else if (id == NotificationCenter.reloadDialogPhotos) { } else if (id == NotificationCenter.reloadDialogPhotos) {
updateProfileData(false); updateProfileData(false);
} else if (id == NotificationCenter.storiesUpdated) {
if (avatarImage != null) {
avatarImage.setHasStories(needInsetForStories());
}
} }
} }
@ -6697,7 +6929,6 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
public void setAvatarAnimationProgress(float progress) { public void setAvatarAnimationProgress(float progress) {
avatarAnimationProgress = currentExpandAnimatorValue = progress; avatarAnimationProgress = currentExpandAnimatorValue = progress;
checkPhotoDescriptionAlpha(); checkPhotoDescriptionAlpha();
if (playProfileAnimation == 2) { if (playProfileAnimation == 2) {
avatarImage.setProgressToExpand(progress); avatarImage.setProgressToExpand(progress);
} }
@ -6766,6 +6997,15 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (aboutLinkCell != null) { if (aboutLinkCell != null) {
aboutLinkCell.invalidate(); aboutLinkCell.invalidate();
} }
if (getDialogId() > 0) {
if (avatarImage != null) {
avatarImage.setProgressToStoriesInsets(avatarAnimationProgress);
}
if (storyView != null) {
storyView.setProgressToStoriesInsets(avatarAnimationProgress);
}
}
} }
boolean profileTransitionInProgress; boolean profileTransitionInProgress;
@ -6879,6 +7119,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
ttlIconView.setAlpha(0f); ttlIconView.setAlpha(0f);
animators.add(ObjectAnimator.ofFloat(ttlIconView, View.ALPHA, 1.0f)); animators.add(ObjectAnimator.ofFloat(ttlIconView, View.ALPHA, 1.0f));
} }
if (floatingButtonContainer != null) {
floatingButtonContainer.setAlpha(0f);
animators.add(ObjectAnimator.ofFloat(floatingButtonContainer, View.ALPHA, 1.0f));
}
boolean onlineTextCrosafade = false; boolean onlineTextCrosafade = false;
@ -6943,6 +7187,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (ttlIconView != null) { if (ttlIconView != null) {
animators.add(ObjectAnimator.ofFloat(ttlIconView, View.ALPHA, ttlIconView.getAlpha(), 0.0f)); animators.add(ObjectAnimator.ofFloat(ttlIconView, View.ALPHA, ttlIconView.getAlpha(), 0.0f));
} }
if (floatingButtonContainer != null) {
animators.add(ObjectAnimator.ofFloat(floatingButtonContainer, View.ALPHA, 0.0f));
}
boolean crossfadeOnlineText = false; boolean crossfadeOnlineText = false;
BaseFragment previousFragment = parentLayout.getFragmentStack().size() > 1 ? parentLayout.getFragmentStack().get(parentLayout.getFragmentStack().size() - 2) : null; BaseFragment previousFragment = parentLayout.getFragmentStack().size() > 1 ? parentLayout.getFragmentStack().get(parentLayout.getFragmentStack().size() - 2) : null;
if (previousFragment instanceof ChatActivity) { if (previousFragment instanceof ChatActivity) {
@ -7071,17 +7318,26 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (avatarsViewPager != null && !isTopic) { if (avatarsViewPager != null && !isTopic) {
avatarsViewPager.setChatInfo(chatInfo); avatarsViewPager.setChatInfo(chatInfo);
} }
if (storyView != null && chatInfo != null) {
storyView.setStories(chatInfo.stories);
}
if (avatarImage != null) {
avatarImage.setHasStories(needInsetForStories());
}
fetchUsersFromChannelInfo(); fetchUsersFromChannelInfo();
} }
private boolean needInsetForStories() { private boolean needInsetForStories() {
return getDialogId() < 0 && getMessagesController().getStoriesController().hasStories(getDialogId()); return getMessagesController().getStoriesController().hasStories(getDialogId());
} }
public void setUserInfo(TLRPC.UserFull value) { public void setUserInfo(TLRPC.UserFull value) {
userInfo = value; userInfo = value;
if (storyView != null) { if (storyView != null) {
storyView.setUserFull(userInfo); storyView.setStories(userInfo.stories);
}
if (avatarImage != null) {
avatarImage.setHasStories(needInsetForStories());
} }
if (sharedMediaLayout != null) { if (sharedMediaLayout != null) {
sharedMediaLayout.setUserInfo(userInfo); sharedMediaLayout.setUserInfo(userInfo);
@ -7224,6 +7480,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (!hasMedia && userInfo != null) { if (!hasMedia && userInfo != null) {
hasMedia = userInfo.stories_pinned_available; hasMedia = userInfo.stories_pinned_available;
} }
if (!hasMedia && chatInfo != null) {
hasMedia = chatInfo.stories_pinned_available;
}
if (userId != 0) { if (userId != 0) {
if (LocaleController.isRTL) { if (LocaleController.isRTL) {
@ -8166,7 +8425,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
otherItem.addSubItem(call_item, R.drawable.msg_voicechat, chat.megagroup && !chat.gigagroup ? LocaleController.getString("StartVoipChat", R.string.StartVoipChat) : LocaleController.getString("StartVoipChannel", R.string.StartVoipChannel)); otherItem.addSubItem(call_item, R.drawable.msg_voicechat, chat.megagroup && !chat.gigagroup ? LocaleController.getString("StartVoipChat", R.string.StartVoipChat) : LocaleController.getString("StartVoipChannel", R.string.StartVoipChannel));
hasVoiceChatItem = true; hasVoiceChatItem = true;
} }
if (chatInfo.can_view_stats && topicId == 0) { if ((chatInfo.can_view_stats || getMessagesController().getStoriesController().canPostStories(getDialogId())) && topicId == 0) {
otherItem.addSubItem(statistics, R.drawable.msg_stats, LocaleController.getString("Statistics", R.string.Statistics)); otherItem.addSubItem(statistics, R.drawable.msg_stats, LocaleController.getString("Statistics", R.string.Statistics));
} }
ChatObject.Call call = getMessagesController().getGroupCall(chatId, false); ChatObject.Call call = getMessagesController().getGroupCall(chatId, false);
@ -8184,6 +8443,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
otherItem.addSubItem(delete_topic, R.drawable.msg_delete, LocaleController.getPluralString("DeleteTopics", 1)); otherItem.addSubItem(delete_topic, R.drawable.msg_delete, LocaleController.getPluralString("DeleteTopics", 1));
} }
} else { } else {
if (chat.creator || chat.admin_rights != null && chat.admin_rights.edit_stories) {
otherItem.addSubItem(channel_stories, R.drawable.msg_archive, LocaleController.getString(R.string.OpenChannelArchiveStories));
}
if (ChatObject.isPublic(chat)) { if (ChatObject.isPublic(chat)) {
otherItem.addSubItem(share, R.drawable.msg_share, LocaleController.getString("BotShare", R.string.BotShare)); otherItem.addSubItem(share, R.drawable.msg_share, LocaleController.getString("BotShare", R.string.BotShare));
} }

View file

@ -106,6 +106,7 @@ import java.util.List;
public class QrActivity extends BaseFragment { public class QrActivity extends BaseFragment {
private static final ArrayMap<String, int[]> qrColorsMap = new ArrayMap<>(); private static final ArrayMap<String, int[]> qrColorsMap = new ArrayMap<>();
private static final int LOGO_OPTIMAL_FRAME = 33;
private static List<EmojiThemes> cachedThemes; private static List<EmojiThemes> cachedThemes;
static { static {
@ -380,6 +381,7 @@ public class QrActivity extends BaseFragment {
} }
fragmentView.postDelayed(() -> { fragmentView.postDelayed(() -> {
onItemSelected(currentTheme, 0, true); onItemSelected(currentTheme, 0, true);
logoImageView.getAnimatedDrawable().cacheFrame(LOGO_OPTIMAL_FRAME);
}, 17); }, 17);
}, 25); }, 25);
@ -714,10 +716,8 @@ public class QrActivity extends BaseFragment {
themeLayout.setVisibility(View.GONE); themeLayout.setVisibility(View.GONE);
closeImageView.setVisibility(View.GONE); closeImageView.setVisibility(View.GONE);
logoImageView.stopAnimation(); logoImageView.setVisibility(View.GONE);
RLottieDrawable drawable = logoImageView.getAnimatedDrawable(); RLottieDrawable drawable = logoImageView.getAnimatedDrawable();
int currentFrame = drawable.getCurrentFrame();
drawable.setCurrentFrame(33, false);
if (qrView != null) { if (qrView != null) {
qrView.setForShare(true); qrView.setForShare(true);
@ -726,12 +726,13 @@ public class QrActivity extends BaseFragment {
fragmentView.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)); fragmentView.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY));
fragmentView.layout(0, 0, width, height); fragmentView.layout(0, 0, width, height);
fragmentView.draw(canvas); fragmentView.draw(canvas);
drawable.setBounds(logoImageView.getLeft(), logoImageView.getTop(), logoImageView.getRight(), logoImageView.getBottom());
drawable.drawFrame(canvas, LOGO_OPTIMAL_FRAME);
canvas.setBitmap(null); canvas.setBitmap(null);
themeLayout.setVisibility(View.VISIBLE); themeLayout.setVisibility(View.VISIBLE);
closeImageView.setVisibility(View.VISIBLE); closeImageView.setVisibility(View.VISIBLE);
drawable.setCurrentFrame(currentFrame, false); logoImageView.setVisibility(View.VISIBLE);
logoImageView.playAnimation();
ViewGroup parent = (ViewGroup) fragmentView.getParent(); ViewGroup parent = (ViewGroup) fragmentView.getParent();
fragmentView.layout(0, 0, parent.getWidth(), parent.getHeight()); fragmentView.layout(0, 0, parent.getWidth(), parent.getHeight());

View file

@ -1652,9 +1652,8 @@ public class SecretMediaViewer implements NotificationCenter.NotificationCenterD
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
if (photoAnimationEndRunnable != null) { if (photoAnimationEndRunnable != null) {
Runnable r = photoAnimationEndRunnable; photoAnimationEndRunnable.run();
photoAnimationEndRunnable = null; photoAnimationEndRunnable = null;
r.run();
} }
} }
}); });
@ -1966,9 +1965,8 @@ public class SecretMediaViewer implements NotificationCenter.NotificationCenterD
if (photoAnimationInProgress != 0) { if (photoAnimationInProgress != 0) {
if (Math.abs(photoTransitionAnimationStartTime - System.currentTimeMillis()) >= 500) { if (Math.abs(photoTransitionAnimationStartTime - System.currentTimeMillis()) >= 500) {
if (photoAnimationEndRunnable != null) { if (photoAnimationEndRunnable != null) {
Runnable r = photoAnimationEndRunnable; photoAnimationEndRunnable.run();
photoAnimationEndRunnable = null; photoAnimationEndRunnable = null;
r.run();
} }
photoAnimationInProgress = 0; photoAnimationInProgress = 0;
} }
@ -2119,9 +2117,8 @@ public class SecretMediaViewer implements NotificationCenter.NotificationCenterD
isVisible = false; isVisible = false;
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
if (photoAnimationEndRunnable != null) { if (photoAnimationEndRunnable != null) {
Runnable r = photoAnimationEndRunnable; photoAnimationEndRunnable.run();
photoAnimationEndRunnable = null; photoAnimationEndRunnable = null;
r.run();
} }
}); });
} }
@ -2163,9 +2160,8 @@ public class SecretMediaViewer implements NotificationCenter.NotificationCenterD
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
if (photoAnimationEndRunnable != null) { if (photoAnimationEndRunnable != null) {
Runnable r = photoAnimationEndRunnable; photoAnimationEndRunnable.run();
photoAnimationEndRunnable = null; photoAnimationEndRunnable = null;
r.run();
} }
} }
}); });

View file

@ -81,6 +81,9 @@ import java.util.Objects;
public class SessionsActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { public class SessionsActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate {
public static final int TYPE_DEVICES = 0;
public static final int TYPE_WEB_SESSIONS = 1;
private ListAdapter listAdapter; private ListAdapter listAdapter;
private RecyclerListView listView; private RecyclerListView listView;
private EmptyTextProgressView emptyView; private EmptyTextProgressView emptyView;
@ -603,6 +606,10 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
listAdapter.notifyDataSetChanged(); listAdapter.notifyDataSetChanged();
} }
if (delegate != null) {
delegate.sessionsLoaded();
}
if (repeatLoad > 0) { if (repeatLoad > 0) {
repeatLoad--; repeatLoad--;
if (repeatLoad > 0) { if (repeatLoad > 0) {
@ -1243,7 +1250,7 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
} }
} }
int getSessionsCount() { public int getSessionsCount() {
if (sessions.size() == 0 && loading) { if (sessions.size() == 0 && loading) {
return 0; return 0;
} }

View file

@ -17,6 +17,7 @@ import android.os.Bundle;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
@ -38,6 +39,7 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.LruCache; import org.telegram.messenger.LruCache;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
@ -75,6 +77,7 @@ import org.telegram.ui.Charts.data.StackLinearChartData;
import org.telegram.ui.Charts.view_data.ChartHeaderView; import org.telegram.ui.Charts.view_data.ChartHeaderView;
import org.telegram.ui.Charts.view_data.LineViewData; import org.telegram.ui.Charts.view_data.LineViewData;
import org.telegram.ui.Charts.view_data.TransitionParams; import org.telegram.ui.Charts.view_data.TransitionParams;
import org.telegram.ui.Components.BottomPagerTabs;
import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.ChatAvatarContainer; import org.telegram.ui.Components.ChatAvatarContainer;
import org.telegram.ui.Components.CombinedDrawable; import org.telegram.ui.Components.CombinedDrawable;
@ -83,6 +86,8 @@ import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieImageView; import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.RadialProgressView; import org.telegram.ui.Components.RadialProgressView;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.ViewPagerFixed;
import org.telegram.ui.Components.voip.VoIPHelper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -90,7 +95,8 @@ import java.util.Locale;
public class StatisticActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { public class StatisticActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate {
private final TLRPC.ChatFull chat; private TLRPC.ChatFull chat;
private final long chatId;
//mutual //mutual
private ChartViewData growthData; private ChartViewData growthData;
@ -133,15 +139,21 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
private BaseChartView.SharedUiComponents sharedUi; private BaseChartView.SharedUiComponents sharedUi;
private LinearLayout progressLayout; private LinearLayout progressLayout;
private final boolean isMegagroup; private final boolean isMegagroup;
private boolean startFromBoosts;
private long maxDateOverview; private long maxDateOverview;
private long minDateOverview; private long minDateOverview;
private AlertDialog[] progressDialog = new AlertDialog[1]; private AlertDialog[] progressDialog = new AlertDialog[1];
private ViewPagerFixed viewPagerFixed;
private ChannelBoostLayout boosLayout;
private boolean onlyBoostsStat;
public StatisticActivity(Bundle args) { public StatisticActivity(Bundle args) {
super(args); super(args);
long chatId = args.getLong("chat_id"); chatId = args.getLong("chat_id");
isMegagroup = args.getBoolean("is_megagroup", false); isMegagroup = args.getBoolean("is_megagroup", false);
startFromBoosts = args.getBoolean("start_from_boosts", false);
onlyBoostsStat = args.getBoolean("only_boosts", false);
this.chat = getMessagesController().getChatFull(chatId); this.chat = getMessagesController().getChatFull(chatId);
} }
@ -164,16 +176,28 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
@Override @Override
public boolean onFragmentCreate() { public boolean onFragmentCreate() {
getNotificationCenter().addObserver(this, NotificationCenter.messagesDidLoad); getNotificationCenter().addObserver(this, NotificationCenter.messagesDidLoad);
getNotificationCenter().addObserver(this, NotificationCenter.chatInfoDidLoad);
if (chat != null) {
loadStatistic();
} else {
MessagesController.getInstance(currentAccount).loadFullChat(chatId, classGuid, true);
}
return super.onFragmentCreate();
}
private void loadStatistic() {
if (onlyBoostsStat) {
return;
}
TLObject req; TLObject req;
if (isMegagroup) { if (isMegagroup) {
TLRPC.TL_stats_getMegagroupStats getMegagroupStats = new TLRPC.TL_stats_getMegagroupStats(); TLRPC.TL_stats_getMegagroupStats getMegagroupStats = new TLRPC.TL_stats_getMegagroupStats();
req = getMegagroupStats; req = getMegagroupStats;
getMegagroupStats.channel = MessagesController.getInstance(currentAccount).getInputChannel(chat.id); getMegagroupStats.channel = MessagesController.getInstance(currentAccount).getInputChannel(chatId);
} else { } else {
TLRPC.TL_stats_getBroadcastStats getBroadcastStats = new TLRPC.TL_stats_getBroadcastStats(); TLRPC.TL_stats_getBroadcastStats getBroadcastStats = new TLRPC.TL_stats_getBroadcastStats();
req = getBroadcastStats; req = getBroadcastStats;
getBroadcastStats.channel = MessagesController.getInstance(currentAccount).getInputChannel(chat.id); getBroadcastStats.channel = MessagesController.getInstance(currentAccount).getInputChannel(chatId);
} }
@ -212,7 +236,7 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
if (recentPostsAll.size() > 0) { if (recentPostsAll.size() > 0) {
int lastPostId = recentPostsAll.get(0).counters.msg_id; int lastPostId = recentPostsAll.get(0).counters.msg_id;
int count = recentPostsAll.size(); int count = recentPostsAll.size();
getMessagesStorage().getMessages(-chat.id, 0, false, count, lastPostId, 0, 0, classGuid, 0, false, 0, 0, true, false, null); getMessagesStorage().getMessages(-chatId, 0, false, count, lastPostId, 0, 0, classGuid, 0, false, 0, 0, true, false, null);
} }
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
@ -298,7 +322,6 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
}, null, null, 0, chat.stats_dc, ConnectionsManager.ConnectionTypeGeneric, true); }, null, null, 0, chat.stats_dc, ConnectionsManager.ConnectionTypeGeneric, true);
getConnectionsManager().bindRequestToGuid(reqId, classGuid); getConnectionsManager().bindRequestToGuid(reqId, classGuid);
return super.onFragmentCreate();
} }
private void dataLoaded(ChartViewData[] chartsViewData) { private void dataLoaded(ChartViewData[] chartsViewData) {
@ -331,6 +354,7 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
@Override @Override
public void onFragmentDestroy() { public void onFragmentDestroy() {
getNotificationCenter().removeObserver(this, NotificationCenter.messagesDidLoad); getNotificationCenter().removeObserver(this, NotificationCenter.messagesDidLoad);
getNotificationCenter().removeObserver(this, NotificationCenter.chatInfoDidLoad);
if (progressDialog[0] != null) { if (progressDialog[0] != null) {
progressDialog[0].dismiss(); progressDialog[0].dismiss();
progressDialog[0] = null; progressDialog[0] = null;
@ -381,14 +405,102 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
diffUtilsCallback.update(); diffUtilsCallback.update();
} }
} }
} else if (id == NotificationCenter.chatInfoDidLoad) {
TLRPC.ChatFull chatFull = (TLRPC.ChatFull) args[0];
if (chatFull.id == chatId) {
if (chat == null) {
chat = chatFull;
loadStatistic();
}
}
} }
} }
@Override @Override
public View createView(Context context) { public View createView(Context context) {
sharedUi = new BaseChartView.SharedUiComponents(); sharedUi = new BaseChartView.SharedUiComponents();
FrameLayout frameLayout = new FrameLayout(context); boolean isChannel = ChatObject.isChannelAndNotMegaGroup(chatId, currentAccount);
fragmentView = frameLayout; BottomPagerTabs storiesTabsView = new BottomPagerTabs(context, getResourceProvider()) {
@Override
public Tab[] createTabs() {
Tab[] tabs = new Tab[]{
new Tab(0, R.raw.stats, LocaleController.getString("Statistics", R.string.Statistics)),
new Tab(1, R.raw.boosts, LocaleController.getString("Boosts", R.string.Boosts))
};
tabs[1].customEndFrameMid = 25;
tabs[1].customEndFrameEnd = 49;
return tabs;
}
};
viewPagerFixed = new ViewPagerFixed(getContext()) {
@Override
protected void onTabAnimationUpdate(boolean manual) {
if (manual) {
return;
}
float progress = currentProgress;
if (currentPosition == 0) {
progress = 1f - progress;
}
storiesTabsView.setScrolling(true);
storiesTabsView.setProgress(progress);
}
};
storiesTabsView.setOnTabClick(position -> {
if (viewPagerFixed.scrollToPosition(position)) {
storiesTabsView.setScrolling(false);
storiesTabsView.setProgress(position);
}
});
FrameLayout statisticLayout = new FrameLayout(context);
if (isChannel) {
boosLayout = new ChannelBoostLayout(StatisticActivity.this, -chatId, getResourceProvider());
}
boolean showTabs = isChannel && !onlyBoostsStat;
if (showTabs && startFromBoosts) {
viewPagerFixed.setPosition(1);
}
viewPagerFixed.setAdapter(new ViewPagerFixed.Adapter() {
@Override
public int getItemCount() {
if (onlyBoostsStat) {
return 1;
}
if (isChannel) {
return 2;
}
return 1;
}
@Override
public View createView(int viewType) {
if (onlyBoostsStat) {
return boosLayout;
}
return viewType == 0 ? statisticLayout : boosLayout;
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public void bindView(View view, int position, int viewType) {
}
});
FrameLayout contentLayout = new FrameLayout(getContext());
contentLayout.addView(viewPagerFixed, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 0, 0, 0, showTabs ? 64 : 0));
if (showTabs) {
contentLayout.addView(storiesTabsView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.FILL_HORIZONTAL));
}
fragmentView = contentLayout;
recyclerListView = new RecyclerListView(context) { recyclerListView = new RecyclerListView(context) {
int lastH; int lastH;
@ -429,7 +541,7 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
progressLayout.addView(loadingTitle, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 0, 0, 0, 10)); progressLayout.addView(loadingTitle, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 0, 0, 0, 10));
progressLayout.addView(loadingSubtitle, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL)); progressLayout.addView(loadingSubtitle, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL));
frameLayout.addView(progressLayout, LayoutHelper.createFrame(240, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 0, 0, 0, 30)); statisticLayout.addView(progressLayout, LayoutHelper.createFrame(240, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 0, 0, 0, 30));
if (adapter == null) { if (adapter == null) {
@ -509,7 +621,7 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
presentFragment(activity); presentFragment(activity);
} else if (i == 1) { } else if (i == 1) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putLong("chat_id", chat.id); bundle.putLong("chat_id", chatId);
bundle.putInt("message_id", messageObject.getId()); bundle.putInt("message_id", messageObject.getId());
bundle.putBoolean("need_remove_previous_same_chat_activity", false); bundle.putBoolean("need_remove_previous_same_chat_activity", false);
ChatActivity chatActivity = new ChatActivity(bundle); ChatActivity chatActivity = new ChatActivity(bundle);
@ -535,17 +647,17 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
return false; return false;
}); });
frameLayout.addView(recyclerListView); statisticLayout.addView(recyclerListView);
avatarContainer = new ChatAvatarContainer(context, null, false); avatarContainer = new ChatAvatarContainer(context, null, false);
avatarContainer.setOccupyStatusBar(!AndroidUtilities.isTablet()); avatarContainer.setOccupyStatusBar(!AndroidUtilities.isTablet());
actionBar.addView(avatarContainer, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, !inPreviewMode ? 56 : 0, 0, 40, 0)); actionBar.addView(avatarContainer, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, !inPreviewMode ? 56 : 0, 0, 40, 0));
TLRPC.Chat chatLocal = getMessagesController().getChat(chat.id); TLRPC.Chat chatLocal = getMessagesController().getChat(chatId);
avatarContainer.setChatAvatar(chatLocal); avatarContainer.setChatAvatar(chatLocal);
avatarContainer.setTitle(chatLocal.title); avatarContainer.setTitle(chatLocal.title);
avatarContainer.setSubtitle(LocaleController.getString("Statistics", R.string.Statistics)); avatarContainer.hideSubtitle();
actionBar.setBackButtonDrawable(new BackDrawable(false)); actionBar.setBackButtonDrawable(new BackDrawable(false));
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@ -1867,7 +1979,7 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
} }
} }
} }
req.channel = MessagesController.getInstance(currentAccount).getInputChannel(chat.id); req.channel = MessagesController.getInstance(currentAccount).getInputChannel(chatId);
messagesIsLoading = true; messagesIsLoading = true;
getConnectionsManager().sendRequest(req, (response, error) -> { getConnectionsManager().sendRequest(req, (response, error) -> {
@ -2319,7 +2431,7 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
dif = (int) (stats.viewers.current - stats.viewers.previous); dif = (int) (stats.viewers.current - stats.viewers.previous);
difPercent = stats.viewers.previous == 0 ? 0 : Math.abs(dif / (float) stats.viewers.previous * 100f); difPercent = stats.viewers.previous == 0 ? 0 : Math.abs(dif / (float) stats.viewers.previous * 100f);
viewingMembersTitle = LocaleController.getString("ViewingMembers", R.string.ViewingMembers); viewingMembersTitle = LocaleController.getString("ViewingMembers", R.string.ViewingMembers);
viewingMembersPrimary = AndroidUtilities.formatWholeNumber((int) stats.viewers.current, 0); viewingMembersPrimary = AndroidUtilities.formatWholeNumber((int) stats.viewers.current, 0);
if (dif == 0 || difPercent == 0) { if (dif == 0 || difPercent == 0) {
@ -2444,6 +2556,14 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
updateColors(); updateColors();
} }
public void setData(int index, String primary, String secondary, String title) {
this.primary[index].setText(primary);
this.secondary[index].setText(secondary);
this.title[index].setText(title);
updateColors();
}
private void updateColors() { private void updateColors() {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
primary[i].setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); primary[i].setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
@ -2702,4 +2822,12 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
int color = Theme.getColor(Theme.key_windowBackgroundWhite); int color = Theme.getColor(Theme.key_windowBackgroundWhite);
return ColorUtils.calculateLuminance(color) > 0.7f; return ColorUtils.calculateLuminance(color) > 0.7f;
} }
@Override
public boolean isSwipeBackEnabled(MotionEvent event) {
if (viewPagerFixed != null && (viewPagerFixed.currentPosition != 0 || viewPagerFixed.currentProgress != 1f)) {
return false;
}
return super.isSwipeBackEnabled(event);
}
} }

View file

@ -0,0 +1,19 @@
package org.telegram.ui.Stories;
import android.text.TextUtils;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.MessagesController;
import org.telegram.tgnet.TLRPC;
public class ChannelBoostUtilities {
public static String createLink(int currentAccount, long dialogId) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
String username = ChatObject.getPublicUsername(chat);
if (!TextUtils.isEmpty(username)) {
return "https://t.me/" + ChatObject.getPublicUsername(chat) + "?boost";
} else {
return "https://t.me/c/" + -dialogId + "?boost";
}
}
}

View file

@ -34,10 +34,9 @@ import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BotWebViewVibrationEffect; import org.telegram.messenger.BotWebViewVibrationEffect;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.Emoji; import org.telegram.messenger.Emoji;
import org.telegram.messenger.ImageReceiver; import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
@ -126,7 +125,6 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
DefaultItemAnimator itemAnimator; DefaultItemAnimator itemAnimator;
LinearLayoutManager layoutManager; LinearLayoutManager layoutManager;
AnimatedTextView titleView; AnimatedTextView titleView;
boolean progressWasDrawn;
boolean drawCircleForce; boolean drawCircleForce;
ArrayList<Runnable> afterNextLayout = new ArrayList<>(); ArrayList<Runnable> afterNextLayout = new ArrayList<>();
private float collapsedProgress1 = -1; private float collapsedProgress1 = -1;
@ -206,14 +204,11 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
openStoryForCell(cell, false); openStoryForCell(cell, false);
}; };
recyclerListView.setOnItemClickListener(itemClickListener); recyclerListView.setOnItemClickListener(itemClickListener);
recyclerListView.setOnItemLongClickListener(new RecyclerListView.OnItemLongClickListener() { recyclerListView.setOnItemLongClickListener((view, position) -> {
@Override if (collapsedProgress == 0 && overscrollPrgoress == 0) {
public boolean onItemClick(View view, int position) { onUserLongPressed(view, ((StoryCell) view).dialogId);
if (collapsedProgress == 0 && overscrollPrgoress == 0) {
onUserLongPressed(view, ((StoryCell) view).dialogId);
}
return false;
} }
return false;
}); });
recyclerListView.setAdapter(adapter); recyclerListView.setAdapter(adapter);
@ -227,7 +222,6 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
titleView.setPadding(0, AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8)); titleView.setPadding(0, AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8));
titleView.setTextSize(AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 18 : 20)); titleView.setTextSize(AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 18 : 20));
addView(titleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); addView(titleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
ellipsizeSpanAnimator.addView(titleView);
titleView.setAlpha(0f); titleView.setAlpha(0f);
@ -334,10 +328,10 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
} }
return; return;
} }
if (!storiesController.hasStories(cell.dialogId) && (!cell.isSelf || !storiesController.hasUploadingStories())) { if (!storiesController.hasStories(cell.dialogId) && !storiesController.hasUploadingStories(cell.dialogId)) {
return; return;
} }
TLRPC.TL_userStories userStories = storiesController.getStories(cell.dialogId); TLRPC.PeerStories userStories = storiesController.getStories(cell.dialogId);
long startFromDialogId = cell.dialogId; long startFromDialogId = cell.dialogId;
if (globalCancelable != null) { if (globalCancelable != null) {
globalCancelable.cancel(); globalCancelable.cancel();
@ -437,10 +431,11 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
items.add(new Item(UserConfig.getInstance(currentAccount).getClientUserId())); items.add(new Item(UserConfig.getInstance(currentAccount).getClientUserId()));
} }
ArrayList<TLRPC.TL_userStories> allStories = type == TYPE_ARCHIVE ? storiesController.getHiddenList() : storiesController.getDialogListStories(); ArrayList<TLRPC.PeerStories> allStories = type == TYPE_ARCHIVE ? storiesController.getHiddenList() : storiesController.getDialogListStories();
for (int i = 0; i < allStories.size(); i++) { for (int i = 0; i < allStories.size(); i++) {
if (allStories.get(i).user_id != UserConfig.getInstance(currentAccount).getClientUserId()) { long dialogId = DialogObject.getPeerDialogId(allStories.get(i).peer);
items.add(new Item(allStories.get(i).user_id)); if (dialogId != UserConfig.getInstance(currentAccount).getClientUserId()) {
items.add(new Item(dialogId));
} }
} }
int size = items.size(); int size = items.size();
@ -452,7 +447,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
totalCount = Math.max(1, Math.max(storiesController.getTotalStoriesCount(hidden), size)); totalCount = Math.max(1, Math.max(storiesController.getTotalStoriesCount(hidden), size));
if (storiesController.hasOnlySelfStories()) { if (storiesController.hasOnlySelfStories()) {
if (!storiesController.getUploadingStories().isEmpty()) { if (storiesController.hasUploadingStories(UserConfig.getInstance(currentAccount).getClientUserId())) {
String str = LocaleController.getString("UploadingStory", R.string.UploadingStory); String str = LocaleController.getString("UploadingStory", R.string.UploadingStory);
int index = str.indexOf(""); int index = str.indexOf("");
if (index > 0) { if (index > 0) {
@ -877,7 +872,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
public void openStoryRecorder() { public void openStoryRecorder() {
final StoriesController.StoryLimit storyLimit = MessagesController.getInstance(currentAccount).getStoriesController().checkStoryLimit(); final StoriesController.StoryLimit storyLimit = MessagesController.getInstance(currentAccount).getStoriesController().checkStoryLimit();
if (storyLimit != null) { if (storyLimit != null) {
fragment.showDialog(new LimitReachedBottomSheet(fragment, getContext(), storyLimit.getLimitReachedType(), currentAccount, fragment.getResourceProvider())); fragment.showDialog(new LimitReachedBottomSheet(fragment, getContext(), storyLimit.getLimitReachedType(), currentAccount, null));
return; return;
} }
@ -899,6 +894,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
EllipsizeSpanAnimator ellipsizeSpanAnimator = new EllipsizeSpanAnimator(this); EllipsizeSpanAnimator ellipsizeSpanAnimator = new EllipsizeSpanAnimator(this);
public void setTitleOverlayText(String titleOverlayText, int textId) { public void setTitleOverlayText(String titleOverlayText, int textId) {
boolean hasEllipsizedText = false;
if (titleOverlayText != null) { if (titleOverlayText != null) {
hasOverlayText = true; hasOverlayText = true;
if (overlayTextId != textId) { if (overlayTextId != textId) {
@ -910,6 +906,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
if (index >= 0) { if (index >= 0) {
SpannableString spannableString = SpannableString.valueOf(textToSet); SpannableString spannableString = SpannableString.valueOf(textToSet);
ellipsizeSpanAnimator.wrap(spannableString, index); ellipsizeSpanAnimator.wrap(spannableString, index);
hasEllipsizedText = true;
textToSet = spannableString; textToSet = spannableString;
} }
} }
@ -920,6 +917,11 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
overlayTextId = 0; overlayTextId = 0;
titleView.setText(currentTitle, true); titleView.setText(currentTitle, true);
} }
if (hasEllipsizedText) {
ellipsizeSpanAnimator.addView(titleView);
} else {
ellipsizeSpanAnimator.removeView(titleView);
}
} }
public void setClipTop(int clipTop) { public void setClipTop(int clipTop) {
@ -944,7 +946,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
public void onResume() { public void onResume() {
storiesController.checkExpiredStories(); storiesController.checkExpiredStories();
for (int i = 0; i < items.size(); i++) { for (int i = 0; i < items.size(); i++) {
TLRPC.TL_userStories stories = storiesController.getStories(items.get(i).dialogId); TLRPC.PeerStories stories = storiesController.getStories(items.get(i).dialogId);
if (stories != null) { if (stories != null) {
storiesController.preloadUserStories(stories); storiesController.preloadUserStories(stories);
} }
@ -956,6 +958,8 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
invalidate(); invalidate();
recyclerListView.invalidate(); recyclerListView.invalidate();
if (overscrollPrgoress != 0) { if (overscrollPrgoress != 0) {
setClipChildren(false);
recyclerListView.setClipChildren(false);
((ViewGroup) getParent()).setClipChildren(false); ((ViewGroup) getParent()).setClipChildren(false);
} else { } else {
((ViewGroup) getParent()).setClipChildren(true); ((ViewGroup) getParent()).setClipChildren(true);
@ -1040,7 +1044,8 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
} }
} }
public StoryCell findSelfStoryCell() {
public StoryCell findStoryCell(long dialogId) {
RecyclerListView parent = recyclerListView; RecyclerListView parent = recyclerListView;
if (currentState == COLLAPSED_STATE) { if (currentState == COLLAPSED_STATE) {
parent = listViewMini; parent = listViewMini;
@ -1049,7 +1054,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
View child = parent.getChildAt(i); View child = parent.getChildAt(i);
if (child instanceof StoryCell) { if (child instanceof StoryCell) {
StoryCell storyCell = (StoryCell) child; StoryCell storyCell = (StoryCell) child;
if (storyCell.isSelf) { if (storyCell.dialogId == dialogId) {
return storyCell; return storyCell;
} }
} }
@ -1057,6 +1062,8 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
return null; return null;
} }
public class StoryCell extends FrameLayout { public class StoryCell extends FrameLayout {
public boolean drawInParent; public boolean drawInParent;
public int position; public int position;
@ -1093,6 +1100,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
private boolean isUploadingState; private boolean isUploadingState;
private float overscrollProgress; private float overscrollProgress;
private boolean selectedForOverscroll; private boolean selectedForOverscroll;
boolean progressWasDrawn;
private final AnimatedFloat failT = new AnimatedFloat(this, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT); private final AnimatedFloat failT = new AnimatedFloat(this, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
@ -1141,7 +1149,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
this.dialogId = dialogId; this.dialogId = dialogId;
isSelf = dialogId == UserConfig.getInstance(currentAccount).getClientUserId(); isSelf = dialogId == UserConfig.getInstance(currentAccount).getClientUserId();
isFail = isSelf && storiesController.isLastUploadingFailed(); isFail = storiesController.isLastUploadingFailed(dialogId);
TLObject object; TLObject object;
if (dialogId > 0) { if (dialogId > 0) {
object = user = MessagesController.getInstance(currentAccount).getUser(dialogId); object = user = MessagesController.getInstance(currentAccount).getUser(dialogId);
@ -1161,18 +1169,18 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
if (mini) { if (mini) {
return; return;
} }
if (dialogId == UserConfig.getInstance(currentAccount).getClientUserId()) { textView.setRightDrawable(null);
textView.setRightDrawable(null); if (storiesController.isLastUploadingFailed(dialogId)) {
if (storiesController.isLastUploadingFailed()) { textView.setText(LocaleController.getString("FailedStory", R.string.FailedStory));
textView.setText(LocaleController.getString("FailedStory", R.string.FailedStory)); isUploadingState = false;
isUploadingState = false; } else if (!Utilities.isNullOrEmpty(storiesController.getUploadingStories(dialogId))) {
} else if (!storiesController.getUploadingStories().isEmpty()) { StoriesUtilities.applyUploadingStr(textView, true, false);
StoriesUtilities.applyUploadingStr(textView, true, false); isUploadingState = true;
isUploadingState = true; } else if (storiesController.getEditingStory(dialogId) != null) {
} else if (storiesController.getEditingStory() != null) { StoriesUtilities.applyUploadingStr(textView, true, false);
StoriesUtilities.applyUploadingStr(textView, true, false); isUploadingState = true;
isUploadingState = true; } else {
} else { if (isSelf) {
if (animated && isUploadingState && !mini) { if (animated && isUploadingState && !mini) {
View oldTextView = textView; View oldTextView = textView;
createTextView(); createTextView();
@ -1213,33 +1221,34 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
AndroidUtilities.runOnUIThread(animationRunnable, 500); AndroidUtilities.runOnUIThread(animationRunnable, 500);
isUploadingState = false; isUploadingState = false;
textView.setText(LocaleController.getString("MyStory", R.string.MyStory));//, animated); textView.setText(LocaleController.getString("MyStory", R.string.MyStory));//, animated);
} } else if (user != null) {
} else if (user != null) { String name = user.first_name == null ? "" : user.first_name.trim();
String name = user.first_name == null ? "" : user.first_name.trim(); int index = name.indexOf(" ");
int index = name.indexOf(" "); if (index > 0) {
if (index > 0) { name = name.substring(0, index);
name = name.substring(0, index);
}
if (user.verified) {
if (verifiedDrawable == null) {
verifiedDrawable = createVerifiedDrawable();
} }
CharSequence text = name; if (user.verified) {
text = Emoji.replaceEmoji(text, textView.getPaint().getFontMetricsInt(), false); if (verifiedDrawable == null) {
textView.setText(text); verifiedDrawable = createVerifiedDrawable();
textView.setRightDrawable(verifiedDrawable); }
CharSequence text = name;
text = Emoji.replaceEmoji(text, textView.getPaint().getFontMetricsInt(), false);
textView.setText(text);
textView.setRightDrawable(verifiedDrawable);
} else {
CharSequence text = name;
text = Emoji.replaceEmoji(text, textView.getPaint().getFontMetricsInt(), false);
textView.setText(text);
textView.setRightDrawable(null);
}//, false);
} else { } else {
CharSequence text = name; CharSequence text = chat.title;
text = Emoji.replaceEmoji(text, textView.getPaint().getFontMetricsInt(), false); text = Emoji.replaceEmoji(text, textView.getPaint().getFontMetricsInt(), false);
textView.setText(text); textView.setText(text);//, false);
textView.setRightDrawable(null); textView.setRightDrawable(null);
}//, false); }
} else {
CharSequence text = chat.title;
text = Emoji.replaceEmoji(text, textView.getPaint().getFontMetricsInt(), false);
textView.setText(text);//, false);
textView.setRightDrawable(null);
} }
} }
@Override @Override
@ -1294,125 +1303,122 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
if (progressToCollapsed != 0) { if (progressToCollapsed != 0) {
canvas.drawCircle(cx, cy, radius + AndroidUtilities.dp(3), backgroundPaint); canvas.drawCircle(cx, cy, radius + AndroidUtilities.dp(3), backgroundPaint);
} }
if (isSelf) {
canvas.save(); canvas.save();
canvas.scale(bounceScale, bounceScale, cx, cy); canvas.scale(bounceScale, bounceScale, cx, cy);
if (radialProgress == null) { if (radialProgress == null) {
radialProgress = DialogStoriesCell.this.radialProgress; radialProgress = DialogStoriesCell.this.radialProgress;
} }
if (!storiesController.getUploadingAndEditingStories().isEmpty() || (progressWasDrawn && radialProgress != null && radialProgress.getAnimatedProgress() < 0.98f)) { ArrayList<StoriesController.UploadingStory> uploadingOrEditingStories = storiesController.getUploadingAndEditingStories(dialogId);
float uploadingProgress = 0; boolean hasUploadingStories = (uploadingOrEditingStories != null && !uploadingOrEditingStories.isEmpty());
boolean closeFriends = false; boolean drawProgress = hasUploadingStories || (progressWasDrawn && radialProgress != null && radialProgress.getAnimatedProgress() < 0.98f);
if (storiesController.getUploadingAndEditingStories().isEmpty()) { if (drawProgress) {
uploadingProgress = 1f; float uploadingProgress = 0;
closeFriends = lastUploadingCloseFriends; boolean closeFriends;
} else { if (!hasUploadingStories) {
for (int i = 0; i < storiesController.getUploadingAndEditingStories().size(); i++) { uploadingProgress = 1f;
uploadingProgress += storiesController.getUploadingAndEditingStories().get(i).progress; closeFriends = lastUploadingCloseFriends;
}
uploadingProgress = uploadingProgress / storiesController.getUploadingAndEditingStories().size();
lastUploadingCloseFriends = closeFriends = storiesController.getUploadingAndEditingStories().get(storiesController.getUploadingAndEditingStories().size() - 1).isCloseFriends();
}
invalidate();
if (radialProgress == null) {
if (DialogStoriesCell.this.radialProgress != null) {
radialProgress = DialogStoriesCell.this.radialProgress;
} else {
DialogStoriesCell.this.radialProgress = radialProgress = new RadialProgress(this);
radialProgress.setBackground(null, true, false);
}
}
if (drawAvatar) {
canvas.save();
canvas.scale(params.getScale(), params.getScale(), params.originalAvatarRect.centerX(), params.originalAvatarRect.centerY());
avatarImage.setImageCoords(params.originalAvatarRect);
avatarImage.draw(canvas);
canvas.restore();
}
radialProgress.setDiff(0);
Paint paint = closeFriends ?
StoriesUtilities.getCloseFriendsPaint(avatarImage) :
StoriesUtilities.getActiveCirclePaint(avatarImage, true);
paint.setAlpha(255);
radialProgress.setPaint(paint);
radialProgress.setProgressRect(
(int) (avatarImage.getImageX() - AndroidUtilities.dp(3)), (int) (avatarImage.getImageY() - AndroidUtilities.dp(3)),
(int) (avatarImage.getImageX2() + AndroidUtilities.dp(3)), (int) (avatarImage.getImageY2() + AndroidUtilities.dp(3))
);
radialProgress.setProgress(Utilities.clamp(uploadingProgress, 1f, 0), progressWasDrawn);
if (avatarImage.getVisible()) {
radialProgress.draw(canvas);
}
progressWasDrawn = true;
drawCircleForce = true;
invalidate();
} else { } else {
float failT = this.failT.set(isFail); for (int i = 0; i < uploadingOrEditingStories.size(); i++) {
if (drawAvatar) { uploadingProgress += uploadingOrEditingStories.get(i).progress;
if (progressWasDrawn) {
animateBounce();
params.forceAnimateProgressToSegments = true;
params.progressToSegments = 0f;
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1f);
valueAnimator.addUpdateListener(animation -> {
params.progressToSegments = AndroidUtilities.lerp(0, 1f - collapsedProgress2, (float) animation.getAnimatedValue());
invalidate();
});
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
params.forceAnimateProgressToSegments = false;
}
});
valueAnimator.setDuration(100);
valueAnimator.start();
}
failT *= params.progressToSegments;
params.animate = !progressWasDrawn;
params.progressToArc = getArcProgress(cx, radius);
params.isLast = isLast;
params.isFirst = isFirst;
params.crossfadeToDialog = 0;
params.alpha = 1f - failT;
StoriesUtilities.drawAvatarWithStory(dialogId, canvas, avatarImage, storiesController.hasSelfStories(), params);
if (failT > 0) {
final Paint paint = StoriesUtilities.getErrorPaint(avatarImage);
paint.setStrokeWidth(AndroidUtilities.dp(2));
paint.setAlpha((int) (0xFF * failT));
canvas.drawCircle(x + finalSize / 2, y + finalSize / 2, (finalSize / 2 + AndroidUtilities.dp(4)) * params.getScale(), paint);
}
} }
progressWasDrawn = false; uploadingProgress = uploadingProgress / uploadingOrEditingStories.size();
if (drawAvatar) { lastUploadingCloseFriends = closeFriends = uploadingOrEditingStories.get(uploadingOrEditingStories.size() - 1).isCloseFriends();
canvas.save(); }
float s = 1f - progressHalf; invalidate();
canvas.scale(s, s, cx + AndroidUtilities.dp(16), cy + AndroidUtilities.dp(16)); if (radialProgress == null) {
drawPlus(canvas, cx, cy, 1f); if (DialogStoriesCell.this.radialProgress != null) {
drawFail(canvas, cx, cy, failT); radialProgress = DialogStoriesCell.this.radialProgress;
canvas.restore(); } else {
DialogStoriesCell.this.radialProgress = radialProgress = new RadialProgress(this);
radialProgress.setBackground(null, true, false);
} }
} }
canvas.restore();
} else {
if (drawAvatar) { if (drawAvatar) {
params.animate = true; canvas.save();
canvas.scale(params.getScale(), params.getScale(), params.originalAvatarRect.centerX(), params.originalAvatarRect.centerY());
avatarImage.setImageCoords(params.originalAvatarRect);
avatarImage.draw(canvas);
canvas.restore();
}
radialProgress.setDiff(0);
Paint paint = closeFriends ?
StoriesUtilities.getCloseFriendsPaint(avatarImage) :
StoriesUtilities.getActiveCirclePaint(avatarImage, true);
paint.setAlpha(255);
radialProgress.setPaint(paint);
radialProgress.setProgressRect(
(int) (avatarImage.getImageX() - AndroidUtilities.dp(3)), (int) (avatarImage.getImageY() - AndroidUtilities.dp(3)),
(int) (avatarImage.getImageX2() + AndroidUtilities.dp(3)), (int) (avatarImage.getImageY2() + AndroidUtilities.dp(3))
);
radialProgress.setProgress(Utilities.clamp(uploadingProgress, 1f, 0), progressWasDrawn);
if (avatarImage.getVisible()) {
radialProgress.draw(canvas);
}
progressWasDrawn = true;
drawCircleForce = true;
invalidate();
} else {
float failT = this.failT.set(isFail);
if (drawAvatar) {
if (progressWasDrawn) {
animateBounce();
params.forceAnimateProgressToSegments = true;
params.progressToSegments = 0f;
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1f);
valueAnimator.addUpdateListener(animation -> {
params.progressToSegments = AndroidUtilities.lerp(0, 1f - collapsedProgress2, (float) animation.getAnimatedValue());
invalidate();
});
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
params.forceAnimateProgressToSegments = false;
}
});
valueAnimator.setDuration(100);
valueAnimator.start();
}
failT *= params.progressToSegments;
params.animate = !progressWasDrawn;
params.progressToArc = getArcProgress(cx, radius); params.progressToArc = getArcProgress(cx, radius);
params.isLast = isLast; params.isLast = isLast;
params.isFirst = isFirst; params.isFirst = isFirst;
if (crossfadeToDialog) { params.alpha = 1f - failT;
if (!isSelf && crossfadeToDialog) {
params.crossfadeToDialog = crossfadeToDialogId; params.crossfadeToDialog = crossfadeToDialogId;
params.crossfadeToDialogProgress = progressToCollapsed2; params.crossfadeToDialogProgress = progressToCollapsed2;
} else { } else {
params.crossfadeToDialog = 0; params.crossfadeToDialog = 0;
} }
StoriesUtilities.drawAvatarWithStory(dialogId, canvas, avatarImage, storiesController.hasStories(dialogId), params); if (isSelf) {
// avatarImage.draw(canvas); StoriesUtilities.drawAvatarWithStory(dialogId, canvas, avatarImage, storiesController.hasSelfStories(), params);
} else {
StoriesUtilities.drawAvatarWithStory(dialogId, canvas, avatarImage, storiesController.hasStories(dialogId), params);
}
if (failT > 0) {
final Paint paint = StoriesUtilities.getErrorPaint(avatarImage);
paint.setStrokeWidth(AndroidUtilities.dp(2));
paint.setAlpha((int) (0xFF * failT));
canvas.drawCircle(x + finalSize / 2, y + finalSize / 2, (finalSize / 2 + AndroidUtilities.dp(4)) * params.getScale(), paint);
}
}
progressWasDrawn = false;
if (drawAvatar) {
canvas.save();
float s = 1f - progressHalf;
canvas.scale(s, s, cx + AndroidUtilities.dp(16), cy + AndroidUtilities.dp(16));
drawPlus(canvas, cx, cy, 1f);
drawFail(canvas, cx, cy, failT);
canvas.restore();
} }
} }
canvas.restore();
if (crossfadeToDialog && progressToCollapsed2 > 0) { if (crossfadeToDialog && progressToCollapsed2 > 0) {
crossfageToAvatarImage.setImageCoords(x, y, finalSize, finalSize); crossfageToAvatarImage.setImageCoords(x, y, finalSize, finalSize);
@ -1532,7 +1538,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
} }
public void drawPlus(Canvas canvas, float cx, float cy, float alpha) { public void drawPlus(Canvas canvas, float cx, float cy, float alpha) {
if (!isSelf || storiesController.hasStories(dialogId) || !storiesController.getUploadingStories().isEmpty()) { if (!isSelf || storiesController.hasStories(dialogId) || !Utilities.isNullOrEmpty(storiesController.getUploadingStories(dialogId))) {
return; return;
} }
float cx2 = cx + AndroidUtilities.dp(16); float cx2 = cx + AndroidUtilities.dp(16);
@ -1561,7 +1567,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
} }
public void drawFail(Canvas canvas, float cx, float cy, float alpha) { public void drawFail(Canvas canvas, float cx, float cy, float alpha) {
if (!isSelf || alpha <= 0) { if (alpha <= 0) {
return; return;
} }
float cx2 = cx + AndroidUtilities.dp(17); float cx2 = cx + AndroidUtilities.dp(17);

View file

@ -15,6 +15,7 @@ public class MessageMediaStoryFull extends TLRPC.TL_messageMediaStory {
id = stream.readInt32(exception); id = stream.readInt32(exception);
storyItem = TLRPC.StoryItem.TLdeserialize(stream, stream.readInt32(exception), exception); storyItem = TLRPC.StoryItem.TLdeserialize(stream, stream.readInt32(exception), exception);
via_mention = stream.readBool(exception); via_mention = stream.readBool(exception);
peer = MessagesController.getInstance(UserConfig.selectedAccount).getPeer(user_id);
} }
public void serializeToStream(AbstractSerializedData stream) { public void serializeToStream(AbstractSerializedData stream) {

View file

@ -8,6 +8,7 @@ import static org.telegram.messenger.Utilities.clamp;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
@ -35,11 +36,13 @@ import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedFloat; import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AnimatedTextView; import org.telegram.ui.Components.AnimatedTextView;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.RadialProgress;
import org.telegram.ui.ProfileActivity; import org.telegram.ui.ProfileActivity;
import java.util.ArrayList; import java.util.ArrayList;
@ -56,7 +59,7 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
private final Paint whitePaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint whitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final int currentAccount; private final int currentAccount;
private final long userId; private final long dialogId;
private final View avatarContainer; private final View avatarContainer;
private final ProfileActivity.AvatarImageView avatarImage; private final ProfileActivity.AvatarImageView avatarImage;
@ -70,6 +73,21 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
private final ArrayList<StoryCircle> circles = new ArrayList<>(); private final ArrayList<StoryCircle> circles = new ArrayList<>();
private boolean attached; private boolean attached;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private boolean lastDrawnStateIsFailed;
private RadialProgress radialProgress;
private boolean progressWasDrawn;
private boolean progressIsDone;
private float bounceScale = 1f;
private float progressToInsets = 1f;
public void setProgressToStoriesInsets(float progressToInsets) {
if (this.progressToInsets == progressToInsets) {
return;
}
this.progressToInsets = progressToInsets;
invalidate();
}
private class StoryCircle { private class StoryCircle {
public StoryCircle(TLRPC.StoryItem storyItem) { public StoryCircle(TLRPC.StoryItem storyItem) {
@ -112,13 +130,16 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
} }
} }
public ProfileStoriesView(Context context, int currentAccount, long userId, @NonNull View avatarContainer, ProfileActivity.AvatarImageView avatarImage, Theme.ResourcesProvider resourcesProvider) { StoriesController storiesController;
public ProfileStoriesView(Context context, int currentAccount, long dialogId, @NonNull View avatarContainer, ProfileActivity.AvatarImageView avatarImage, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
this.userId = userId; this.dialogId = dialogId;
this.avatarContainer = avatarContainer; this.avatarContainer = avatarContainer;
this.avatarImage = avatarImage; this.avatarImage = avatarImage;
storiesController = MessagesController.getInstance(currentAccount).getStoriesController();
storiesGradientTools = new StoriesGradientTools(); storiesGradientTools = new StoriesGradientTools();
storiesGradientTools.paint.setStyle(Paint.Style.STROKE); storiesGradientTools.paint.setStyle(Paint.Style.STROKE);
@ -140,7 +161,8 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
titleDrawable.setCallback(this); titleDrawable.setCallback(this);
clipOutAvatar.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); clipOutAvatar.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
paint.setStrokeWidth(dpf2(2.33f));
paint.setStyle(Paint.Style.STROKE);
updateStories(false, false); updateStories(false, false);
} }
@ -149,18 +171,18 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
return who == titleDrawable || super.verifyDrawable(who); return who == titleDrawable || super.verifyDrawable(who);
} }
private TLRPC.UserFull userFull; private TLRPC.PeerStories peerStories;
public void setUserFull(TLRPC.UserFull userFull) { public void setStories(TLRPC.PeerStories peerStories) {
this.userFull = userFull; this.peerStories = peerStories;
updateStories(true, false); updateStories(true, false);
} }
private void updateStories(boolean animated, boolean asUpdate) { private void updateStories(boolean animated, boolean asUpdate) {
final boolean me = userId == UserConfig.getInstance(currentAccount).getClientUserId(); final boolean me = dialogId == UserConfig.getInstance(currentAccount).getClientUserId();
TLRPC.TL_userStories userFullStories = userFull != null && !me ? userFull.stories : null; TLRPC.PeerStories userFullStories = peerStories;
TLRPC.TL_userStories stateStories = MessagesController.getInstance(currentAccount).getStoriesController().getStories(userId); TLRPC.PeerStories stateStories = MessagesController.getInstance(currentAccount).getStoriesController().getStories(dialogId);
final TLRPC.TL_userStories userStories; final TLRPC.PeerStories userStories;
if (userId == 0) { if (dialogId == 0) {
userStories = null; userStories = null;
// } else if (stateStories != null) { // } else if (stateStories != null) {
// userStories = stateStories; // userStories = stateStories;
@ -309,7 +331,7 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
} }
if (index == -1) { if (index == -1) {
storyItem.dialogId = userId; storyItem.dialogId = dialogId;
StoryCircle circle = new StoryCircle(storyItem); StoryCircle circle = new StoryCircle(storyItem);
circle.index = i; circle.index = i;
circle.scale = 1f; circle.scale = 1f;
@ -368,6 +390,8 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
private final AnimatedFloat segmentsCountAnimated = new AnimatedFloat(this, 0, 240 * 2, CubicBezierInterpolator.EASE_OUT_QUINT); private final AnimatedFloat segmentsCountAnimated = new AnimatedFloat(this, 0, 240 * 2, CubicBezierInterpolator.EASE_OUT_QUINT);
private final AnimatedFloat segmentsUnreadCountAnimated = new AnimatedFloat(this, 0, 240, CubicBezierInterpolator.EASE_OUT_QUINT); private final AnimatedFloat segmentsUnreadCountAnimated = new AnimatedFloat(this, 0, 240, CubicBezierInterpolator.EASE_OUT_QUINT);
private final AnimatedFloat progressToUploading = new AnimatedFloat(this, 0, 150, CubicBezierInterpolator.DEFAULT);
private final AnimatedFloat progressToFail = new AnimatedFloat(this, 0, 150, CubicBezierInterpolator.DEFAULT);
private float newStoryBounceT = 1; private float newStoryBounceT = 1;
private ValueAnimator newStoryBounce; private ValueAnimator newStoryBounce;
@ -425,7 +449,8 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
@Override @Override
protected void dispatchDraw(Canvas canvas) { protected void dispatchDraw(Canvas canvas) {
float rright = rightAnimated.set(this.right); float rright = rightAnimated.set(this.right);
float insetMain = 0; float insetMain = AndroidUtilities.dpf2(3.5f);
insetMain *= progressToInsets;
float ax = avatarContainer.getX() + insetMain * avatarContainer.getScaleX(); float ax = avatarContainer.getX() + insetMain * avatarContainer.getScaleX();
float ay = avatarContainer.getY() + insetMain * avatarContainer.getScaleY(); float ay = avatarContainer.getY() + insetMain * avatarContainer.getScaleY();
float aw = (avatarContainer.getWidth() - insetMain * 2) * avatarContainer.getScaleX(); float aw = (avatarContainer.getWidth() - insetMain * 2) * avatarContainer.getScaleX();
@ -454,13 +479,115 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
Collections.sort(circles, (a, b) -> (int) (b.cachedIndex - a.cachedIndex)); Collections.sort(circles, (a, b) -> (int) (b.cachedIndex - a.cachedIndex));
} }
final float segmentsAlpha = clamp(1f - expandProgress / 0.2f, 1, 0); float segmentsAlpha = clamp(1f - expandProgress / 0.2f, 1, 0);
final float segmentsCount = segmentsCountAnimated.set(count); boolean isFailed = storiesController.isLastUploadingFailed(dialogId);
final float segmentsUnreadCount = segmentsUnreadCountAnimated.set(unreadCount); boolean isUploading = (storiesController.hasUploadingStories(dialogId) && !isFailed) || progressWasDrawn && !progressIsDone;
float progressToUploading = this.progressToUploading.set(isUploading);
canvas.save();
canvas.scale(bounceScale, bounceScale, rect1.centerX(), rect1.centerY());
// float cy = lerp(rect1.centerY(), this.cy, expandProgress);
float cy = lerp(rect1.centerY(), this.expandY, expandProgress); float cy = lerp(rect1.centerY(), this.expandY, expandProgress);
storiesGradientTools.setBounds(this.left, cy - dp(24), this.right, cy + dp(24)); storiesGradientTools.setBounds(this.left, cy - dp(24), this.right, cy + dp(24));
if (progressToUploading > 0) {
rect2.set(rect1);
rect2.inset(-dpf2(2.66f + 2.23f / 2), -dpf2(2.66f + 2.23f / 2));
if (radialProgress == null) {
radialProgress = new RadialProgress(this);
radialProgress.setBackground(null, true, false);
}
float uploadingProgress = 0;
if (!storiesController.hasUploadingStories(dialogId) || storiesController.isLastUploadingFailed(dialogId)) {
uploadingProgress = 1f;
} else {
ArrayList<StoriesController.UploadingStory> uploadingOrEditingStories = storiesController.getUploadingStories(dialogId);
for (int i = 0; i < uploadingOrEditingStories.size(); i++) {
uploadingProgress += uploadingOrEditingStories.get(i).progress;
}
uploadingProgress = uploadingProgress / uploadingOrEditingStories.size();
}
radialProgress.setDiff(0);
storiesGradientTools.paint.setAlpha((int) (255 * segmentsAlpha * progressToUploading));
storiesGradientTools.paint.setStrokeWidth(dpf2(2.33f));
radialProgress.setPaint(storiesGradientTools.paint);
radialProgress.setProgressRect((int) rect2.left, (int) rect2.top, (int) rect2.right, (int) rect2.bottom);
radialProgress.setProgress(Utilities.clamp(uploadingProgress, 1f, 0.2f), true);
radialProgress.draw(canvas);
progressWasDrawn = true;
boolean oldIsDone = progressIsDone;
progressIsDone = radialProgress.getAnimatedProgress() >= 0.98f;
if (oldIsDone != progressIsDone) {
animateBounce();
}
} else {
progressWasDrawn = false;
}
if (progressToUploading < 1f) {
segmentsAlpha = clamp(1f - expandProgress / 0.2f, 1, 0) * (1f - progressToUploading);
final float segmentsCount = segmentsCountAnimated.set(count);
final float segmentsUnreadCount = segmentsUnreadCountAnimated.set(unreadCount);
storiesGradientTools.setBounds(this.left, cy - dp(24), this.right, cy + dp(24));
if (isFailed) {
rect2.set(rect1);
rect2.inset(-dpf2(2.66f + 2.23f / 2), -dpf2(2.66f + 2.23f / 2));
final Paint paint = StoriesUtilities.getErrorPaint(rect2);
paint.setStrokeWidth(AndroidUtilities.dp(2));
paint.setAlpha((int) (255 * segmentsAlpha));
canvas.drawCircle(rect2.centerX(), rect2.centerY(), rect2.width() / 2f, paint);
} else if (mainCircle != null && segmentsAlpha > 0) {
rect2.set(rect1);
rect2.inset(-dpf2(2.66f + 2.23f / 2), -dpf2(2.66f + 2.23f / 2));
rect3.set(rect1);
rect3.inset(-dpf2(2.66f + 1.5f / 2), -dpf2(2.66f + 1.5f / 2));
final float separatorAngle = lerp(0, (float) (dpf2(2 + 2.23f) / (rect1.width() * Math.PI) * 360f), clamp(segmentsCount - 1, 1, 0) * segmentsAlpha);
final float maxCount = 50; // (float) (AndroidUtilities.dp(60) * Math.PI / dpf2(4));
final int mcount = Math.min(count, (int) maxCount);
final float animcount = Math.min(segmentsCount, maxCount);
final float widthAngle = (360 - Math.max(0, animcount) * separatorAngle) / Math.max(1, animcount);
readPaint.setColor(ColorUtils.blendARGB(0x5affffff, 0x3a000000, actionBarProgress));
readPaintAlpha = readPaint.getAlpha();
float a = -90 - separatorAngle / 2f;
for (int i = 0; i < mcount; ++i) {
final float read = 1f - clamp(segmentsUnreadCount - i, 1, 0);
final float appear = 1f - clamp(mcount - animcount - i, 1, 0);
if (appear < 0) {
continue;
}
float bounceScale = i == 0 ? 1 + (newStoryBounceT - 1) / 2.5f : 1f;
if (bounceScale != 1) {
canvas.save();
canvas.scale(bounceScale, bounceScale, rect2.centerX(), rect2.centerY());
}
if (read < 1) {
storiesGradientTools.paint.setAlpha((int) (0xFF * (1f - read) * segmentsAlpha));
storiesGradientTools.paint.setStrokeWidth(dpf2(2.33f));
canvas.drawArc(rect2, a, -widthAngle * appear, false, storiesGradientTools.paint);
}
if (read > 0) {
readPaint.setAlpha((int) (readPaintAlpha * read * segmentsAlpha));
readPaint.setStrokeWidth(dpf2(1.5f));
canvas.drawArc(rect3, a, -widthAngle * appear, false, readPaint);
}
if (bounceScale != 1) {
canvas.restore();
}
a -= widthAngle * appear + separatorAngle * appear;
}
}
}
if (expandProgress > 0 && segmentsAlpha < 1) { if (expandProgress > 0 && segmentsAlpha < 1) {
float ix = 0; float ix = 0;
w = 0; w = 0;
@ -500,15 +627,15 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
int wasAlpha = whitePaint.getAlpha(); int wasAlpha = whitePaint.getAlpha();
whitePaint.setAlpha((int) (wasAlpha * expandProgress)); whitePaint.setAlpha((int) (wasAlpha * expandProgress));
canvas.drawCircle( canvas.drawCircle(
circle.cachedRect.centerX(), circle.cachedRect.centerX(),
circle.cachedRect.centerY(), circle.cachedRect.centerY(),
Math.min(circle.cachedRect.width(), circle.cachedRect.height()) / 2f + Math.min(circle.cachedRect.width(), circle.cachedRect.height()) / 2f +
lerp( lerp(
dpf2(2.66f) + storiesGradientTools.paint.getStrokeWidth() / 2f, dpf2(2.66f) + storiesGradientTools.paint.getStrokeWidth() / 2f,
dpf2(2.33f) - readPaint.getStrokeWidth() / 2f, dpf2(2.33f) - readPaint.getStrokeWidth() / 2f,
circle.cachedRead circle.cachedRead
) * expandProgress, ) * expandProgress,
whitePaint whitePaint
); );
whitePaint.setAlpha(wasAlpha); whitePaint.setAlpha(wasAlpha);
} }
@ -519,14 +646,14 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
StoryCircle C = nearest(i + 1 < circles.size() ? circles.get(i + 1) : null, i + 2 < circles.size() ? circles.get(i + 2) : null, B); StoryCircle C = nearest(i + 1 < circles.size() ? circles.get(i + 1) : null, i + 2 < circles.size() ? circles.get(i + 2) : null, B);
if (A != null && ( if (A != null && (
Math.abs(A.borderRect.centerX() - B.borderRect.centerX()) < Math.abs(B.borderRect.width() / 2f - A.borderRect.width() / 2f) || Math.abs(A.borderRect.centerX() - B.borderRect.centerX()) < Math.abs(B.borderRect.width() / 2f - A.borderRect.width() / 2f) ||
Math.abs(A.borderRect.centerX() - B.borderRect.centerX()) > A.borderRect.width() / 2f + B.borderRect.width() / 2f Math.abs(A.borderRect.centerX() - B.borderRect.centerX()) > A.borderRect.width() / 2f + B.borderRect.width() / 2f
)) { )) {
A = null; A = null;
} }
if (C != null && ( if (C != null && (
Math.abs(C.borderRect.centerX() - B.borderRect.centerX()) < Math.abs(B.borderRect.width() / 2f - C.borderRect.width() / 2f) || Math.abs(C.borderRect.centerX() - B.borderRect.centerX()) < Math.abs(B.borderRect.width() / 2f - C.borderRect.width() / 2f) ||
Math.abs(C.borderRect.centerX() - B.borderRect.centerX()) > C.borderRect.width() / 2f + B.borderRect.width() / 2f Math.abs(C.borderRect.centerX() - B.borderRect.centerX()) > C.borderRect.width() / 2f + B.borderRect.width() / 2f
)) { )) {
C = null; C = null;
} }
@ -555,55 +682,8 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
} }
canvas.restore(); canvas.restore();
} }
if (mainCircle != null && segmentsAlpha > 0) {
rect2.set(rect1);
rect2.inset(-dpf2(2.66f + 2.23f / 2), -dpf2(2.66f + 2.23f / 2));
rect3.set(rect1);
rect3.inset(-dpf2(2.66f + 1.5f / 2), -dpf2(2.66f + 1.5f / 2));
final float separatorAngle = lerp(0, (float) (dpf2(2 + 2.23f) / (rect1.width() * Math.PI) * 360f), clamp(segmentsCount - 1, 1, 0) * segmentsAlpha); canvas.restore();
final float maxCount = 50; // (float) (AndroidUtilities.dp(60) * Math.PI / dpf2(4));
final int mcount = Math.min(count, (int) maxCount);
final float animcount = Math.min(segmentsCount, maxCount);
final float widthAngle = (360 - Math.max(0, animcount) * separatorAngle) / Math.max(1, animcount);
readPaint.setColor(ColorUtils.blendARGB(0x5affffff, 0x3a000000, actionBarProgress));
readPaintAlpha = readPaint.getAlpha();
float a = -90 - separatorAngle / 2f;
for (int i = 0; i < mcount; ++i) {
final float read = 1f - clamp(segmentsUnreadCount - i, 1, 0);
final float appear = 1f - clamp(mcount - animcount - i, 1, 0);
if (appear < 0) {
continue;
}
float bounceScale = i == 0 ? 1 + (newStoryBounceT - 1) / 2.5f : 1f;
if (bounceScale != 1) {
canvas.save();
canvas.scale(bounceScale, bounceScale, rect2.centerX(), rect2.centerY());
}
if (read < 1) {
storiesGradientTools.paint.setAlpha((int) (0xFF * (1f - read) * segmentsAlpha));
storiesGradientTools.paint.setStrokeWidth(dpf2(2.33f));
canvas.drawArc(rect2, a, -widthAngle * appear, false, storiesGradientTools.paint);
}
if (read > 0) {
readPaint.setAlpha((int) (readPaintAlpha * read * segmentsAlpha));
readPaint.setStrokeWidth(dpf2(1.5f));
canvas.drawArc(rect3, a, -widthAngle * appear, false, readPaint);
}
if (bounceScale != 1) {
canvas.restore();
}
a -= widthAngle * appear + separatorAngle * appear;
}
}
// float titleAlpha = Math.max(0, (expandProgress - .5f) * 2f); // float titleAlpha = Math.max(0, (expandProgress - .5f) * 2f);
// if (titleAlpha > 0) { // if (titleAlpha > 0) {
@ -616,6 +696,35 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
// } // }
} }
private void animateBounce() {
AnimatorSet animatorSet = new AnimatorSet();
ValueAnimator inAnimator = ValueAnimator.ofFloat(1, 1.05f);
inAnimator.setDuration(100);
inAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT);
ValueAnimator outAnimator = ValueAnimator.ofFloat(1.05f, 1f);
outAnimator.setDuration(250);
outAnimator.setInterpolator(new OvershootInterpolator());
ValueAnimator.AnimatorUpdateListener updater = animation -> {
avatarImage.bounceScale = bounceScale = (float) animation.getAnimatedValue();
avatarImage.invalidate();
invalidate();
};
inAnimator.addUpdateListener(updater);
outAnimator.addUpdateListener(updater);
animatorSet.playSequentially(inAnimator, outAnimator);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
avatarImage.bounceScale = bounceScale = 1f;
avatarImage.invalidate();
invalidate();
}
});
animatorSet.start();
}
private void clipCircle(Canvas canvas, StoryCircle circle, StoryCircle nextCircle) { private void clipCircle(Canvas canvas, StoryCircle circle, StoryCircle nextCircle) {
if (nextCircle == null) { if (nextCircle == null) {
return; return;
@ -895,7 +1004,7 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
tapY = event.getY(); tapY = event.getY();
return true; return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) { } else if (event.getAction() == MotionEvent.ACTION_UP) {
if (hit && System.currentTimeMillis() - tapTime <= ViewConfiguration.getTapTimeout() && MathUtils.distance(tapX, tapY, event.getX(), event.getY()) <= AndroidUtilities.dp(12) && !circles.isEmpty()) { if (hit && System.currentTimeMillis() - tapTime <= ViewConfiguration.getTapTimeout() && MathUtils.distance(tapX, tapY, event.getX(), event.getY()) <= AndroidUtilities.dp(12) && (storiesController.hasUploadingStories(dialogId) || storiesController.hasStories(dialogId) || !circles.isEmpty())) {
onTap(provider); onTap(provider);
return true; return true;
} }

View file

@ -248,7 +248,6 @@ public abstract class SelfStoriesPreviewView extends View {
imageReceiversTmp.get(i).onDetach(); imageReceiversTmp.get(i).onDetach();
} }
imageReceiversTmp.clear(); imageReceiversTmp.clear();
// canvas.drawLine(getMeasuredWidth() / 2f, 0, getMeasuredWidth() / 2f, getMeasuredHeight(), new Paint());
} }
abstract void onDragging(); abstract void onDragging();

View file

@ -483,7 +483,8 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
} }
} }
public void setStoryItem(SelfStoryViewsView.StoryItemInternal storyItem) { public void setStoryItem(long dialogId, SelfStoryViewsView.StoryItemInternal storyItem) {
this.dialogId = dialogId;
this.storyItem = storyItem; this.storyItem = storyItem;
updateViewsVisibility(); updateViewsVisibility();
updateViewState(false); updateViewState(false);
@ -507,7 +508,7 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
if (defaultModel != null) { if (defaultModel != null) {
defaultModel.release(); defaultModel.release();
} }
defaultModel = new ViewsModel(currentAccount, serverItem, true); defaultModel = new ViewsModel(currentAccount, dialogId, serverItem, true);
defaultModel.reloadIfNeed(state, showContactsFilter, showReactionsSort); defaultModel.reloadIfNeed(state, showContactsFilter, showReactionsSort);
defaultModel.loadNext(); defaultModel.loadNext();
MessagesController.getInstance(currentAccount).storiesController.selfViewsModel.put(serverItem.id, defaultModel); MessagesController.getInstance(currentAccount).storiesController.selfViewsModel.put(serverItem.id, defaultModel);
@ -581,7 +582,7 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
((MarginLayoutParams) shadowView2.getLayoutParams()).topMargin = AndroidUtilities.dp(TOP_PADDING - 17); ((MarginLayoutParams) shadowView2.getLayoutParams()).topMargin = AndroidUtilities.dp(TOP_PADDING - 17);
} }
public static void preload(int currentAccount, TLRPC.StoryItem storyItem) { public static void preload(int currentAccount, long dialogId, TLRPC.StoryItem storyItem) {
if (storyItem == null) { if (storyItem == null) {
return; return;
} }
@ -591,7 +592,7 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
if (model != null) { if (model != null) {
model.release(); model.release();
} }
model = new ViewsModel(currentAccount, storyItem, true); model = new ViewsModel(currentAccount, dialogId, storyItem, true);
model.loadNext(); model.loadNext();
MessagesController.getInstance(currentAccount).storiesController.selfViewsModel.put(storyItem.id, model); MessagesController.getInstance(currentAccount).storiesController.selfViewsModel.put(storyItem.id, model);
} }
@ -651,14 +652,14 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
public void didReceivedNotification(int id, int account, Object... args) { public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.storiesUpdated) { if (id == NotificationCenter.storiesUpdated) {
if (storyItem.uploadingStory != null) { if (storyItem.uploadingStory != null) {
TLRPC.TL_userStories stories = MessagesController.getInstance(currentAccount).storiesController.getStories(UserConfig.getInstance(currentAccount).clientUserId); TLRPC.PeerStories stories = MessagesController.getInstance(currentAccount).storiesController.getStories(UserConfig.getInstance(currentAccount).clientUserId);
if (stories != null) { if (stories != null) {
for (int i = 0; i < stories.stories.size(); i++) { for (int i = 0; i < stories.stories.size(); i++) {
TLRPC.StoryItem storyItem = stories.stories.get(i); TLRPC.StoryItem storyItem = stories.stories.get(i);
if (storyItem.attachPath != null && storyItem.attachPath.equals(this.storyItem.uploadingStory.path)) { if (storyItem.attachPath != null && storyItem.attachPath.equals(this.storyItem.uploadingStory.path)) {
this.storyItem.uploadingStory = null; this.storyItem.uploadingStory = null;
this.storyItem.storyItem = storyItem; this.storyItem.storyItem = storyItem;
setStoryItem(this.storyItem); setStoryItem(dialogId, this.storyItem);
break; break;
} }
} }
@ -955,6 +956,7 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
public int totalCount; public int totalCount;
TLRPC.StoryItem storyItem; TLRPC.StoryItem storyItem;
private long dialogId;
int currentAccount; int currentAccount;
boolean loading; boolean loading;
ArrayList<TLRPC.TL_storyView> views = new ArrayList<>(); ArrayList<TLRPC.TL_storyView> views = new ArrayList<>();
@ -971,9 +973,10 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
ArrayList<SelfStoryViewsPage> listeners = new ArrayList<>(); ArrayList<SelfStoryViewsPage> listeners = new ArrayList<>();
FiltersState state = new FiltersState(); FiltersState state = new FiltersState();
public ViewsModel(int currentAccount, TLRPC.StoryItem storyItem, boolean isDefault) { public ViewsModel(int currentAccount, long dialogId, TLRPC.StoryItem storyItem, boolean isDefault) {
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
this.storyItem = storyItem; this.storyItem = storyItem;
this.dialogId = dialogId;
this.totalCount = storyItem.views == null ? 0 : storyItem.views.views_count; this.totalCount = storyItem.views == null ? 0 : storyItem.views.views_count;
if (totalCount < 200) { if (totalCount < 200) {
useLocalFilters = true; useLocalFilters = true;
@ -1006,6 +1009,7 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
} }
TLRPC.TL_stories_getStoryViewsList req = new TLRPC.TL_stories_getStoryViewsList(); TLRPC.TL_stories_getStoryViewsList req = new TLRPC.TL_stories_getStoryViewsList();
req.id = storyItem.id; req.id = storyItem.id;
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId);
if (useLocalFilters) { if (useLocalFilters) {
req.q = ""; req.q = "";
req.just_contacts = false; req.just_contacts = false;

View file

@ -22,6 +22,7 @@ import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.AdjustPanLayoutHelper; import org.telegram.ui.ActionBar.AdjustPanLayoutHelper;
@ -48,6 +49,7 @@ public class SelfStoryViewsView extends FrameLayout {
int keyboardHeight; int keyboardHeight;
int animatedKeyboardHeight; int animatedKeyboardHeight;
private long dialogId;
ViewPagerInner viewPager; ViewPagerInner viewPager;
ArrayList<StoryItemInternal> storyItems = new ArrayList<>(); ArrayList<StoryItemInternal> storyItems = new ArrayList<>();
@ -197,7 +199,7 @@ public class SelfStoryViewsView extends FrameLayout {
item.setTag(position); item.setTag(position);
item.setShadowDrawable(shadowDrawable); item.setShadowDrawable(shadowDrawable);
item.setPadding(0, AndroidUtilities.dp(16), 0 , 0); item.setPadding(0, AndroidUtilities.dp(16), 0 , 0);
item.setStoryItem(storyItems.get(position)); item.setStoryItem(dialogId,storyItems.get(position));
// bottomPadding = (selfStoriesPreviewView.getTop() + toHeight + AndroidUtilities.dp(24)); // bottomPadding = (selfStoriesPreviewView.getTop() + toHeight + AndroidUtilities.dp(24));
item.setListBottomPadding(bottomPadding); item.setListBottomPadding(bottomPadding);
@ -346,14 +348,18 @@ public class SelfStoryViewsView extends FrameLayout {
viewPagerContainer.setTranslationY(-bottomPadding + getMeasuredHeight() - selfStoriesViewsOffset); viewPagerContainer.setTranslationY(-bottomPadding + getMeasuredHeight() - selfStoriesViewsOffset);
} }
public void setItems(ArrayList<TLRPC.StoryItem> storyItems, int selectedPosition) { public void setItems(long dialogId, ArrayList<TLRPC.StoryItem> storyItems, int selectedPosition) {
this.storyItems.clear(); this.storyItems.clear();
this.dialogId = dialogId;
for (int i = 0; i < storyItems.size(); i++) { for (int i = 0; i < storyItems.size(); i++) {
this.storyItems.add(new StoryItemInternal(storyItems.get(i))); this.storyItems.add(new StoryItemInternal(storyItems.get(i)));
} }
ArrayList<StoriesController.UploadingStory> uploadingStories = MessagesController.getInstance(storyViewer.currentAccount).storiesController.getUploadingStories(); long clientUserId = UserConfig.getInstance(UserConfig.selectedAccount).getClientUserId();
for (int i = 0; i < uploadingStories.size(); i++) { ArrayList<StoriesController.UploadingStory> uploadingStories = MessagesController.getInstance(storyViewer.currentAccount).storiesController.getUploadingStories(clientUserId);
this.storyItems.add(new StoryItemInternal(uploadingStories.get(i))); if (uploadingStories != null) {
for (int i = 0; i < uploadingStories.size(); i++) {
this.storyItems.add(new StoryItemInternal(uploadingStories.get(i)));
}
} }
selfStoriesPreviewView.setItems(this.storyItems, selectedPosition); selfStoriesPreviewView.setItems(this.storyItems, selectedPosition);
viewPager.setAdapter(null); viewPager.setAdapter(null);

View file

@ -107,11 +107,12 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider {
holder.clipParent = storiesCell; holder.clipParent = storiesCell;
holder.clipTop = holder.clipBottom = 0; holder.clipTop = holder.clipBottom = 0;
holder.alpha = 1; holder.alpha = 1;
if (cell.isFail) { if (cell.isFail && storiesCell.isExpanded()) {
final Path path = new Path(); final Path path = new Path();
holder.drawClip = (canvas, bounds, alpha, opening) -> { holder.drawClip = (canvas, bounds, alpha, opening) -> {
if (opening) return;
path.rewind(); path.rewind();
final float t = opening ? 1f - (float) Math.pow(1f - alpha, 2) : (float) Math.pow(alpha, 2); final float t = (float) Math.pow(alpha, 2);
path.addCircle(bounds.right + dp(7) - dp(14) * t, bounds.bottom + dp(7) - dp(14) * t, dp(11), Path.Direction.CW); path.addCircle(bounds.right + dp(7) - dp(14) * t, bounds.bottom + dp(7) - dp(14) * t, dp(11), Path.Direction.CW);
canvas.clipPath(path, Region.Op.DIFFERENCE); canvas.clipPath(path, Region.Op.DIFFERENCE);
}; };

View file

@ -1,8 +1,6 @@
package org.telegram.ui.Stories; package org.telegram.ui.Stories;
import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import androidx.collection.LongSparseArray; import androidx.collection.LongSparseArray;
@ -14,24 +12,20 @@ import org.telegram.SQLite.SQLiteException;
import org.telegram.SQLite.SQLitePreparedStatement; import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars; import org.telegram.messenger.BuildVars;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessageCustomParamsHelper;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.support.LongSparseIntArray; import org.telegram.messenger.support.LongSparseIntArray;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.NativeByteBuffer; import org.telegram.tgnet.NativeByteBuffer;
import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -51,7 +45,7 @@ public class StoriesStorage {
storage.getStorageQueue().postRunnable(() -> { storage.getStorageQueue().postRunnable(() -> {
SQLiteDatabase database = storage.getDatabase(); SQLiteDatabase database = storage.getDatabase();
SQLiteCursor cursor = null; SQLiteCursor cursor = null;
ArrayList<TLRPC.TL_userStories> userStoriesArray = new ArrayList<>(); ArrayList<TLRPC.PeerStories> userStoriesArray = new ArrayList<>();
ArrayList<Long> usersToLoad = new ArrayList<>(); ArrayList<Long> usersToLoad = new ArrayList<>();
ArrayList<Long> chatsToLoad = new ArrayList<>(); ArrayList<Long> chatsToLoad = new ArrayList<>();
boolean failed = false; boolean failed = false;
@ -93,11 +87,11 @@ public class StoriesStorage {
} }
cursor.dispose(); cursor.dispose();
cursor = null; cursor = null;
TLRPC.TL_userStories userStories; TLRPC.PeerStories userStories;
userStories = new TLRPC.TL_userStories(); userStories = new TLRPC.TL_peerStories();
userStories.stories = storyItems; userStories.stories = storyItems;
userStories.max_read_id = maxReadId; userStories.max_read_id = maxReadId;
userStories.user_id = dialogId; userStories.peer = MessagesController.getInstance(currentAccount).getPeer(dialogId);
userStoriesArray.add(userStories); userStoriesArray.add(userStories);
} }
} catch (Throwable e) { } catch (Throwable e) {
@ -113,19 +107,21 @@ public class StoriesStorage {
return; return;
} }
TLRPC.TL_stories_allStories storiesResponse = new TLRPC.TL_stories_allStories(); TLRPC.TL_stories_allStories storiesResponse = new TLRPC.TL_stories_allStories();
storiesResponse.user_stories = userStoriesArray; storiesResponse.peer_stories = userStoriesArray;
storiesResponse.users = storage.getUsers(usersToLoad); storiesResponse.users = storage.getUsers(usersToLoad);
for (int i = 0; i < storiesResponse.user_stories.size(); i++) { storiesResponse.chats = storage.getChats(chatsToLoad);
TLRPC.TL_userStories userStories = storiesResponse.user_stories.get(i); for (int i = 0; i < storiesResponse.peer_stories.size(); i++) {
checkExpiredStories(userStories.user_id, userStories.stories); TLRPC.PeerStories userStories = storiesResponse.peer_stories.get(i);
long dialogId = DialogObject.getPeerDialogId(userStories.peer);
checkExpiredStories(dialogId, userStories.stories);
if (userStories.stories.isEmpty()) { if (userStories.stories.isEmpty()) {
storiesResponse.user_stories.remove(i); storiesResponse.peer_stories.remove(i);
i--; i--;
} }
Collections.sort(userStories.stories, StoriesController.storiesComparator); Collections.sort(userStories.stories, StoriesController.storiesComparator);
} }
Collections.sort(storiesResponse.user_stories, Comparator.comparingInt(o -> -o.stories.get(o.stories.size() - 1).date)); Collections.sort(storiesResponse.peer_stories, Comparator.comparingInt(o -> -o.stories.get(o.stories.size() - 1).date));
AndroidUtilities.runOnUIThread(() -> consumer.accept(storiesResponse)); AndroidUtilities.runOnUIThread(() -> consumer.accept(storiesResponse));
}); });
@ -162,7 +158,7 @@ public class StoriesStorage {
} }
public void putStoriesInternal(long dialogId, TLRPC.TL_userStories userStories) { public void putStoriesInternal(long dialogId, TLRPC.PeerStories userStories) {
SQLiteDatabase database = storage.getDatabase(); SQLiteDatabase database = storage.getDatabase();
try { try {
if (userStories != null) { if (userStories != null) {
@ -232,12 +228,12 @@ public class StoriesStorage {
} }
} }
public void saveAllStories(ArrayList<TLRPC.TL_userStories> user_stories, boolean isNext, boolean hidden, Runnable callback) { public void saveAllStories(ArrayList<TLRPC.PeerStories> user_stories, boolean isNext, boolean hidden, Runnable callback) {
storage.getStorageQueue().postRunnable(() -> { storage.getStorageQueue().postRunnable(() -> {
SQLiteDatabase database = storage.getDatabase(); SQLiteDatabase database = storage.getDatabase();
for (int i = 0; i < user_stories.size(); i++) { for (int i = 0; i < user_stories.size(); i++) {
TLRPC.TL_userStories stories = user_stories.get(i); TLRPC.PeerStories stories = user_stories.get(i);
fillSkippedStories(stories.user_id, stories); fillSkippedStories(DialogObject.getPeerDialogId(stories.peer), stories);
} }
if (!isNext) { if (!isNext) {
try { try {
@ -246,12 +242,22 @@ public class StoriesStorage {
ArrayList<Long> dialogsToDelete = new ArrayList<>(); ArrayList<Long> dialogsToDelete = new ArrayList<>();
while (cursor.next()) { while (cursor.next()) {
long dialogId = cursor.longValue(0); long dialogId = cursor.longValue(0);
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId); if (dialogId > 0) {
if (user == null) { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
user = MessagesStorage.getInstance(currentAccount).getUser(dialogId); if (user == null) {
} user = MessagesStorage.getInstance(currentAccount).getUser(dialogId);
if (user == null || user.stories_hidden == hidden && !dialogsToDelete.contains(dialogId)) { }
dialogsToDelete.add(dialogId); if (user == null || user.stories_hidden == hidden && !dialogsToDelete.contains(dialogId)) {
dialogsToDelete.add(dialogId);
}
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
if (chat == null) {
chat = MessagesStorage.getInstance(currentAccount).getChat(-dialogId);
}
if (chat == null || chat.stories_hidden == hidden && !dialogsToDelete.contains(dialogId)) {
dialogsToDelete.add(dialogId);
}
} }
} }
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
@ -263,8 +269,8 @@ public class StoriesStorage {
} }
} }
for (int i = 0; i < user_stories.size(); i++) { for (int i = 0; i < user_stories.size(); i++) {
TLRPC.TL_userStories stories = user_stories.get(i); TLRPC.PeerStories stories = user_stories.get(i);
putStoriesInternal(stories.user_id, stories); putStoriesInternal(DialogObject.getPeerDialogId(stories.peer), stories);
} }
if (callback != null) { if (callback != null) {
AndroidUtilities.runOnUIThread(callback); AndroidUtilities.runOnUIThread(callback);
@ -272,7 +278,7 @@ public class StoriesStorage {
}); });
} }
private void fillSkippedStories(long user_id, TLRPC.TL_userStories userStories) { private void fillSkippedStories(long user_id, TLRPC.PeerStories userStories) {
try { try {
if (userStories != null) { if (userStories != null) {
ArrayList<TLRPC.StoryItem> storyItems = userStories.stories; ArrayList<TLRPC.StoryItem> storyItems = userStories.stories;
@ -321,17 +327,17 @@ public class StoriesStorage {
} }
public void getStories(long dialogId, Consumer<TLRPC.TL_userStories> consumer) { public void getStories(long dialogId, Consumer<TLRPC.PeerStories> consumer) {
storage.getStorageQueue().postRunnable(() -> { storage.getStorageQueue().postRunnable(() -> {
TLRPC.TL_userStories finalUserStories = getStoriesInternal(dialogId); TLRPC.PeerStories finalUserStories = getStoriesInternal(dialogId);
AndroidUtilities.runOnUIThread(() -> consumer.accept(finalUserStories)); AndroidUtilities.runOnUIThread(() -> consumer.accept(finalUserStories));
}); });
} }
private TLRPC.TL_userStories getStoriesInternal(long dialogId) { private TLRPC.PeerStories getStoriesInternal(long dialogId) {
SQLiteDatabase database = storage.getDatabase(); SQLiteDatabase database = storage.getDatabase();
SQLiteCursor cursor = null; SQLiteCursor cursor = null;
TLRPC.TL_userStories userStories = null; TLRPC.PeerStories userStories = null;
try { try {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT count, max_read FROM stories_counter WHERE dialog_id = %d", dialogId)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT count, max_read FROM stories_counter WHERE dialog_id = %d", dialogId));
int count = 0; int count = 0;
@ -360,10 +366,10 @@ public class StoriesStorage {
} }
cursor.dispose(); cursor.dispose();
cursor = null; cursor = null;
userStories = new TLRPC.TL_userStories(); userStories = new TLRPC.TL_peerStories();
userStories.max_read_id = maxReadId; userStories.max_read_id = maxReadId;
userStories.stories = storyItems; userStories.stories = storyItems;
userStories.user_id = dialogId; userStories.peer = MessagesController.getInstance(currentAccount).getPeer(dialogId);
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
@ -423,10 +429,18 @@ public class StoriesStorage {
} }
public void updateMaxReadId(long dialogId, int max_read_id) { public void updateMaxReadId(long dialogId, int max_read_id) {
TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(dialogId); if (dialogId > 0) {
if (userFull != null && userFull.stories != null) { TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(dialogId);
userFull.stories.max_read_id = max_read_id; if (userFull != null && userFull.stories != null) {
storage.updateUserInfo(userFull, false); userFull.stories.max_read_id = max_read_id;
storage.updateUserInfo(userFull, false);
}
} else {
TLRPC.ChatFull chatFull = MessagesController.getInstance(currentAccount).getChatFull(-dialogId);
if (chatFull != null && chatFull.stories != null) {
chatFull.stories.max_read_id = max_read_id;
storage.updateChatInfo(chatFull, false);
}
} }
storage.getStorageQueue().postRunnable(() -> { storage.getStorageQueue().postRunnable(() -> {
SQLiteDatabase database = storage.getDatabase(); SQLiteDatabase database = storage.getDatabase();
@ -443,7 +457,7 @@ public class StoriesStorage {
SQLiteDatabase database = storage.getDatabase(); SQLiteDatabase database = storage.getDatabase();
SQLiteCursor cursor = null; SQLiteCursor cursor = null;
try { try {
long dialogId = updateStory.user_id; long dialogId = DialogObject.getPeerDialogId(updateStory.peer);
int count = 0; int count = 0;
int storyId = updateStory.story.id; int storyId = updateStory.story.id;
boolean storyExist = false; boolean storyExist = false;
@ -495,10 +509,10 @@ public class StoriesStorage {
}); });
} }
public void updateStories(TLRPC.TL_userStories currentStories) { public void updateStories(TLRPC.PeerStories currentStories) {
storage.getStorageQueue().postRunnable(() -> { storage.getStorageQueue().postRunnable(() -> {
for (int i = 0; i < currentStories.stories.size(); i++) { for (int i = 0; i < currentStories.stories.size(); i++) {
updateStoryItemInternal(currentStories.user_id, currentStories.stories.get(i)); updateStoryItemInternal(DialogObject.getPeerDialogId(currentStories.peer), currentStories.stories.get(i));
} }
}); });
} }
@ -565,7 +579,7 @@ public class StoriesStorage {
long dialogId = messagesWithUnknownStories.keyAt(i); long dialogId = messagesWithUnknownStories.keyAt(i);
ArrayList<MessageObject> messageObjects = messagesWithUnknownStories.valueAt(i); ArrayList<MessageObject> messageObjects = messagesWithUnknownStories.valueAt(i);
TLRPC.TL_stories_getStoriesByID request = new TLRPC.TL_stories_getStoriesByID(); TLRPC.TL_stories_getStoriesByID request = new TLRPC.TL_stories_getStoriesByID();
request.user_id = MessagesController.getInstance(currentAccount).getInputUser(dialogId); request.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId);
for (int j = 0; j < messageObjects.size(); j++) { for (int j = 0; j < messageObjects.size(); j++) {
request.id.add(getStoryId(messageObjects.get(j))); request.id.add(getStoryId(messageObjects.get(j)));
} }
@ -612,7 +626,8 @@ public class StoriesStorage {
} }
if (messageObject.type == MessageObject.TYPE_STORY || messageObject.type == MessageObject.TYPE_STORY_MENTION) { if (messageObject.type == MessageObject.TYPE_STORY || messageObject.type == MessageObject.TYPE_STORY_MENTION) {
MessageMediaStoryFull mediaStoryFull = new MessageMediaStoryFull(); MessageMediaStoryFull mediaStoryFull = new MessageMediaStoryFull();
mediaStoryFull.user_id = messageObject.messageOwner.media.user_id; mediaStoryFull.user_id = DialogObject.getPeerDialogId(messageObject.messageOwner.media.peer);
mediaStoryFull.peer = messageObject.messageOwner.media.peer;
mediaStoryFull.id = messageObject.messageOwner.media.id; mediaStoryFull.id = messageObject.messageOwner.media.id;
mediaStoryFull.storyItem = checkExpiredStateLocal(currentAccount, dialogId, storyItem); mediaStoryFull.storyItem = checkExpiredStateLocal(currentAccount, dialogId, storyItem);
mediaStoryFull.via_mention = messageObject.messageOwner.media.via_mention; mediaStoryFull.via_mention = messageObject.messageOwner.media.via_mention;
@ -741,9 +756,9 @@ public class StoriesStorage {
}); });
} }
public void putUserStories(TLRPC.TL_userStories userStories) { public void putPeerStories(TLRPC.PeerStories userStories) {
storage.getStorageQueue().postRunnable(() -> { storage.getStorageQueue().postRunnable(() -> {
putStoriesInternal(userStories.user_id, userStories); putStoriesInternal(DialogObject.getPeerDialogId(userStories.peer), userStories);
}); });
} }

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