From 702839a85366a56fa39caefa4f3f51ce27959d43 Mon Sep 17 00:00:00 2001 From: xaxtix Date: Thu, 24 Aug 2023 22:30:23 +0400 Subject: [PATCH] update to 10.0.3 (3801) --- TMessagesProj/jni/ffmpeg/arm64-v8a/libvpx.a | Bin 1765430 -> 1765638 bytes TMessagesProj/jni/ffmpeg/armeabi-v7a/libvpx.a | Bin 1496286 -> 1496450 bytes TMessagesProj/jni/ffmpeg/x86/libvpx.a | Bin 2146722 -> 2146894 bytes TMessagesProj/jni/ffmpeg/x86_64/libvpx.a | Bin 2521364 -> 2521572 bytes .../jni/tgnet/ConnectionsManager.cpp | 8 +- .../telegram/messenger/AndroidUtilities.java | 19 + .../org/telegram/messenger/BuildVars.java | 4 +- .../messenger/DatabaseMigrationHelper.java | 7 + .../messenger/DownloadController.java | 2 +- .../telegram/messenger/FileLoadOperation.java | 15 +- .../org/telegram/messenger/FileLoader.java | 3 + .../messenger/FileStreamLoadOperation.java | 27 + .../org/telegram/messenger/ImageReceiver.java | 2 +- .../messenger/MessagesController.java | 11 +- .../telegram/messenger/MessagesStorage.java | 4 +- .../messenger/PushListenerController.java | 9 +- .../messenger/SendMessagesHelper.java | 6 +- .../org/telegram/messenger/SharedConfig.java | 18 +- .../org/telegram/messenger/UserConfig.java | 1 + .../video/MediaCodecVideoConvertor.java | 48 +- .../video/VideoPlayerHolderBase.java | 426 ++++++++++++++++ .../telegram/ui/ActionBar/AlertDialog.java | 5 +- .../ui/ActionBar/FloatingToolbar.java | 7 +- .../java/org/telegram/ui/ActionBar/Theme.java | 14 +- .../telegram/ui/Adapters/DialogsAdapter.java | 16 +- .../java/org/telegram/ui/ArticleViewer.java | 225 ++++++++- .../org/telegram/ui/CalendarActivity.java | 2 +- .../org/telegram/ui/Cells/ChatActionCell.java | 2 +- .../telegram/ui/Cells/ChatMessageCell.java | 4 +- .../telegram/ui/Cells/ProfileSearchCell.java | 10 +- .../ui/Cells/ReactedUserHolderView.java | 2 + .../telegram/ui/Cells/StickerEmojiCell.java | 2 +- .../java/org/telegram/ui/ChatActivity.java | 4 +- .../ui/Components/ChatAttachAlert.java | 21 +- .../ChatAttachAlertPhotoLayout.java | 2 - .../ui/Components/EditTextBoldCursor.java | 2 +- .../telegram/ui/Components/FilterShaders.java | 1 + .../Premium/LimitReachedBottomSheet.java | 2 +- .../Premium/PremiumLockIconView.java | 70 +-- .../ui/Components/ProfileGalleryView.java | 4 +- .../ui/Components/SharedMediaLayout.java | 57 ++- .../telegram/ui/Components/StickersAlert.java | 41 +- .../ui/Components/ViewPagerFixed.java | 10 +- .../java/org/telegram/ui/DialogsActivity.java | 5 +- .../org/telegram/ui/GroupCallActivity.java | 25 + .../java/org/telegram/ui/LaunchActivity.java | 20 +- .../java/org/telegram/ui/LoginActivity.java | 14 +- .../java/org/telegram/ui/PhotoViewer.java | 61 ++- .../org/telegram/ui/PinchToZoomHelper.java | 14 +- .../java/org/telegram/ui/ProfileActivity.java | 7 +- .../ui/Stories/DialogStoriesCell.java | 50 +- .../telegram/ui/Stories/PeerStoriesView.java | 191 +++++-- .../ui/Stories/ProfileStoriesView.java | 2 +- .../ui/Stories/SelfStoryViewsPage.java | 25 +- .../ui/Stories/SelfStoryViewsView.java | 3 +- .../ui/Stories/StoriesController.java | 181 +++++-- .../ui/Stories/StoriesListPlaceProvider.java | 20 +- .../telegram/ui/Stories/StoriesStorage.java | 4 +- .../telegram/ui/Stories/StoriesUtilities.java | 47 +- .../telegram/ui/Stories/StoryCaptionView.java | 2 +- .../telegram/ui/Stories/StoryFailView.java | 95 ++++ .../org/telegram/ui/Stories/StoryViewer.java | 468 ++++-------------- .../recorder/CaptionContainerView.java | 2 +- .../ui/Stories/recorder/DownloadButton.java | 2 +- .../ui/Stories/recorder/DraftsController.java | 196 +++++--- .../ui/Stories/recorder/GalleryListView.java | 4 +- .../ui/Stories/recorder/PaintView.java | 1 + .../ui/Stories/recorder/StoryEntry.java | 10 +- .../recorder/StoryPrivacyBottomSheet.java | 19 +- .../ui/Stories/recorder/StoryRecorder.java | 24 +- TMessagesProj/src/main/res/values/strings.xml | 7 +- gradle.properties | 6 +- 72 files changed, 1877 insertions(+), 741 deletions(-) create mode 100644 TMessagesProj/src/main/java/org/telegram/messenger/video/VideoPlayerHolderBase.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryFailView.java diff --git a/TMessagesProj/jni/ffmpeg/arm64-v8a/libvpx.a b/TMessagesProj/jni/ffmpeg/arm64-v8a/libvpx.a index 1d44d64a22c515b02ced12dcef45c284493deb27..a03f8d0370e61a9784172c7a4b4be44ffd2f3aa8 100644 GIT binary patch delta 36530 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 J|I(`T`d{&rvOWL+ diff --git a/TMessagesProj/jni/ffmpeg/armeabi-v7a/libvpx.a b/TMessagesProj/jni/ffmpeg/armeabi-v7a/libvpx.a index c480b6e0c4334f037716a122f1ed41462bdb28b5..59b8bea303634e04318a8da476bf313cc43bbde4 100644 GIT binary patch delta 40245 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 delta 39162 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 diff --git a/TMessagesProj/jni/ffmpeg/x86_64/libvpx.a b/TMessagesProj/jni/ffmpeg/x86_64/libvpx.a index 9b3dd7a78e55a5b8644167c854cf6a18fb9e1498..9e9b5a2f4e3fb03e74c6e54158c17f1be46ee092 100644 GIT binary patch delta 41453 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 = 0; request->startTimeMillis = 0; request->minStartTime = (int32_t) (getCurrentTimeMonotonicMillis() / 1000 + 2); - } else if (error->error_code == 420) { + } else if (error->error_code == 420 && (request->requestFlags & RequestFlagIgnoreFloodWait) == 0 && error->error_message.find("STORY_SEND_FLOOD") == std::string::npos) { int32_t waitTime = 2; static std::string floodWait = "FLOOD_WAIT_"; static std::string slowmodeWait = "SLOWMODE_WAIT_"; - discardResponse = (request->requestFlags & RequestFlagIgnoreFloodWait) == 0; + discardResponse = true; if (error->error_message.find(floodWait) != std::string::npos) { std::string num = error->error_message.substr(floodWait.size(), error->error_message.size() - floodWait.size()); waitTime = atoi(num.c_str()); @@ -3060,7 +3060,9 @@ void ConnectionsManager::updateDcSettings(uint32_t dcNum, bool workaround, bool if (!workaround && updatingDcSettingsAgain && updatingDcSettingsAgainDcNum == dcNum) { updatingDcSettingsAgain = false; for (auto & datacenter : datacenters) { - datacenter.second->resetInitVersion(); + if (datacenter.first == dcNum) { + datacenter.second->resetInitVersion(); + } } updateDcSettings(updatingDcSettingsAgainDcNum, false, false); return; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java index c7f31914a..bc1c7c326 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java @@ -701,6 +701,9 @@ public class AndroidUtilities { public static void getViewPositionInParent(View view, ViewGroup parent, float[] pointPosition) { pointPosition[0] = 0; pointPosition[1] = 0; + if (view == null || parent == null) { + return; + } View currentView = view; while (currentView != parent) { //fix strange offset inside view pager @@ -736,6 +739,22 @@ public class AndroidUtilities { } } + @RequiresApi(api = Build.VERSION_CODES.N) + public static void getBitmapFromSurface(Surface surface, Bitmap surfaceBitmap) { + if (surface == null || !surface.isValid()) { + return; + } + CountDownLatch countDownLatch = new CountDownLatch(1); + PixelCopy.request(surface, surfaceBitmap, copyResult -> { + countDownLatch.countDown(); + }, Utilities.searchQueue.getHandler()); + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + public static float[] getCoordinateInParent(ViewGroup parentView, View view) { float x = 0, y = 0; View child = view; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 5eaa3d40b..bbb0543ae 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -24,8 +24,8 @@ public class BuildVars { public static boolean USE_CLOUD_STRINGS = true; public static boolean CHECK_UPDATES = true; public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29; - public static int BUILD_VERSION = 3793; - public static String BUILD_VERSION_STRING = "10.0.1"; + public static int BUILD_VERSION = 3801; + public static String BUILD_VERSION_STRING = "10.0.3"; public static int APP_ID = 4; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java b/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java index 885a008a5..9011aff2f 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java @@ -1333,6 +1333,13 @@ public class DatabaseMigrationHelper { version = 128; } + if (version == 128) { + database.executeFast("ALTER TABLE story_drafts ADD COLUMN type INTEGER default 0").stepThis().dispose(); + + database.executeFast("PRAGMA user_version = 129").stepThis().dispose(); + version = 129; + } + return version; } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/DownloadController.java b/TMessagesProj/src/main/java/org/telegram/messenger/DownloadController.java index e32ed9e9c..fb571fe8b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/DownloadController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/DownloadController.java @@ -92,7 +92,7 @@ public class DownloadController extends BaseController implements NotificationCe public int maxVideoBitrate; public Preset(int[] m, long p, long v, long f, boolean pv, boolean pm, boolean e, boolean l, int bitrate, boolean preloadStories) { - System.arraycopy(m, 0, mask, 0, mask.length); + System.arraycopy(m, 0, mask, 0, Math.max(m.length, mask.length)); sizes[PRESET_SIZE_NUM_PHOTO] = p; sizes[PRESET_SIZE_NUM_VIDEO] = v; sizes[PRESET_SIZE_NUM_DOCUMENT] = f; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java index 8ac61b73c..1fb787d2d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java @@ -74,9 +74,18 @@ public class FileLoadOperation { public boolean checkPrefixPreloadFinished() { if (preloadPrefixSize > 0 && downloadedBytes > preloadPrefixSize) { long minStart = Long.MAX_VALUE; - for (int b = 0; b < notLoadedBytesRanges.size(); b++) { - Range range = notLoadedBytesRanges.get(b); - minStart = Math.min(minStart, range.start); + ArrayList array = notLoadedBytesRanges; + if (array == null) { + return true; + } + try { + for (int b = 0; b < array.size(); b++) { + Range range = array.get(b); + minStart = Math.min(minStart, range.start); + } + } catch (Throwable e) { + FileLog.e(e); + return true; } if (minStart > preloadPrefixSize) { return true; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java index 53ee7e570..af76fdd3e 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java @@ -309,6 +309,9 @@ public class FileLoader extends BaseController { } public void cancelFileUpload(final String location, final boolean enc) { + if (location == null) { + return; + } fileLoaderQueue.postRunnable(() -> { FileUploadOperation operation; if (!enc) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileStreamLoadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileStreamLoadOperation.java index f62f59fd2..b99a1a45a 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileStreamLoadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileStreamLoadOperation.java @@ -24,6 +24,8 @@ import java.io.EOFException; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; @@ -226,4 +228,29 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO priorityMap.put(document.id, priority); } } + + @Nullable + public static Uri prepareUri(int currentAccount, TLRPC.Document document, Object parent) { + String attachFileName = FileLoader.getAttachFileName(document); + File file = FileLoader.getInstance(currentAccount).getPathToAttach(document); + + if (file != null && file.exists()) { + return Uri.fromFile(file); + } + try { + String params = "?account=" + currentAccount + + "&id=" + document.id + + "&hash=" + document.access_hash + + "&dc=" + document.dc_id + + "&size=" + document.size + + "&mime=" + URLEncoder.encode(document.mime_type, "UTF-8") + + "&rid=" + FileLoader.getInstance(currentAccount).getFileReference(parent) + + "&name=" + URLEncoder.encode(FileLoader.getDocumentFileName(document), "UTF-8") + + "&reference=" + Utilities.bytesToHex(document.file_reference != null ? document.file_reference : new byte[0]); + return Uri.parse("tg://" + attachFileName + params); + } catch (UnsupportedEncodingException e) { + FileLog.e(e); + } + return null; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java b/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java index 23ac4df39..3c21811e8 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java @@ -2249,7 +2249,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg } public boolean hasNotThumb() { - return currentImageDrawable != null || currentMediaDrawable != null || staticThumbDrawable instanceof VectorAvatarThumbDrawable; + return currentImageDrawable != null || currentMediaDrawable != null || staticThumbDrawable instanceof VectorAvatarThumbDrawable || (staticThumbDrawable != null && currentImageKey == null && currentMediaKey == null); } public boolean hasStaticThumb() { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index 77c565936..9de875bf8 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -143,7 +143,7 @@ public class MessagesController extends BaseController implements NotificationCe public StoriesController storiesController; private boolean hasArchivedChats; private boolean hasStories; - public long storiesChangelogUserId; + public long storiesChangelogUserId = 777000; public static TLRPC.Peer getPeerFromInputPeer(TLRPC.InputPeer peer) { if (peer.chat_id != 0) { @@ -395,10 +395,9 @@ public class MessagesController extends BaseController implements NotificationCe try { SQLiteDatabase database = MessagesStorage.getInstance(currentAccount).getDatabase(); if (database != null) { - if (data == null) { - database.executeFast("DELETE FROM app_config").stepThis().dispose(); - } else { - SQLitePreparedStatement state = database.executeFast("REPLACE INTO app_config VALUES(?)"); + database.executeFast("DELETE FROM app_config").stepThis().dispose(); + if (data != null) { + SQLitePreparedStatement state = database.executeFast("INSERT INTO app_config VALUES(?)"); state.requery(); NativeByteBuffer buffer = new NativeByteBuffer(data.getObjectSize()); data.serializeToStream(buffer); @@ -16238,7 +16237,7 @@ public class MessagesController extends BaseController implements NotificationCe } } } else if (baseUpdate instanceof TLRPC.TL_updateSentStoryReaction) { - storiesController.updateStoryReaction(((TLRPC.TL_updateSentStoryReaction) baseUpdate).user_id, ((TLRPC.TL_updateSentStoryReaction) baseUpdate).story_id, ((TLRPC.TL_updateSentStoryReaction) baseUpdate).reaction); + getStoriesController().updateStoryReaction(((TLRPC.TL_updateSentStoryReaction) baseUpdate).user_id, ((TLRPC.TL_updateSentStoryReaction) baseUpdate).story_id, ((TLRPC.TL_updateSentStoryReaction) baseUpdate).reaction); } } if (editor != null) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java index 2fd1bc172..b9b1a4224 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java @@ -95,7 +95,7 @@ public class MessagesStorage extends BaseController { } } - public final static int LAST_DB_VERSION = 128; + public final static int LAST_DB_VERSION = 129; private boolean databaseMigrationInProgress; public boolean showClearDatabaseAlert; private LongSparseIntArray dialogIsForum = new LongSparseIntArray(); @@ -678,7 +678,7 @@ public class MessagesStorage extends BaseController { database.executeFast("CREATE TABLE profile_stories (dialog_id INTEGER, story_id INTEGER, data BLOB, PRIMARY KEY(dialog_id, story_id));").stepThis().dispose(); database.executeFast("CREATE TABLE archived_stories (story_id INTEGER PRIMARY KEY, data BLOB);").stepThis().dispose(); - database.executeFast("CREATE TABLE story_drafts (id INTEGER PRIMARY KEY, date INTEGER, data BLOB);").stepThis().dispose(); + database.executeFast("CREATE TABLE story_drafts (id INTEGER PRIMARY KEY, date INTEGER, data BLOB, type INTEGER);").stepThis().dispose(); database.executeFast("CREATE TABLE story_pushes (uid INTEGER, sid INTEGER, date INTEGER, localName TEXT, flags INTEGER, expire_date INTEGER, PRIMARY KEY(uid, sid));").stepThis().dispose(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java b/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java index 56d685a26..cc3d5709e 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java @@ -77,12 +77,9 @@ public class PushListenerController { req.events.add(event); sendStat = false; - ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { - if (error != null) { - SharedConfig.pushStatSent = true; - SharedConfig.saveConfig(); - } - })); + SharedConfig.pushStatSent = true; + SharedConfig.saveConfig(); + ConnectionsManager.getInstance(currentAccount).sendRequest(req, null); } AndroidUtilities.runOnUIThread(() -> MessagesController.getInstance(currentAccount).registerForPush(pushType, token)); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java index 450fdd4ec..de8d646dc 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java @@ -4736,11 +4736,15 @@ public class SendMessagesHelper extends BaseController implements NotificationCe reqSend.reply_to = SendMessagesHelper.creteReplyInput(replyToTopMsg.getId()); reqSend.flags |= 512; } + if (newMsg.from_id != null) { reqSend.send_as = getMessagesController().getInputPeer(newMsg.from_id); } reqSend.hide_via = !params.containsKey("bot"); - if (newMsg.reply_to != null && newMsg.reply_to.reply_to_msg_id != 0) { + if (replyToStoryItem != null) { + reqSend.reply_to = creteReplyInput(replyToStoryItem); + reqSend.flags |= 1; + } else if (newMsg.reply_to != null && newMsg.reply_to.reply_to_msg_id != 0) { reqSend.flags |= 1; reqSend.reply_to = SendMessagesHelper.creteReplyInput(newMsg.reply_to.reply_to_msg_id); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java index ab1535634..5cbfdeb02 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java @@ -735,7 +735,7 @@ public class SharedConfig { if (updateVersionString == null) { updateVersionString = BuildVars.BUILD_VERSION_STRING; } - if (update.version == null || updateVersionString.compareTo(update.version) >= 0) { + if (update.version == null || versionBiggerOrEqual(updateVersionString, update.version)) { return false; } pendingAppUpdate = update; @@ -744,6 +744,22 @@ public class SharedConfig { return true; } + // returns a >= b + private static boolean versionBiggerOrEqual(String a, String b) { + String[] partsA = a.split("\\."); + String[] partsB = b.split("\\."); + for (int i = 0; i < Math.min(partsA.length, partsB.length); ++i) { + int numA = Integer.parseInt(partsA[i]); + int numB = Integer.parseInt(partsB[i]); + if (numA < numB) { + return false; + } else if (numA > numB) { + return true; + } + } + return true; + } + public static boolean checkPasscode(String passcode) { if (passcodeSalt.length == 0) { boolean result = Utilities.MD5(passcode).equals(passcodeHash); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index 589e88deb..7a55d21ff 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java @@ -272,6 +272,7 @@ public class UserConfig extends BaseController { getMediaDataController().loadPremiumPromo(false); getMediaDataController().loadReactions(false, true); + getMessagesController().getStoriesController().invalidateStoryLimit(); }); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/video/MediaCodecVideoConvertor.java b/TMessagesProj/src/main/java/org/telegram/messenger/video/MediaCodecVideoConvertor.java index 2bff56b50..cec8e3a6c 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/video/MediaCodecVideoConvertor.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/video/MediaCodecVideoConvertor.java @@ -349,7 +349,6 @@ public class MediaCodecVideoConvertor { long lastFramePts = -1; if (videoIndex >= 0) { - try { long videoTime = -1; boolean outputDone = false; @@ -444,27 +443,22 @@ public class MediaCodecVideoConvertor { outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, framerate); outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); -// boolean hasHDR = false; -// int hdrType = 0; -// int colorTransfer = 0, colorStandard = 0, colorRange = 0; -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { -// if (videoFormat.containsKey(MediaFormat.KEY_COLOR_TRANSFER)) { -// colorTransfer = videoFormat.getInteger(MediaFormat.KEY_COLOR_TRANSFER); -// } -// if (videoFormat.containsKey(MediaFormat.KEY_COLOR_STANDARD)) { -// colorStandard = videoFormat.getInteger(MediaFormat.KEY_COLOR_STANDARD); -// } -// if (videoFormat.containsKey(MediaFormat.KEY_COLOR_RANGE)) { -// colorRange = videoFormat.getInteger(MediaFormat.KEY_COLOR_RANGE); -// } -// if (videoFormat.containsKey(MediaFormat.KEY_HDR_STATIC_INFO)) { -// ByteBuffer bytes = videoFormat.getByteBuffer(MediaFormat.KEY_HDR_STATIC_INFO); -// } -// if ((colorTransfer == MediaFormat.COLOR_TRANSFER_ST2084 || colorTransfer == MediaFormat.COLOR_TRANSFER_HLG) && colorStandard == MediaFormat.COLOR_STANDARD_BT2020) { -// hasHDR = true; -// hdrType = colorTransfer == MediaFormat.COLOR_TRANSFER_HLG ? 1 : 2; -// } -// } + boolean hasHDR = false; + int colorTransfer = 0, colorStandard = 0, colorRange = 0; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (videoFormat.containsKey(MediaFormat.KEY_COLOR_TRANSFER)) { + colorTransfer = videoFormat.getInteger(MediaFormat.KEY_COLOR_TRANSFER); + } + if (videoFormat.containsKey(MediaFormat.KEY_COLOR_STANDARD)) { + colorStandard = videoFormat.getInteger(MediaFormat.KEY_COLOR_STANDARD); + } + if (videoFormat.containsKey(MediaFormat.KEY_COLOR_RANGE)) { + colorRange = videoFormat.getInteger(MediaFormat.KEY_COLOR_RANGE); + } + if ((colorTransfer == MediaFormat.COLOR_TRANSFER_ST2084 || colorTransfer == MediaFormat.COLOR_TRANSFER_HLG) && colorStandard == MediaFormat.COLOR_STANDARD_BT2020) { + hasHDR = true; + } + } if (Build.VERSION.SDK_INT < 23 && Math.min(h, w) <= 480 && !isAvatar) { if (bitrate > 921600) { @@ -482,6 +476,15 @@ public class MediaCodecVideoConvertor { encoder.start(); outputSurface = new OutputSurface(savedFilterState, null, paintPath, mediaEntities, cropState, resultWidth, resultHeight, originalWidth, originalHeight, rotationValue, framerate, false, gradientTopColor, gradientBottomColor, hdrInfo, parts); + if (hdrInfo == null && outputSurface.supportsEXTYUV() && hasHDR) { + hdrInfo = new StoryEntry.HDRInfo(); + hdrInfo.colorTransfer = colorTransfer; + hdrInfo.colorStandard = colorStandard; + hdrInfo.colorRange = colorRange; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + outputFormat.setInteger(MediaFormat.KEY_COLOR_TRANSFER, MediaFormat.COLOR_TRANSFER_SDR_VIDEO); + } + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && hdrInfo != null && hdrInfo.getHDRType() != 0 && outputSurface.supportsEXTYUV()) { outputSurface.changeFragmentShader( hdrFragmentShader(originalWidth, originalHeight, resultWidth, resultHeight, true, hdrInfo), @@ -1164,6 +1167,7 @@ public class MediaCodecVideoConvertor { } shaderCode = shaderCode.replace("$dstWidth", dstWidth + ".0"); shaderCode = shaderCode.replace("$dstHeight", dstHeight + ".0"); + // TODO(@dkaraush): use minlum/maxlum return shaderCode + "\n" + "in vec2 vTextureCoord;\n" + "out vec4 fragColor;\n" + diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/video/VideoPlayerHolderBase.java b/TMessagesProj/src/main/java/org/telegram/messenger/video/VideoPlayerHolderBase.java new file mode 100644 index 000000000..5e30a3317 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/messenger/video/VideoPlayerHolderBase.java @@ -0,0 +1,426 @@ +package org.telegram.messenger.video; + +import android.graphics.Bitmap; +import android.graphics.Paint; +import android.graphics.SurfaceTexture; +import android.net.Uri; +import android.os.Build; +import android.view.SurfaceView; +import android.view.TextureView; + +import com.google.android.exoplayer2.ExoPlayer; + +import org.telegram.messenger.AndroidUtilities; +import org.telegram.messenger.DispatchQueue; +import org.telegram.messenger.FileLoader; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.FileStreamLoadOperation; +import org.telegram.messenger.Utilities; +import org.telegram.tgnet.TLRPC; +import org.telegram.ui.Components.VideoPlayer; + +//used for player in background thread +public class VideoPlayerHolderBase { + + public boolean paused; + public TLRPC.Document document; + VideoPlayer videoPlayer; + Runnable initRunnable; + volatile boolean released; + public boolean firstFrameRendered; + + public float progress; + int lastState; + public long currentPosition; + private int currentAccount; + long playerDuration; + boolean audioDisabled; + public boolean stubAvailable; + + private TextureView textureView; + private SurfaceView surfaceView; + public Bitmap playerStubBitmap; + public Paint playerStubPaint; + public long pendingSeekTo; + Uri contentUri; + + public VideoPlayerHolderBase() { + + } + + public VideoPlayerHolderBase with(SurfaceView surfaceView) { + this.surfaceView = surfaceView; + this.textureView = null; + return this; + } + + public VideoPlayerHolderBase with(TextureView textureView) { + this.surfaceView = null; + this.textureView = textureView; + return this; + } + + + final DispatchQueue dispatchQueue = Utilities.getOrCreatePlayerQueue(); + public Uri uri; + + Runnable progressRunnable = new Runnable() { + @Override + public void run() { + if (videoPlayer != null) { + if (lastState == ExoPlayer.STATE_ENDED) { + progress = 1f; + } else { + currentPosition = videoPlayer.getCurrentPosition(); + playerDuration = videoPlayer.getDuration(); + } + if (lastState == ExoPlayer.STATE_READY) { + dispatchQueue.cancelRunnable(progressRunnable); + dispatchQueue.postRunnable(progressRunnable, 16); + } + } + } + }; + + long startTime; + + public void preparePlayer(Uri uri, boolean audioDisabled) { + this.audioDisabled = audioDisabled; + this.currentAccount = currentAccount; + this.contentUri = uri; + paused = true; + if (initRunnable != null) { + dispatchQueue.cancelRunnable(initRunnable); + } + dispatchQueue.postRunnable(initRunnable = () -> { + if (released) { + return; + } + ensurePlayerCreated(audioDisabled); + videoPlayer.preparePlayer(uri, "other", FileLoader.PRIORITY_LOW); + videoPlayer.setPlayWhenReady(false); + videoPlayer.setWorkerQueue(dispatchQueue); + }); + } + + public void start(boolean paused, Uri uri, long t, boolean audioDisabled) { + startTime = System.currentTimeMillis(); + this.audioDisabled = audioDisabled; + this.paused = paused; + dispatchQueue.postRunnable(initRunnable = () -> { + if (released) { + return; + } + if (videoPlayer == null) { + ensurePlayerCreated(audioDisabled); + videoPlayer.preparePlayer(uri, "other"); + videoPlayer.setWorkerQueue(dispatchQueue); + if (!paused) { + if (surfaceView != null) { + videoPlayer.setSurfaceView(surfaceView); + } else { + videoPlayer.setTextureView(textureView); + } + videoPlayer.setPlayWhenReady(true); + } + } else { + if (!paused) { + if (surfaceView != null) { + videoPlayer.setSurfaceView(surfaceView); + } else { + videoPlayer.setTextureView(textureView); + } + videoPlayer.play(); + } + } + if (t > 0) { + videoPlayer.seekTo(t); + } + + // videoPlayer.setVolume(isInSilentMode ? 0 : 1f); + AndroidUtilities.runOnUIThread(() -> initRunnable = null); + }); + } + + private void ensurePlayerCreated(boolean audioDisabled) { + if (videoPlayer != null) { + videoPlayer.releasePlayer(true); + } + videoPlayer = new VideoPlayer(false, audioDisabled); + videoPlayer.setDelegate(new VideoPlayer.VideoPlayerDelegate() { + @Override + public void onStateChanged(boolean playWhenReady, int playbackState) { + lastState = playbackState; + if (playbackState == ExoPlayer.STATE_READY || playbackState == ExoPlayer.STATE_BUFFERING) { + dispatchQueue.cancelRunnable(progressRunnable); + dispatchQueue.postRunnable(progressRunnable); + } else if (playbackState == ExoPlayer.STATE_ENDED) { + if (needRepeat()) { + progress = 0; + videoPlayer.seekTo(0); + videoPlayer.play(); + } else { + progress = 1f; + } + } + VideoPlayerHolderBase.this.onStateChanged(playWhenReady, playbackState); + } + + @Override + public void onError(VideoPlayer player, Exception e) { + FileLog.e(e); + } + + @Override + public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) { + + } + + @Override + public void onRenderedFirstFrame() { + AndroidUtilities.runOnUIThread(() -> { + if (released ) { + return; + } + VideoPlayerHolderBase.this.onRenderedFirstFrame(); + + if (onReadyListener != null) { + onReadyListener.run(); + onReadyListener = null; + } + }, 16); + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { + + } + + @Override + public boolean onSurfaceDestroyed(SurfaceTexture surfaceTexture) { + return false; + } + }); + videoPlayer.setIsStory(); + } + + + private Runnable onReadyListener; + public void setOnReadyListener(Runnable listener) { + onReadyListener = listener; + } + + public boolean release(Runnable whenReleased) { + TLRPC.Document document = this.document; + if (document != null) { + int priority = FileStreamLoadOperation.getStreamPrioriy(document); + if (priority != FileLoader.PRIORITY_LOW) { + FileStreamLoadOperation.setPriorityForDocument(document, FileLoader.PRIORITY_LOW); + FileLoader.getInstance(currentAccount).changePriority(FileLoader.PRIORITY_LOW, document, null, null, null, null, null); + } + } + released = true; + dispatchQueue.cancelRunnable(initRunnable); + initRunnable = null; + dispatchQueue.postRunnable(() -> { + if (videoPlayer != null) { + videoPlayer.setTextureView(null); + videoPlayer.setSurfaceView(null); + videoPlayer.releasePlayer(false); + } + if (document != null) { + FileLoader.getInstance(currentAccount).cancelLoadFile(document); + } + if (whenReleased != null) { + AndroidUtilities.runOnUIThread(whenReleased); + } + videoPlayer = null; + }); + if (playerStubBitmap != null) { + AndroidUtilities.recycleBitmap(playerStubBitmap); + playerStubBitmap = null; + } + return true; + } + + public void pause() { + if (released) { + return; + } + if (paused) { + return; + } + paused = true; + if (surfaceView != null && firstFrameRendered && surfaceView.getHolder().getSurface().isValid()) { + stubAvailable = true; + if (playerStubBitmap == null) { + playerStubBitmap = Bitmap.createBitmap(720, 1280, Bitmap.Config.ARGB_8888); + playerStubPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + AndroidUtilities.getBitmapFromSurface(surfaceView, playerStubBitmap); + } + } + dispatchQueue.postRunnable(() -> { + if (videoPlayer != null) { + videoPlayer.pause(); + } + }); + } + + public void play() { + if (released) { + return; + } + if (!paused) { + return; + } + paused = false; + dispatchQueue.postRunnable(() -> { + if (videoPlayer != null) { + if (surfaceView != null) { + videoPlayer.setSurfaceView(surfaceView); + } else { + videoPlayer.setTextureView(textureView); + } + if (pendingSeekTo > 0) { + videoPlayer.seekTo(pendingSeekTo); + pendingSeekTo = 0; + } + videoPlayer.setPlayWhenReady(true); + } + }); + } + + public void setAudioEnabled(boolean enabled, boolean prepared) { + boolean disabled = !enabled; + if (audioDisabled == disabled) { + return; + } + audioDisabled = disabled; + dispatchQueue.postRunnable(() -> { + if (videoPlayer == null) { + return; + } + boolean playing = videoPlayer.isPlaying(); + if (enabled && !videoPlayer.createdWithAudioTrack()) { + //release and create new with audio track + videoPlayer.pause(); + long position = videoPlayer.getCurrentPosition(); + videoPlayer.releasePlayer(false); + videoPlayer = null; + ensurePlayerCreated(audioDisabled); + videoPlayer.preparePlayer(uri, "other"); + videoPlayer.setWorkerQueue(dispatchQueue); + if (!prepared) { + if (surfaceView != null) { + videoPlayer.setSurfaceView(surfaceView); + } else { + videoPlayer.setTextureView(textureView); + } + } + // videoPlayer.setTextureView(textureView); + videoPlayer.seekTo(position + 50); + if (playing && !prepared) { + videoPlayer.setPlayWhenReady(true); + videoPlayer.play(); + } else { + videoPlayer.setPlayWhenReady(false); + videoPlayer.pause(); + } + } else { + videoPlayer.setVolume(enabled ? 1f : 0); + } + }); + } + + public float getPlaybackProgress(long totalDuration) { + if (lastState == ExoPlayer.STATE_ENDED) { + progress = 1f; + } else { + float localProgress; + if (totalDuration != 0) { + localProgress = currentPosition / (float) totalDuration; + } else { + localProgress = currentPosition / (float) playerDuration; + } + if (localProgress < progress) { + return progress; + } + progress = localProgress; + } + return progress; + } + + public void loopBack() { + progress = 0; + lastState = ExoPlayer.STATE_IDLE; + dispatchQueue.postRunnable(() -> { + if (videoPlayer != null) { + videoPlayer.seekTo(0); + } + progress = 0; + currentPosition = 0; + }); + } + + public void setVolume(float v) { + dispatchQueue.postRunnable(() -> { + if (videoPlayer != null) { + videoPlayer.setVolume(v); + } + }); + } + + public boolean isBuffering() { + return !released && lastState == ExoPlayer.STATE_BUFFERING; + } + + public long getCurrentPosition() { + return currentPosition; + } + + public long getDuration() { + return playerDuration; + } + + public boolean isPlaying() { + return !paused; + } + + public void onRenderedFirstFrame() { + + } + + public void onStateChanged(boolean playWhenReady, int playbackState) { + + } + + public boolean needRepeat() { + return false; + } + + public void seekTo(long position) { + dispatchQueue.postRunnable(() -> { + if (videoPlayer == null) { + pendingSeekTo = position; + return; + } + videoPlayer.seekTo(position); + }); + } + + public Uri getCurrentUri() { + return contentUri; + } + + public void setPlaybackSpeed(float currentVideoSpeed) { + dispatchQueue.postRunnable(() -> { + if (videoPlayer == null) { + return; + } + videoPlayer.setPlaybackSpeed(currentVideoSpeed); + }); + + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java index a393aef40..d1f4ba8c5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java @@ -56,6 +56,7 @@ import androidx.core.graphics.ColorUtils; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.Emoji; import org.telegram.messenger.FileLog; +import org.telegram.messenger.LiteMode; import org.telegram.messenger.LocaleController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; @@ -271,10 +272,10 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati super(context, R.style.TransparentDialog); this.resourcesProvider = resourcesProvider; - blurredNativeBackground = supportsNativeBlur() && progressViewStyle == ALERT_TYPE_MESSAGE; backgroundColor = getThemedColor(Theme.key_dialogBackground); final boolean isDark = AndroidUtilities.computePerceivedBrightness(backgroundColor) < 0.721f; - blurredBackground = blurredNativeBackground || !supportsNativeBlur() && SharedConfig.getDevicePerformanceClass() >= SharedConfig.PERFORMANCE_CLASS_HIGH && isDark; + blurredNativeBackground = supportsNativeBlur() && progressViewStyle == ALERT_TYPE_MESSAGE; + blurredBackground = (blurredNativeBackground || !supportsNativeBlur() && SharedConfig.getDevicePerformanceClass() >= SharedConfig.PERFORMANCE_CLASS_HIGH && LiteMode.isEnabled(LiteMode.FLAG_CHAT_BLUR)) && isDark; backgroundPaddings = new Rect(); if (progressStyle != ALERT_TYPE_SPINNER || blurredBackground) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/FloatingToolbar.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/FloatingToolbar.java index aa2f89f45..19fdccd9c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/FloatingToolbar.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/FloatingToolbar.java @@ -65,6 +65,7 @@ import android.widget.TextView; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.BotWebViewVibrationEffect; import org.telegram.messenger.LocaleController; +import org.telegram.messenger.MessagesController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; @@ -989,8 +990,12 @@ public final class FloatingToolbar { }); } final int size = menuItems.size(); + final boolean premiumLocked = MessagesController.getInstance(UserConfig.selectedAccount).premiumLocked; for (int i = 0; i < size; i++) { - overflowPanelAdapter.add(menuItems.get(i)); + final MenuItem menuItem = menuItems.get(i); + if (!premiumOptions.contains(menuItem.getItemId()) || !premiumLocked) { + overflowPanelAdapter.add(menuItem); + } } mOverflowPanel.setAdapter(overflowPanelAdapter); if (mOpenOverflowUpwards) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java index b932f502a..84b2dff5e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java @@ -1067,7 +1067,7 @@ public class Theme { for (int a = 0, N = accents.size(); a < N; a++) { ThemeAccent accent = accents.get(a); File wallpaper = accent.getPathToWallpaper(); - if (wallpaper != null && wallpaper.exists()) { + if (wallpaper != null && wallpaper.length() > 0) { accents.remove(a); a--; N--; @@ -9580,7 +9580,9 @@ public class Theme { int gradientToColor2 = currentColors.get(key_chat_wallpaper_gradient_to2); int gradientToColor1 = currentColors.get(key_chat_wallpaper_gradient_to1); + boolean bitmapCreated = false; if (wallpaperFile != null && wallpaperFile.exists()) { + bitmapCreated = true; try { if (backgroundColor != 0 && gradientToColor1 != 0 && gradientToColor2 != 0) { MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(backgroundColor, gradientToColor1, gradientToColor2, gradientToColor3, false); @@ -9592,6 +9594,9 @@ public class Theme { patternBitmap = patternBitmap.copy(Bitmap.Config.ALPHA_8, false); toRecycle.recycle(); } + if (patternBitmap == null) { + bitmapCreated = false; + } motionBackgroundDrawable.setPatternBitmap(intensity, patternBitmap); motionBackgroundDrawable.setPatternColorFilter(motionBackgroundDrawable.getPatternColor()); settings.wallpaper = motionBackgroundDrawable; @@ -9604,6 +9609,9 @@ public class Theme { } catch (Throwable e) { FileLog.e(e); } + } + if (bitmapCreated) { + } else if (backgroundColor != 0) { int rotation = currentColors.get(key_chat_wallpaper_gradient_rotation, -1); if (rotation == -1) { @@ -9620,7 +9628,9 @@ public class Theme { FileOutputStream stream = null; try { stream = new FileOutputStream(wallpaperFile); - patternBitmap.compress(Bitmap.CompressFormat.PNG, 90, stream); + Bitmap bitmap = patternBitmap.copy(Bitmap.Config.ARGB_8888, true); + bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream); + bitmap.recycle(); stream.close(); } catch (Exception e) { FileLog.e(e); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java index d718af337..c45120211 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java @@ -492,15 +492,13 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements } else { tabsTranslation = 0; } - if (hasHiddenArchive && position == 0 && recyclerListView.getPaddingTop() - view.getTop() - view.getMeasuredHeight() + tabsTranslation < 0) { - position = 1; - offset = tabsTranslation; + if (recyclerListView.getScrollState() != RecyclerView.SCROLL_STATE_DRAGGING) { + if (hasHiddenArchive && position == 0 && recyclerListView.getPaddingTop() - view.getTop() - view.getMeasuredHeight() + tabsTranslation < 0) { + position = 1; + offset = tabsTranslation; + } + layoutManager.scrollToPositionWithOffset(position, (int) offset); } -// if (firstUpdate && hasStories) { -// offset -= AndroidUtilities.dp(DialogStoriesCell.HEIGHT_IN_DP); -// } -// firstUpdate = false; - layoutManager.scrollToPositionWithOffset(position, (int) offset); } } DiffUtil.calculateDiff(new DiffUtil.Callback() { @@ -1110,7 +1108,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements } } - parentFragment.getOrCreateStoryViewer().open(mContext, null, peerIds, 0, null, null, StoriesListPlaceProvider.of(recyclerListView), false); + parentFragment.getOrCreateStoryViewer().open(mContext, null, peerIds, 0, null, null, StoriesListPlaceProvider.of(recyclerListView, true), false); } public void setIsTransitionSupport() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java index 504935764..b43cad665 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.database.DataSetObserver; +import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; @@ -65,6 +66,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.SoundEffectConstants; +import android.view.Surface; import android.view.TextureView; import android.view.VelocityTracker; import android.view.View; @@ -112,6 +114,7 @@ import org.telegram.messenger.DownloadController; import org.telegram.messenger.Emoji; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; +import org.telegram.messenger.FileStreamLoadOperation; import org.telegram.messenger.ImageLoader; import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageReceiver; @@ -127,6 +130,7 @@ import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; import org.telegram.messenger.WebFile; import org.telegram.messenger.browser.Browser; +import org.telegram.messenger.video.VideoPlayerHolderBase; import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLRPC; @@ -171,6 +175,7 @@ import org.telegram.ui.Components.TextPaintUrlSpan; import org.telegram.ui.Components.TextPaintWebpageUrlSpan; import org.telegram.ui.Components.TranslateAlert2; import org.telegram.ui.Components.TypefaceSpan; +import org.telegram.ui.Components.VideoPlayer; import org.telegram.ui.Components.WebPlayerView; import java.io.File; @@ -830,6 +835,11 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg protected void onDetachedFromWindow() { super.onDetachedFromWindow(); attachedToWindow = false; + if (videoPlayer != null) { + videoPlayer.release(null); + videoPlayer = null; + } + currentPlayer = null; } @Override @@ -3042,6 +3052,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg windowView.setClipChildren(true); windowView.setFocusable(false); containerView = new FrameLayout(activity) { + @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { if (windowView.movingPage) { @@ -3107,7 +3118,8 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg windowView.addView(fullscreenVideoContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); fullscreenAspectRatioView = new AspectRatioFrameLayout(activity); - fullscreenAspectRatioView.setVisibility(View.GONE); + fullscreenAspectRatioView.setVisibility(View.VISIBLE); + fullscreenAspectRatioView.setBackgroundColor(Color.BLACK); fullscreenVideoContainer.addView(fullscreenAspectRatioView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.CENTER)); fullscreenTextureView = new TextureView(activity); @@ -3169,6 +3181,12 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg setCurrentHeaderHeight((int) (windowView.startMovingHeaderHeight + (AndroidUtilities.dp(56) - windowView.startMovingHeaderHeight) * progress)); } } + + @Override + protected void dispatchDraw(Canvas canvas) { + checkVideoPlayer(); + super.dispatchDraw(canvas); + } }; ((DefaultItemAnimator) listView[i].getItemAnimator()).setDelayAnimations(false); listView[i].setLayoutManager(layoutManager[i] = new LinearLayoutManager(parentActivity, LinearLayoutManager.VERTICAL, false)); @@ -3286,6 +3304,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg if (recyclerView.getChildCount() == 0) { return; } + recyclerView.invalidate(); textSelectionHelper.onParentScrolled(); headerView.invalidate(); checkScroll(dy); @@ -3738,13 +3757,10 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg }); containerView.addView(textSelectionHelper.getOverlayView(activity)); - pinchToZoomHelper = new PinchToZoomHelper(containerView, windowView); - pinchToZoomHelper.setClipBoundsListener(new PinchToZoomHelper.ClipBoundsListener() { - @Override - public void getClipTopBottom(float[] topBottom) { - topBottom[0] = currentHeaderHeight; - topBottom[1] = listView[0].getMeasuredHeight(); - } + pinchToZoomHelper = new PinchToZoomHelper(containerView, containerView); + pinchToZoomHelper.setClipBoundsListener(topBottom -> { + topBottom[0] = currentHeaderHeight; + topBottom[1] = listView[0].getMeasuredHeight(); }); pinchToZoomHelper.setCallback(new PinchToZoomHelper.Callback() { @Override @@ -3757,6 +3773,43 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg updatePaintColors(); } + VideoPlayerHolderBase videoPlayer; + BlockVideoCell currentPlayer; + + private void checkVideoPlayer() { + RecyclerView recyclerView = listView[0]; + if (recyclerView == null && attachedToWindow) { + return; + } + BlockVideoCell bestView = null; + float bestViewCenterX = 0; + float parentCenterX = recyclerView.getMeasuredHeight() / 2f; + for (int i = 0; i < recyclerView.getChildCount(); i++) { + View child = recyclerView.getChildAt(i); + if (child instanceof BlockVideoCell) { + float centerX = child.getTop() + child.getMeasuredHeight() / 2f; + if (bestView == null || (Math.abs(parentCenterX - centerX) < (Math.abs(parentCenterX - bestViewCenterX)))) { + bestView = (BlockVideoCell) child; + bestViewCenterX = centerX; + } + } + } + boolean allowPlayer = !PhotoViewer.getInstance().isVisibleOrAnimating(); + if (!allowPlayer || (currentPlayer != null && currentPlayer != bestView && videoPlayer != null)) { + if (videoPlayer != null) { + currentPlayer.playFrom = videoPlayer.getCurrentPosition(); + videoPlayer.release(null); + } + videoPlayer = null; + currentPlayer = null; + } + if (allowPlayer && bestView != null) { + bestView.startVideoPlayer(); + currentPlayer = bestView; + } + + } + private void showSearch(boolean show) { if (searchContainer == null || (searchContainer.getTag() != null) == show) { return; @@ -4054,7 +4107,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg return; } int maxHeight = AndroidUtilities.dp(56); - int minHeight = Math.max(AndroidUtilities.statusBarHeight, AndroidUtilities.dp(24)); + int minHeight = AndroidUtilities.dp(24); if (newHeight < minHeight) { newHeight = minHeight; @@ -5976,9 +6029,12 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg private class BlockVideoCell extends FrameLayout implements DownloadController.FileDownloadProgressListener, TextSelectionHelper.ArticleSelectableView { + public long playFrom; private DrawingText captionLayout; private DrawingText creditLayout; private ImageReceiver imageView; + private AspectRatioFrameLayout aspectRatioFrameLayout; + private TextureView textureView; private RadialProgress2 radialProgress; private BlockChannelCell channelCell; private int currentType; @@ -6007,6 +6063,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg private MessageObject.GroupedMessagePosition groupPosition; private WebpageAdapter parentAdapter; + private boolean firstFrameRendered; public BlockVideoCell(Context context, WebpageAdapter adapter, int type) { super(context); @@ -6022,9 +6079,25 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg radialProgress.setColors(0x66000000, 0x7f000000, 0xffffffff, 0xffd9d9d9); TAG = DownloadController.getInstance(currentAccount).generateObserverTag(); channelCell = new BlockChannelCell(context, parentAdapter, 1); + + aspectRatioFrameLayout = new AspectRatioFrameLayout(context); + aspectRatioFrameLayout.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT); + textureView = new TextureView(context); + textureView.setOpaque(false); + aspectRatioFrameLayout.addView(textureView); + + addView(aspectRatioFrameLayout); addView(channelCell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); } + @Override + protected boolean drawChild(Canvas canvas, View child, long drawingTime) { + if (child == aspectRatioFrameLayout && pinchToZoomHelper.isInOverlayModeFor(this)) { + return true; + } + return super.drawChild(canvas, child, drawingTime); + } + public void setBlock(TLRPC.TL_pageBlockVideo block, boolean first, boolean last) { currentBlock = block; parentBlock = null; @@ -6050,7 +6123,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg @Override public boolean onTouchEvent(MotionEvent event) { - if (pinchToZoomHelper.checkPinchToZoom(event, this, imageView, null)) { + if (pinchToZoomHelper.checkPinchToZoom(event, this, imageView, textureView, null)) { return true; } float x = event.getX(); @@ -6158,23 +6231,29 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg } } imageView.setQualityThumbDocument(currentDocument); - imageView.setImageCoords(photoX, (isFirst || currentType == 1 || currentType == 2 || currentBlock.level > 0) ? 0 : AndroidUtilities.dp(8), photoWidth, photoHeight); - + int photoY = (isFirst || currentType == 1 || currentType == 2 || currentBlock.level > 0) ? 0 : AndroidUtilities.dp(8); + imageView.setImageCoords(photoX, photoY, photoWidth, photoHeight); if (isGif) { autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(DownloadController.AUTODOWNLOAD_TYPE_VIDEO, currentDocument.size); File path = FileLoader.getInstance(currentAccount).getPathToAttach(currentDocument, true); if (autoDownload || path.exists()) { imageView.setStrippedLocation(null); - imageView.setImage(ImageLocation.getForDocument(currentDocument), ImageLoader.AUTOPLAY_FILTER, null, null, ImageLocation.getForDocument(thumb, currentDocument), "80_80_b", null, currentDocument.size, null, parentAdapter.currentPage, 1); + TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(currentDocument.thumbs, 1000); + imageView.setImage(null, null, ImageLocation.getForObject(photoSize, currentDocument), "200_200", ImageLocation.getForDocument(thumb, currentDocument), "80_80_b", null, currentDocument.size, null, parentAdapter.currentPage, 1); } else { imageView.setStrippedLocation(ImageLocation.getForDocument(currentDocument)); imageView.setImage(null, null, null, null, ImageLocation.getForDocument(thumb, currentDocument), "80_80_b", null, currentDocument.size, null, parentAdapter.currentPage, 1); } + FrameLayout.LayoutParams params = (LayoutParams) aspectRatioFrameLayout.getLayoutParams(); + params.leftMargin = photoX; + params.topMargin = photoY; + params.width = photoWidth; + params.height = photoHeight; } else { imageView.setStrippedLocation(null); imageView.setImage(null, null, ImageLocation.getForDocument(thumb, currentDocument), "80_80_b", 0, null, parentAdapter.currentPage, 1); } - imageView.setAspectFit(true); + // imageView.setAspectFit(true); buttonX = (int) (imageView.getImageX() + (imageView.getImageWidth() - size) / 2.0f); buttonY = (int) (imageView.getImageY() + (imageView.getImageHeight() - size) / 2.0f); radialProgress.setProgressRect(buttonX, buttonY, buttonX + size, buttonY + size); @@ -6208,7 +6287,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg channelCell.measure(widthMeasureSpec, heightMeasureSpec); channelCell.setTranslationY(imageView.getImageHeight() - AndroidUtilities.dp(39)); - setMeasuredDimension(width, height); + super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); } @Override @@ -6221,9 +6300,6 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg } if (!pinchToZoomHelper.isInOverlayModeFor(this)) { imageView.draw(canvas); - if (imageView.getVisible()) { - radialProgress.draw(canvas); - } } int count = 0; if (captionLayout != null) { @@ -6243,6 +6319,13 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg if (currentBlock.level > 0) { canvas.drawRect(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(20), getMeasuredHeight() - (currentBlock.bottom ? AndroidUtilities.dp(6) : 0), quoteLinePaint); } + super.onDraw(canvas); + + if (!pinchToZoomHelper.isInOverlayModeFor(this)) { + if (imageView.getVisible()) { + radialProgress.draw(canvas); + } + } } private int getIconForCurrentState() { @@ -6330,11 +6413,14 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg } } + @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); imageView.onDetachedFromWindow(); DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this); + playFrom = 0; + firstFrameRendered = false; } @Override @@ -6344,6 +6430,41 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg updateButtonState(false); } + private void startVideoPlayer() { + if (currentDocument == null || videoPlayer != null) { + return; + } +// if (!firstFrameRendered) { +// textureView.setAlpha(0f); +// } + videoPlayer = new VideoPlayerHolderBase() { + @Override + public boolean needRepeat() { + return true; + } + + @Override + public void onRenderedFirstFrame() { + super.onRenderedFirstFrame(); + if (!firstFrameRendered) { + firstFrameRendered = true; + textureView.setAlpha(1f); + } + } + }.with(textureView); + + TLRPC.Document document = currentDocument; + Uri uri = FileStreamLoadOperation.prepareUri(currentAccount, document, parentAdapter.currentPage); + if (uri == null) { + return; + } + + videoPlayer.seekTo(playFrom); + videoPlayer.preparePlayer(uri, true); + videoPlayer.play(); + + } + @Override public void onFailedDownload(String fileName, boolean canceled) { updateButtonState(false); @@ -9934,7 +10055,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg @Override public boolean onTouchEvent(MotionEvent event) { - if (pinchToZoomHelper.checkPinchToZoom(event, this, imageView, null)) { + if (pinchToZoomHelper.checkPinchToZoom(event, this, imageView, null, null)) { return true; } float x = event.getX(); @@ -11261,7 +11382,11 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg } final PhotoViewer photoViewer = PhotoViewer.getInstance(); photoViewer.setParentActivity(parentFragment); - return photoViewer.openPhoto(index, new RealPageBlocksAdapter(adapter.currentPage, pageBlocks), new PageBlocksPhotoViewerProvider(pageBlocks)); + if (photoViewer.openPhoto(index, new RealPageBlocksAdapter(adapter.currentPage, pageBlocks), new PageBlocksPhotoViewerProvider(pageBlocks))) { + checkVideoPlayer(); + return true; + } + return false; } @@ -11295,6 +11420,11 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg return !(index >= pageBlocks.size() || index < 0) && WebPageUtils.isVideo(page, get(index)); } + @Override + public boolean isHardwarePlayer(int index) { + return !(index >= pageBlocks.size() || index < 0) && !WebPageUtils.isVideo(page, get(index)) && adapter[0].getTypeForBlock(get(index)) == 5; + } + @Override public TLObject getMedia(int index) { if (index >= pageBlocks.size() || index < 0) { @@ -11461,6 +11591,19 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg BlockVideoCell cell = (BlockVideoCell) view; if (cell.currentBlock == pageBlock) { view.getLocationInWindow(coords); + if (cell == currentPlayer && videoPlayer != null && videoPlayer.firstFrameRendered) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + Surface surface = new Surface(cell.textureView.getSurfaceTexture()); + Bitmap bitmap = Bitmap.createBitmap(cell.textureView.getMeasuredWidth(), cell.textureView.getMeasuredHeight(), Bitmap.Config.ARGB_8888); + AndroidUtilities.getBitmapFromSurface(surface, bitmap); + surface.release(); + cell.imageView.setImageBitmap(bitmap); + } else { + cell.imageView.setImageBitmap(cell.textureView.getBitmap()); + } + cell.firstFrameRendered = false; + cell.textureView.setAlpha(0); + } return cell.imageView; } } else if (view instanceof BlockCollageCell) { @@ -11492,5 +11635,47 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg } return null; } + + @Override + public void onClose() { + super.onClose(); + checkVideoPlayer(); + } + + @Override + public void onReleasePlayerBeforeClose(int photoIndex) { + VideoPlayer player = PhotoViewer.getInstance().getVideoPlayer(); + TextureView textureView = PhotoViewer.getInstance().getVideoTextureView(); + BlockVideoCell videoCell = getViewFromListView(listView[0], pageBlocks.get(photoIndex)); + if (videoCell != null && player != null && textureView != null) { + videoCell.playFrom = player.getCurrentPosition(); + videoCell.firstFrameRendered = false; + videoCell.textureView.setAlpha(0); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + Surface surface = new Surface(textureView.getSurfaceTexture()); + Bitmap bitmap = Bitmap.createBitmap(textureView.getMeasuredWidth(), textureView.getMeasuredHeight(), Bitmap.Config.ARGB_8888); + AndroidUtilities.getBitmapFromSurface(surface, bitmap); + surface.release(); + videoCell.imageView.setImageBitmap(bitmap); + } else { + videoCell.imageView.setImageBitmap(textureView.getBitmap()); + } + } + checkVideoPlayer(); + } + + private BlockVideoCell getViewFromListView(ViewGroup listView, TLRPC.PageBlock pageBlock) { + int count = listView.getChildCount(); + for (int a = 0; a < count; a++) { + View view = listView.getChildAt(a); + if (view instanceof BlockVideoCell) { + BlockVideoCell cell = (BlockVideoCell) view; + if (cell.currentBlock == pageBlock) { + return cell; + } + } + } + return null; + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/CalendarActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/CalendarActivity.java index 67a723b50..af8276a01 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/CalendarActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/CalendarActivity.java @@ -194,7 +194,7 @@ public class CalendarActivity extends BaseFragment implements NotificationCenter holder.storyImage = imageReceiver; if (storiesPlaceDrawAbove == null) { - storiesPlaceDrawAbove = (canvas, bounds, alpha) -> { + storiesPlaceDrawAbove = (canvas, bounds, alpha, opening) -> { blackoutPaint.setAlpha((int) (80 * alpha)); float r = AndroidUtilities.lerp(0, Math.min(bounds.width(), bounds.height()) / 2f, alpha); canvas.drawRoundRect(bounds, r, r, blackoutPaint); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java index d0c525054..c98472ef8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java @@ -1391,7 +1391,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD } else { giftPremiumSubtitleLayout.draw(canvas); } - } else { + } else if (giftPremiumSubtitleLayout != null) { giftPremiumSubtitleLayout.draw(canvas); } canvas.restore(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java index 7ebed445c..c1dd40712 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -3253,7 +3253,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate isRoundVideo || currentMessageObject.isAnimatedSticker() || (currentMessageObject.isDocument() && !currentMessageObject.isGif()) || currentMessageObject.needDrawBluredPreview()) { return false; } - return pinchToZoomHelper.checkPinchToZoom(ev, this, photoImage, currentMessageObject); + return pinchToZoomHelper.checkPinchToZoom(ev, this, photoImage, null, currentMessageObject); } private boolean checkTextSelection(MotionEvent event) { @@ -6786,7 +6786,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate photoImage.setImage(null, null, thumb, null, messageObject, 0); } if (!reactionsLayoutInBubble.isSmall) { - reactionsLayoutInBubble.measure(maxWidth, currentMessageObject.isOutOwner() && (currentMessageObject.isAnimatedEmoji() || currentMessageObject.isAnyKindOfSticker()) ? Gravity.RIGHT : Gravity.LEFT); + reactionsLayoutInBubble.measure(maxWidth + AndroidUtilities.dp(36), currentMessageObject.isOutOwner() && (currentMessageObject.isAnimatedEmoji() || currentMessageObject.isAnyKindOfSticker()) ? Gravity.RIGHT : Gravity.LEFT); reactionsLayoutInBubble.drawServiceShaderBackground = 1f; reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(8); additionHeight += reactionsLayoutInBubble.totalHeight; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java index 4a50325a5..0cb677bbb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java @@ -325,6 +325,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No drawPremium = !savedMessages && MessagesController.getInstance(currentAccount).isPremiumUser(user); updateStatus(drawCheck, user, false); } else if (contact != null) { + dialog_id = 0; if (!LocaleController.isRTL) { nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline); } else { @@ -749,7 +750,12 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No actionLayout.draw(canvas); canvas.restore(); } - StoriesUtilities.drawAvatarWithStory(dialog_id, canvas, avatarImage, avatarStoryParams); + if (user != null) { + StoriesUtilities.drawAvatarWithStory(user.id, canvas, avatarImage, avatarStoryParams); + } else { + avatarImage.setImageCoords(avatarStoryParams.originalAvatarRect); + avatarImage.draw(canvas); + } } @Override @@ -794,7 +800,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No @Override public boolean onTouchEvent(MotionEvent event) { - if (avatarStoryParams.checkOnTouchEvent(event, this)) { + if (user != null && avatarStoryParams.checkOnTouchEvent(event, this)) { return true; } if (actionButton != null && actionButton.checkTouchEvent(event)) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ReactedUserHolderView.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ReactedUserHolderView.java index 50c933c07..d64114e93 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ReactedUserHolderView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ReactedUserHolderView.java @@ -194,6 +194,7 @@ public class ReactedUserHolderView extends FrameLayout { String contentDescription; boolean hasReactImage = false; if (like) { + reactView.setAnimatedEmojiDrawable(null); hasReactImage = true; Drawable likeDrawableFilled = ContextCompat.getDrawable(getContext(), R.drawable.media_like_active).mutate(); reactView.setColorFilter(new PorterDuffColorFilter(0xFFFF2E38, PorterDuff.Mode.MULTIPLY)); @@ -202,6 +203,7 @@ public class ReactedUserHolderView extends FrameLayout { } else if (reaction != null) { ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(reaction); if (visibleReaction.emojicon != null) { + reactView.setAnimatedEmojiDrawable(null); TLRPC.TL_availableReaction r = MediaDataController.getInstance(currentAccount).getReactionsMap().get(visibleReaction.emojicon); if (r != null) { SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(r.static_icon.thumbs, Theme.key_windowBackgroundGray, 1.0f); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerEmojiCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerEmojiCell.java index 1b0ed9fcb..5acdf0a21 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerEmojiCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerEmojiCell.java @@ -280,7 +280,7 @@ public class StickerEmojiCell extends FrameLayout implements NotificationCenter. } public boolean showingBitmap() { - return imageView.getBitmap() != null; + return imageView.hasNotThumb(); } public ImageReceiver getImageView() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 1e423d5b1..55f781cce 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -8681,7 +8681,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not blurredView.animate().setListener(new HideViewAfterAnimation(blurredView)).alpha(0).start(); blurredView.setTag(null); chatListView.invalidate(); - fragmentView.invalidate(); + if (fragmentView != null) { + fragmentView.invalidate(); + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlert.java index cb60f4b81..99f92bbea 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlert.java @@ -1708,10 +1708,15 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N } } - canvas.save(); - canvas.clipRect(backgroundPaddingLeft, actionBar.getY() + actionBar.getMeasuredHeight() - currentPanTranslationY, getMeasuredWidth() - backgroundPaddingLeft, getMeasuredHeight()); - boolean result = super.drawChild(canvas, child, drawingTime); - canvas.restore(); + boolean result; + if (child != contactsLayout && child != audioLayout) { + canvas.save(); + canvas.clipRect(backgroundPaddingLeft, actionBar.getY() + actionBar.getMeasuredHeight() - currentPanTranslationY, getMeasuredWidth() - backgroundPaddingLeft, getMeasuredHeight()); + result = super.drawChild(canvas, child, drawingTime); + canvas.restore(); + } else { + result = super.drawChild(canvas, child, drawingTime); + } if (drawBackground) { if (rad != 1.0f && actionBarType != 2) { @@ -2113,11 +2118,15 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N buttonsRecyclerView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); containerView.addView(buttonsRecyclerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 84, Gravity.BOTTOM | Gravity.LEFT)); buttonsRecyclerView.setOnItemClickListener((view, position) -> { - if (baseFragment != null && baseFragment.getParentActivity() == null) { + BaseFragment lastFragment = baseFragment; + if (lastFragment == null) { + lastFragment = LaunchActivity.getLastFragment(); + } + if (lastFragment == null || lastFragment.getParentActivity() == null) { return; } if (view instanceof AttachButton) { - final Activity activity = baseFragment.getParentActivity(); + final Activity activity = lastFragment.getParentActivity(); int num = (Integer) view.getTag(); if (num == 1) { if (!photosEnabled && !videosEnabled) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java index c2cc7b17a..fe64c5dd8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java @@ -54,7 +54,6 @@ import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.Keep; -import androidx.exifinterface.media.ExifInterface; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearSmoothScroller; @@ -105,7 +104,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java index f4fcf4ff9..b110fc991 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java @@ -565,7 +565,7 @@ public class EditTextBoldCursor extends EditTextEffects { public void setHintText(CharSequence text, boolean animated) { if (hintAnimatedDrawable != null) { - hintAnimatedDrawable.setText(text, true); + hintAnimatedDrawable.setText(text, !LocaleController.isRTL); } else { if (text == null) { text = ""; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/FilterShaders.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/FilterShaders.java index 78c561d3b..0ec78a981 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/FilterShaders.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/FilterShaders.java @@ -3,6 +3,7 @@ package org.telegram.ui.Components; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.PointF; +import android.media.MediaFormat; import android.opengl.GLES11Ext; import android.opengl.GLES20; import android.opengl.GLUtils; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/LimitReachedBottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/LimitReachedBottomSheet.java index 2a080128f..bd8a780c9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/LimitReachedBottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/LimitReachedBottomSheet.java @@ -666,7 +666,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView { description.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); description.setGravity(Gravity.CENTER_HORIZONTAL); description.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider)); - addView(description, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 0, 24, 0, 24, 24)); + addView(description, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 24, 0, 24, 24)); updatePremiumButtonText(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumLockIconView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumLockIconView.java index 685469bbf..90f593b08 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumLockIconView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumLockIconView.java @@ -110,43 +110,45 @@ public class PremiumLockIconView extends ImageView { invalidate(); } } - if (type == TYPE_REACTIONS) { - if (currentColor != 0) { - canvas.drawPath(path, paint); - } else { - PremiumGradient.getInstance().updateMainGradientMatrix(0, 0, getMeasuredWidth(), getMeasuredHeight(), -AndroidUtilities.dp(24), 0); - canvas.drawPath(path, PremiumGradient.getInstance().getMainGradientPaint()); - } - if (cellFlickerDrawable == null) { - cellFlickerDrawable = new CellFlickerDrawable(); - } - cellFlickerDrawable.setParentWidth(getMeasuredWidth() / 2); - cellFlickerDrawable.drawFrame = false; - cellFlickerDrawable.draw(canvas, path, this); - canvas.save(); - canvas.clipPath(path); - starParticles.onDraw(canvas); - canvas.restore(); - invalidate(); - } else { - float cx = getMeasuredWidth() / 2f; - float cy = getMeasuredHeight() / 2f; - if (oldShaderPaint == null) { - shaderCrossfadeProgress = 1f; - } - if (shaderCrossfadeProgress != 1f) { - paint.setAlpha((int) (255 * shaderCrossfadeProgress)); - canvas.drawCircle(cx, cy, cx, oldShaderPaint); - canvas.drawCircle(cx, cy, cx, paint); - shaderCrossfadeProgress += 16 / 150f; - if (shaderCrossfadeProgress > 1f) { - shaderCrossfadeProgress = 1f; - oldShaderPaint = null; + if (paint != null) { + if (type == TYPE_REACTIONS) { + if (currentColor != 0) { + canvas.drawPath(path, paint); + } else { + PremiumGradient.getInstance().updateMainGradientMatrix(0, 0, getMeasuredWidth(), getMeasuredHeight(), -AndroidUtilities.dp(24), 0); + canvas.drawPath(path, PremiumGradient.getInstance().getMainGradientPaint()); } + if (cellFlickerDrawable == null) { + cellFlickerDrawable = new CellFlickerDrawable(); + } + cellFlickerDrawable.setParentWidth(getMeasuredWidth() / 2); + cellFlickerDrawable.drawFrame = false; + cellFlickerDrawable.draw(canvas, path, this); + canvas.save(); + canvas.clipPath(path); + starParticles.onDraw(canvas); + canvas.restore(); invalidate(); - paint.setAlpha(255); } else { - canvas.drawCircle(cx, cy, cx, paint); + float cx = getMeasuredWidth() / 2f; + float cy = getMeasuredHeight() / 2f; + if (oldShaderPaint == null) { + shaderCrossfadeProgress = 1f; + } + if (shaderCrossfadeProgress != 1f) { + paint.setAlpha((int) (255 * shaderCrossfadeProgress)); + canvas.drawCircle(cx, cy, cx, oldShaderPaint); + canvas.drawCircle(cx, cy, cx, paint); + shaderCrossfadeProgress += 16 / 150f; + if (shaderCrossfadeProgress > 1f) { + shaderCrossfadeProgress = 1f; + oldShaderPaint = null; + } + invalidate(); + paint.setAlpha(255); + } else { + canvas.drawCircle(cx, cy, cx, paint); + } } } super.onDraw(canvas); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ProfileGalleryView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ProfileGalleryView.java index 439208441..c68dd6e5b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ProfileGalleryView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ProfileGalleryView.java @@ -402,8 +402,8 @@ public class ProfileGalleryView extends CircularViewPager implements Notificatio if (pinchToZoomHelper != null && getCurrentItemView() != null) { if (action != MotionEvent.ACTION_DOWN && isDownReleased && !pinchToZoomHelper.isInOverlayMode()) { - pinchToZoomHelper.checkPinchToZoom(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0), this, getCurrentItemView().getImageReceiver(), null); - } else if (pinchToZoomHelper.checkPinchToZoom(ev, this, getCurrentItemView().getImageReceiver(), null)) { + pinchToZoomHelper.checkPinchToZoom(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0), this, getCurrentItemView().getImageReceiver(), null,null); + } else if (pinchToZoomHelper.checkPinchToZoom(ev, this, getCurrentItemView().getImageReceiver(), null,null)) { if (!isDownReleased) { isDownReleased = true; callback.onRelease(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SharedMediaLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SharedMediaLayout.java index a3a4259ca..81bddc7ef 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SharedMediaLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SharedMediaLayout.java @@ -53,6 +53,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.GridLayoutManager; @@ -79,6 +80,7 @@ import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.SendMessagesHelper; import org.telegram.messenger.SharedConfig; +import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserObject; import org.telegram.messenger.Utilities; import org.telegram.messenger.browser.Browser; @@ -1009,7 +1011,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter mediaPages[0].listView.getLocationInWindow(coords); object.animatingImageViewYOffset = -coords[1]; object.imageReceiver = imageReceiver; - object.allowTakeAnimation = false; + object.allowTakeAnimation = true; object.radius = object.imageReceiver.getRoundRadius(); object.thumb = object.imageReceiver.getBitmapSafe(); object.parentView.getLocationInWindow(coords); @@ -1503,8 +1505,10 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter if (isStories) { StoriesAdapter adapter = tab == TAB_STORIES ? storiesAdapter : archivedStoriesAdapter; - showPhotosItem.setChecked(adapter.storiesList.showPhotos()); - showVideosItem.setChecked(adapter.storiesList.showVideos()); + if (adapter.storiesList != null) { + showPhotosItem.setChecked(adapter.storiesList.showPhotos()); + showVideosItem.setChecked(adapter.storiesList.showVideos()); + } showPhotosItem.setOnClickListener(v -> { if (changeTypeAnimation) { return; @@ -1514,6 +1518,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter return; } showPhotosItem.getCheckView().setChecked(!showPhotosItem.getCheckView().isChecked(), true); + if (adapter.storiesList == null) { + return; + } adapter.storiesList.updateFilters(showPhotosItem.getCheckView().isChecked(), showVideosItem.getCheckView().isChecked()); }); showVideosItem.setOnClickListener(v -> { @@ -1525,6 +1532,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter return; } showVideosItem.getCheckView().setChecked(!showVideosItem.getCheckView().isChecked(), true); + if (adapter.storiesList == null) { + return; + } adapter.storiesList.updateFilters(showPhotosItem.getCheckView().isChecked(), showVideosItem.getCheckView().isChecked()); }); } else { @@ -2554,10 +2564,10 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter } public void setStoriesFilter(boolean photos, boolean videos) { - if (storiesAdapter != null) { + if (storiesAdapter != null && storiesAdapter.storiesList != null) { storiesAdapter.storiesList.updateFilters(photos, videos); } - if (archivedStoriesAdapter != null) { + if (archivedStoriesAdapter != null && archivedStoriesAdapter.storiesList != null) { archivedStoriesAdapter.storiesList.updateFilters(photos, videos); } } @@ -5387,6 +5397,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter } } else if (selectedMode == TAB_STORIES || selectedMode == TAB_ARCHIVED_STORIES) { StoriesController.StoriesList storiesList = (selectedMode == TAB_STORIES ? storiesAdapter : archivedStoriesAdapter).storiesList; + if (storiesList == null) { + return; + } profileActivity.getOrCreateStoryViewer().open(getContext(), message.getId(), storiesList, StoriesListPlaceProvider.of(mediaPages[a].listView).with(forward -> { if (forward) { storiesList.load(false, 30); @@ -6759,10 +6772,16 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter } public int getStoriesCount(int tab) { + StoriesController.StoriesList list; if (tab == TAB_STORIES) { - return storiesAdapter.storiesList.getCount(); + list = storiesAdapter.storiesList; } else if (tab == TAB_ARCHIVED_STORIES) { - return archivedStoriesAdapter.storiesList.getCount(); + list = archivedStoriesAdapter.storiesList; + } else { + return 0; + } + if (list != null) { + return list.getCount(); } return 0; } @@ -6770,7 +6789,8 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter private class StoriesAdapter extends SharedPhotoVideoAdapter { private final boolean isArchive; - public StoriesController.StoriesList storiesList; + @Nullable + public final StoriesController.StoriesList storiesList; private StoriesAdapter supportingAdapter; private int id; @@ -6778,7 +6798,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter super(context); this.isArchive = isArchive; storiesList = profileActivity.getMessagesController().getStoriesController().getStoriesList(dialog_id, isArchive ? StoriesController.StoriesList.TYPE_ARCHIVE : StoriesController.StoriesList.TYPE_PINNED); - id = storiesList.link(); + if (storiesList != null) { + id = storiesList.link(); + } checkColumns(); } @@ -6801,6 +6823,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter } private void checkColumns() { + if (storiesList == null) { + return; + } if (!isArchive && (!storiesColumnsCountSet || allowStoriesSingleColumn && storiesList.getCount() > 1) && storiesList.getCount() > 0 && !isStoriesView()) { if (storiesList.getCount() < 5) { mediaColumnsCount[1] = storiesList.getCount(); @@ -6845,6 +6870,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter @Override public int getItemCount() { + if (storiesList == null) { + return 0; + } return storiesList.isOnlyCache() && hasInternet() ? 0 : storiesList.getCount(); } @@ -6877,6 +6905,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + if (storiesList == null) { + return; + } int viewType = holder.getItemViewType(); if (viewType == 0) { SharedPhotoVideoCell2 cell = (SharedPhotoVideoCell2) holder.itemView; @@ -6884,6 +6915,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter position -= getTopOffset(); if (position < 0 || position >= storiesList.messageObjects.size()) { cell.setMessageObject(null, columnsCount()); + cell.isStory = true; return; } MessageObject messageObject = storiesList.messageObjects.get(position); @@ -6897,6 +6929,10 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter } public void load(boolean force) { + if (storiesList == null) { + return; + } + final int columnCount = columnsCount(); final int count = Math.min(100, Math.max(1, columnCount / 2) * columnCount * columnCount); storiesList.load(force, count); @@ -6909,6 +6945,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter @Override public String getLetter(int position) { + if (storiesList == null) { + return null; + } position -= getTopOffset(); if (position < 0 || position >= storiesList.messageObjects.size()) { return null; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/StickersAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/StickersAlert.java index b4f71ecbd..9534e202c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/StickersAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/StickersAlert.java @@ -634,19 +634,16 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not protected void onDraw(Canvas canvas) { int y = scrollOffsetY - backgroundPaddingTop + AndroidUtilities.dp(6); int top = scrollOffsetY - backgroundPaddingTop - AndroidUtilities.dp(13); - int height = getMeasuredHeight() + AndroidUtilities.dp(15) + backgroundPaddingTop; int statusBarHeight = 0; float radProgress = 1.0f; if (Build.VERSION.SDK_INT >= 21) { top += AndroidUtilities.statusBarHeight; y += AndroidUtilities.statusBarHeight; - height -= AndroidUtilities.statusBarHeight; if (fullHeight) { if (top + backgroundPaddingTop < AndroidUtilities.statusBarHeight * 2) { int diff = Math.min(AndroidUtilities.statusBarHeight, AndroidUtilities.statusBarHeight * 2 - top - backgroundPaddingTop); top -= diff; - height += diff; radProgress = 1.0f - Math.min(1.0f, (diff * 2) / (float) AndroidUtilities.statusBarHeight); } if (top + backgroundPaddingTop < AndroidUtilities.statusBarHeight) { @@ -655,7 +652,7 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not } } - shadowDrawable.setBounds(0, top, getMeasuredWidth(), height); + shadowDrawable.setBounds(0, top, getMeasuredWidth(), getMeasuredHeight()); shadowDrawable.draw(canvas); if (radProgress != 1.0f) { @@ -925,6 +922,7 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.fileUploaded); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.fileUploadFailed); } + NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.stickersDidLoad); updateFields(); updateSendButton(); @@ -1142,9 +1140,10 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not premiumButtonView.setVisibility(View.INVISIBLE); } + final MediaDataController mediaDataController = MediaDataController.getInstance(currentAccount); boolean notInstalled; if (stickerSet != null && stickerSet.set != null && stickerSet.set.emojis) { - ArrayList sets = MediaDataController.getInstance(currentAccount).getStickerSets(MediaDataController.TYPE_EMOJIPACKS); + ArrayList sets = mediaDataController.getStickerSets(MediaDataController.TYPE_EMOJIPACKS); boolean has = false; for (int i = 0; sets != null && i < sets.size(); ++i) { if (sets.get(i) != null && sets.get(i).set != null && sets.get(i).set.id == stickerSet.set.id) { @@ -1154,7 +1153,7 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not } notInstalled = !has; } else { - notInstalled = stickerSet == null || stickerSet.set == null || !MediaDataController.getInstance(currentAccount).isStickerPackInstalled(stickerSet.set.id); + notInstalled = stickerSet == null || stickerSet.set == null || !mediaDataController.isStickerPackInstalled(stickerSet.set.id); } if (customButtonDelegate != null) { @@ -1163,7 +1162,22 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not dismiss(); } }, customButtonDelegate.getCustomButtonText(), customButtonDelegate.getCustomButtonTextColorKey(), customButtonDelegate.getCustomButtonColorKey(), customButtonDelegate.getCustomButtonRippleColorKey()); - } else if (notInstalled) { + return; + } + if (notInstalled) { + int type = MediaDataController.TYPE_IMAGE; + if (stickerSet != null && stickerSet.set != null && stickerSet.set.emojis) { + type = MediaDataController.TYPE_EMOJIPACKS; + } else if (stickerSet != null && stickerSet.set != null && stickerSet.set.masks) { + type = MediaDataController.TYPE_MASK; + } + if (!mediaDataController.areStickersLoaded(type)) { + mediaDataController.checkStickers(type); + setButton(null, "", -1, -1, -1); + return; + } + } + if (notInstalled) { String text; if (stickerSet != null && stickerSet.set != null && stickerSet.set.masks) { text = LocaleController.formatPluralString("AddManyMasksCount", stickerSet.documents == null ? 0 : stickerSet.documents.size()); @@ -1602,6 +1616,7 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.fileUploaded); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.fileUploadFailed); } + NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.stickersDidLoad); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.startAllHeavyOperations, 4); } @@ -1674,6 +1689,8 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not if (uploadImportStickers.isEmpty()) { updateFields(); } + } else if (id == NotificationCenter.stickersDidLoad) { + updateFields(); } } @@ -1692,16 +1709,24 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not ViewGroup.MarginLayoutParams shadowParams = (ViewGroup.MarginLayoutParams) shadow[1].getLayoutParams(); ViewGroup.MarginLayoutParams gridParams = (ViewGroup.MarginLayoutParams) gridView.getLayoutParams(); ViewGroup.MarginLayoutParams emptyParams = (ViewGroup.MarginLayoutParams) emptyView.getLayoutParams(); - if (backgroundColorKey >= 0 && backgroundSelectorColorKey >= 0) { + if (onClickListener == null) { + pickerBottomLayout.setAlpha(0f); + } else if (backgroundColorKey >= 0 && backgroundSelectorColorKey >= 0) { pickerBottomLayout.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(6), getThemedColor(backgroundColorKey), getThemedColor(backgroundSelectorColorKey))); pickerBottomFrameLayout.setBackgroundColor(getThemedColor(Theme.key_dialogBackground)); params.leftMargin = params.topMargin = params.rightMargin = params.bottomMargin = dp(8); emptyParams.bottomMargin = gridParams.bottomMargin = shadowParams.bottomMargin = dp(64); + if (pickerBottomLayout.getAlpha() < 1f) { + pickerBottomLayout.animate().alpha(1f).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).setDuration(240).start(); + } } else { pickerBottomLayout.setBackground(Theme.createSelectorWithBackgroundDrawable(getThemedColor(Theme.key_dialogBackground), Theme.multAlpha(getThemedColor(Theme.key_text_RedBold), .1f))); pickerBottomFrameLayout.setBackgroundColor(Color.TRANSPARENT); params.leftMargin = params.topMargin = params.rightMargin = params.bottomMargin = 0; emptyParams.bottomMargin = gridParams.bottomMargin = shadowParams.bottomMargin = dp(48); + if (pickerBottomLayout.getAlpha() < 1f) { + pickerBottomLayout.animate().alpha(1f).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).setDuration(240).start(); + } } containerView.requestLayout(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ViewPagerFixed.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ViewPagerFixed.java index 24cdb5ced..2653730a5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ViewPagerFixed.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ViewPagerFixed.java @@ -235,10 +235,12 @@ public class ViewPagerFixed extends FrameLayout { onTabPageSelected(page); int trasnlationX = viewPages[0] != null ? viewPages[0].getMeasuredWidth() : 0; - if (forward) { - viewPages[1].setTranslationX(trasnlationX); - } else { - viewPages[1].setTranslationX(-trasnlationX); + if (viewPages[1] != null) { + if (forward) { + viewPages[1].setTranslationX(trasnlationX); + } else { + viewPages[1].setTranslationX(-trasnlationX); + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java index 53669f0bb..2512d2b79 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java @@ -1916,7 +1916,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. protected void onMeasure(int widthSpec, int heightSpec) { int t = 0; int pos = parentPage.layoutManager.findFirstVisibleItemPosition(); - if (pos != RecyclerView.NO_POSITION && parentPage.itemTouchhelper.isIdle() && !parentPage.layoutManager.hasPendingScrollPosition()) { + if (pos != RecyclerView.NO_POSITION && parentPage.itemTouchhelper.isIdle() && !parentPage.layoutManager.hasPendingScrollPosition() && parentPage.listView.getScrollState() != RecyclerView.SCROLL_STATE_DRAGGING) { RecyclerView.ViewHolder holder = parentPage.listView.findViewHolderForAdapterPosition(pos); if (holder != null) { int top = holder.itemView.getTop(); @@ -6424,6 +6424,9 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. boolean hasNotStoragePermission = (Build.VERSION.SDK_INT <= 28 || BuildVars.NO_SCOPED_STORAGE) && activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED; boolean hasNotNotificationsPermission = Build.VERSION.SDK_INT >= 33 && activity.checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED; AndroidUtilities.runOnUIThread(() -> { + if (getParentActivity() == null) { + return; + } afterSignup = false; if (hasNotNotificationsPermission || hasNotContactsPermission || hasNotStoragePermission) { askingForPermissions = true; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCallActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCallActivity.java index 20703bd42..e2502af8e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCallActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCallActivity.java @@ -121,6 +121,8 @@ import org.telegram.ui.Components.AudioPlayerAlert; import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.BlobDrawable; +import org.telegram.ui.Components.Bulletin; +import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.CheckBoxSquare; import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.EditTextBoldCursor; @@ -152,6 +154,7 @@ import org.telegram.ui.Components.voip.GroupCallStatusIcon; import org.telegram.ui.Components.voip.PrivateVideoPreviewDialog; import org.telegram.ui.Components.voip.RTMPStreamPipOverlay; import org.telegram.ui.Components.voip.VoIPToggleButton; +import org.webrtc.voiceengine.WebRtcAudioTrack; import java.io.File; import java.util.ArrayList; @@ -8704,4 +8707,26 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter public boolean isRtmpStream() { return call != null && call.call.rtmp_stream; } + + @Override + public boolean dispatchKeyEvent(@NonNull KeyEvent event) { + if (parentActivity == null) { + return super.dispatchKeyEvent(event); + } + if (event.getAction() == KeyEvent.ACTION_DOWN && (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN)) { + if (VoIPService.getSharedInstance() != null) { + if (Build.VERSION.SDK_INT >= 32) { + boolean oldValue = WebRtcAudioTrack.isSpeakerMuted(); + AudioManager am = (AudioManager) parentActivity.getSystemService(AUDIO_SERVICE); + int minVolume = am.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL); + boolean mute = am.getStreamVolume(AudioManager.STREAM_VOICE_CALL) == minVolume && event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN; + WebRtcAudioTrack.setSpeakerMute(mute); + if (oldValue != WebRtcAudioTrack.isSpeakerMuted()) { + getUndoView().showWithAction(0, mute ? UndoView.ACTION_VOIP_SOUND_MUTED : UndoView.ACTION_VOIP_SOUND_UNMUTED, null); + } + } + } + } + return super.dispatchKeyEvent(event); + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index 507282c53..064668fbc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -7074,6 +7074,10 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati int keyCode = event.getKeyCode(); if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) { BaseFragment baseFragment = getLastFragment(); + if (baseFragment != null && baseFragment.overlayStoryViewer != null && baseFragment.overlayStoryViewer.isShown()) { + baseFragment.overlayStoryViewer.dispatchKeyEvent(event); + return true; + } if (baseFragment != null && baseFragment.storyViewer != null && baseFragment.storyViewer.isShown()) { baseFragment.storyViewer.dispatchKeyEvent(event); return true; @@ -7406,14 +7410,14 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati public void requestCustomNavigationBar() { if (customNavigationBar == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { customNavigationBar = drawerLayoutContainer.createNavigationBar(); - if (customNavigationBar != null) { - FrameLayout decorView = (FrameLayout) getWindow().getDecorView(); - decorView.addView(customNavigationBar); - if (customNavigationBar.getLayoutParams().height != AndroidUtilities.navigationBarHeight || ((FrameLayout.LayoutParams)customNavigationBar.getLayoutParams()).topMargin != customNavigationBar.getHeight()) { - customNavigationBar.getLayoutParams().height = AndroidUtilities.navigationBarHeight; - ((FrameLayout.LayoutParams)customNavigationBar.getLayoutParams()).topMargin = drawerLayoutContainer.getMeasuredHeight(); - customNavigationBar.requestLayout(); - } + FrameLayout decorView = (FrameLayout) getWindow().getDecorView(); + decorView.addView(customNavigationBar); + } + if (customNavigationBar != null) { + if (customNavigationBar.getLayoutParams().height != AndroidUtilities.navigationBarHeight || ((FrameLayout.LayoutParams)customNavigationBar.getLayoutParams()).topMargin != customNavigationBar.getHeight()) { + customNavigationBar.getLayoutParams().height = AndroidUtilities.navigationBarHeight; + ((FrameLayout.LayoutParams)customNavigationBar.getLayoutParams()).topMargin = drawerLayoutContainer.getMeasuredHeight(); + customNavigationBar.requestLayout(); } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java index ea97ad406..ff9498cc3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -1624,6 +1624,7 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No ContactsController.getInstance(currentAccount).checkAppAccount(); MessagesController.getInstance(currentAccount).checkPromoInfo(true); ConnectionsManager.getInstance(currentAccount).updateDcSettings(); + MessagesController.getInstance(currentAccount).loadAppConfig(); if (res.future_auth_token != null) { AuthTokensHelper.saveLogInToken(res); @@ -4063,7 +4064,7 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No } else if (nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_SMS || nextType == AUTH_TYPE_MISSED_CALL) { createTimer(); } - } else if (currentType == AUTH_TYPE_SMS && (nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_FLASH_CALL)) { + } else if (currentType == AUTH_TYPE_SMS && (nextType == AUTH_TYPE_SMS || nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_FLASH_CALL)) { timeText.setText(LocaleController.formatString("CallAvailableIn", R.string.CallAvailableIn, 2, 0)); setProblemTextVisible(time < 1000); timeText.setVisibility(time < 1000 ? GONE : VISIBLE); @@ -4139,6 +4140,9 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No return; } codeTime = 15000; + if (time > codeTime) { + codeTime = time; + } codeTimer = new Timer(); lastCodeTime = System.currentTimeMillis(); codeTimer.schedule(new TimerTask() { @@ -4201,6 +4205,8 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No int seconds = time / 1000 - minutes * 60; if (nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_FLASH_CALL || nextType == AUTH_TYPE_MISSED_CALL) { timeText.setText(LocaleController.formatString("CallAvailableIn", R.string.CallAvailableIn, minutes, seconds)); + } else if (currentType == AUTH_TYPE_SMS && nextType == AUTH_TYPE_SMS) { + timeText.setText(LocaleController.formatString("ResendSmsAvailableIn", R.string.ResendSmsAvailableIn, minutes, seconds)); } else if (nextType == AUTH_TYPE_SMS) { timeText.setText(LocaleController.formatString("SmsAvailableIn", R.string.SmsAvailableIn, minutes, seconds)); } @@ -4386,7 +4392,11 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No tryHideProgress(false); nextPressed = false; if (error == null) { - animateSuccess(() -> new AlertDialog.Builder(getParentActivity()) + Activity activity = getParentActivity(); + if (activity == null) { + return; + } + animateSuccess(() -> new AlertDialog.Builder(activity) .setTitle(LocaleController.getString(R.string.CancelLinkSuccessTitle)) .setMessage(LocaleController.formatString("CancelLinkSuccess", R.string.CancelLinkSuccess, PhoneFormat.getInstance().format("+" + phone))) .setPositiveButton(LocaleController.getString(R.string.Close), null) diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java index b5db12750..704c57bd1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -30,7 +30,6 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Outline; import android.graphics.Paint; @@ -70,7 +69,6 @@ import android.transition.TransitionManager; import android.transition.TransitionSet; import android.transition.TransitionValues; import android.util.FloatProperty; -import android.util.Log; import android.util.Pair; import android.util.Property; import android.util.Range; @@ -149,6 +147,7 @@ import org.telegram.messenger.DownloadController; import org.telegram.messenger.Emoji; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; +import org.telegram.messenger.FileStreamLoadOperation; import org.telegram.messenger.ImageLoader; import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageReceiver; @@ -156,7 +155,6 @@ import org.telegram.messenger.LiteMode; import org.telegram.messenger.LocaleController; import org.telegram.messenger.MediaController; import org.telegram.messenger.MediaDataController; -import org.telegram.messenger.MessageCustomParamsHelper; import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesStorage; @@ -257,7 +255,6 @@ import org.telegram.ui.Components.VideoTimelinePlayView; import org.telegram.ui.Components.ViewHelper; import org.telegram.ui.Components.spoilers.SpoilersTextView; import org.telegram.ui.Stories.DarkThemeResourceProvider; -import org.telegram.ui.Stories.StoryCaptionView; import java.io.ByteArrayInputStream; import java.io.File; @@ -283,6 +280,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private int classGuid; private PhotoViewerProvider placeProvider; private boolean isVisible; + private boolean isVisibleOrAnimating; private int maxSelectedPhotos = -1; private boolean allowOrder = true; @@ -309,6 +307,14 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat public boolean closePhotoAfterSelect = true; private TextSelectionHelper.SimpleTextSelectionHelper textSelectionHelper; + public TextureView getVideoTextureView() { + return videoTextureView; + } + + public boolean isVisibleOrAnimating() { + return isVisibleOrAnimating; + } + private static class PhotoViewerActionBarContainer extends FrameLayout implements NotificationCenter.NotificationCenterDelegate { private FrameLayout container; @@ -1744,6 +1750,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat TLRPC.PhotoSize getFileLocation(TLObject media, int[] size); void updateSlideshowCell(TLRPC.PageBlock currentPageBlock); Object getParentObject(); + boolean isHardwarePlayer(int index); } private Rect hitRect = new Rect(); @@ -2533,6 +2540,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat default boolean canLoadMoreAvatars() { return true; } + default void onReleasePlayerBeforeClose(int currentIndex) {}; } private class FrameLayoutDrawer extends SizeNotifierFrameLayoutPhoto { @@ -3737,7 +3745,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat boolean animated = a == 0 || a == 1 && sideImage == rightImage || a == 2 && sideImage == leftImage; photoProgressViews[a].setProgress(1.0f, animated); checkProgress(a, false, animated); - if (videoPlayer == null && a == 0 && (currentMessageObject != null && currentMessageObject.isVideo() || currentBotInlineResult != null && (currentBotInlineResult.type.equals("video") || MessageObject.isVideoDocument(currentBotInlineResult.document)) || pageBlocksAdapter != null && pageBlocksAdapter.isVideo(currentIndex))) { + if (videoPlayer == null && a == 0 && (currentMessageObject != null && currentMessageObject.isVideo() || currentBotInlineResult != null && (currentBotInlineResult.type.equals("video") || MessageObject.isVideoDocument(currentBotInlineResult.document)) || pageBlocksAdapter != null && (pageBlocksAdapter.isVideo(currentIndex) || pageBlocksAdapter.isHardwarePlayer(currentIndex)))) { onActionClick(false); } if (a == 0 && videoPlayer != null) { @@ -5174,6 +5182,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat PipInstance = Instance; Instance = null; isVisible = false; + isVisibleOrAnimating = false; if (currentPlaceObject != null && !currentPlaceObject.imageReceiver.getVisible()) { currentPlaceObject.imageReceiver.setVisible(true, true); } @@ -7732,6 +7741,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat Instance = null; switchingInlineMode = true; isVisible = false; + isVisibleOrAnimating = false; AndroidUtilities.cancelRunOnUIThread(hideActionBarRunnable); if (currentPlaceObject != null && !currentPlaceObject.imageReceiver.getVisible()) { currentPlaceObject.imageReceiver.setVisible(true, true); @@ -8092,6 +8102,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat try { isVisible = true; + isVisibleOrAnimating = true; WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE); wm.addView(windowView, windowLayoutParams); onShowView(); @@ -9240,9 +9251,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat waitingForFirstTextureUpload = 0; } - if (firstFrameView != null) { - firstFrameView.checkFromPlayer(videoPlayer); - } + AndroidUtilities.runOnUIThread(() -> { + if (firstFrameView != null) { + firstFrameView.checkFromPlayer(videoPlayer); + } + }); } }); } @@ -9303,7 +9316,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat videoPlayer.setPlayWhenReady(playWhenReady); } - playerLooping = currentMessageObject != null && currentMessageObject.getDuration() <= 30; + playerLooping = (currentMessageObject != null && currentMessageObject.getDuration() <= 30) || (pageBlocksAdapter != null && pageBlocksAdapter.isHardwarePlayer(currentIndex)); videoPlayerControlFrameLayout.setSeekBarTransitionEnabled(playerLooping); videoPlayer.setLooping(playerLooping); @@ -9323,8 +9336,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (pageBlocksAdapter != null) { bottomLayout.setVisibility(View.VISIBLE); } - - setVideoPlayerControlVisible(!isCurrentVideo, true); + if (pageBlocksAdapter != null && pageBlocksAdapter.isHardwarePlayer(currentIndex) && !pageBlocksAdapter.isVideo(currentIndex)) { + setVideoPlayerControlVisible(false, true); + } else { + setVideoPlayerControlVisible(!isCurrentVideo, true); + } if (!isCurrentVideo) { scheduleActionBarHide(playerAutoStarted ? 3000 : 1000); } @@ -12160,7 +12176,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat MessagesController.getInstance(currentAccount).loadDialogPhotos(avatarsDialogId, 80, 0, true, classGuid); } } - if (currentMessageObject != null && currentMessageObject.isVideo() || currentBotInlineResult != null && (currentBotInlineResult.type.equals("video") || MessageObject.isVideoDocument(currentBotInlineResult.document)) || (pageBlocksAdapter != null && pageBlocksAdapter.isVideo(index)) || (sendPhotoType == SELECT_TYPE_NO_SELECT && ((MediaController.PhotoEntry)imagesArrLocals.get(index)).isVideo)) { + if (currentMessageObject != null && currentMessageObject.isVideo() || currentBotInlineResult != null && (currentBotInlineResult.type.equals("video") || MessageObject.isVideoDocument(currentBotInlineResult.document)) || (pageBlocksAdapter != null && (pageBlocksAdapter.isVideo(index) || pageBlocksAdapter.isHardwarePlayer(index))) || (sendPhotoType == SELECT_TYPE_NO_SELECT && ((MediaController.PhotoEntry)imagesArrLocals.get(index)).isVideo)) { playerAutoStarted = true; onActionClick(false); } else if (!imagesArrLocals.isEmpty()) { @@ -12782,7 +12798,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat countView.updateShow(size > 1, true); countView.set(switchingToIndex + 1, size); } - if (currentAnimation != null) { + if (currentAnimation != null || (!pageBlocksAdapter.isVideo(index) && pageBlocksAdapter.isHardwarePlayer(index))) { menuItem.hideSubItem(gallery_menu_save); if (allowShare) { menuItem.showSubItem(gallery_menu_savegif); @@ -13108,7 +13124,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat final TLRPC.PageBlock pageBlock = pageBlocksAdapter.get(currentIndex); sameImage = currentPageBlock != null && currentPageBlock == pageBlock; currentPageBlock = pageBlock; - isVideo = pageBlocksAdapter.isVideo(currentIndex); + isVideo = pageBlocksAdapter.isVideo(currentIndex) || pageBlocksAdapter.isHardwarePlayer(currentIndex); } setMenuItemIcon(false, true); @@ -13595,7 +13611,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat f2 = new File(FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE), currentFileNames[a]); } else if (pageBlocksAdapter != null) { f1 = pageBlocksAdapter.getFile(index); - isVideo = pageBlocksAdapter.isVideo(index); + isVideo = pageBlocksAdapter.isVideo(index) || pageBlocksAdapter.isHardwarePlayer(index); canAutoPlay = shouldIndexAutoPlayed(index); } File f1Final = f1; @@ -13911,7 +13927,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat ImageLocation imageLocation = needFullImage ? ImageLocation.getForPhoto(fileLocation, photo) : null; imageReceiver.setImage(imageLocation, null, imageThumbLocation, "b", thumbPlaceHolder, size[0], null, pageBlocksAdapter.getParentObject(), 1); imageReceiver.setMark(needFullImage ? null : MARK_DEFERRED_IMAGE_LOADING); - } else if (pageBlocksAdapter.isVideo(index)) { + } else if (pageBlocksAdapter.isVideo(index) || pageBlocksAdapter.isHardwarePlayer(index)) { if (!(fileLocation.location instanceof TLRPC.TL_fileLocationUnavailable)) { ImageReceiver.BitmapHolder placeHolder = null; if (currentThumb != null && imageReceiver == centerImage) { @@ -14224,6 +14240,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } isVisible = true; + isVisibleOrAnimating = true; togglePhotosListView(false, false); @@ -14530,6 +14547,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } isVisible = true; + isVisibleOrAnimating = true; togglePhotosListView(false, false); @@ -15072,6 +15090,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat qualityPicker.cancelButton.callOnClick(); return; } + isVisibleOrAnimating = false; openedFullScreenVideo = false; try { if (visibleDialog != null) { @@ -15142,6 +15161,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat view.setScaleY(1f); } } + if (placeProvider != null) { + placeProvider.onReleasePlayerBeforeClose(currentIndex); + } final PlaceProviderObject object = placeProvider.getPlaceForPhoto(currentMessageObject, getFileLocation(currentFileLocation), currentIndex, true); if (videoPlayer != null && object != null) { AnimatedFileDrawable animation = object.imageReceiver.getAnimation(); @@ -15530,6 +15552,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat FileLoader.getInstance(currentAccount).cancelLoadFile(currentMessageObject.getDocument()); } isVisible = false; + isVisibleOrAnimating = false; cropInitied = false; disableShowCheck = true; currentMessageObject = null; @@ -16212,7 +16235,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private boolean shouldIndexAutoPlayed(int index) { if (pageBlocksAdapter != null) { - if (pageBlocksAdapter.isVideo(index) && SharedConfig.isAutoplayVideo()) { + if ((pageBlocksAdapter.isVideo(index) || pageBlocksAdapter.isHardwarePlayer(index)) && SharedConfig.isAutoplayVideo()) { final File mediaFile = pageBlocksAdapter.getFile(index); if (mediaFile != null && mediaFile.exists()) { return true; @@ -17137,7 +17160,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } file = pageBlocksAdapter.getFile(currentIndex); if (file != null && !file.exists()) { - file = null; + uri = FileStreamLoadOperation.prepareUri(currentAccount, (TLRPC.Document) media, pageBlocksAdapter.getParentObject()); + isStreaming = true; } } else if (sendPhotoType == SELECT_TYPE_NO_SELECT) { if (!imagesArrLocals.isEmpty() && currentIndex >= 0 && currentIndex < imagesArrLocals.size()) { @@ -17190,6 +17214,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat return; } preparePlayer(uri, true, false); + videoSizeSet = true; } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PinchToZoomHelper.java b/TMessagesProj/src/main/java/org/telegram/ui/PinchToZoomHelper.java index f995c14db..aab9968f2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PinchToZoomHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PinchToZoomHelper.java @@ -53,6 +53,7 @@ public class PinchToZoomHelper { private ZoomOverlayView overlayView; private View child; private ImageReceiver childImage; + private TextureView childTextureView; private ImageReceiver fullImage = new ImageReceiver(); private ImageReceiver blurImage = new ImageReceiver(); @@ -116,7 +117,7 @@ public class PinchToZoomHelper { this.isSimple = true; } - public void startZoom(View child, ImageReceiver image, MessageObject messageObject) { + public void startZoom(View child, ImageReceiver image, TextureView textureView, MessageObject messageObject) { this.child = child; this.messageObject = messageObject; @@ -202,6 +203,7 @@ public class PinchToZoomHelper { } else { isHardwareVideo = false; this.childImage = new ImageReceiver(); + this.childTextureView = textureView; this.childImage.onAttachedToWindow(); Drawable drawable = image.getDrawable(); this.childImage.setImageBitmap(drawable); @@ -584,6 +586,12 @@ public class PinchToZoomHelper { fullImage.draw(canvas); } } + if (childTextureView != null) { + canvas.save(); + canvas.translate(childImage.getImageX(), childImage.getImageY()); + childTextureView.draw(canvas); + canvas.restore(); + } } else { videoPlayerContainer.setPivotX(pinchCenterX - imageX); videoPlayerContainer.setPivotY(pinchCenterY - imageY); @@ -708,7 +716,7 @@ public class PinchToZoomHelper { void getClipTopBottom(float[] topBottom); } - public boolean checkPinchToZoom(MotionEvent ev, View child, ImageReceiver image, MessageObject messageObject) { + public boolean checkPinchToZoom(MotionEvent ev, View child, ImageReceiver image, TextureView textureView, MessageObject messageObject) { if (!zoomEnabled(child, image)) { return false; } @@ -749,7 +757,7 @@ public class PinchToZoomHelper { pinchTranslationX = 0f; pinchTranslationY = 0f; child.getParent().requestDisallowInterceptTouchEvent(true); - startZoom(child, image, messageObject); + startZoom(child, image, textureView, messageObject); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index 7aa159917..73a99a4da 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -7774,7 +7774,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } onlineTextView[2].setVisibility(View.VISIBLE); - onlineTextView[3].setVisibility(View.VISIBLE); + if (!searchMode) { + onlineTextView[3].setVisibility(View.VISIBLE); + } if (previousTransitionFragment != null) { previousTransitionFragment.checkAndUpdateAvatar(); @@ -8420,6 +8422,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. avatarContainer.setVisibility(View.VISIBLE); nameTextView[1].setVisibility(View.VISIBLE); onlineTextView[1].setVisibility(View.VISIBLE); + onlineTextView[3].setVisibility(View.VISIBLE); actionBar.onSearchFieldVisibilityChanged(searchTransitionProgress > 0.5f); int itemVisibility = searchTransitionProgress > 0.5f ? View.VISIBLE : View.GONE; @@ -8469,6 +8472,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } nameTextView[1].setAlpha(progressHalf); onlineTextView[1].setAlpha(progressHalf); + onlineTextView[3].setAlpha(progressHalf); searchItem.getSearchField().setAlpha(progressHalfEnd); if (enter && searchTransitionProgress < 0.7f) { @@ -8548,6 +8552,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } nameTextView[1].setVisibility(hide); onlineTextView[1].setVisibility(hide); + onlineTextView[3].setVisibility(hide); if (otherItem != null) { otherItem.setAlpha(1f); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/DialogStoriesCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/DialogStoriesCell.java index e272d3c67..69cb3b9f5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/DialogStoriesCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/DialogStoriesCell.java @@ -52,6 +52,7 @@ import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.SimpleTextView; import org.telegram.ui.ActionBar.Theme; +import org.telegram.ui.Components.AnimatedFloat; import org.telegram.ui.Components.AnimatedTextView; import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.ButtonBounce; @@ -333,7 +334,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter } return; } - if (!storiesController.hasStories(cell.dialogId)) { + if (!storiesController.hasStories(cell.dialogId) && (!cell.isSelf || !storiesController.hasUploadingStories())) { return; } TLRPC.TL_userStories userStories = storiesController.getStories(cell.dialogId); @@ -1075,6 +1076,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter SimpleTextView textView; long dialogId; boolean isSelf; + boolean isFail; boolean crossfadeToDialog; long crossfadeToDialogId; @@ -1093,6 +1095,8 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter private float overscrollProgress; private boolean selectedForOverscroll; + private final AnimatedFloat failT = new AnimatedFloat(this, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT); + public StoryCell(Context context) { super(context); params.isArchive = type == TYPE_ARCHIVE; @@ -1138,6 +1142,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter this.dialogId = dialogId; isSelf = dialogId == UserConfig.getInstance(currentAccount).getClientUserId(); + isFail = isSelf && storiesController.isLastUploadingFailed(); TLObject object; if (dialogId > 0) { object = user = MessagesController.getInstance(currentAccount).getUser(dialogId); @@ -1159,7 +1164,10 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter } if (dialogId == UserConfig.getInstance(currentAccount).getClientUserId()) { textView.setRightDrawable(null); - if (!storiesController.getUploadingStories().isEmpty()) { + if (storiesController.isLastUploadingFailed()) { + textView.setText(LocaleController.getString("FailedStory", R.string.FailedStory)); + isUploadingState = false; + } else if (!storiesController.getUploadingStories().isEmpty()) { StoriesUtilities.applyUploadingStr(textView, true, false); isUploadingState = true; } else if (storiesController.getEditingStory() != null) { @@ -1340,6 +1348,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter drawCircleForce = true; invalidate(); } else { + float failT = this.failT.set(isFail); if (drawAvatar) { if (progressWasDrawn) { animateBounce(); @@ -1360,14 +1369,23 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter 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); - // avatarImage.draw(canvas); + + 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) { @@ -1375,6 +1393,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter 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(); } } @@ -1542,6 +1561,31 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter addNewStoryDrawable.draw(canvas); } + public void drawFail(Canvas canvas, float cx, float cy, float alpha) { + if (!isSelf || alpha <= 0) { + return; + } + float cx2 = cx + AndroidUtilities.dp(17); + float cy2 = cy + AndroidUtilities.dp(17); + addCirclePaint.setColor(Theme.multAlpha(Theme.getColor(Theme.key_text_RedBold), alpha)); + if (type == TYPE_DIALOGS) { + backgroundPaint.setColor(Theme.multAlpha(Theme.getColor(Theme.key_actionBarDefault), alpha)); + } else { + backgroundPaint.setColor(Theme.multAlpha(Theme.getColor(Theme.key_actionBarDefaultArchived), alpha)); + } + float r = AndroidUtilities.dp(9) * CubicBezierInterpolator.EASE_OUT_BACK.getInterpolation(alpha); + canvas.drawCircle(cx2, cy2, r + AndroidUtilities.dp(2), backgroundPaint); + canvas.drawCircle(cx2, cy2, r, addCirclePaint); + + addCirclePaint.setColor(Theme.multAlpha(getTextColor(), alpha)); + + AndroidUtilities.rectTmp.set(cx2 - AndroidUtilities.dp(1), cy2 - AndroidUtilities.dpf2(4.6f), cx2 + AndroidUtilities.dp(1), cy2 + AndroidUtilities.dpf2(1.6f)); + canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(3), AndroidUtilities.dp(3), addCirclePaint); + + AndroidUtilities.rectTmp.set(cx2 - AndroidUtilities.dp(1), cy2 + AndroidUtilities.dpf2(2.6f), cx2 + AndroidUtilities.dp(1), cy2 + AndroidUtilities.dpf2(2.6f + 2)); + canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(3), AndroidUtilities.dp(3), addCirclePaint); + } + @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/PeerStoriesView.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/PeerStoriesView.java index 609e5d462..593dcb3c7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/PeerStoriesView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/PeerStoriesView.java @@ -42,6 +42,7 @@ import android.view.SurfaceView; import android.view.TextureView; import android.view.View; import android.view.ViewGroup; +import android.view.ViewPropertyAnimator; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; @@ -125,6 +126,7 @@ import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LoadingDrawable; import org.telegram.ui.Components.MediaActivity; import org.telegram.ui.Components.MentionsContainerView; +import org.telegram.ui.Components.Premium.LimitReachedBottomSheet; import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet; import org.telegram.ui.Components.RLottieDrawable; import org.telegram.ui.Components.RLottieImageView; @@ -240,12 +242,15 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica Delegate delegate; private boolean paused; StoriesController storiesController; - private boolean isUploading, isEditing; + private boolean isUploading, isEditing, isFailed; private FrameLayout selfView; ChatActivityEnterView chatActivityEnterView; private ValueAnimator changeBoundAnimator; ReactionsContainerLayout reactionsContainerLayout; + private StoryFailView failView; + private ViewPropertyAnimator failViewAnimator; + Paint inputBackgroundPaint; int lastKeyboardHeight; @@ -431,12 +436,12 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica imageReceiver.setImageCoords(0, 0, getMeasuredWidth(), getMeasuredHeight() + 1); imageReceiver.draw(canvas); if (isActive) { - if (storyViewer.USE_SURFACE_VIEW && playerSharedScope.player != null && playerSharedScope.player.paused && storyViewer.playerStubBitmap != null && playerSharedScope.player.stubAvailable) { - float sx = getMeasuredWidth() / (float) storyViewer.playerStubBitmap.getWidth(); - float sy = getMeasuredHeight() / (float) storyViewer.playerStubBitmap.getHeight(); + if (storyViewer.USE_SURFACE_VIEW && playerSharedScope.player != null && playerSharedScope.player.paused && playerSharedScope.player.playerStubBitmap != null && playerSharedScope.player.stubAvailable) { + float sx = getMeasuredWidth() / (float) playerSharedScope.player.playerStubBitmap.getWidth(); + float sy = getMeasuredHeight() / (float) playerSharedScope.player.playerStubBitmap.getHeight(); canvas.save(); canvas.scale(sx, sy); - canvas.drawBitmap(storyViewer.playerStubBitmap, 0, 0, storyViewer.playerStubPaint); + canvas.drawBitmap(playerSharedScope.player.playerStubBitmap, 0, 0, playerSharedScope.player.playerStubPaint); canvas.restore(); } else { if (!storyViewer.USE_SURFACE_VIEW || allowDrawSurface) { @@ -467,11 +472,11 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica } boolean storyDrawing; if (currentStory.isVideo) { - storyDrawing = playerSharedScope.renderView != null && playerSharedScope.firstFrameRendered && !(playerSharedScope.player.progress == 0 && playerSharedScope.isBuffering()); + storyDrawing = playerSharedScope.renderView != null && playerSharedScope.player != null && playerSharedScope.firstFrameRendered && !(playerSharedScope.player.progress == 0 && playerSharedScope.isBuffering() && !playerSharedScope.player.paused); } else { storyDrawing = imageReceiver.hasNotThumb(); } - loadingDrawableAlpha2.set(!storyDrawing && currentStory.uploadingStory == null ? 1f : 0f); + loadingDrawableAlpha2.set(isActive && !storyDrawing && currentStory.uploadingStory == null ? 1f : 0f); loadingDrawableAlpha.set(loadingDrawableAlpha2.get() == 1f ? 1f : 0); if (loadingDrawableAlpha.get() > 0) { @@ -617,7 +622,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica } } invalidate(); - } else if (!paused && isActive && !isUploading && !isEditing && imageReceiver.hasNotThumb()) { + } else if (!paused && isActive && !isUploading && !isEditing && !isFailed && imageReceiver.hasNotThumb()) { long currentTime = System.currentTimeMillis(); if (lastDrawTime != 0) { if (!isCaptionPartVisible) { @@ -638,7 +643,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica switchEventSent = true; post(() -> { if (delegate != null) { - if (isUploading || isEditing) { + if (isUploading || isEditing || isFailed) { if (currentStory.isVideo()) { playerSharedScope.player.loopBack(); } else { @@ -951,6 +956,17 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica if (isSelf) { TLRPC.StoryItem storyItem = currentStory.storyItem; if (currentStory.uploadingStory != null) { +// if (currentStory.uploadingStory.failed) { +// ActionBarMenuSubItem item = ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_edit, LocaleController.getString("Edit", R.string.Edit), false, resourcesProvider); +// item.setOnClickListener(v -> { +// Activity activity = AndroidUtilities.findActivity(context); +// if (activity == null) { +// return; +// } +// StoryRecorder.getInstance(activity, currentAccount) +// .openEdit(StoryRecorder.SourceView.fromStoryViewer(storyViewer), currentStory.uploadingStory.entry, 0, true); +// }); +// } ActionBarMenuSubItem item = ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_cancel, LocaleController.getString("Cancel", R.string.Cancel), false, resourcesProvider); item.setOnClickListener(v -> { if (currentStory.uploadingStory != null) { @@ -1079,7 +1095,9 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica }); } - createStealthModeItem(popupLayout); + if (!MessagesController.getInstance(currentAccount).premiumLocked) { + createStealthModeItem(popupLayout); + } if (allowShareLink) { ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_shareout, LocaleController.getString("BotShare", R.string.BotShare), false, resourcesProvider).setOnClickListener(v -> { @@ -1171,7 +1189,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica popupMenu.dismiss(); } }); - } else { + } else if (!MessagesController.getInstance(currentAccount).premiumLocked) { Drawable lockIcon = ContextCompat.getDrawable(context, R.drawable.msg_gallery_locked2); lockIcon.setColorFilter(new PorterDuffColorFilter(ColorUtils.blendARGB(Color.WHITE, Color.BLACK, 0.5f), PorterDuff.Mode.MULTIPLY)); CombinedDrawable combinedDrawable = new CombinedDrawable( @@ -1200,7 +1218,9 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica } } - createStealthModeItem(popupLayout); + if (!MessagesController.getInstance(currentAccount).premiumLocked) { + createStealthModeItem(popupLayout); + } if (allowShareLink) { ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_link, LocaleController.getString("CopyLink", R.string.CopyLink), false, resourcesProvider).setOnClickListener(v -> { AndroidUtilities.addToClipboard(currentStory.createLink()); @@ -1628,6 +1648,22 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica return false;//linesCount > 20; } + private void createFailView() { + if (failView != null) { + return; + } + failView = new StoryFailView(getContext(), resourcesProvider); + failView.setOnClickListener(v -> { + if (currentStory != null && currentStory.uploadingStory != null) { + currentStory.uploadingStory.tryAgain(); + updatePosition(); + } + }); + failView.setAlpha(0f); + failView.setVisibility(View.GONE); + addView(failView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM, 0, 0, 0, 0)); + } + private void createEnterView() { Theme.ResourcesProvider emojiResourceProvider = new WrappedResourceProvider(resourcesProvider) { @Override @@ -1960,7 +1996,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica params.put("query_id", "" + result.query_id); params.put("bot", "" + uid); params.put("bot_name", mentionContainer.getAdapter().getContextBotName()); - SendMessagesHelper.prepareSendingBotContextResult(storyViewer.fragment, getAccountInstance(), result, params, dialogId, null, null, null, notify, scheduleDate); + SendMessagesHelper.prepareSendingBotContextResult(storyViewer.fragment, getAccountInstance(), result, params, dialogId, null, null, currentStory.storyItem, notify, scheduleDate); chatActivityEnterView.setFieldText(""); afterMessageSend(); MediaDataController.getInstance(currentAccount).increaseInlineRaiting(uid); @@ -2372,14 +2408,15 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica if (chatActivityEnterView == null) { createEnterView(); } + if (failView != null) { + failView.setVisibility(View.GONE); + } if (startFromPosition == -1) { updateSelectedPosition(); } if (chatActivityEnterView != null) { chatActivityEnterView.setVisibility(View.VISIBLE); - if (!TextUtils.isEmpty(chatActivityEnterView.getEditField().getText())) { - chatActivityEnterView.getEditField().setText(""); - } + chatActivityEnterView.getEditField().setText(storyViewer.getDraft(dialogId, currentStory.storyItem)); chatActivityEnterView.setDialogId(dialogId, currentAccount); TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(dialogId); if (userFull != null) { @@ -2717,6 +2754,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.storiesUpdated); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.storiesListUpdated); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.stealthModeChanged); + NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.storiesLimitUpdate); NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded); } @@ -2744,6 +2782,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.storiesUpdated); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.storiesListUpdated); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.stealthModeChanged); + NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.storiesLimitUpdate); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded); } @@ -2782,6 +2821,44 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica storyCaptionView.captionTextview.invalidate(); } else if (id == NotificationCenter.stealthModeChanged) { checkStealthMode(true); + } else if (id == NotificationCenter.storiesLimitUpdate) { + StoriesController.StoryLimit storyLimit = MessagesController.getInstance(currentAccount).getStoriesController().checkStoryLimit(); + if (storyLimit == null || delegate == null) { + return; + } + final Activity activity = storyViewer != null && storyViewer.parentActivity != null ? storyViewer.parentActivity : AndroidUtilities.findActivity(getContext()); + if (activity == null) { + return; + } + final LimitReachedBottomSheet sheet = new LimitReachedBottomSheet(new BaseFragment() { + @Override + public boolean isLightStatusBar() { + return false; + } + + @Override + public Activity getParentActivity() { + return activity; + } + + @Override + public Theme.ResourcesProvider getResourceProvider() { + return new WrappedResourceProvider(resourcesProvider) { + @Override + public void appendColors() { + sparseIntArray.append(Theme.key_dialogBackground, 0xFF1F1F1F); + sparseIntArray.append(Theme.key_windowBackgroundGray, 0xFF333333); + } + }; + } + + @Override + public boolean presentFragment(BaseFragment fragment) { + storyViewer.presentFragment(fragment); + return true; + } + }, activity, storyLimit.getLimitReachedType(), currentAccount); + delegate.showDialog(sheet); } } @@ -2830,6 +2907,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica final boolean wasUploading = isUploading; final boolean wasEditing = isEditing; + final boolean wasFailed = isFailed; currentStory.editingSourceItem = null; if (!uploadingStories.isEmpty() && position >= storyItems.size()) { @@ -2840,6 +2918,8 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica return; } StoriesController.UploadingStory uploadingStory = uploadingStories.get(position); + isFailed = uploadingStory.failed; + isUploading = !isFailed; Drawable thumbDrawable = null; imageReceiver.setCrossfadeWithOldImage(false); imageReceiver.setCrossfadeDuration(ImageReceiver.DEFAULT_CROSSFADE_DURATION); @@ -2848,7 +2928,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica Utilities.blurBitmap(blurredBitmap, 3, 1, blurredBitmap.getWidth(), blurredBitmap.getHeight(), blurredBitmap.getRowBytes()); thumbDrawable = new BitmapDrawable(blurredBitmap); } - if (uploadingStory.isVideo) { + if (uploadingStory.isVideo || uploadingStory.hadFailed) { imageReceiver.setImage(null, null, ImageLocation.getForPath(uploadingStory.firstFramePath), filter, null, null, thumbDrawable, 0, null, null, 0); } else { imageReceiver.setImage(null, null, ImageLocation.getForPath(uploadingStory.path), filter, null, null, thumbDrawable, 0, null, null, 0); @@ -2859,6 +2939,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica } else { isUploading = false; isEditing = false; + isFailed = false; if (position < 0 || position > storyItems.size() - 1) { storyViewer.close(true); return; @@ -2968,7 +3049,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica final boolean sameId = getStoryId(currentStory.storyItem, currentStory.uploadingStory) == getStoryId(oldStoryItem, oldUploadingStory) || oldUploadingStory != null && currentStory.storyItem != null && TextUtils.equals(oldUploadingStory.path, currentStory.storyItem.attachPath); - final boolean animateSubtitle = sameId && (isEditing != wasEditing || isUploading != wasUploading); + final boolean animateSubtitle = sameId && (isEditing != wasEditing || isUploading != wasUploading || isFailed != wasFailed); boolean storyChanged = false; if (!( @@ -2977,7 +3058,10 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica )) { storyChanged = true; if (chatActivityEnterView != null) { - chatActivityEnterView.getEditField().setText(""); + if (oldStoryItem != null) { + storyViewer.saveDraft(oldStoryItem.dialogId, oldStoryItem, chatActivityEnterView.getEditField().getText()); + } + chatActivityEnterView.getEditField().setText(storyViewer.getDraft(dialogId, currentStory.storyItem)); } currentImageTime = 0; switchEventSent = false; @@ -2997,7 +3081,11 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica if (storyChanged || oldUploadingStory != null && currentStory.uploadingStory == null) { if (currentStory.uploadingStory != null) { - headerView.setSubtitle(StoriesUtilities.getUploadingStr(headerView.subtitleView[0], false, isEditing), animateSubtitle); + if (currentStory.uploadingStory.failed) { + headerView.setSubtitle(LocaleController.getString("FailedToUploadStory", R.string.FailedToUploadStory), animateSubtitle); + } else { + headerView.setSubtitle(StoriesUtilities.getUploadingStr(headerView.subtitleView[0], false, isEditing), animateSubtitle); + } } else if (currentStory.storyItem != null) { if (currentStory.storyItem.date == -1) { headerView.setSubtitle(LocaleController.getString("CachedStory", R.string.CachedStory)); @@ -3144,26 +3232,36 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica } } -// final boolean closeFriends = currentStory.forCloseFriends(); -// if (oldStoryItem != null && currentStory.storyItem != null && oldStoryItem.id == currentStory.storyItem.id) { -// if (closeFriends) { -// closeFriendsBadge.setVisibility(View.VISIBLE); -// } -// closeFriendsBadge.clearAnimation(); -// closeFriendsBadge.animate().scaleX(closeFriends ? 1 : 0).scaleY(closeFriends ? 1 : 0).withEndAction(() -> { -// if (!closeFriends) { -// closeFriendsBadge.setVisibility(View.GONE); -// } -// }).setInterpolator(closeFriends ? new OvershootInterpolator(3) : CubicBezierInterpolator.DEFAULT).setDuration(closeFriends ? 240 : 120).start(); -// } else { -// closeFriendsBadge.setScaleX(closeFriends ? 1 : 0); -// closeFriendsBadge.setScaleY(closeFriends ? 1 : 0); -// closeFriendsBadge.setVisibility(currentStory.forCloseFriends() ? View.VISIBLE : View.GONE); -// } -// closeFriendsBadge.setTranslationX(muteIconContainer.getVisibility() == View.VISIBLE ? -AndroidUtilities.dp(44) : 0); - //sharedResources.muteDrawable.setIcon(storyViewer.soundEnabled() ? R.drawable.media_mute : R.drawable.media_unmute, false); - sharedResources.setIconMuted(!storyViewer.soundEnabled(), false); + if (currentStory.uploadingStory != null && currentStory.uploadingStory.failed) { + createFailView(); + failView.set(currentStory.uploadingStory.entry.error); + failView.setVisibility(View.VISIBLE); + if (failViewAnimator != null) { + failViewAnimator.cancel(); + failViewAnimator = null; + } + if (sameId) { + failViewAnimator = failView.animate().alpha(1f).setDuration(180).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT); + failViewAnimator.start(); + } else { + failView.setAlpha(1f); + } + } else if (failView != null) { + if (failViewAnimator != null) { + failViewAnimator.cancel(); + failViewAnimator = null; + } + if (sameId) { + failView.setVisibility(View.VISIBLE); + failViewAnimator = failView.animate().alpha(0f).setDuration(180).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).withEndAction(() -> failView.setVisibility(View.GONE)); + failViewAnimator.start(); + } else { + failView.setAlpha(0f); + failView.setVisibility(View.GONE); + } + } + sharedResources.setIconMuted(!storyViewer.soundEnabled(), false); if (isActive && currentStory.storyItem != null) { FileLog.d("StoryViewer displayed story dialogId=" + dialogId + " storyId=" + currentStory.storyItem.id); } @@ -3244,6 +3342,9 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica StoriesController.UploadingStory uploadingStory = uploadingStories.get(position); setStoryImage(uploadingStory, imageReceiver, filter); } else { + if (storyItems.isEmpty()) { + continue; + } if (position < 0) { position = 0; } @@ -3654,6 +3755,9 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica updatePreloadImages(); muteIconView.setAnimation(sharedResources.muteDrawable); isActive = true; + if (currentStory.storyItem != null) { + FileLog.d("StoryViewer displayed story dialogId=" + dialogId + " storyId=" + currentStory.storyItem.id); + } //storyViewer.allowScreenshots(allowScreenshots); } else { @@ -3809,7 +3913,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica } public void checkPinchToZoom(MotionEvent ev) { - pinchToZoomHelper.checkPinchToZoom(ev, storyContainer, null, null); + pinchToZoomHelper.checkPinchToZoom(ev, storyContainer, null, null,null); } @@ -4056,7 +4160,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica if ((storyItemHolder != null && storyItemHolder.uploadingStory != null) || progressToUploading != 0) { float progress = 1f; final boolean disappearing; - if (storyItemHolder != null && storyItemHolder.uploadingStory != null) { + if (storyItemHolder != null && storyItemHolder.uploadingStory != null && !storyItemHolder.uploadingStory.failed) { progressToUploading = 1f; progress = storyItemHolder.uploadingStory.progress; disappearing = false; @@ -4451,6 +4555,8 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica lastOpenedKeyboardHeight = keyboardHeight; checkReactionsLayout(); ReactionsEffectOverlay.dismissAll(); + } else { + storyViewer.saveDraft(dialogId, currentStory.storyItem, chatActivityEnterView.getEditText()); } if (keyboardVisible && mentionContainer != null) { mentionContainer.setVisibility(View.VISIBLE); @@ -4882,6 +4988,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica instantCameraView.resetCameraFile(); instantCameraView.cancel(false); } + storyViewer.clearDraft(dialogId, currentStory.storyItem); messageSent = true; storyViewer.closeKeyboardOrEmoji(); BulletinFactory bulletinFactory = BulletinFactory.of(storyContainer, resourcesProvider); @@ -5152,7 +5259,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica @Override public boolean needEnterText() { - delegate.requestAdjust(true); + delegate.requestAdjust(false); return false; } }); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/ProfileStoriesView.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/ProfileStoriesView.java index d9a266178..43b959a42 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/ProfileStoriesView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/ProfileStoriesView.java @@ -840,7 +840,7 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif if (a != null && b != null) { final RectF aRect = new RectF(a.cachedRect), bRect = new RectF(b.cachedRect); final StoryCircle circle = a, nextCircle = b; - holder.drawClip = (canvas, bounds, alpha) -> { + holder.drawClip = (canvas, bounds, alpha, opening) -> { aRect.set(circle.cachedRect); bRect.set(nextCircle.cachedRect); circle.cachedRect.set(bounds); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/SelfStoryViewsPage.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/SelfStoryViewsPage.java index f060affe9..567625ec5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/SelfStoryViewsPage.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/SelfStoryViewsPage.java @@ -642,7 +642,7 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente updateViewsVisibility(); } listAdapter.updateRows(); - recyclerItemsEnterAnimator.showItemsAnimated(oldCount); + recyclerItemsEnterAnimator.showItemsAnimated(oldCount - 1); checkLoadMore(); // }); } @@ -742,8 +742,15 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente view = new ReactedUserHolderView(ReactedUserHolderView.STYLE_STORY, currentAccount, getContext(), resourcesProvider) { @Override public void openStory(long dialogId, Runnable onDone) { - LaunchActivity.getLastFragment().getOrCreateOverlayStoryViewer().doOnAnimationReady(onDone); - LaunchActivity.getLastFragment().getOrCreateOverlayStoryViewer().open(getContext(), dialogId, StoriesListPlaceProvider.of(recyclerListView)); + BaseFragment lastFragment = LaunchActivity.getLastFragment(); + if (lastFragment == null) { + return; + } + if (lastFragment.getOrCreateOverlayStoryViewer().isShowing) { + return; + } + lastFragment.getOrCreateOverlayStoryViewer().doOnAnimationReady(onDone); + lastFragment.getOrCreateOverlayStoryViewer().open(getContext(), dialogId, StoriesListPlaceProvider.of(recyclerListView)); } }; break; @@ -830,14 +837,12 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente emptyView.title.setVisibility(View.GONE); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); spannableStringBuilder.append(AndroidUtilities.replaceTags(LocaleController.getString("ExpiredViewsStub", R.string.ExpiredViewsStub))); - spannableStringBuilder.append("\n\n"); - spannableStringBuilder.append(AndroidUtilities.replaceSingleTag(LocaleController.getString("ExpiredViewsStubPremiumDescription", R.string.ExpiredViewsStubPremiumDescription), () -> { - showPremiumAlert(); - })); + if (!MessagesController.getInstance(currentAccount).premiumLocked) { + spannableStringBuilder.append("\n\n"); + spannableStringBuilder.append(AndroidUtilities.replaceSingleTag(LocaleController.getString("ExpiredViewsStubPremiumDescription", R.string.ExpiredViewsStubPremiumDescription), SelfStoryViewsPage.this::showPremiumAlert)); + emptyView.createButtonLayout(LocaleController.getString("LearnMore", R.string.LearnMore), SelfStoryViewsPage.this::showPremiumAlert); + } emptyView.subtitle.setText(spannableStringBuilder); - emptyView.createButtonLayout(LocaleController.getString("LearnMore", R.string.LearnMore), () -> { - showPremiumAlert(); - }); } else { emptyView.title.setVisibility(View.VISIBLE); emptyView.title.setText(LocaleController.getString("NoViews", R.string.NoViews)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/SelfStoryViewsView.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/SelfStoryViewsView.java index 2f5f5e1f4..ff177e741 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/SelfStoryViewsView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/SelfStoryViewsView.java @@ -312,7 +312,8 @@ public class SelfStoryViewsView extends FrameLayout { final PeerStoriesView currentView = storyViewer.getCurrentPeerView(); if (oldProgressToOpen == 1f && progressToOpen != 1f) { if (storyViewer.storiesList != null) { - MessageObject object = storyViewer.storiesList.messageObjects.get(selfStoriesPreviewView.getClosestPosition()); + int p = Utilities.clamp(selfStoriesPreviewView.getClosestPosition(), storyViewer.storiesList.messageObjects.size() - 1, 0); + MessageObject object = storyViewer.storiesList.messageObjects.get(p); long date = StoriesController.StoriesList.day(object); if (storyViewer.transitionViewHolder.storyImage != null) { storyViewer.transitionViewHolder.storyImage.setVisible(true, true); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesController.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesController.java index 11e61e965..cf51f151d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesController.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesController.java @@ -8,6 +8,7 @@ import android.util.SparseArray; import android.webkit.MimeTypeMap; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.collection.LongSparseArray; import com.google.android.exoplayer2.util.Consumer; @@ -199,9 +200,11 @@ public class StoriesController { for (int k = 0; k < list.size(); k++) { TLRPC.TL_userStories userStories = list.get(k); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(userStories.user_id); + boolean removed = false; if (user != null && !isContactOrService(user)) { list.remove(k); k--; + removed = true; } for (int i = 0; i < userStories.stories.size(); i++) { if (userStories.stories.get(i) instanceof TLRPC.TL_storyItemDeleted) { @@ -209,7 +212,7 @@ public class StoriesController { i--; } } - if (userStories.stories.isEmpty()) { + if (!removed && userStories.stories.isEmpty()) { list.remove(k); k--; } @@ -222,6 +225,9 @@ public class StoriesController { } public boolean hasStories(long dialogId) { + if (getSelfUserId() == dialogId && hasUploadingStories()) { + return true; + } TLRPC.TL_userStories stories = allStoriesMap.get(dialogId); return stories != null && !stories.stories.isEmpty(); } @@ -389,8 +395,16 @@ public class StoriesController { hiddenListStories.clear(); } } - FileLog.d("StoriesController processAllStoriesResponse " + storiesResponse.user_stories.size() + " " + fromCache + " " + hidden); - + if (BuildVars.LOGS_ENABLED) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < storiesResponse.user_stories.size(); i++) { + if (builder.length() != 0) { + builder.append(", "); + } + builder.append(storiesResponse.user_stories.get(i).user_id); + } + FileLog.d("StoriesController cache=" + fromCache + " hidden=" + hidden + " processAllStoriesResponse {" + builder + "}"); + } MessagesController.getInstance(currentAccount).putUsers(storiesResponse.users, fromCache); for (int i = 0; i < storiesResponse.user_stories.size(); i++) { @@ -406,14 +420,12 @@ public class StoriesController { allStoriesMap.put(userStories.user_id, userStories); for (int k = 0; k < 2; k++) { ArrayList storiesList = k == 0 ? hiddenListStories : dialogListStories; - // if (isNext) { - for (int j = 0; j < storiesList.size(); j++) { - if (storiesList.get(j).user_id == userStories.user_id) { - storiesList.remove(j); - break; - } + for (int j = 0; j < storiesList.size(); j++) { + if (storiesList.get(j).user_id == userStories.user_id) { + storiesList.remove(j); + break; } - // } + } } TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(userStories.user_id); if (user == null) { @@ -523,6 +535,13 @@ public class StoriesController { NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesUpdated); } + public void putUploadingDrafts(ArrayList entries) { + for (StoryEntry entry : entries) { + uploadingStories.add(new UploadingStory(entry)); + } + NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesUpdated); + } + public ArrayList getDialogListStories() { return dialogListStories; } @@ -535,6 +554,13 @@ public class StoriesController { return uploadingStories; } + public boolean isLastUploadingFailed() { + if (uploadingStories.isEmpty()) { + return false; + } + return uploadingStories.get(uploadingStories.size() - 1).failed; + } + public ArrayList getUploadingAndEditingStories() { return uploadingAndEditingStories; } @@ -910,7 +936,9 @@ public class StoriesController { TLRPC.TL_userStories userStories = getStories(dialogId); if (userStories == null) { TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(dialogId); - userStories = userFull.stories; + if (userFull != null) { + userStories = userFull.stories; + } } return markStoryAsRead(userStories, storyItem, false); } @@ -1361,13 +1389,17 @@ public class StoriesController { private boolean putMessages; private boolean isCloseFriends; + public boolean hadFailed; + public boolean failed; + public UploadingStory(StoryEntry entry) { + this.entry = entry; random_id = Utilities.random.nextLong(); edit = entry.isEdit; - this.entry = entry; if (entry.uploadThumbFile != null) { this.firstFramePath = entry.uploadThumbFile.getAbsolutePath(); } + failed = hadFailed = entry.isError; } private void startForeground() { @@ -1425,6 +1457,21 @@ public class StoriesController { startForeground(); } + public void tryAgain() { + failed = false; + entryDestroyed = false; + progress = 0; + uploadProgress = 0; + convertingProgress = 0; + if (path != null) { + try { + new File(path).delete(); + path = null; + } catch (Exception ignore) {} + } + start(); + } + private void upload() { if (entry.shareUserIds != null) { putMessages(); @@ -1440,7 +1487,9 @@ public class StoriesController { NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.filePreparingFailed); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.filePreparingStarted); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.fileNewChunkAvailable); - uploadingStories.remove(UploadingStory.this); + if (!failed) { + uploadingStories.remove(UploadingStory.this); + } uploadingAndEditingStories.remove(UploadingStory.this); if (edit) { editingStories.remove(entry.editStoryId); @@ -1484,7 +1533,15 @@ public class StoriesController { } } else if (id == NotificationCenter.filePreparingFailed) { if (args[0] == messageObject) { - // TODO + if (!edit) { + entry.isError = true; + entry.error = new TLRPC.TL_error(); + entry.error.code = 400; + entry.error.text = "FILE_PREPARE_FAILED"; + entryDestroyed = true; + hadFailed = failed = true; + getDraftsController().edit(entry); + } cleanup(); } } else if (id == NotificationCenter.fileUploaded) { @@ -1659,8 +1716,9 @@ public class StoriesController { req = sendStory; } - currentRequest = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> { + final RequestDelegate requestDelegate = (response, error) -> { if (response != null) { + failed = false; TLRPC.Updates updates = (TLRPC.Updates) response; int storyId = 0; TLRPC.StoryItem storyItem = null; @@ -1713,6 +1771,11 @@ public class StoriesController { final TLRPC.StoryItem storyItemFinal = storyItem; AndroidUtilities.runOnUIThread(() -> { entryDestroyed = true; + if (entry.isError) { + getDraftsController().delete(entry); + } + entry.isError = false; + entry.error = null; getDraftsController().saveForEdit(entry, did, storyItemFinal); if (!edit) { invalidateStoryLimit(); @@ -1720,10 +1783,31 @@ public class StoriesController { }); MessagesController.getInstance(currentAccount).processUpdateArray(updates.updates, updates.users, updates.chats, false, updates.date); } + } else if (error != null && !edit) { + AndroidUtilities.runOnUIThread(() -> { + entry.isError = true; + if (checkStoryError(error)) { + entry.error = null; + } else { + entry.error = error; + } + entryDestroyed = true; + hadFailed = failed = true; + getDraftsController().edit(entry); + }); } AndroidUtilities.runOnUIThread(this::cleanup); - }); + }; + + if (BuildVars.DEBUG_PRIVATE_VERSION && !edit && entry.caption != null && entry.caption.toString().contains("#failtest") && !hadFailed) { + TLRPC.TL_error error = new TLRPC.TL_error(); + error.code = 400; + error.text = "FORCED_TO_FAIL"; + requestDelegate.run(null, error); + } else { + currentRequest = ConnectionsManager.getInstance(currentAccount).sendRequest(req, requestDelegate); + } } private void putMessages() { @@ -1745,6 +1829,10 @@ public class StoriesController { } public void cancel() { + if (failed) { + getDraftsController().delete(entry); + uploadingStories.remove(UploadingStory.this); + } canceled = true; if (entry.wouldBeVideo()) { MediaController.getInstance().cancelVideoConvert(messageObject); @@ -1763,12 +1851,16 @@ public class StoriesController { private final HashMap[] storiesLists = new HashMap[2]; - @NonNull + @Nullable public StoriesList getStoriesList(long userId, int type) { return getStoriesList(userId, type, true); } + @Nullable private StoriesList getStoriesList(long userId, int type, boolean createIfNotExist) { + if (type == StoriesList.TYPE_ARCHIVE && userId != getSelfUserId()) { + return null; + } if (storiesLists[type] == null) { storiesLists[type] = new HashMap<>(); } @@ -2711,26 +2803,49 @@ public class StoriesController { storyLimitFetched = true; if (res instanceof TLRPC.TL_boolTrue) { storyLimitCached = null; - } else if (err != null && err.text != null) { - if (err.text.startsWith("STORY_SEND_FLOOD_WEEKLY_")) { - long until = 0; - try { - until = Long.parseLong(err.text.substring("STORY_SEND_FLOOD_WEEKLY_".length())); - } catch (Exception ignore) {} - storyLimitCached = new StoryLimit(StoryLimit.LIMIT_WEEK, until); - } else if (err.text.startsWith("STORY_SEND_FLOOD_MONTHLY_")) { - long until = 0; - try { - until = Long.parseLong(err.text.substring("STORY_SEND_FLOOD_MONTHLY_".length())); - } catch (Exception ignore) {} - storyLimitCached = new StoryLimit(StoryLimit.LIMIT_MONTH, until); - } + NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesLimitUpdate); + } else { + checkStoryError(err); } - NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesLimitUpdate); - })); + }), ConnectionsManager.RequestFlagDoNotWaitFloodWait); return null; } + public boolean checkStoryError(TLRPC.TL_error err) { + boolean limitUpdate = false; + if (err != null && err.text != null) { + if (err.text.startsWith("STORY_SEND_FLOOD_WEEKLY_")) { + long until = 0; + try { + until = Long.parseLong(err.text.substring("STORY_SEND_FLOOD_WEEKLY_".length())); + } catch (Exception ignore) {} + storyLimitCached = new StoryLimit(StoryLimit.LIMIT_WEEK, until); + limitUpdate = true; + } else if (err.text.startsWith("STORY_SEND_FLOOD_MONTHLY_")) { + long until = 0; + try { + until = Long.parseLong(err.text.substring("STORY_SEND_FLOOD_MONTHLY_".length())); + } catch (Exception ignore) {} + storyLimitCached = new StoryLimit(StoryLimit.LIMIT_MONTH, until); + limitUpdate = true; + } else if (err.text.equals("STORIES_TOO_MUCH")) { + storyLimitCached = new StoryLimit(StoryLimit.LIMIT_COUNT, 0); + limitUpdate = true; + } else if (err.text.equals("PREMIUM_ACCOUNT_REQUIRED")) { + MessagesController mc = MessagesController.getInstance(currentAccount); + if ("enabled".equals(mc.storiesPosting)) { + mc.getMainSettings().edit().putString("storiesPosting", mc.storiesPosting = "premium").apply(); + NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesEnabledUpdate); + } + limitUpdate = true; + } + } + if (limitUpdate) { + NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesLimitUpdate); + } + return limitUpdate; + } + public boolean hasStoryLimit() { StoryLimit storyLimit = checkStoryLimit(); return storyLimit != null && storyLimit.active(currentAccount); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesListPlaceProvider.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesListPlaceProvider.java index b3e0e61cb..e5ddb45c8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesListPlaceProvider.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesListPlaceProvider.java @@ -1,7 +1,11 @@ package org.telegram.ui.Stories; +import static org.telegram.messenger.AndroidUtilities.dp; + import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Region; import android.view.View; import org.telegram.messenger.AndroidUtilities; @@ -9,6 +13,7 @@ import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessagesController; import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserConfig; +import org.telegram.messenger.Utilities; import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.Cells.ChatActionCell; @@ -102,12 +107,23 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider { holder.clipParent = storiesCell; holder.clipTop = holder.clipBottom = 0; holder.alpha = 1; + if (cell.isFail) { + final Path path = new Path(); + holder.drawClip = (canvas, bounds, alpha, opening) -> { + path.rewind(); + final float t = opening ? 1f - (float) Math.pow(1f - alpha, 2) : (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); + canvas.clipPath(path, Region.Op.DIFFERENCE); + }; + } else { + holder.drawClip = null; + } // updateClip(holder); return true; } } else if (child instanceof DialogCell) { DialogCell cell = (DialogCell) child; - if (cell.getDialogId() == dialogId || (isHiddenArchive && cell.isDialogFolder())) { + if ((cell.getDialogId() == dialogId && !isHiddenArchive) || (isHiddenArchive && cell.isDialogFolder())) { holder.view = child; holder.params = cell.storyParams; holder.avatarImage = cell.avatarImage; @@ -162,7 +178,7 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider { } holder.view = child; holder.storyImage = cell.imageReceiver; - holder.drawAbove = (canvas, bounds, alpha) -> { + holder.drawAbove = (canvas, bounds, alpha, opening) -> { cell.drawDuration(canvas, bounds, alpha); if (fastScroll != null && fastScroll.isVisible && fastScroll.getVisibility() == View.VISIBLE) { canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), (int) (0xFF * alpha), Canvas.ALL_SAVE_FLAG); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesStorage.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesStorage.java index 8f5016e4d..ff3012f0a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesStorage.java @@ -281,11 +281,11 @@ public class StoriesStorage { } if (!isNext) { try { - SQLiteCursor cursor = database.queryFinalized("SELECT dialog_id FROM stories"); + SQLiteCursor cursor = database.queryFinalized("SELECT DISTINCT dialog_id FROM stories"); ArrayList dialogsToDelete = new ArrayList<>(); while (cursor.next()) { - long dialogId = cursor.longValue(1); + long dialogId = cursor.longValue(0); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId); if (user == null) { user = MessagesStorage.getInstance(currentAccount).getUser(dialogId); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesUtilities.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesUtilities.java index 0a0009233..77d8d1f43 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoriesUtilities.java @@ -59,6 +59,7 @@ public class StoriesUtilities { public static final int STATE_PROGRESS = 3; public static GradientTools[] storiesGradientTools = new GradientTools[2]; public static GradientTools closeFriendsGradientTools; + public static GradientTools errorGradientTools; public static Paint grayPaint; public static Paint closeFriendsLastColor; @@ -207,9 +208,9 @@ public class StoriesUtilities { float inset = params.isStoryCell ? -AndroidUtilities.dp(4) : 0;//AndroidUtilities.lerp(AndroidUtilities.dp(2), 0, imageScale); if (animateOut) { inset += AndroidUtilities.dp(5) * progressToSate; - gradientTools.paint.setAlpha((int) (255 * (1f - progressToSate))); + gradientTools.paint.setAlpha((int) (0xFF * params.alpha * (1f - progressToSate))); } else { - gradientTools.paint.setAlpha((int) (255 * progressToSate)); + gradientTools.paint.setAlpha((int) (0xFF * params.alpha * progressToSate)); inset += AndroidUtilities.dp(5) * (1f - progressToSate); } rectTmp.set(params.originalAvatarRect); @@ -231,9 +232,9 @@ public class StoriesUtilities { Paint closeFriendsPaint = null; if (params.drawSegments) { unreadPaint = getActiveCirclePaint(avatarImage, params.isStoryCell); - unreadPaint.setAlpha(255); + unreadPaint.setAlpha((int) (0xFF * params.alpha)); closeFriendsPaint = getCloseFriendsPaint(avatarImage); - closeFriendsPaint.setAlpha(255); + closeFriendsPaint.setAlpha((int) (0xFF * params.alpha)); checkGrayPaint(params.resourcesProvider); } float inset; @@ -244,9 +245,9 @@ public class StoriesUtilities { } if (animateOut) { inset += AndroidUtilities.dp(5) * progressToSate; - paint.setAlpha((int) (255 * (1f - progressToSate))); + paint.setAlpha((int) (0xFF * params.alpha * (1f - progressToSate))); } else { - paint.setAlpha((int) (255 * progressToSate)); + paint.setAlpha((int) (0xFF * params.alpha * progressToSate)); inset += AndroidUtilities.dp(5) * (1f - progressToSate); } rectTmp.set(params.originalAvatarRect); @@ -277,9 +278,9 @@ public class StoriesUtilities { Paint closeFriendsPaint = null; if (params.drawSegments) { unreadPaint = getActiveCirclePaint(avatarImage, params.isStoryCell); - unreadPaint.setAlpha(255); + unreadPaint.setAlpha((int) (0xFF * params.alpha)); closeFriendsPaint = getCloseFriendsPaint(avatarImage); - closeFriendsPaint.setAlpha(255); + closeFriendsPaint.setAlpha((int) (0xFF * params.alpha)); checkGrayPaint(params.resourcesProvider); } float inset; @@ -291,9 +292,9 @@ public class StoriesUtilities { boolean animateOut = params.prevState == STATE_PROGRESS && params.progressToSate != 1f; if (animateOut) { inset += AndroidUtilities.dp(7) * progressToSate; - paint.setAlpha((int) (255 * (1f - progressToSate))); + paint.setAlpha((int) (0xFF * params.alpha * (1f - progressToSate))); } else { - paint.setAlpha((int) (255 * progressToSate)); + paint.setAlpha((int) (0xFF * params.alpha * progressToSate)); inset += AndroidUtilities.dp(5) * (1f - progressToSate); } rectTmp.set(params.originalAvatarRect); @@ -587,6 +588,12 @@ public class StoriesUtilities { if (storiesGradientTools[1] != null) { storiesGradientTools[1].setColors(Theme.getColor(Theme.key_stories_circle1), Theme.getColor(Theme.key_stories_circle2)); } + if (errorGradientTools != null) { + int orange = Theme.getColor(Theme.key_color_orange); + final int red = Theme.getColor(Theme.key_text_RedBold); + orange = ColorUtils.blendARGB(orange, red, .25f); + errorGradientTools.setColors(orange, red); + } } public static Paint getCloseFriendsPaint(ImageReceiver avatarImage) { @@ -595,7 +602,7 @@ public class StoriesUtilities { closeFriendsGradientTools.isDiagonal = true; closeFriendsGradientTools.isRotate = true; closeFriendsGradientTools.setColors(Theme.getColor(Theme.key_stories_circle_closeFriends1), Theme.getColor(Theme.key_stories_circle_closeFriends2)); - closeFriendsGradientTools.paint.setStrokeWidth(AndroidUtilities.dp(2.3f)); + closeFriendsGradientTools.paint.setStrokeWidth(AndroidUtilities.dpf2(2.3f)); closeFriendsGradientTools.paint.setStyle(Paint.Style.STROKE); closeFriendsGradientTools.paint.setStrokeCap(Paint.Cap.ROUND); } @@ -603,6 +610,23 @@ public class StoriesUtilities { return closeFriendsGradientTools.paint; } + public static Paint getErrorPaint(ImageReceiver avatarImage) { + if (errorGradientTools == null) { + errorGradientTools = new GradientTools(); + errorGradientTools.isDiagonal = true; + errorGradientTools.isRotate = true; + int orange = Theme.getColor(Theme.key_color_orange); + final int red = Theme.getColor(Theme.key_text_RedBold); + orange = ColorUtils.blendARGB(orange, red, .25f); + errorGradientTools.setColors(orange, red); + errorGradientTools.paint.setStrokeWidth(AndroidUtilities.dpf2(2.3f)); + errorGradientTools.paint.setStyle(Paint.Style.STROKE); + errorGradientTools.paint.setStrokeCap(Paint.Cap.ROUND); + } + errorGradientTools.setBounds(avatarImage.getImageX(), avatarImage.getImageY(), avatarImage.getImageX2(), avatarImage.getImageY2()); + return errorGradientTools.paint; + } + public static void setStoryMiniImage(ImageReceiver imageReceiver, TLRPC.StoryItem storyItem) { if (storyItem == null) { return; @@ -960,6 +984,7 @@ public class StoriesUtilities { public long crossfadeToDialog; public float crossfadeToDialogProgress; public float progressToProgressSegments; + public float alpha = 1f; private long dialogId; public int currentState; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryCaptionView.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryCaptionView.java index 2db9e5586..282a61159 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryCaptionView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryCaptionView.java @@ -488,7 +488,7 @@ public class StoryCaptionView extends NestedScrollView { ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f); valueAnimator.addUpdateListener(animation -> { float value = (float) animation.getAnimatedValue(); - final float toScrollY = (captionContainer.getBottom() - getMeasuredHeight()); + final float toScrollY = Math.min(getMeasuredHeight() - blackoutBottomOffset - AndroidUtilities.dp(64), captionContainer.getBottom() - getMeasuredHeight()); setScrollY((int) AndroidUtilities.lerp(fromScrollY, toScrollY, value)); captionTextview.progressToExpand = AndroidUtilities.lerp(fromP, toP, value); captionTextview.invalidate(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryFailView.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryFailView.java new file mode 100644 index 000000000..ad89eafe6 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryFailView.java @@ -0,0 +1,95 @@ +package org.telegram.ui.Stories; + +import static org.telegram.messenger.AndroidUtilities.dp; +import static org.telegram.messenger.AndroidUtilities.dpf2; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.text.TextUtils; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; + +import org.telegram.messenger.AndroidUtilities; +import org.telegram.messenger.LocaleController; +import org.telegram.messenger.R; +import org.telegram.tgnet.TLRPC; +import org.telegram.ui.ActionBar.Theme; +import org.telegram.ui.Components.LayoutHelper; +import org.webrtc.voiceengine.WebRtcAudioEffects; + +public class StoryFailView extends FrameLayout { + + private final Paint redPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private final Paint whitePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + + private final TextView titleTextView; + private final TextView subtitleTextView; + private final TextView button; + + public StoryFailView(Context context, Theme.ResourcesProvider resourcesProvider) { + super(context); + + redPaint.setColor(Theme.getColor(Theme.key_text_RedBold, resourcesProvider)); + whitePaint.setColor(Color.WHITE); + setWillNotDraw(false); + + titleTextView = new TextView(context); + titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + titleTextView.setText(LocaleController.getString(R.string.StoryError)); + titleTextView.setTextColor(Color.WHITE); + addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.LEFT, 44, 0, 0, 0)); + + subtitleTextView = new TextView(context); + subtitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 8); + subtitleTextView.setTextColor(Theme.multAlpha(Color.WHITE, .5f)); + subtitleTextView.setVisibility(View.GONE); + subtitleTextView.setTranslationY(dp(9)); + addView(subtitleTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.LEFT, 44, 0, 0, 0)); + + button = new TextView(context); + button.setPadding(dp(13), 0, dp(13), 0); + button.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(16), 0x1fffffff, 0x38ffffff)); + button.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)); + button.setText(LocaleController.getString(R.string.TryAgain)); + button.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + button.setTextColor(Color.WHITE); + button.setGravity(Gravity.CENTER); + addView(button, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 32, Gravity.CENTER_VERTICAL | Gravity.RIGHT, 0, 0, 12, 0)); + } + + public void set(TLRPC.TL_error error) { + if (error == null || TextUtils.isEmpty(error.text)) { + titleTextView.setTranslationY(0); + subtitleTextView.setVisibility(View.GONE); + } else { + titleTextView.setTranslationY(-dpf2(5.33f)); + subtitleTextView.setText(error.text); + subtitleTextView.setVisibility(View.VISIBLE); + } + } + + @Override + public void setOnClickListener(@Nullable OnClickListener l) { + button.setOnClickListener(l); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + final float cx = dp(13 + 10), cy = getHeight() / 2f; + + canvas.drawCircle(cx, cy, dp(10), redPaint); + AndroidUtilities.rectTmp.set(cx - AndroidUtilities.dp(1), cy - AndroidUtilities.dpf2(4.6f), cx + AndroidUtilities.dp(1), cy + AndroidUtilities.dpf2(1.6f)); + canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(3), AndroidUtilities.dp(3), whitePaint); + AndroidUtilities.rectTmp.set(cx - AndroidUtilities.dp(1), cy + AndroidUtilities.dpf2(2.6f), cx + AndroidUtilities.dp(1), cy + AndroidUtilities.dpf2(2.6f + 2)); + canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(3), AndroidUtilities.dp(3), whitePaint); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryViewer.java index 39a35e3ea..1fe1732b8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/StoryViewer.java @@ -18,11 +18,11 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.RectF; -import android.graphics.SurfaceTexture; import android.media.AudioManager; import android.net.Uri; import android.os.Build; -import android.util.Log; +import android.text.Editable; +import android.util.LongSparseArray; import android.util.SparseArray; import android.view.GestureDetector; import android.view.Gravity; @@ -45,12 +45,11 @@ import androidx.viewpager.widget.ViewPager; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; +import com.google.android.exoplayer2.util.Log; -import org.checkerframework.checker.units.qual.A; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AnimationNotificationsLocker; import org.telegram.messenger.BuildVars; -import org.telegram.messenger.DispatchQueue; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.FileStreamLoadOperation; @@ -62,6 +61,8 @@ import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; import org.telegram.messenger.support.LongSparseIntArray; +import org.telegram.messenger.support.SparseLongArray; +import org.telegram.messenger.video.VideoPlayerHolderBase; import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.AdjustPanLayoutHelper; import org.telegram.ui.ActionBar.BaseFragment; @@ -73,9 +74,7 @@ import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.RadialProgress; import org.telegram.ui.Components.RecyclerListView; -import org.telegram.ui.Components.SharedMediaLayout; import org.telegram.ui.Components.SizeNotifierFrameLayout; -import org.telegram.ui.Components.VideoPlayer; import org.telegram.ui.LaunchActivity; import java.util.ArrayList; @@ -106,6 +105,7 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat private static TLRPC.StoryItem lastStoryItem; Theme.ResourcesProvider resourcesProvider = new DarkThemeResourceProvider(); + private boolean opening; ValueAnimator openCloseAnimator; ValueAnimator swipeToDissmissBackAnimator; ValueAnimator swipeToReplyBackAnimator; @@ -221,6 +221,8 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat private boolean isLikesReactions; private float lastStoryContainerHeight; + LongSparseArray replyDrafts = new LongSparseArray<>(); + public static boolean isShowingImage(MessageObject messageObject) { if (lastStoryItem == null || messageObject.type != MessageObject.TYPE_STORY && !messageObject.isWebpage() || runOpenAnimationAfterLayout) { return false; @@ -654,11 +656,11 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat transitionViewHolder.storyImage.setVisible(true, false); int r = canvas.getSaveCount(); if (transitionViewHolder.drawClip != null) { - transitionViewHolder.drawClip.clip(canvas, rect3, 1f - progress2); + transitionViewHolder.drawClip.clip(canvas, rect3, 1f - progress2, opening); } transitionViewHolder.storyImage.draw(canvas); if (transitionViewHolder.drawAbove != null) { - transitionViewHolder.drawAbove.draw(canvas, rect3, 1f - progress2); + transitionViewHolder.drawAbove.draw(canvas, rect3, 1f - progress2, opening); } transitionViewHolder.storyImage.setVisible(wasVisible, false); transitionViewHolder.storyImage.setImageCoords(x, y, w, h); @@ -686,23 +688,27 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat rect2.set(toX, toY, toX + headerView.backupImageView.getMeasuredWidth(), toY + headerView.backupImageView.getMeasuredHeight()); } - AndroidUtilities.lerp(rect1, rect2, progressToOpen, AndroidUtilities.rectTmp); + AndroidUtilities.lerp(rect1, rect2, progressToOpen, rect3); + int r = canvas.getSaveCount(); + if (transitionViewHolder != null && transitionViewHolder.drawClip != null) { + transitionViewHolder.drawClip.clip(canvas, rect3, 1f - progress2, opening); + } if (animateAvatar) { boolean crossfade = transitionViewHolder != null && transitionViewHolder.crossfadeToAvatarImage != null; if (!crossfade || progressToOpen != 0) { - headerView.backupImageView.getImageReceiver().setImageCoords(AndroidUtilities.rectTmp); - headerView.backupImageView.getImageReceiver().setRoundRadius((int) (AndroidUtilities.rectTmp.width() / 2f)); + headerView.backupImageView.getImageReceiver().setImageCoords(rect3); + headerView.backupImageView.getImageReceiver().setRoundRadius((int) (rect3.width() / 2f)); headerView.backupImageView.getImageReceiver().setVisible(true, false); final float alpha = crossfade ? progressToOpen : 1f; float thisAlpha = alpha; if (transitionViewHolder != null && transitionViewHolder.alpha < 1 && transitionViewHolder.bgPaint != null) { transitionViewHolder.bgPaint.setAlpha((int) (0xFF * (1f - progress2))); - canvas.drawCircle(AndroidUtilities.rectTmp.centerX(), AndroidUtilities.rectTmp.centerY(), AndroidUtilities.rectTmp.width() / 2f, transitionViewHolder.bgPaint); + canvas.drawCircle(rect3.centerX(), rect3.centerY(), rect3.width() / 2f, transitionViewHolder.bgPaint); thisAlpha = AndroidUtilities.lerp(transitionViewHolder.alpha, thisAlpha, progress2); } headerView.backupImageView.getImageReceiver().setAlpha(thisAlpha); - headerView.drawUploadingProgress(canvas, AndroidUtilities.rectTmp, !runOpenAnimationAfterLayout, progressToOpen); + headerView.drawUploadingProgress(canvas, rect3, !runOpenAnimationAfterLayout, progressToOpen); headerView.backupImageView.getImageReceiver().draw(canvas); headerView.backupImageView.getImageReceiver().setAlpha(alpha); headerView.backupImageView.getImageReceiver().setVisible(false, false); @@ -716,10 +722,10 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat ); int oldRadius = transitionViewHolder.crossfadeToAvatarImage.getRoundRadius()[0]; boolean isVisible = transitionViewHolder.crossfadeToAvatarImage.getVisible(); - transitionViewHolder.crossfadeToAvatarImage.setImageCoords(AndroidUtilities.rectTmp); - transitionViewHolder.crossfadeToAvatarImage.setRoundRadius((int) (AndroidUtilities.rectTmp.width() / 2f)); + transitionViewHolder.crossfadeToAvatarImage.setImageCoords(rect3); + transitionViewHolder.crossfadeToAvatarImage.setRoundRadius((int) (rect3.width() / 2f)); transitionViewHolder.crossfadeToAvatarImage.setVisible(true, false); - canvas.saveLayerAlpha(AndroidUtilities.rectTmp, (int) (255 * (1f - progressToOpen)), Canvas.ALL_SAVE_FLAG); + canvas.saveLayerAlpha(rect3, (int) (255 * (1f - progressToOpen)), Canvas.ALL_SAVE_FLAG); transitionViewHolder.crossfadeToAvatarImage.draw(canvas); canvas.restore(); transitionViewHolder.crossfadeToAvatarImage.setVisible(isVisible, false); @@ -728,6 +734,10 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat // transitionViewHolder.crossfadeToAvatarImage.setVisible(false, false); } } + if (transitionViewHolder != null && transitionViewHolder.drawAbove != null) { + transitionViewHolder.drawAbove.draw(canvas, rect3, 1f - progress2, opening); + } + canvas.restoreToCount(r); } @@ -1272,7 +1282,7 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat } } if (playerHolder == null) { - playerHolder = new VideoPlayerHolder(); + playerHolder = new VideoPlayerHolder(surfaceView, textureView); playerHolder.document = document; } // if (surfaceView != null) { @@ -1412,7 +1422,7 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat } for (int i = 0; i < uries.size(); i++) { Uri uri = uries.get(i); - VideoPlayerHolder playerHolder = new VideoPlayerHolder(); + VideoPlayerHolder playerHolder = new VideoPlayerHolder(surfaceView, textureView); playerHolder.uri = uri; playerHolder.document = documents.get(i); FileStreamLoadOperation.setPriorityForDocument(playerHolder.document, FileLoader.PRIORITY_LOW); @@ -1476,6 +1486,7 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); if (ATTACH_TO_FRAGMENT) { + AndroidUtilities.removeFromParent(windowView); windowView.setFitsSystemWindows(true); fragment.getLayoutContainer().addView(windowView); AndroidUtilities.requestAdjustResize(fragment.getParentActivity(), fragment.getClassGuid()); @@ -1707,7 +1718,9 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat private void lockOrientation(boolean lock) { Activity activity = AndroidUtilities.findActivity(fragment.getContext()); if (activity != null) { - activity.setRequestedOrientation(lock ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + try { + activity.setRequestedOrientation(lock ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + } catch (Exception ignore) {} if (lock) { activity.getWindow().addFlags(FLAG_KEEP_SCREEN_ON); } else { @@ -2001,6 +2014,7 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat peerStoriesView.headerView.radialProgress.copyParams(transitionViewHolder.radialProgressUpload); } } + opening = true; openCloseAnimator = ValueAnimator.ofFloat(0, 1f); openCloseAnimator.addUpdateListener(animation -> { progressToOpen = (float) animation.getAnimatedValue(); @@ -2095,6 +2109,7 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat updateTransitionParams(); locker.lock(); fromDismissOffset = swipeToDismissOffset; + opening = false; openCloseAnimator = ValueAnimator.ofFloat(progressToOpen, 0); openCloseAnimator.addUpdateListener(animation -> { progressToOpen = (float) animation.getAnimatedValue(); @@ -2117,6 +2132,9 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat layoutAndFindView(); } AndroidUtilities.runOnUIThread(() -> { + if (openCloseAnimator == null) { + return; + } containerView.enableHwAcceleration(); openCloseAnimator.addListener(new AnimatorListenerAdapter() { @Override @@ -2473,6 +2491,33 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat } } + public void saveDraft(long dialogId, TLRPC.StoryItem storyItem, CharSequence text) { + if (dialogId == 0 || storyItem == null) { + return; + } + Log.d("kek", "saveDraft" + dialogId + "_" + storyItem.id + " " + text); + replyDrafts.put(draftHash(dialogId, storyItem), text); + } + + public CharSequence getDraft(long dialogId, TLRPC.StoryItem storyItem) { + if (dialogId == 0 || storyItem == null) { + return ""; + } + Log.d("kek", "getDraft " + dialogId + "_" + storyItem.id + " " + replyDrafts.get(draftHash(dialogId, storyItem), "")); + return replyDrafts.get(draftHash(dialogId, storyItem), ""); + } + + public void clearDraft(long dialogId, TLRPC.StoryItem storyItem) { + if (dialogId == 0 || storyItem == null) { + return; + } + replyDrafts.remove(draftHash(dialogId, storyItem)); + } + + private long draftHash(long dialogId, TLRPC.StoryItem oldStoryItem) { + return dialogId + (dialogId >> 16) + ((long) oldStoryItem.id << 16); + } + public interface PlaceProvider { boolean findView(long dialogId, int messageId, int storyId, int type, TransitionViewHolder holder); @@ -2483,11 +2528,11 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat } public interface HolderDrawAbove { - void draw(Canvas canvas, RectF bounds, float alpha); + void draw(Canvas canvas, RectF bounds, float alpha, boolean opening); } public interface HolderClip { - void clip(Canvas canvas, RectF bounds, float alpha); + void clip(Canvas canvas, RectF bounds, float alpha, boolean opening); } public static class TransitionViewHolder { @@ -2527,356 +2572,55 @@ public class StoryViewer implements NotificationCenter.NotificationCenterDelegat static int queuePointer = 0; - public class VideoPlayerHolder { + public class VideoPlayerHolder extends VideoPlayerHolderBase { - public boolean paused; - public TLRPC.Document document; - VideoPlayer videoPlayer; - Runnable initRunnable; - volatile boolean released; - boolean firstFrameRendered; - - float progress; - int lastState; - public long currentPosition; - long playerDuration; - boolean audioDisabled; - boolean stubAvailable; boolean logBuffering; - final DispatchQueue dispatchQueue = Utilities.getOrCreatePlayerQueue(); - Uri uri; - - Runnable progressRunnable = new Runnable() { - @Override - public void run() { - if (videoPlayer != null) { - if (lastState == ExoPlayer.STATE_ENDED) { - progress = 1f; - } else { - currentPosition = videoPlayer.getCurrentPosition(); - playerDuration = videoPlayer.getDuration(); - } - if (lastState == ExoPlayer.STATE_READY) { - dispatchQueue.cancelRunnable(progressRunnable); - dispatchQueue.postRunnable(progressRunnable, 16); - } - } - } - }; - - long startTime; - - void preparePlayer(Uri uri, boolean audioDisabled) { - this.audioDisabled = audioDisabled; - paused = true; - if (initRunnable != null) { - dispatchQueue.cancelRunnable(initRunnable); - } - dispatchQueue.postRunnable(initRunnable = () -> { - if (released) { - return; - } - ensurePlayerCreated(audioDisabled); - videoPlayer.preparePlayer(uri, "other", FileLoader.PRIORITY_LOW); - videoPlayer.setPlayWhenReady(false); - videoPlayer.setWorkerQueue(dispatchQueue); - }); - } - - void start(boolean paused, Uri uri, long t, boolean audioDisabled) { - startTime = System.currentTimeMillis(); - this.audioDisabled = audioDisabled; - this.paused = paused; - dispatchQueue.postRunnable(initRunnable = () -> { - if (released) { - return; - } - if (videoPlayer == null) { - ensurePlayerCreated(audioDisabled); - videoPlayer.preparePlayer(uri, "other"); - videoPlayer.setWorkerQueue(dispatchQueue); - if (!paused) { - if (USE_SURFACE_VIEW) { - videoPlayer.setSurfaceView(surfaceView); - } else { - videoPlayer.setTextureView(textureView); - } - videoPlayer.setPlayWhenReady(true); - } - } else { - if (!paused) { - if (USE_SURFACE_VIEW) { - videoPlayer.setSurfaceView(surfaceView); - } else { - videoPlayer.setTextureView(textureView); - } - videoPlayer.play(); - } - } - if (t > 0) { - videoPlayer.seekTo(t); - } - - videoPlayer.setVolume(isInSilentMode ? 0 : 1f); - AndroidUtilities.runOnUIThread(() -> initRunnable = null); - }); - } - - private void ensurePlayerCreated(boolean audioDisabled) { - if (videoPlayer != null) { - videoPlayer.releasePlayer(true); - } - videoPlayer = new VideoPlayer(false, audioDisabled); - videoPlayer.setDelegate(new VideoPlayer.VideoPlayerDelegate() { - @Override - public void onStateChanged(boolean playWhenReady, int playbackState) { - lastState = playbackState; - if (playbackState == ExoPlayer.STATE_READY || playbackState == ExoPlayer.STATE_BUFFERING) { - dispatchQueue.cancelRunnable(progressRunnable); - dispatchQueue.postRunnable(progressRunnable); - if (firstFrameRendered && playbackState == ExoPlayer.STATE_BUFFERING) { - logBuffering = true; - AndroidUtilities.runOnUIThread(() -> { - final PeerStoriesView storiesView = getCurrentPeerView(); - if (storiesView != null && storiesView.currentStory.storyItem != null) { - FileLog.d("StoryViewer displayed story buffering dialogId=" + storiesView.getCurrentPeer() + " storyId=" + storiesView.currentStory.storyItem.id); - } - }); - } - if (logBuffering && playbackState == ExoPlayer.STATE_READY) { - logBuffering = false; - AndroidUtilities.runOnUIThread(() -> { - final PeerStoriesView storiesView = getCurrentPeerView(); - if (storiesView != null && storiesView.currentStory.storyItem != null) { - FileLog.d("StoryViewer displayed story playing dialogId=" + storiesView.getCurrentPeer() + " storyId=" + storiesView.currentStory.storyItem.id); - } - }); - } - - - } else if (playbackState == ExoPlayer.STATE_ENDED) { - if (isCaptionPartVisible) { - progress = 0; - videoPlayer.seekTo(0); - videoPlayer.play(); - } else { - progress = 1f; - } - } - } - - @Override - public void onError(VideoPlayer player, Exception e) { - FileLog.e(e); - } - - @Override - public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) { - - } - - @Override - public void onRenderedFirstFrame() { - AndroidUtilities.runOnUIThread(() -> { - if (released || currentPlayerScope == null) { - return; - } - firstFrameRendered = currentPlayerScope.firstFrameRendered = true; - currentPlayerScope.invalidate(); - - if (onReadyListener != null) { - onReadyListener.run(); - onReadyListener = null; - } - }, 16); - } - - @Override - public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { - - } - - @Override - public boolean onSurfaceDestroyed(SurfaceTexture surfaceTexture) { - return false; - } - }); - videoPlayer.setIsStory(); - } - - private Runnable onReadyListener; - public void setOnReadyListener(Runnable listener) { - onReadyListener = listener; - } - - boolean release(Runnable whenReleased) { - TLRPC.Document document = this.document; - if (document != null) { - int priority = FileStreamLoadOperation.getStreamPrioriy(document); - if (priority != FileLoader.PRIORITY_LOW) { - FileStreamLoadOperation.setPriorityForDocument(document, FileLoader.PRIORITY_LOW); - FileLoader.getInstance(currentAccount).changePriority(FileLoader.PRIORITY_LOW, document, null, null, null, null, null); - // FileLoader.getInstance(currentAccount).cancelLoadFile(document); - } - // FileLoader.getInstance(currentAccount).changePriority(FileLoader.PRIORITY_LOW, document, null, null, null, null, null); - } - released = true; - dispatchQueue.cancelRunnable(initRunnable); - initRunnable = null; - dispatchQueue.postRunnable(() -> { - if (videoPlayer != null) { - try { - videoPlayer.setTextureView(null); - videoPlayer.setSurfaceView(null); - } catch (Exception e) { - - } - videoPlayer.releasePlayer(false); - } - if (document != null) { - FileLoader.getInstance(currentAccount).cancelLoadFile(document); - // FileLoader.getInstance(currentAccount).changePriority(FileLoader.PRIORITY_LOW, document, null, null, null, null, null); - } - if (whenReleased != null) { - AndroidUtilities.runOnUIThread(whenReleased); - } - videoPlayer = null; - }); - if (playerStubBitmap != null) { - AndroidUtilities.recycleBitmap(playerStubBitmap); - playerStubBitmap = null; - } - return true; - } - - public void pause() { - if (released) { - return; - } - if (paused) { - return; - } - paused = true; - if (USE_SURFACE_VIEW && surfaceView != null && firstFrameRendered && surfaceView.getHolder().getSurface().isValid()) { - stubAvailable = true; - if (playerStubBitmap == null) { - playerStubBitmap = Bitmap.createBitmap(720, 1280, Bitmap.Config.ARGB_8888); - playerStubPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - AndroidUtilities.getBitmapFromSurface(surfaceView, playerStubBitmap); - } - } - dispatchQueue.postRunnable(() -> { - if (videoPlayer != null) { - videoPlayer.pause(); - } - }); - } - - public void play() { - if (released) { - return; - } - if (!paused) { - return; - } - paused = false; - dispatchQueue.postRunnable(() -> { - if (videoPlayer != null) { - if (USE_SURFACE_VIEW) { - videoPlayer.setSurfaceView(surfaceView); - } else { - videoPlayer.setTextureView(textureView); - } - videoPlayer.setPlayWhenReady(true); - } - }); - } - - public void setAudioEnabled(boolean enabled, boolean prepared) { - boolean disabled = !enabled; - if (audioDisabled == disabled) { - return; - } - audioDisabled = disabled; - dispatchQueue.postRunnable(() -> { - if (videoPlayer == null) { - return; - } - boolean playing = videoPlayer.isPlaying(); - if (enabled && !videoPlayer.createdWithAudioTrack()) { - //release and create new with audio track - videoPlayer.pause(); - long position = videoPlayer.getCurrentPosition(); - videoPlayer.releasePlayer(false); - videoPlayer = null; - ensurePlayerCreated(audioDisabled); - videoPlayer.preparePlayer(uri, "other"); - videoPlayer.setWorkerQueue(dispatchQueue); - if (!prepared) { - if (USE_SURFACE_VIEW) { - videoPlayer.setSurfaceView(surfaceView); - } else { - videoPlayer.setTextureView(textureView); - } - } - // videoPlayer.setTextureView(textureView); - videoPlayer.seekTo(position + 50); - if (playing && !prepared) { - videoPlayer.setPlayWhenReady(true); - videoPlayer.play(); - } else { - videoPlayer.setPlayWhenReady(false); - videoPlayer.pause(); - } - } else { - videoPlayer.setVolume(enabled ? 1f : 0); - } - }); - } - - public float getPlaybackProgress(long totalDuration) { - if (lastState == ExoPlayer.STATE_ENDED) { - progress = 1f; + public VideoPlayerHolder(SurfaceView surfaceView, TextureView textureView) { + if (USE_SURFACE_VIEW) { + with(surfaceView); } else { - float localProgress; - if (totalDuration != 0) { - localProgress = currentPosition / (float) totalDuration; - } else { - localProgress = currentPosition / (float) playerDuration; - } - if (localProgress < progress) { - return progress; - } - progress = localProgress; + with(textureView); } - return progress; } - public void loopBack() { - progress = 0; - lastState = ExoPlayer.STATE_IDLE; - dispatchQueue.postRunnable(() -> { - if (videoPlayer != null) { - videoPlayer.seekTo(0); + + @Override + public boolean needRepeat() { + return isCaptionPartVisible; + } + + @Override + public void onRenderedFirstFrame() { + if (currentPlayerScope == null) { + return; + } + firstFrameRendered = currentPlayerScope.firstFrameRendered = true; + currentPlayerScope.invalidate(); + } + + @Override + public void onStateChanged(boolean playWhenReady, int playbackState) { + if (playbackState == ExoPlayer.STATE_READY || playbackState == ExoPlayer.STATE_BUFFERING) { + if (firstFrameRendered && playbackState == ExoPlayer.STATE_BUFFERING) { + logBuffering = true; + AndroidUtilities.runOnUIThread(() -> { + final PeerStoriesView storiesView = getCurrentPeerView(); + if (storiesView != null && storiesView.currentStory.storyItem != null) { + FileLog.d("StoryViewer displayed story buffering dialogId=" + storiesView.getCurrentPeer() + " storyId=" + storiesView.currentStory.storyItem.id); + } + }); } - progress = 0; - currentPosition = 0; - }); - } - - public void setVolume(float v) { - dispatchQueue.postRunnable(() -> { - if (videoPlayer != null) { - videoPlayer.setVolume(v); + if (logBuffering && playbackState == ExoPlayer.STATE_READY) { + logBuffering = false; + AndroidUtilities.runOnUIThread(() -> { + final PeerStoriesView storiesView = getCurrentPeerView(); + if (storiesView != null && storiesView.currentStory.storyItem != null) { + FileLog.d("StoryViewer displayed story playing dialogId=" + storiesView.getCurrentPeer() + " storyId=" + storiesView.currentStory.storyItem.id); + } + }); } - }); - } - - public boolean isBuffering() { - return !released && lastState == ExoPlayer.STATE_BUFFERING; + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/CaptionContainerView.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/CaptionContainerView.java index 2018b6448..15049911b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/CaptionContainerView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/CaptionContainerView.java @@ -205,7 +205,7 @@ public class CaptionContainerView extends FrameLayout { limitTextView.cancelAnimation(); limitTextView.setText(limitText); limitTextView.setTextColor(length >= limit ? 0xffEC7777 : 0xffffffff); - if (length > limit && !premium && length < MessagesController.getInstance(currentAccount).storyCaptionLengthLimitPremium && length > lastLength && captionLimitToast()) { + if (length > limit && !premium && length < MessagesController.getInstance(currentAccount).storyCaptionLengthLimitPremium && length > lastLength && (captionLimitToast() || MessagesController.getInstance(currentAccount).premiumLocked)) { AndroidUtilities.shakeViewSpring(limitTextView, shiftDp = -shiftDp); BotWebViewVibrationEffect.APP_ERROR.vibrate(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/DownloadButton.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/DownloadButton.java index 761aa4509..765a54615 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/DownloadButton.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/DownloadButton.java @@ -174,7 +174,7 @@ public class DownloadButton extends ImageView { } private void onClickInternal() { - if (!preparing) { + if (!preparing || currentEntry == null) { return; } preparing = false; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/DraftsController.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/DraftsController.java index a93706e5f..9a58c1a72 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/DraftsController.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/DraftsController.java @@ -1,13 +1,10 @@ package org.telegram.ui.Stories.recorder; -import android.net.wifi.WifiManager; import android.text.SpannableString; import android.text.TextUtils; -import android.util.Log; import androidx.annotation.NonNull; -import org.checkerframework.checker.units.qual.A; import org.telegram.SQLite.SQLiteCursor; import org.telegram.SQLite.SQLiteDatabase; import org.telegram.SQLite.SQLitePreparedStatement; @@ -15,27 +12,22 @@ import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.Emoji; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; -import org.telegram.messenger.ImageLoader; import org.telegram.messenger.MediaController; import org.telegram.messenger.MediaDataController; import org.telegram.messenger.MessageObject; +import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.Utilities; import org.telegram.messenger.VideoEditedInfo; import org.telegram.tgnet.AbstractSerializedData; import org.telegram.tgnet.NativeByteBuffer; -import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.Theme; import java.io.File; import java.io.IOException; -import java.nio.file.CopyOption; -import java.nio.file.Files; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.List; public class DraftsController { @@ -46,27 +38,22 @@ public class DraftsController { public DraftsController(int currentAccount) { this.currentAccount = currentAccount; + loadFailed(); } - private boolean loaded, loading; public final ArrayList drafts = new ArrayList<>(); - public void load() { - if (loaded || loading) { - return; - } - - loading = true; + private void loadInternal(final boolean failed, Utilities.Callback> callback) { final MessagesStorage storage = MessagesStorage.getInstance(currentAccount); storage.getStorageQueue().postRunnable(() -> { SQLiteCursor cursor = null; - final ArrayList savedDrafts = new ArrayList<>(); + final ArrayList loadedDrafts = new ArrayList<>(); try { SQLiteDatabase database = storage.getDatabase(); if (database == null) { return; } - cursor = database.queryFinalized("SELECT id, data FROM story_drafts ORDER BY date DESC"); + cursor = database.queryFinalized("SELECT id, data, type FROM story_drafts WHERE type = " + (failed ? "2" : "0 OR type = 1") + " ORDER BY date DESC"); while (cursor.next()) { long id = cursor.longValue(0); NativeByteBuffer buffer = cursor.byteBufferValue(1); @@ -74,7 +61,7 @@ public class DraftsController { try { StoryDraft draft = new StoryDraft(buffer, true); draft.id = id; - savedDrafts.add(draft); + loadedDrafts.add(draft); } catch (Exception e) { FileLog.e(e); } @@ -89,36 +76,83 @@ public class DraftsController { } } - AndroidUtilities.runOnUIThread(() -> { - final long now = System.currentTimeMillis(); - ArrayList ids = new ArrayList<>(); - ArrayList deleteEntries = new ArrayList<>(); - for (int i = 0; i < savedDrafts.size(); ++i) { - StoryEntry entry = savedDrafts.get(i).toEntry(); - if (entry == null) { - continue; - } - if ( - entry.file == null || - !entry.file.exists() || - (entry.isEdit ? - (now > entry.editExpireDate) : - (now - entry.draftDate > EXPIRATION_PERIOD) - ) - ) { - deleteEntries.add(entry); - } else { - drafts.add(entry); - ids.add(entry.draftId); - } + AndroidUtilities.runOnUIThread(() -> callback.run(loadedDrafts)); + }); + } + + private boolean loaded, loading; + public void load() { + if (loaded || loading) { + return; + } + + loading = true; + loadInternal(false, loadedDrafts -> { + final long now = System.currentTimeMillis(); + ArrayList ids = new ArrayList<>(); + ArrayList deleteEntries = new ArrayList<>(); + for (int i = 0; i < loadedDrafts.size(); ++i) { + StoryEntry entry = loadedDrafts.get(i).toEntry(); + if (entry == null) { + continue; } - delete(deleteEntries); + if ( + entry.file == null || + !entry.file.exists() || + (entry.isEdit ? + (now > entry.editExpireDate) : + (now - entry.draftDate > EXPIRATION_PERIOD) + ) + ) { + deleteEntries.add(entry); + } else { + drafts.add(entry); + ids.add(entry.draftId); + } + } + delete(deleteEntries); - loading = false; - loaded = true; + loading = false; + loaded = true; - NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesDraftsUpdated); - }); + NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesDraftsUpdated); + }); + } + + private boolean loadedFailed, loadingFailed; + private void loadFailed() { + if (loadedFailed || loadingFailed) { + return; + } + + loadingFailed = true; + loadInternal(true, loadedDrafts -> { + final long now = System.currentTimeMillis(); + ArrayList ids = new ArrayList<>(); + ArrayList deleteEntries = new ArrayList<>(); + ArrayList appendEntries = new ArrayList<>(); + for (int i = 0; i < loadedDrafts.size(); ++i) { + StoryEntry entry = loadedDrafts.get(i).toEntry(); + if (entry == null) { + continue; + } + if ( + entry.file == null || + !entry.file.exists() || + now - entry.draftDate > EXPIRATION_PERIOD + ) { + deleteEntries.add(entry); + } else { + appendEntries.add(entry); + ids.add(entry.draftId); + } + } + delete(deleteEntries); + + loadingFailed = false; + loadedFailed = true; + + MessagesController.getInstance(currentAccount).getStoriesController().putUploadingDrafts(appendEntries); }); } @@ -128,7 +162,9 @@ public class DraftsController { } prepare(entry); drafts.remove(entry); - drafts.add(0, entry); + if (!entry.isError) { + drafts.add(0, entry); + } final StoryDraft draft = new StoryDraft(entry); final MessagesStorage storage = MessagesStorage.getInstance(currentAccount); storage.getStorageQueue().postRunnable(() -> { @@ -139,13 +175,20 @@ public class DraftsController { return; } - state = database.executeFast("REPLACE INTO story_drafts VALUES (?, ?, ?)"); + state = database.executeFast("REPLACE INTO story_drafts VALUES (?, ?, ?, ?)"); state.requery(); NativeByteBuffer data = new NativeByteBuffer(draft.getObjectSize()); draft.toStream(data); state.bindLong(1, draft.id); state.bindLong(2, draft.date); state.bindByteBuffer(3, data); + int type = 0; + if (draft.isEdit) { + type = 1; + } else if (draft.isError) { + type = 2; + } + state.bindInteger(4, type); state.step(); data.reuse(); state.dispose(); @@ -166,6 +209,8 @@ public class DraftsController { return; } + if (entry.draftId == 0) + entry.draftId = Utilities.random.nextLong(); entry.draftDate = System.currentTimeMillis(); entry.isDraft = true; @@ -211,8 +256,7 @@ public class DraftsController { return; } prepare(entry); - final long id = Utilities.random.nextLong(); - entry.draftId = id; + entry.draftId = Utilities.random.nextLong(); final StoryDraft draft = new StoryDraft(entry); drafts.remove(entry); drafts.add(0, entry); @@ -221,7 +265,7 @@ public class DraftsController { private void append(StoryDraft draft) { final MessagesStorage storage = MessagesStorage.getInstance(currentAccount); - FileLog.d("StoryDraft append " + draft.id + " (edit=" + draft.edit + (draft.edit ? ", storyId=" + draft.editStoryId + ", " + (draft.editDocumentId != 0 ? "documentId=" + draft.editDocumentId : "photoId=" + draft.editPhotoId) + ", expireDate=" + draft.editExpireDate : "") + ", now="+System.currentTimeMillis()+")"); + FileLog.d("StoryDraft append " + draft.id + " (edit=" + draft.isEdit + (draft.isEdit ? ", storyId=" + draft.editStoryId + ", " + (draft.editDocumentId != 0 ? "documentId=" + draft.editDocumentId : "photoId=" + draft.editPhotoId) + ", expireDate=" + draft.editExpireDate : "") + ", now="+System.currentTimeMillis()+")"); storage.getStorageQueue().postRunnable(() -> { SQLitePreparedStatement state = null; try { @@ -230,13 +274,20 @@ public class DraftsController { return; } - state = database.executeFast("INSERT INTO story_drafts VALUES (?, ?, ?)"); + state = database.executeFast("INSERT INTO story_drafts VALUES (?, ?, ?, ?)"); state.requery(); NativeByteBuffer data = new NativeByteBuffer(draft.getObjectSize()); draft.toStream(data); state.bindLong(1, draft.id); state.bindLong(2, draft.date); state.bindByteBuffer(3, data); + int type = 0; + if (draft.isEdit) { + type = 1; + } else if (draft.isError) { + type = 2; + } + state.bindInteger(4, type); state.step(); data.reuse(); state.dispose(); @@ -294,7 +345,7 @@ public class DraftsController { final long id = Utilities.random.nextLong(); entry.draftId = id; final StoryDraft draft = new StoryDraft(entry); - draft.edit = entry.isEdit = true; + draft.isEdit = entry.isEdit = true; draft.editStoryPeerId = entry.editStoryPeerId = dialogId; draft.editStoryId = entry.editStoryId = storyItem.id; draft.editExpireDate = entry.editExpireDate = storyItem.expire_date * 1000L; @@ -393,6 +444,7 @@ public class DraftsController { public long id; public long date; public String thumb; + public String fullThumb; public boolean isVideo; public String file; @@ -426,17 +478,21 @@ public class DraftsController { private final ArrayList parts = new ArrayList<>(); - public boolean edit; + public boolean isEdit; public int editStoryId; public long editStoryPeerId; public long editDocumentId; public long editPhotoId; public long editExpireDate; + public boolean isError; + public TLRPC.TL_error error; + public StoryDraft(@NonNull StoryEntry entry) { this.id = entry.draftId; this.date = entry.draftDate; this.thumb = entry.draftThumbFile == null ? "" : entry.draftThumbFile.toString(); + this.fullThumb = entry.uploadThumbFile == null ? "" : entry.uploadThumbFile.toString(); this.isVideo = entry.isVideo; this.file = entry.file == null ? "" : entry.file.toString(); this.fileDeletable = entry.fileDeletable; @@ -467,6 +523,8 @@ public class DraftsController { this.period = entry.period; this.parts.clear(); this.parts.addAll(entry.parts); + this.isError = entry.isError; + this.error = entry.error; } public StoryEntry toEntry() { @@ -474,9 +532,12 @@ public class DraftsController { entry.draftId = id; entry.isDraft = true; entry.draftDate = date; - if (thumb != null) { + if (!TextUtils.isEmpty(thumb)) { entry.draftThumbFile = new File(thumb); } + if (!TextUtils.isEmpty(fullThumb)) { + entry.uploadThumbFile = new File(fullThumb); + } entry.isVideo = isVideo; if (file != null) { entry.file = new File(file); @@ -530,12 +591,14 @@ public class DraftsController { for (int i = 0; i < parts.size(); ++i) { entry.partsMaxId = Math.max(entry.partsMaxId, parts.get(i).id); } - entry.isEdit = edit; + entry.isEdit = isEdit; entry.editStoryId = editStoryId; entry.editStoryPeerId = editStoryPeerId; entry.editExpireDate = editExpireDate; entry.editPhotoId = editPhotoId; entry.editDocumentId = editDocumentId; + entry.isError = isError; + entry.error = error; return entry; } @@ -606,13 +669,20 @@ public class DraftsController { for (int i = 0; i < parts.size(); ++i) { parts.get(i).serializeToStream(stream); } - stream.writeBool(edit); + stream.writeBool(isEdit); stream.writeInt32(editStoryId); stream.writeInt64(editStoryPeerId); stream.writeInt64(editExpireDate); stream.writeInt64(editPhotoId); stream.writeInt64(editDocumentId); stream.writeString(paintEntitiesFilePath); + stream.writeBool(isError); + if (error == null) { + stream.writeInt32(TLRPC.TL_null.constructor); + } else { + error.serializeToStream(stream); + } + stream.writeString(fullThumb); } public int getObjectSize() { @@ -745,7 +815,7 @@ public class DraftsController { } } if (stream.remaining() > 0) { - edit = stream.readBool(exception); + isEdit = stream.readBool(exception); editStoryId = stream.readInt32(exception); editStoryPeerId = stream.readInt64(exception); editExpireDate = stream.readInt64(exception); @@ -758,6 +828,16 @@ public class DraftsController { paintEntitiesFilePath = null; } } + if (stream.remaining() > 0) { + isError = stream.readBool(exception); + magic = stream.readInt32(exception); + if (magic == TLRPC.TL_null.constructor) { + error = null; + } else { + error = TLRPC.TL_error.TLdeserialize(stream, magic, exception); + } + fullThumb = stream.readString(exception); + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/GalleryListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/GalleryListView.java index 2d18cd04c..25bcae58f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/GalleryListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/GalleryListView.java @@ -454,7 +454,7 @@ public class GalleryListView extends FrameLayout implements NotificationCenter.N if (!onlyPhotos) { ArrayList draftArray = MessagesController.getInstance(currentAccount).getStoriesController().getDraftsController().drafts; for (StoryEntry draft : draftArray) { - if (!draft.isEdit) { + if (!draft.isEdit && !draft.isError) { drafts.add(draft); } } @@ -1406,7 +1406,7 @@ public class GalleryListView extends FrameLayout implements NotificationCenter.N if (!onlyPhotos) { ArrayList draftArray = MessagesController.getInstance(currentAccount).getStoriesController().getDraftsController().drafts; for (StoryEntry draft : draftArray) { - if (!draft.isEdit) { + if (!draft.isEdit && !draft.isError) { drafts.add(draft); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/PaintView.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/PaintView.java index 4d203b5cc..906654cb9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/PaintView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/PaintView.java @@ -3530,6 +3530,7 @@ public class PaintView extends SizeNotifierFrameLayoutPhoto implements IPhotoPai @Override public void onEntityDragEnd(boolean delete) { updatePreviewViewTranslationY(); + forceChanges = true; } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryEntry.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryEntry.java index 60a10ea92..e1b163f9e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryEntry.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryEntry.java @@ -65,6 +65,9 @@ public class StoryEntry extends IStoryPart { public boolean editedMedia, editedCaption, editedPrivacy; public ArrayList editedMediaAreas; + public boolean isError; + public TLRPC.TL_error error; + public long editDocumentId; public long editPhotoId; public long editExpireDate; @@ -828,9 +831,10 @@ public class StoryEntry extends IStoryPart { public float minlum; public int getHDRType() { - if (maxlum <= 0 && minlum <= 0) { - return 0; - } else if (colorStandard == MediaFormat.COLOR_STANDARD_BT2020) { +// if (maxlum <= 0 && minlum <= 0) { +// return 0; +// } else + if (colorStandard == MediaFormat.COLOR_STANDARD_BT2020) { if (colorTransfer == MediaFormat.COLOR_TRANSFER_HLG) { return 1; } else if (colorTransfer == MediaFormat.COLOR_TRANSFER_ST2084) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryPrivacyBottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryPrivacyBottomSheet.java index 56c41c453..d2c5aaca5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryPrivacyBottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryPrivacyBottomSheet.java @@ -413,7 +413,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification } else { TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(id); TLRPC.ChatFull chatFull = MessagesController.getInstance(currentAccount).getChatFull(id); - if (chatFull != null && chatFull.participants != null && !chatFull.participants.participants.isEmpty()) { + if (chatFull != null && chatFull.participants != null && chatFull.participants.participants != null && !chatFull.participants.participants.isEmpty() && chatFull.participants.participants.size() >= (chatFull.participants_count - 1)) { selectChat(id, chatFull.participants); } else { if (progressDialog != null) { @@ -427,7 +427,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification storage.getStorageQueue().postRunnable(() -> { boolean isChannel = ChatObject.isChannel(chat); TLRPC.ChatFull info = storage.loadChatInfoInQueue(id, isChannel, true, true, 0); - if (info == null || info.participants == null) { + if (info == null || info.participants == null || info.participants.participants != null && info.participants.participants.size() < (info.participants_count - 1)) { AndroidUtilities.runOnUIThread(() -> { if (isChannel) { MessagesController.getInstance(currentAccount).loadChannelParticipants(id, participants -> { @@ -1599,7 +1599,11 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification ItemInner item = items.get(position); UserCell cell = (UserCell) child; cell.setChecked(item.checked || item.halfChecked, animated); - cell.setCheckboxAlpha(item.halfChecked && !item.checked ? .5f : 1f, animated); + if (item.chat != null) { + cell.setCheckboxAlpha(getParticipantsCount(item.chat) > 200 ? .3f : 1f, animated); + } else { + cell.setCheckboxAlpha(item.halfChecked && !item.checked ? .5f : 1f, animated); + } } } @@ -1929,6 +1933,8 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification smallChatsParticipantsCount.putAll(participantsCountByChat); }); }); + + MessagesController.getInstance(currentAccount).getStoriesController().loadBlocklist(false); } private void init(Context context) { @@ -2499,7 +2505,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification } } else if (includeSmallChats && DialogObject.isChatDialog(dialog.id)) { TLRPC.Chat chat = messagesController.getChat(-dialog.id); - if (chat == null || ChatObject.isForum(chat) || ChatObject.isChannelAndNotMegaGroup(chat)) { + if (chat == null || ChatObject.isChannelAndNotMegaGroup(chat)) { continue; } // int participants_count = getParticipantsCount(chat); @@ -2583,7 +2589,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification avatarDrawable.setRoundRadius(AndroidUtilities.dp(40)); imageView = new BackupImageView(context); - imageView.setRoundRadius(AndroidUtilities.dp(40)); + imageView.setRoundRadius(AndroidUtilities.dp(20)); addView(imageView, LayoutHelper.createFrame(40, 40, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), 53, 0, 53, 0)); titleTextView = new SimpleTextView(context); @@ -2651,6 +2657,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification public void setUser(TLRPC.User user) { avatarDrawable.setInfo(user); + imageView.setRoundRadius(dp(20)); imageView.setForUserOrChat(user, avatarDrawable); CharSequence text = UserObject.getUserName(user); @@ -2667,6 +2674,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification public void setChat(TLRPC.Chat chat, int participants_count) { avatarDrawable.setInfo(chat); + imageView.setRoundRadius(dp(ChatObject.isForum(chat) ? 12 : 20)); imageView.setForUserOrChat(chat, avatarDrawable); CharSequence text = chat.title; @@ -2778,6 +2786,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification checkBox.setVisibility(View.GONE); radioButton.setVisibility(View.VISIBLE); imageView.setImageDrawable(avatarDrawable); + imageView.setRoundRadius(dp(20)); } private void setSubtitle(CharSequence text) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryRecorder.java b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryRecorder.java index 78625309b..909e7c72b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryRecorder.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Stories/recorder/StoryRecorder.java @@ -1609,6 +1609,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg @Override protected boolean captionLimitToast() { + if (MessagesController.getInstance(currentAccount).premiumLocked) { + return false; + } Bulletin visibleBulletin = Bulletin.getVisibleBulletin(); if (visibleBulletin != null && visibleBulletin.tag == 2) { return false; @@ -2108,9 +2111,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg if (storyEntry == null || previewView.getWidth() <= 0 || previewView.getHeight() <= 0) { return null; } - if (!forDraft && !storyEntry.wouldBeVideo() && !storyEntry.isEdit) { - return null; - } +// if (!forDraft && !storyEntry.wouldBeVideo() && !storyEntry.isEdit) { +// return null; +// } File file = forDraft ? storyEntry.draftThumbFile : storyEntry.uploadThumbFile; if (file != null) { file.delete(); @@ -3069,7 +3072,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg // privacySelector.setStoryPeriod(outputEntry == null || !UserConfig.getInstance(currentAccount).isPremium() ? 86400 : outputEntry.period); captionEdit.setPeriod(outputEntry == null ? 86400 : outputEntry.period, false); - captionEdit.setPeriodVisible(outputEntry == null || !outputEntry.isEdit); + captionEdit.setPeriodVisible(!MessagesController.getInstance(currentAccount).premiumLocked && (outputEntry == null || !outputEntry.isEdit)); } if (toPage == PAGE_PREVIEW) { videoError = false; @@ -3224,11 +3227,14 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg createFilterPhotoView(); // animatePhotoFilterTexture(true, animated); previewTouchable = photoFilterView; - photoFilterView.getToolsView().setAlpha(0f); - photoFilterView.getToolsView().setVisibility(View.VISIBLE); - animators.add(ObjectAnimator.ofFloat(photoFilterView.getToolsView(), View.TRANSLATION_Y, 0)); - animators.add(ObjectAnimator.ofFloat(photoFilterView.getToolsView(), View.ALPHA, 1)); - TextureView textureView = photoFilterView.getMyTextureView(); + View toolsView = photoFilterView != null ? photoFilterView.getToolsView() : null; + if (toolsView != null) { + toolsView.setAlpha(0f); + toolsView.setVisibility(View.VISIBLE); + animators.add(ObjectAnimator.ofFloat(toolsView, View.TRANSLATION_Y, 0)); + animators.add(ObjectAnimator.ofFloat(toolsView, View.ALPHA, 1)); + } + TextureView textureView = photoFilterView != null ? photoFilterView.getMyTextureView() : null; if (textureView != null) { animators.add(ObjectAnimator.ofFloat(textureView, View.ALPHA, 1)); } diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index ce527feca..91a2947fc 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -62,6 +62,7 @@ The deletion process was cancelled for your account %1$s. You may close this window now. Your login code is **%1$s**. Enter it in the Telegram app where you are trying to log in.\n\nDo not give this code to anyone. You can request an SMS in %1$d:%2$02d + You can request a new SMS in %1$d:%2$02d Get the code via SMS You can request a voice call in %1$d:%2$02d Call me to dictate the code @@ -6685,6 +6686,10 @@ Uploading story error My Story Uploading… + Failed + failed to upload + Couldn’t upload + Try Again Story Message sent. Just now @@ -7100,7 +7105,7 @@ %d likes %d likes You can post **%1$d** stories in **24** hours.\nSubscribe to **Telegram Premium** to increase this limit to **%2$d**. - Sorry, you can’t post more than **%1$d** stories. + Sorry, you can’t post more than **%1$d** stories in **24** hours. You can post **%1$d** stories in a week.\nSubscribe to **Telegram Premium** to increase this limit to **%2$d**. Sorry, you can’t post more than **%1$d** stories in a week. You can post **%1$d** stories in a month.\nSubscribe to **Telegram Premium** to increase this limit to **%2$d**. diff --git a/gradle.properties b/gradle.properties index 0071896fe..e3315adac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,8 +13,8 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Sat Mar 12 05:53:50 MSK 2016 -APP_VERSION_CODE=3721 -APP_VERSION_NAME=9.7.6 +APP_VERSION_CODE=3801 +APP_VERSION_NAME=10.0.3 APP_PACKAGE=org.telegram.messenger RELEASE_KEY_PASSWORD=android RELEASE_KEY_ALIAS=androidkey @@ -25,4 +25,4 @@ org.gradle.parallel=true org.gradle.configureondemand=false android.useAndroidX=true android.enableJetifier=true -android.defaults.buildfeatures.buildconfig=true +android.defaults.buildfeatures.buildconfig=true \ No newline at end of file