diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 747858dc74..d48b69cac1 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -13164,3 +13164,40 @@ Sorry for the inconvenience."; "PeerInfo.BotBalance.Title" = "BALANCE"; "PeerInfo.BotBalance.Ton" = "Ton"; "PeerInfo.BotBalance.Stars" = "Stars"; + +"Gallery.ToastVideoSpeedSwipe" = "Swipe sideways to adjust speed."; +"Gallery.VideoSettings.QualitySectionTitle" = "QUALITY"; +"Gallery.VideoSettings.SpeedSectionTitle" = "PLAYBACK SPEED"; +"Gallery.VideoSettings.SpeedControlTitle" = "Speed"; + +"Gallery.VideoSettings.QualityAuto" = "Auto"; +"Gallery.VideoSettings.QualityLow" = "Low"; +"Gallery.VideoSettings.QualityMedium" = "Medium"; +"Gallery.VideoSettings.QualityHD" = "High"; +"Gallery.VideoSettings.QualityFHD" = "Full HD"; +"Gallery.VideoSettings.QualityQHD" = "Ultra-High"; + +"Gallery.VideoSettings.IconQualityLow" = "L"; +"Gallery.VideoSettings.IconQualityMedium" = "SD"; +"Gallery.VideoSettings.IconQualityHD" = "HD"; +"Gallery.VideoSettings.IconQualityFHD" = "FHD"; +"Gallery.VideoSettings.IconQualityQHD" = "QHD"; + +"Gallery.MenuSaveToGallery" = "Save to Gallery"; +"Gallery.SaveToGallery.Quality" = "Save in %@p"; +"Gallery.SaveToGallery.Original" = "Save Original"; + +"VideoChat.ScheduleButtonTitle" = "Schedule Video Chat"; + +"Chat.ToastImprovingVideo.Title" = "Improving video..."; +"Chat.ToastImprovingVideo.Text" = "The video will be published after it's optimized for the best viewing experience."; +"Chat.ToastVideoPublished.Title" = "Video Published"; +"Chat.ToastVideoPublished.Action" = "View"; +"Chat.MessageTooltipVideoProcessing" = "Processing video may take a few minutes."; + +"Chat.VideoProcessingServiceMessage_1" = "This video will be published once converted and optimized"; +"Chat.VideoProcessingServiceMessage_any" = "These videos will be published once converted and optimized"; + +"Chat.ScheduledForceSendProcessingVideo.Title" = "Wait!"; +"Chat.ScheduledForceSendProcessingVideo.Text" = "This video hasn't been converted and optimized yet. If you send it now, the viewers of the video may experience slow download speed."; +"Chat.ScheduledForceSendProcessingVideo.Action" = "Send Anyway"; diff --git a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift index 25d86232d9..a7776fedcd 100644 --- a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift @@ -600,8 +600,6 @@ final class SettingsHeaderButton: HighlightableButtonNode { self.dotLayer.bounds = CGRect(origin: CGPoint(), size: dotFrame.size) } } - - //self.setBadges(speed: "1.5x", quality: "HD", transition: .immediate) } override func didLoad() { @@ -1619,12 +1617,11 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { activeEdgeRateIndicatorTransition = .immediate } - //TODO:localize let activeEdgeRateIndicatorSize = activeEdgeRateIndicator.update( transition: ComponentTransition(activeEdgeRateIndicatorTransition), component: AnyComponent(GalleryRateToastComponent( rate: activeEdgeRateState.currentRate, - displayTooltip: "Swipe sideways to adjust speed." + displayTooltip: self.presentationData.strings.Gallery_ToastVideoSpeedSwipe )), environment: {}, containerSize: CGSize(width: layout.size.width - layout.safeInsets.left * 2.0, height: 100.0) @@ -1902,15 +1899,15 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { var qualityString: String? if case let .quality(quality) = videoQuality { if quality <= 360 { - qualityString = "SD" + qualityString = self.presentationData.strings.Gallery_VideoSettings_IconQualityLow } else if quality <= 480 { - qualityString = "SD" + qualityString = self.presentationData.strings.Gallery_VideoSettings_IconQualityMedium } else if quality <= 720 { - qualityString = "HD" + qualityString = self.presentationData.strings.Gallery_VideoSettings_IconQualityHD } else if quality <= 1080 { - qualityString = "FHD" + qualityString = self.presentationData.strings.Gallery_VideoSettings_IconQualityFHD } else { - qualityString = "UHD" + qualityString = self.presentationData.strings.Gallery_VideoSettings_IconQualityQHD } } @@ -3474,7 +3471,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { if isSettings { let sliderValuePromise = ValuePromise(nil) - topItems.append(.custom(SliderContextItem(title: "Speed", minValue: 0.2, maxValue: 2.5, value: status.baseRate, valueChanged: { [weak self] newValue, _ in + topItems.append(.custom(SliderContextItem(title: strongSelf.presentationData.strings.Gallery_VideoSettings_SpeedControlTitle, minValue: 0.2, maxValue: 2.5, value: status.baseRate, valueChanged: { [weak self] newValue, _ in guard let strongSelf = self, let videoNode = strongSelf.videoNode else { return } @@ -3488,7 +3485,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { if let videoQualityState = strongSelf.videoNode?.videoQualityState(), !videoQualityState.available.isEmpty { } else { - items.append(.custom(SectionTitleContextItem(text: "PLAYBACK SPEED"), false)) + items.append(.custom(SectionTitleContextItem(text: strongSelf.presentationData.strings.Gallery_VideoSettings_SpeedSectionTitle), false)) for (text, _, rate) in strongSelf.speedList(strings: strongSelf.presentationData.strings) { let isSelected = abs(status.baseRate - rate) < 0.01 items.append(.action(ContextMenuActionItem(text: text, icon: { _ in return nil }, iconSource: ContextMenuActionItemIconSource(size: CGSize(width: 24.0, height: 24.0), signal: sliderValuePromise.get() @@ -3514,12 +3511,11 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { } if let videoQualityState = strongSelf.videoNode?.videoQualityState(), !videoQualityState.available.isEmpty { - items.append(.custom(SectionTitleContextItem(text: "VIDEO QUALITY"), false)) + items.append(.custom(SectionTitleContextItem(text: strongSelf.presentationData.strings.Gallery_VideoSettings_QualitySectionTitle), false)) - //TODO:localize do { let isSelected = videoQualityState.preferred == .auto - let qualityText: String = "Auto" + let qualityText: String = strongSelf.presentationData.strings.Gallery_VideoSettings_QualityAuto let textLayout: ContextMenuActionItemTextLayout if videoQualityState.current != 0 { textLayout = .secondLineWithValue("\(videoQualityState.current)p") @@ -3551,15 +3547,15 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { let isSelected = videoQualityState.preferred == .quality(quality) let qualityTitle: String if quality <= 360 { - qualityTitle = "Low" + qualityTitle = strongSelf.presentationData.strings.Gallery_VideoSettings_QualityLow } else if quality <= 480 { - qualityTitle = "Medium" + qualityTitle = strongSelf.presentationData.strings.Gallery_VideoSettings_QualityMedium } else if quality <= 720 { - qualityTitle = "High" + qualityTitle = strongSelf.presentationData.strings.Gallery_VideoSettings_QualityHD } else if quality <= 1080 { - qualityTitle = "Full HD" + qualityTitle = strongSelf.presentationData.strings.Gallery_VideoSettings_QualityFHD } else { - qualityTitle = "Ultra HD" + qualityTitle = strongSelf.presentationData.strings.Gallery_VideoSettings_QualityQHD } items.append(.action(ContextMenuActionItem(text: qualityTitle, textLayout: .secondLineWithValue("\(quality)p"), icon: { _ in if isSelected { @@ -3584,7 +3580,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { } } else { if let (message, maybeFile, _) = strongSelf.contentInfo(), let file = maybeFile, !message.isCopyProtected() && !item.peerIsCopyProtected && message.paidContent == nil { - items.append(.action(ContextMenuActionItem(text: "Save to Gallery", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) }, action: { c, _ in + items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Gallery_MenuSaveToGallery, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) }, action: { c, _ in guard let self else { c?.dismiss(result: .default, completion: nil) return @@ -3616,9 +3612,9 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { let fileSizeString = dataSizeString(qualityFileSize, formatting: DataSizeStringFormatting(presentationData: self.presentationData)) let title: String if let quality { - title = "Save in \(quality)p" + title = self.presentationData.strings.Gallery_SaveToGallery_Quality("\(quality)").string } else { - title = "Save Original" + title = self.presentationData.strings.Gallery_SaveToGallery_Original } items.append(.action(ContextMenuActionItem(text: title, textLayout: .secondLineWithValue(fileSizeString), icon: { _ in return nil diff --git a/submodules/TelegramCallsUI/Sources/ScheduleVideoChatSheetScreen.swift b/submodules/TelegramCallsUI/Sources/ScheduleVideoChatSheetScreen.swift index 08b7019d97..6ceaf18ebf 100644 --- a/submodules/TelegramCallsUI/Sources/ScheduleVideoChatSheetScreen.swift +++ b/submodules/TelegramCallsUI/Sources/ScheduleVideoChatSheetScreen.swift @@ -110,9 +110,8 @@ private final class ScheduleVideoChatSheetContentComponent: Component { var contentHeight: CGFloat = 0.0 contentHeight += 16.0 - //TODO:localize let titleString = NSMutableAttributedString() - titleString.append(NSAttributedString(string: "Schedule Video Chat", font: Font.semibold(17.0), textColor: environment.theme.list.itemPrimaryTextColor)) + titleString.append(NSAttributedString(string: environment.strings.VideoChat_ScheduleButtonTitle, font: Font.semibold(17.0), textColor: environment.theme.list.itemPrimaryTextColor)) let titleSize = self.title.update( transition: .immediate, @@ -272,7 +271,7 @@ private final class ScheduleVideoChatSheetContentComponent: Component { pressedColor: UIColor(rgb: 0x2B2B2F).withMultipliedAlpha(0.8) ), content: AnyComponentWithIdentity(id: AnyHashable(0 as Int), component: AnyComponent( - Text(text: "Cancel", font: Font.semibold(17.0), color: environment.theme.list.itemPrimaryTextColor) + Text(text: environment.strings.Common_Cancel, font: Font.semibold(17.0), color: environment.theme.list.itemPrimaryTextColor) )), isEnabled: true, tintWhenDisabled: false, diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift index 76e276e40e..b10cae7bec 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift @@ -4603,15 +4603,14 @@ extension ChatControllerImpl { c?.displayProcessingVideoTooltip(messageId: firstEvent.id) } - //TODO:localize c.present( UndoOverlayController( presentationData: self.presentationData, content: .universalImage( image: generateTintedImage(image: UIImage(bundleImageName: "Chat/ToastImprovingVideo"), color: .white)!, size: nil, - title: "Improving video...", - text: "The video will be published after it's optimized for the bese viewing experience.", + title: self.presentationData.strings.Chat_ToastImprovingVideo_Title, + text: self.presentationData.strings.Chat_ToastImprovingVideo_Text, customUndoText: nil, timeout: 5.0 ), diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerToasts.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerToasts.swift index 6e60a3c266..f2ddc3926b 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerToasts.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerToasts.swift @@ -61,7 +61,7 @@ extension ChatControllerImpl { context: self.context, file: .message(message: MessageReference(message._asMessage()), media: file), title: nil, - text: "Video Published", + text: self.presentationData.strings.Chat_ToastVideoPublished_Title, undoText: nil, customAction: nil ), @@ -74,15 +74,14 @@ extension ChatControllerImpl { self.dismiss() } } else { - //TODO:localize self.controllerInteraction?.presentControllerInCurrent(UndoOverlayController( presentationData: self.presentationData, content: .media( context: self.context, file: .message(message: MessageReference(message._asMessage()), media: file), title: nil, - text: "Video Published", - undoText: "View", + text: self.presentationData.strings.Chat_ToastVideoPublished_Title, + undoText: self.presentationData.strings.Chat_ToastVideoPublished_Action, customAction: { [weak self] in guard let self else { return diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 0c5e9c5a36..9c4a1ce845 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -10357,8 +10357,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let bounds = statusNode.view.convert(statusNode.view.bounds, to: self.chatDisplayNode.view) let location = CGPoint(x: bounds.midX, y: bounds.minY - 8.0) - //TODO:localize - let tooltipController = TooltipController(content: .text("Processing video may take a few minutes."), baseFontSize: self.presentationData.listsFontSize.baseDisplaySize, balancedTextLayout: true, isBlurred: true, timeout: 4.5, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true) + let tooltipController = TooltipController(content: .text(self.presentationData.strings.Chat_MessageTooltipVideoProcessing), baseFontSize: self.presentationData.listsFontSize.baseDisplaySize, balancedTextLayout: true, isBlurred: true, timeout: 4.5, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true) self.checksTooltipController = tooltipController tooltipController.dismissed = { [weak self, weak tooltipController] _ in if let strongSelf = self, let tooltipController = tooltipController, strongSelf.checksTooltipController === tooltipController { diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift index 566e3f5b24..bff0145832 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift @@ -297,7 +297,6 @@ func chatHistoryEntriesForView( } let insertPendingProcessingMessage: ([Message], Int) -> Void = { messages, index in - //TODO:localize let serviceMessage = Message( stableId: UInt32.max - messages[0].stableId, stableVersion: 0, @@ -316,7 +315,7 @@ func chatHistoryEntriesForView( author: nil, text: "", attributes: [], - media: [TelegramMediaAction(action: .customText(text: "This video will be published once converted and optimized", entities: [], additionalAttributes: nil))], + media: [TelegramMediaAction(action: .customText(text: presentationData.strings.Chat_VideoProcessingServiceMessage(Int32(messages.count)), entities: [], additionalAttributes: nil))], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index 343a4e02a8..0a60d44b7f 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -1145,13 +1145,12 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState c?.dismiss(completion: { let presentationData = context.sharedContext.currentPresentationData.with { $0 } - //TODO:localize controllerInteraction.presentController(standardTextAlertController( theme: AlertControllerTheme(presentationData: presentationData), - title: "Wait!", - text: "This video hasn't been converted and optimized yet. If you send it now, the viewers of the video may experience slow download speed.", + title: presentationData.strings.Chat_ScheduledForceSendProcessingVideo_Title, + text: presentationData.strings.Chat_ScheduledForceSendProcessingVideo_Text, actions: [ - TextAlertAction(type: .defaultAction, title: "Send Anyway", action: { + TextAlertAction(type: .defaultAction, title: presentationData.strings.Chat_ScheduledForceSendProcessingVideo_Action, action: { controllerInteraction.sendScheduledMessagesNow(selectAll ? messages.map { $0.id } : [message.id]) }), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}) @@ -2864,7 +2863,9 @@ private final class ChatReadReportContextItemNode: ASDisplayNode, ContextMenuCus }) } - item.context.account.viewTracker.updateReactionsForMessageIds(messageIds: [item.message.id], force: true) + if !self.item.isEdit { + item.context.account.viewTracker.updateReactionsForMessageIds(messageIds: [item.message.id], force: true) + } } deinit { @@ -3131,7 +3132,7 @@ private final class ChatReadReportContextItemNode: ASDisplayNode, ContextMenuCus let placeholderAvatarsContent: AnimatedAvatarSetContext.Content var avatarsPeers: [EnginePeer] = [] - if self.item.message.id.peerId.namespace == Namespaces.Peer.CloudUser { + if self.item.message.id.peerId.namespace == Namespaces.Peer.CloudUser || self.item.isEdit { } else if let recentPeers = self.item.message.reactionsAttribute?.recentPeers, !recentPeers.isEmpty { for recentPeer in recentPeers { if let peer = self.item.message.peers[recentPeer.peerId] { diff --git a/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift b/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift index 0f2203e3a4..4767b433e7 100644 --- a/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift +++ b/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift @@ -604,7 +604,6 @@ private final class NativeVideoContentNode: ASDisplayNode, UniversalVideoContent self._status.set(.never()) self.player.pause() - //TODO:release coordinate fetchAutomatically self.player = MediaPlayer(audioSessionManager: self.audioSessionManager, postbox: self.postbox, userLocation: self.userLocation, userContentType: userContentType, resourceReference: updatedFileReference.resourceReference(selectedFile.resource), tempFilePath: nil, streamable: self.streamVideo, video: true, preferSoftwareDecoding: false, playAutomatically: false, enableSound: self.enableSound, baseRate: self.baseRate, fetchAutomatically: true, soundMuted: self.soundMuted, ambient: beginWithAmbientSound, mixWithOthers: mixWithOthers, continuePlayingWithoutSoundOnLostAudioSession: self.continuePlayingWithoutSoundOnLostAudioSession, storeAfterDownload: nil, isAudioVideoMessage: self.isAudioVideoMessage) var actionAtEndImpl: (() -> Void)?