diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 7d8bb72d3..0a6f6bc35 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 = 2900; - public static String BUILD_VERSION_STRING = "9.1.1"; + public static int BUILD_VERSION = 2902; + public static String BUILD_VERSION_STRING = "9.1.2"; public static int APP_ID = 4; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java index 32cbfb406..3e4837808 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java @@ -2268,7 +2268,6 @@ public class MessagesStorage extends BaseController { database.executeFast("DELETE FROM topics").stepThis().dispose(); database.executeFast("DELETE FROM media_holes_topics").stepThis().dispose(); database.executeFast("DELETE FROM media_topics").stepThis().dispose(); - database.executeFast("DELETE FROM media_topics").stepThis().dispose(); database.executeFast("DELETE FROM media_counts_topics").stepThis().dispose(); database.executeFast("DELETE FROM chat_pinned_v2").stepThis().dispose(); database.executeFast("DELETE FROM chat_pinned_count").stepThis().dispose(); @@ -2330,7 +2329,7 @@ public class MessagesStorage extends BaseController { database.executeFast("DELETE FROM media_holes_v2 WHERE uid = " + did).stepThis().dispose(); MediaDataController.getInstance(currentAccount).clearBotKeyboard(did, null); if (messageId != -1) { - MessagesStorage.createFirstHoles(did, state5, state6, messageId); + MessagesStorage.createFirstHoles(did, state5, state6, messageId, 0); } } cursor.dispose(); @@ -2383,6 +2382,17 @@ public class MessagesStorage extends BaseController { private void saveTopicsInternal(long dialogId, List topics, boolean replace, boolean inTransaction) { SQLitePreparedStatement state = null; try { + HashSet existingTopics = new HashSet<>(); + for (int i = 0; i < topics.size(); i++) { + TLRPC.TL_forumTopic topic = topics.get(i); + SQLiteCursor cursor = database.queryFinalized("SELECT did FROM topics WHERE did = " + dialogId + " AND topic_id = " + topic.id); + boolean exist = cursor.next(); + cursor.dispose(); + cursor = null; + if (exist) { + existingTopics.add(i); + } + } if (replace) { database.executeFast("DELETE FROM topics WHERE did = " + dialogId).stepThis().dispose(); } @@ -2393,6 +2403,8 @@ public class MessagesStorage extends BaseController { for (int i = 0; i < topics.size(); i++) { TLRPC.TL_forumTopic topic = topics.get(i); + boolean exist = existingTopics.contains(i); + state.requery(); state.bindLong(1, dialogId); state.bindInteger(2, topic.id); @@ -2416,8 +2428,21 @@ public class MessagesStorage extends BaseController { messageData.reuse(); data.reuse(); - closeHolesInTable("messages_holes_topics", dialogId, topic.top_message, topic.top_message, topic.id); - closeHolesInMedia(dialogId, topic.top_message, topic.top_message, -1, 0); + if (exist) { + closeHolesInTable("messages_holes_topics", dialogId, topic.top_message, topic.top_message, topic.id); + closeHolesInMedia(dialogId, topic.top_message, topic.top_message, -1, 0); + } else { + database.executeFast(String.format(Locale.ENGLISH, "DELETE FROM messages_holes_topics WHERE uid = %d AND topic_id = %d", dialogId, topic.id)).stepThis().dispose(); + database.executeFast(String.format(Locale.ENGLISH, "DELETE FROM media_holes_topics WHERE uid = %d AND topic_id = %d", dialogId, topic.id)).stepThis().dispose(); + database.executeFast(String.format(Locale.ENGLISH, "DELETE FROM messages_topics WHERE uid = %d AND topic_id = %d", dialogId, topic.id)).stepThis().dispose(); + database.executeFast(String.format(Locale.ENGLISH, "DELETE FROM media_topics WHERE uid = %d AND topic_id = %d", dialogId, topic.id)).stepThis().dispose(); + + SQLitePreparedStatement state_holes = database.executeFast("REPLACE INTO messages_holes_topics VALUES(?, ?, ?, ?)"); + SQLitePreparedStatement state_media_holes = database.executeFast("REPLACE INTO media_holes_topics VALUES(?, ?, ?, ?, ?)"); + createFirstHoles(dialogId, state_holes, state_media_holes, topic.top_message, topic.id); + state_holes.dispose(); + state_holes.dispose(); + } } resetAllUnreadCounters(false); @@ -4739,7 +4764,7 @@ public class MessagesStorage extends BaseController { state5 = database.executeFast("REPLACE INTO messages_holes VALUES(?, ?, ?)"); state6 = database.executeFast("REPLACE INTO media_holes_v2 VALUES(?, ?, ?, ?)"); if (messageId != -1) { - createFirstHoles(did, state5, state6, messageId); + createFirstHoles(did, state5, state6, messageId, 0); } state5.dispose(); state5 = null; @@ -5208,41 +5233,53 @@ public class MessagesStorage extends BaseController { if (dialogs != null) { database.beginTransaction(); SQLitePreparedStatement state = database.executeFast("UPDATE messages_v2 SET data = ? WHERE mid = ? AND uid = ?"); + SQLitePreparedStatement state_topics = database.executeFast("UPDATE messages_topics SET data = ? WHERE mid = ? AND uid = ?"); for (int b = 0, N2 = dialogs.size(); b < N2; b++) { long dialogId = dialogs.keyAt(b); ArrayList mids = dialogs.valueAt(b); for (int a = 0, N = mids.size(); a < N; a++) { Integer mid = mids.get(a); - cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM messages_v2 WHERE mid = %d AND uid = %d", mid, dialogId)); - if (cursor.next()) { - NativeByteBuffer data = cursor.byteBufferValue(0); - if (data != null) { - TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false); - message.readAttachPath(data, getUserConfig().clientUserId); - data.reuse(); - if (message.media instanceof TLRPC.TL_messageMediaPoll) { - TLRPC.TL_messageMediaPoll media = (TLRPC.TL_messageMediaPoll) message.media; - if (poll != null) { - media.poll = poll; - } - if (results != null) { - MessageObject.updatePollResults(media, results); - } - - data = new NativeByteBuffer(message.getObjectSize()); - message.serializeToStream(data); - state.requery(); - state.bindByteBuffer(1, data); - state.bindInteger(2, mid); - state.bindLong(3, dialogId); - state.step(); - data.reuse(); - } + boolean foundMessage = false; + for (int k = 0; k < 2; k++) { + boolean isTopic = k == 1; + if (isTopic) { + cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM messages_topics WHERE mid = %d AND uid = %d", mid, dialogId)); + } else { + cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM messages_v2 WHERE mid = %d AND uid = %d", mid, dialogId)); } - } else { + SQLitePreparedStatement currentState = isTopic ? state_topics : state; + if (cursor.next()) { + NativeByteBuffer data = cursor.byteBufferValue(0); + if (data != null) { + TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false); + message.readAttachPath(data, getUserConfig().clientUserId); + data.reuse(); + if (message.media instanceof TLRPC.TL_messageMediaPoll) { + TLRPC.TL_messageMediaPoll media = (TLRPC.TL_messageMediaPoll) message.media; + if (poll != null) { + media.poll = poll; + } + if (results != null) { + MessageObject.updatePollResults(media, results); + } + + data = new NativeByteBuffer(message.getObjectSize()); + message.serializeToStream(data); + currentState.requery(); + currentState.bindByteBuffer(1, data); + currentState.bindInteger(2, mid); + currentState.bindLong(3, dialogId); + currentState.step(); + data.reuse(); + } + } + foundMessage = true; + } + cursor.dispose(); + } + if (!foundMessage) { database.executeFast(String.format(Locale.US, "DELETE FROM polls_v2 WHERE mid = %d AND uid = %d", mid, dialogId)).stepThis().dispose(); } - cursor.dispose(); } } state.dispose(); @@ -14975,19 +15012,27 @@ public class MessagesStorage extends BaseController { }); } - public static void createFirstHoles(long did, SQLitePreparedStatement state5, SQLitePreparedStatement state6, int messageId) throws Exception { + public static void createFirstHoles(long did, SQLitePreparedStatement state5, SQLitePreparedStatement state6, int messageId, int topicId) throws Exception { state5.requery(); - state5.bindLong(1, did); - state5.bindInteger(2, messageId == 1 ? 1 : 0); - state5.bindInteger(3, messageId); + int pointer = 1; + state5.bindLong(pointer++, did); + if (topicId != 0) { + state5.bindInteger(pointer++, topicId); + } + state5.bindInteger(pointer++, messageId == 1 ? 1 : 0); + state5.bindInteger(pointer++, messageId); state5.step(); for (int b = 0; b < MediaDataController.MEDIA_TYPES_COUNT; b++) { state6.requery(); - state6.bindLong(1, did); - state6.bindInteger(2, b); - state6.bindInteger(3, messageId == 1 ? 1 : 0); - state6.bindInteger(4, messageId); + pointer = 1; + state6.bindLong(pointer++, did); + if (topicId != 0) { + state6.bindInteger(pointer++, topicId); + } + state6.bindInteger(pointer++, b); + state6.bindInteger(pointer++, messageId == 1 ? 1 : 0); + state6.bindInteger(pointer++, messageId); state6.step(); } } @@ -15157,7 +15202,7 @@ public class MessagesStorage extends BaseController { closeHolesInTable("messages_holes", dialog.id, message.id, message.id, 0); closeHolesInMedia(dialog.id, message.id, message.id, -1, 0); } else { - createFirstHoles(dialog.id, state_holes, state_media_holes, message.id); + createFirstHoles(dialog.id, state_holes, state_media_holes, message.id, 0); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/browser/Browser.java b/TMessagesProj/src/main/java/org/telegram/messenger/browser/Browser.java index 029212870..a7a2ae7a3 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/browser/Browser.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/browser/Browser.java @@ -44,7 +44,6 @@ import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.LaunchActivity; -import org.w3c.dom.Text; import java.lang.ref.WeakReference; import java.net.URLEncoder; @@ -372,7 +371,11 @@ public class Browser { } intent.putExtra(android.provider.Browser.EXTRA_CREATE_NEW_TAB, true); intent.putExtra(android.provider.Browser.EXTRA_APPLICATION_ID, context.getPackageName()); - context.startActivity(intent); + if (internalUri && context instanceof LaunchActivity) { + ((LaunchActivity) context).onNewIntent(intent); + } else { + context.startActivity(intent); + } } catch (Exception e) { FileLog.e(e); } 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 01a9adbe0..e1d02ab38 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -8270,7 +8270,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } radii[a * 2] = radii[a * 2 + 1] = 0; } - if (!out && !drawPinnedBottom && currentPosition == null) { + if (!out && !drawPinnedBottom && currentPosition == null && (currentMessageObject == null || currentMessageObject.type != MessageObject.TYPE_POLL)) { path.moveTo(rect.left + AndroidUtilities.dp(6), rect.top); path.lineTo(rect.left + AndroidUtilities.dp(6), rect.bottom - AndroidUtilities.dp(6) - AndroidUtilities.dp(2 + 3)); AndroidUtilities.rectTmp.set( @@ -10344,12 +10344,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (currentMessageObject == null || currentMessageObject != null && currentMessageObject.hasExtendedMedia()) { return MediaActionDrawable.ICON_NONE; } - if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject.isVoiceTranscriptionOpen()) { - if (currentMessageObject.isOutOwner()) { - radialProgress.setColors(Theme.key_chat_outLoader, Theme.key_chat_outLoaderSelected, Theme.key_chat_outMediaIcon, Theme.key_chat_outMediaIconSelected); - } else { - radialProgress.setColors(Theme.key_chat_inLoader, Theme.key_chat_inLoaderSelected, Theme.key_chat_inMediaIcon, Theme.key_chat_inMediaIconSelected); - } + if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject.isVoiceTranscriptionOpen() && (currentMessageObject != null && currentMessageObject.attachPathExists && !TextUtils.isEmpty(currentMessageObject.messageOwner.attachPath) || currentMessageObject.mediaExists)) { if (buttonState == 1 || buttonState == 4) { return MediaActionDrawable.ICON_PAUSE; } @@ -10414,6 +10409,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } } } + if (currentMessageObject != null && isRoundVideo && currentMessageObject.isVoiceTranscriptionOpen()) { + return MediaActionDrawable.ICON_PLAY; + } return MediaActionDrawable.ICON_NONE; } @@ -10531,7 +10529,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } boolean fromBot = currentMessageObject.messageOwner.params != null && currentMessageObject.messageOwner.params.containsKey("query_id"); - if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen()) { + if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen() && fileExists) { if (currentMessageObject.isOut() && (currentMessageObject.isSending() && !currentMessageObject.isForwarded() || currentMessageObject.isEditing() && currentMessageObject.isEditingMedia()) || currentMessageObject.isSendError() && fromBot) { if (!TextUtils.isEmpty(currentMessageObject.messageOwner.attachPath)) { DownloadController.getInstance(currentAccount).addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, currentMessageObject, this); @@ -10910,7 +10908,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate currentMessageObject.putInDownloadsStore = true; } if (buttonState == 0 && (!drawVideoImageButton || video)) { - if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen()) { + if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen() && currentMessageObject.mediaExists) { if (miniButtonState == 0) { FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, 0); currentMessageObject.loadingCancelled = false; @@ -14156,7 +14154,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate endX += AndroidUtilities.dp(14); buttonX -= AndroidUtilities.dp(10); } - commentButtonRect.set(buttonX - AndroidUtilities.dp((currentMessageObject == null || !currentMessageObject.isOut()) && !drawPinnedBottom && currentPosition == null ? 6 : 0), (int) buttonY, endX - AndroidUtilities.dp(14), layoutHeight - AndroidUtilities.dp(h)); + commentButtonRect.set( + buttonX - AndroidUtilities.dp((currentMessageObject == null || !currentMessageObject.isOut()) && !drawPinnedBottom && currentPosition == null && (currentMessageObject == null || currentMessageObject.type != MessageObject.TYPE_POLL) ? 6 : 0), + (int) buttonY, + endX - AndroidUtilities.dp(14), + layoutHeight - AndroidUtilities.dp(h) + ); if (selectorDrawable[1] != null && selectorDrawableMaskType[1] == 2) { int count = canvas.getSaveCount(); selectorDrawable[1].setBounds(commentButtonRect); @@ -16174,7 +16177,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate radialProgress.setBackgroundDrawable(isDrawSelectionBackground() ? currentBackgroundSelectedDrawable : currentBackgroundDrawable); } boolean restore = false; - if (currentMessageObject.isOutOwner() && !currentMessageObject.isSent()) { + boolean on = false; + if (currentMessageObject != null && currentMessageObject.isRoundVideo() && (getVideoTranscriptionProgress() <= 0 && !currentMessageObject.mediaExists)) { radialProgress.setProgressRect( photoImage.getImageX() + (photoImage.getImageWidth() - radialProgress.getRadius()) / 2f, photoImage.getImageY() + (photoImage.getImageHeight() - radialProgress.getRadius()) / 2f, @@ -16194,11 +16198,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate restore = true; } if ((!isRoundVideo || !hasLinkPreview) && (!currentMessageObject.needDrawBluredPreview() || !MediaController.getInstance().isPlayingMessage(currentMessageObject))) { - if (isRoundVideo) { + if (isRoundVideo && !on) { radialProgress.overrideCircleAlpha = .25f + .75f * (1f - getVideoTranscriptionProgress()); } radialProgress.draw(canvas); - if (isRoundVideo) { + if (isRoundVideo && !on) { radialProgress.overrideCircleAlpha = 1f; } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 6baff249f..fa022d527 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -57,7 +57,6 @@ import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.Spanned; -import android.text.StaticLayout; import android.text.TextPaint; import android.text.TextUtils; import android.text.style.CharacterStyle; @@ -15183,6 +15182,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not needAnimateToMessage = null; } + MessageObject oldMessage = messagesDict[loadIndex].get(messageId); messagesDict[loadIndex].put(messageId, obj); ArrayList dayArray = messagesByDays.get(obj.dateKey); @@ -15270,7 +15270,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not newRowsCount++; dayArray.add(obj); - obj.stableId = lastStableId++; + if (oldMessage != null) { + obj.stableId = oldMessage.stableId; + } else { + obj.stableId = lastStableId++; + } if (load_type == 1) { messages.add(0, obj); } else { @@ -16522,11 +16526,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not MediaController.getInstance().setTextureView(createTextureView(true), aspectRatioFrameLayout, videoPlayerContainer, true); updateTextureViewPosition(true, true); } else { - MediaController.getInstance().setTextureView(createTextureView(true), aspectRatioFrameLayout, videoPlayerContainer, true, () -> { - checkTextureViewPosition = true; - updateMessagesVisiblePart(false); - updateTextureViewPosition(true, false); - }); + MediaController.getInstance().setTextureView(createTextureView(true), aspectRatioFrameLayout, videoPlayerContainer, true); } } @@ -26167,9 +26167,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (messageObject.isVoice() || messageObject.isRoundVideo()) { boolean result = MediaController.getInstance().playMessage(messageObject, muted); MediaController.getInstance().setVoiceMessagesPlaylist(result ? createVoiceMessagesPlaylist(messageObject, false) : null, false); -// if (messageObject.isRoundVideo() && messageObject.isVoiceTranscriptionOpen()) { -// AndroidUtilities.runOnUIThread(() -> updateMessagesVisiblePart(false), 450); -// } return result; } else if (messageObject.isMusic()) { return MediaController.getInstance().setPlaylist(messages, messageObject, mergeDialogId); @@ -26407,6 +26404,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not new PremiumFeatureBottomSheet(ChatActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_VOICE_TO_TEXT, true).show(); getMessagesController().pressTranscribeButton(); }); + try { + topUndoView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } catch (Exception ignored) {} } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java index 399c9ebd0..9fe7db70f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java @@ -44,6 +44,7 @@ import androidx.core.util.Consumer; import androidx.core.view.ViewCompat; import androidx.dynamicanimation.animation.DynamicAnimation; import androidx.dynamicanimation.animation.FloatPropertyCompat; +import androidx.dynamicanimation.animation.FloatValueHolder; import androidx.dynamicanimation.animation.SpringAnimation; import androidx.dynamicanimation.animation.SpringForce; @@ -77,6 +78,8 @@ public class Bulletin { public int tag; public int hash; + private View.OnLayoutChangeListener containerLayoutListener; + private SpringAnimation bottomOffsetSpring; public static Bulletin make(@NonNull FrameLayout containerLayout, @NonNull Layout contentLayout, int duration) { return new Bulletin(null, containerLayout, contentLayout, duration); @@ -198,6 +201,33 @@ public class Bulletin { visibleBulletin = this; layout.onAttach(this); + containerLayout.addOnLayoutChangeListener(containerLayoutListener = (v, left, top1, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { + if (!top) { + int newOffset = currentDelegate != null ? currentDelegate.getBottomOffset(tag) : 0; + if (currentBottomOffset != newOffset) { + if (bottomOffsetSpring == null || !bottomOffsetSpring.isRunning()) { + bottomOffsetSpring = new SpringAnimation(new FloatValueHolder(currentBottomOffset)) + .setSpring(new SpringForce() + .setFinalPosition(newOffset) + .setStiffness(900f) + .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)); + bottomOffsetSpring.addUpdateListener((animation, value, velocity) -> { + currentBottomOffset = (int) value; + updatePosition(); + }); + bottomOffsetSpring.addEndListener((animation, canceled, value, velocity) -> { + if (bottomOffsetSpring == animation) { + bottomOffsetSpring = null; + } + }); + } else { + bottomOffsetSpring.getSpring().setFinalPosition(newOffset); + } + bottomOffsetSpring.start(); + } + } + }); + layout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int t, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { @@ -205,7 +235,9 @@ public class Bulletin { if (showing) { layout.onShow(); currentDelegate = findDelegate(containerFragment, containerLayout); - currentBottomOffset = currentDelegate != null ? currentDelegate.getBottomOffset(tag) : 0; + if (bottomOffsetSpring == null || !bottomOffsetSpring.isRunning()) { + currentBottomOffset = currentDelegate != null ? currentDelegate.getBottomOffset(tag) : 0; + } if (currentDelegate != null) { currentDelegate.onShow(Bulletin.this); } @@ -314,6 +346,7 @@ public class Bulletin { layout.onExitTransitionEnd(); layout.onHide(); containerLayout.removeView(parentLayout); + containerLayout.removeOnLayoutChangeListener(containerLayoutListener); layout.onDetach(); }, offset -> { if (currentDelegate != null && !layout.top) { @@ -332,7 +365,10 @@ public class Bulletin { layout.onExitTransitionEnd(); layout.onHide(); if (containerLayout != null) { - AndroidUtilities.runOnUIThread(() -> containerLayout.removeView(parentLayout)); + AndroidUtilities.runOnUIThread(() -> { + containerLayout.removeView(parentLayout); + containerLayout.removeOnLayoutChangeListener(containerLayoutListener); + }); } layout.onDetach(); } @@ -739,12 +775,19 @@ public class Bulletin { if (top) { translation -= delegate.getTopOffset(bulletin != null ? bulletin.tag : 0); } else { - translation += delegate.getBottomOffset(bulletin != null ? bulletin.tag : 0); + translation += getBottomOffset(); } } setTranslationY(-translation + inOutOffset * (top ? -1 : 1)); } + public float getBottomOffset() { + if (bulletin != null && bulletin.bottomOffsetSpring != null && bulletin.bottomOffsetSpring.isRunning()) { + return bulletin.currentBottomOffset; + } + return delegate.getBottomOffset(bulletin != null ? bulletin.tag : 0); + } + public interface Callback { default void onAttach(@NonNull Layout layout, @NonNull Bulletin bulletin) { } @@ -919,7 +962,7 @@ public class Bulletin { 0, delegate.getTopOffset(bulletin.tag) - getY(), getMeasuredWidth(), - ((View) getParent()).getMeasuredHeight() - delegate.getBottomOffset(bulletin.tag) - getY() + ((View) getParent()).getMeasuredHeight() - getBottomOffset() - getY() ); background.draw(canvas); super.dispatchDraw(canvas); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumFeatureBottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumFeatureBottomSheet.java index db7bf45eb..25e996c90 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumFeatureBottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumFeatureBottomSheet.java @@ -420,7 +420,7 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) { premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.UnlockPremiumReactions)); premiumButtonView.setIcon(R.raw.unlock_icon); - } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADS || startType == PremiumPreviewFragment.PREMIUM_FEATURE_DOWNLOAD_SPEED || startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT) { + } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADS || startType == PremiumPreviewFragment.PREMIUM_FEATURE_DOWNLOAD_SPEED || startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT || startType == PremiumPreviewFragment.PREMIUM_FEATURE_VOICE_TO_TEXT) { premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.AboutTelegramPremium)); } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_APPLICATION_ICONS) { premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.UnlockPremiumIcons)); @@ -609,6 +609,9 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT) { title.setText(LocaleController.getString(R.string.PremiumPreviewAdvancedChatManagement)); description.setText(LocaleController.getString(R.string.PremiumPreviewAdvancedChatManagementDescription2)); + } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_VOICE_TO_TEXT) { + title.setText(LocaleController.getString(R.string.PremiumPreviewVoiceToText)); + description.setText(LocaleController.getString(R.string.PremiumPreviewVoiceToTextDescription2)); } topViewOnFullHeight = false; } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/VideoScreenPreview.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/VideoScreenPreview.java index a81a4f7e9..21ba44e82 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/VideoScreenPreview.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/VideoScreenPreview.java @@ -54,9 +54,19 @@ public class VideoScreenPreview extends FrameLayout implements PagerHeaderView, String attachFileName; ImageReceiver imageReceiver = new ImageReceiver(this); + Runnable nextCheck; + private void checkVideo() { if (file != null && file.exists() || SharedConfig.streamMedia) { if (file != null && file.exists()) { + if ((NotificationCenter.getGlobalInstance().getCurrentHeavyOperationFlags() & 512) != 0) { + if (nextCheck != null) { + AndroidUtilities.cancelRunOnUIThread(nextCheck); + } + AndroidUtilities.runOnUIThread(nextCheck = this::checkVideo, 300); + return; + } + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); retriever.setDataSource(ApplicationLoader.applicationContext, Uri.fromFile(file)); int width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)); @@ -71,6 +81,7 @@ public class VideoScreenPreview extends FrameLayout implements PagerHeaderView, runVideoPlayer(); } } + nextCheck = null; } int currentAccount; diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index e55d25b54..178db30c1 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -5546,6 +5546,7 @@ Sorry, you can\'t add more than **%1$d** accounts. Voice-to-Text Conversion Ability to read the transcript of any incoming voice message. + Subscribe to Telegram Premium to be able to convert voice and video messages to text. Advanced Chat Management Premium Premuim Stickers diff --git a/gradle.properties b/gradle.properties index 228ff0486..780592585 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_NAME=9.1.1 -APP_VERSION_CODE=2900 +APP_VERSION_NAME=9.1.2 +APP_VERSION_CODE=2902 APP_PACKAGE=org.telegram.messenger RELEASE_KEY_PASSWORD=TelegramAndroidPswd RELEASE_KEY_ALIAS=tmessages