Various UI fixes

This commit is contained in:
Ilya Laktyushin 2019-08-27 05:23:06 +03:00
parent a1bd27dcf3
commit fd76dcbd46
20 changed files with 191 additions and 120 deletions

View File

@ -402,7 +402,7 @@ private class ChatListStatusFailedNode: ChatListStatusContentNode {
}
let diameter: CGFloat = 14.0
let rect = CGRect(origin: CGPoint(x: floor((bounds.width - diameter) / 2.0), y: floor((bounds.height - diameter) / 2.0)), size: CGSize(width: diameter, height: diameter)).offsetBy(dx: 1.0, dy: 1.0)
let rect = CGRect(origin: CGPoint(x: floor((bounds.width - diameter) / 2.0), y: floor((bounds.height - diameter) / 2.0)), size: CGSize(width: diameter, height: diameter)).offsetBy(dx: 1.0, dy: UIScreenPixel)
context.setFillColor(parameters.fill.cgColor)
context.fillEllipse(in: rect)
@ -412,7 +412,7 @@ private class ChatListStatusFailedNode: ChatListStatusContentNode {
let stringRect = string.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil)
UIGraphicsPushContext(context)
string.draw(at: CGPoint(x: rect.minX + floor((rect.width - stringRect.width) / 2.0), y: 1.0 + rect.minY + floor((rect.height - stringRect.height) / 2.0)))
string.draw(at: CGPoint(x: rect.minX + floor((rect.width - stringRect.width) / 2.0), y: 1.0 - UIScreenPixel + rect.minY + floor((rect.height - stringRect.height) / 2.0)))
UIGraphicsPopContext()
}

View File

@ -147,7 +147,7 @@
UIImpactFeedbackGenerator *generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium];
[generator impactOccurred];
TGMediaPickerSendActionSheetController *controller = [[TGMediaPickerSendActionSheetController alloc] initWithContext:strongSelf->_context sendButtonFrame:strongSelf.galleryModel.interfaceView.doneButtonFrame canSendSilently:hasSilentPosting];
TGMediaPickerSendActionSheetController *controller = [[TGMediaPickerSendActionSheetController alloc] initWithContext:strongSelf->_context sendButtonFrame:strongSelf.galleryModel.interfaceView.doneButtonFrame canSendSilently:hasSilentPosting canSchedule:hasSchedule];
controller.send = ^{
__strong TGMediaPickerModernGalleryMixin *strongSelf = weakSelf;
if (strongSelf == nil)

View File

@ -8,7 +8,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, copy) void (^sendSilently)(void);
@property (nonatomic, copy) void (^schedule)(void);
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context sendButtonFrame:(CGRect)sendButtonFrame canSendSilently:(bool)canSendSilently;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context sendButtonFrame:(CGRect)sendButtonFrame canSendSilently:(bool)canSendSilently canSchedule:(bool)canSchedule;
@end

View File

@ -75,6 +75,7 @@
CGRect _sendButtonFrame;
bool _canSendSilently;
bool _canSchedule;
bool _autorotationWasEnabled;
bool _dismissed;
@ -90,12 +91,13 @@
@implementation TGMediaPickerSendActionSheetController
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context sendButtonFrame:(CGRect)sendButtonFrame canSendSilently:(bool)canSendSilently {
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context sendButtonFrame:(CGRect)sendButtonFrame canSendSilently:(bool)canSendSilently canSchedule:(bool)canSchedule {
self = [super initWithContext:context];
if (self != nil) {
_context = context;
_sendButtonFrame = sendButtonFrame;
_canSendSilently = canSendSilently;
_canSchedule = canSchedule;
}
return self;
}
@ -125,12 +127,14 @@
[_containerView addSubview:_sendSilentlyButton];
}
_scheduleButton = [[TGMediaPickerSendActionSheetItemView alloc] initWithTitle:TGLocalized(@"Conversation.SendMessage.ScheduleMessage") icon:TGComponentsImageNamed(@"MediaSchedule")];
_scheduleButton.pressed = ^{
__strong TGMediaPickerSendActionSheetController *strongSelf = weakSelf;
[strongSelf schedulePressed];
};
[_containerView addSubview:_scheduleButton];
if (_canSchedule) {
_scheduleButton = [[TGMediaPickerSendActionSheetItemView alloc] initWithTitle:TGLocalized(@"Conversation.SendMessage.ScheduleMessage") icon:TGComponentsImageNamed(@"MediaSchedule")];
_scheduleButton.pressed = ^{
__strong TGMediaPickerSendActionSheetController *strongSelf = weakSelf;
[strongSelf schedulePressed];
};
[_containerView addSubview:_scheduleButton];
}
TGMediaAssetsPallete *pallete = nil;
if ([[LegacyComponentsGlobals provider] respondsToSelector:@selector(mediaAssetsPallete)])
@ -238,7 +242,7 @@
CGFloat itemHeight = 44.0;
CGFloat containerWidth = 240.0;
CGFloat containerHeight = _canSendSilently ? itemHeight * 2.0 : itemHeight;
CGFloat containerHeight = _canSendSilently && _canSchedule ? itemHeight * 2.0 : itemHeight;
containerWidth = MAX(containerWidth, MAX(_sendSilentlyButton.buttonLabel.frame.size.width, _scheduleButton.buttonLabel.frame.size.width) + 84.0);
if (!_dismissed) {
_containerView.frame = CGRectMake(CGRectGetMaxX(_sendButtonFrame) - containerWidth - 8.0, _sendButtonFrame.origin.y - containerHeight - 4.0, containerWidth, containerHeight);

View File

@ -20,7 +20,7 @@ public struct LegacyAttachmentMenuMediaEditing: OptionSet {
public static let imageOrVideo = LegacyAttachmentMenuMediaEditing(rawValue: 1 << 0)
}
public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, theme: PresentationTheme, strings: PresentationStrings, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentScheduleController: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void) -> TGMenuSheetController {
public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, hasSchedule: Bool, theme: PresentationTheme, strings: PresentationStrings, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void) -> TGMenuSheetController {
let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat
let controller = TGMenuSheetController(context: parentController.context, dark: false)!
@ -72,13 +72,13 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
}
if peer.id != context.account.peerId {
if peer is TelegramUser {
carouselItem.hasTimer = true
carouselItem.hasTimer = !hasSchedule
}
carouselItem.hasSilentPosting = !isSecretChat
}
carouselItem.hasSchedule = !isSecretChat
carouselItem.hasSchedule = hasSchedule
carouselItem.presentScheduleController = { done in
presentScheduleController { time in
presentSchedulePicker { time in
done?(time)
}
}

View File

@ -17,7 +17,7 @@ public func guessMimeTypeByFileExtension(_ ext: String) -> String {
return TGMimeTypeMap.mimeType(forExtension: ext) ?? "application/binary"
}
public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: String, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void, presentScheduleController: @escaping (@escaping (Int32) -> Void) -> Void) {
public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: String, hasSchedule: Bool, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void) {
let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat
controller.captionsEnabled = captionsEnabled
@ -25,13 +25,13 @@ public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, co
controller.suggestionContext = legacySuggestionContext(account: context.account, peerId: peer.id)
if peer.id != context.account.peerId {
if peer is TelegramUser {
controller.hasTimer = true
controller.hasTimer = !hasSchedule
}
controller.hasSilentPosting = !isSecretChat
}
controller.hasSchedule = !isSecretChat
controller.hasSchedule = hasSchedule
controller.presentScheduleController = { done in
presentScheduleController { time in
presentSchedulePicker { time in
done?(time)
}
}

View File

@ -35,6 +35,7 @@ private final class ProxySettingsControllerArguments {
private enum ProxySettingsControllerSection: Int32 {
case enabled
case servers
case share
case calls
}
@ -68,8 +69,10 @@ private enum ProxySettingsControllerEntry: ItemListNodeEntry {
switch self {
case .enabled:
return ProxySettingsControllerSection.enabled.rawValue
case .serversHeader, .addServer, .server, .shareProxyList:
case .serversHeader, .addServer, .server:
return ProxySettingsControllerSection.servers.rawValue
case .shareProxyList:
return ProxySettingsControllerSection.share.rawValue
case .useForCalls, .useForCallsInfo:
return ProxySettingsControllerSection.calls.rawValue
}

View File

@ -1230,10 +1230,11 @@ public func settingsController(context: AccountContext, accountManager: AccountM
} else {
return Signal { subscriber in
let size = CGSize(width: 31.0, height: 31.0)
let inset: CGFloat = 3.0
let image = generateImage(size, rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.translateBy(x: 3.0, y: 3.0)
drawPeerAvatarLetters(context: context, size: size, font: avatarFont, letters: primary.1.displayLetters, accountPeerId: primary.1.id, peerId: primary.1.id)
context.translateBy(x: inset, y: inset)
drawPeerAvatarLetters(context: context, size: CGSize(width: size.width - inset * 2.0, height: size.height - inset * 2.0), font: avatarFont, letters: primary.1.displayLetters, accountPeerId: primary.1.id, peerId: primary.1.id)
})?.withRenderingMode(.alwaysOriginal)
subscriber.putNext(image)
subscriber.putCompletion()

View File

@ -919,9 +919,9 @@ public final class AccountViewTracker {
}
}
public func scheduledMessagesViewForLocation(_ chatLocation: ChatLocation) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
public func scheduledMessagesViewForLocation(_ chatLocation: ChatLocation, additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
if let account = self.account {
let signal = account.postbox.aroundMessageHistoryViewForLocation(chatLocation, anchor: .upperBound, count: 200, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: nil, namespaces: .just(Namespaces.Message.allScheduled), orderStatistics: [], additionalData: [])
let signal = account.postbox.aroundMessageHistoryViewForLocation(chatLocation, anchor: .upperBound, count: 200, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: nil, namespaces: .just(Namespaces.Message.allScheduled), orderStatistics: [], additionalData: additionalData)
return withState(signal, { [weak self] () -> Int32 in
if let strongSelf = self {
return OSAtomicIncrement32(&strongSelf.nextViewId)

View File

@ -632,7 +632,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return false
}
if let _ = strongSelf.presentationInterfaceState.slowmodeState {
if let _ = strongSelf.presentationInterfaceState.slowmodeState, !strongSelf.presentationInterfaceState.isScheduledMessages {
strongSelf.interfaceInteraction?.displaySlowmodeTooltip(sourceNode, sourceRect)
return false
}
@ -663,7 +663,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return true
}, sendGif: { [weak self] fileReference, sourceNode, sourceRect in
if let strongSelf = self {
if let _ = strongSelf.presentationInterfaceState.slowmodeState {
if let _ = strongSelf.presentationInterfaceState.slowmodeState, !strongSelf.presentationInterfaceState.isScheduledMessages {
strongSelf.interfaceInteraction?.displaySlowmodeTooltip(sourceNode, sourceRect)
return false
}
@ -1342,45 +1342,83 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
guard let strongSelf = self else {
return
}
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Message] in
return transaction.getMessageFailedGroup(id) ?? []
} |> deliverOnMainQueue).start(next: { messages in
guard let strongSelf = self, !messages.isEmpty else {
return
}
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
var items: [ActionSheetItem] = []
items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_MessageDialogRetry, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
guard let strongSelf = self else {
if id.namespace == Namespaces.Message.ScheduledCloud {
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Message] in
return transaction.getMessageGroup(id) ?? []
} |> deliverOnMainQueue).start(next: { messages in
guard let strongSelf = self, let message = messages.filter({ $0.id == id }).first else {
return
}
let _ = resendMessages(account: strongSelf.context.account, messageIds: [id]).start()
}))
if messages.count != 1 {
items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_MessageDialogRetryAll(messages.count).0, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
guard let strongSelf = self else {
return
var actions: [ContextMenuItem] = []
actions.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.ScheduledMessages_SendNow, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.actionSheet.primaryTextColor)
}, action: { [weak self] _, f in
if let strongSelf = self {
strongSelf.controllerInteraction?.sendScheduledMessagesNow(messages.map { $0.id })
}
let _ = resendMessages(account: strongSelf.context.account, messageIds: messages.map({ $0.id })).start()
}))
}
items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_MessageDialogDelete, color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
guard let strongSelf = self else {
f(.dismissWithoutContent)
})))
actions.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.ScheduledMessages_EditTime, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Schedule"), color: theme.actionSheet.primaryTextColor)
}, action: { [weak self] _, f in
if let strongSelf = self {
strongSelf.controllerInteraction?.editScheduledMessagesTime(messages.map { $0.id })
}
f(.dismissWithoutContent)
})))
actions.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_ContextMenuDelete, textColor: .destructive, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor)
}, action: { [weak self] controller, f in
if let strongSelf = self {
strongSelf.interfaceInteraction?.deleteMessages(messages, controller, f)
}
})))
let controller = ContextController(account: strongSelf.context.account, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, source: ChatMessageContextControllerContentSource(chatNode: strongSelf.chatDisplayNode, message: message), items: actions, reactionItems: [], recognizer: nil)
strongSelf.currentContextController = controller
strongSelf.window?.presentInGlobalOverlay(controller)
})
} else {
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Message] in
return transaction.getMessageFailedGroup(id) ?? []
} |> deliverOnMainQueue).start(next: { messages in
guard let strongSelf = self, let message = messages.filter({ $0.id == id }).first else {
return
}
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: [id], type: .forLocalPeer).start()
}))
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])])
strongSelf.chatDisplayNode.dismissInput()
strongSelf.present(actionSheet, in: .window(.root))
})
var actions: [ContextMenuItem] = []
actions.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_MessageDialogRetry, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.actionSheet.primaryTextColor)
}, action: { [weak self] _, f in
if let strongSelf = self {
let _ = resendMessages(account: strongSelf.context.account, messageIds: [id]).start()
}
f(.dismissWithoutContent)
})))
if messages.count != 1 {
actions.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_MessageDialogRetryAll(messages.count).0, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.actionSheet.primaryTextColor)
}, action: { [weak self] _, f in
if let strongSelf = self {
let _ = resendMessages(account: strongSelf.context.account, messageIds: messages.map({ $0.id })).start()
}
f(.dismissWithoutContent)
})))
}
actions.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_ContextMenuDelete, textColor: .destructive, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor)
}, action: { [weak self] controller, f in
if let strongSelf = self {
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: [id], type: .forLocalPeer).start()
}
})))
let controller = ContextController(account: strongSelf.context.account, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, source: ChatMessageContextControllerContentSource(chatNode: strongSelf.chatDisplayNode, message: message), items: actions, reactionItems: [], recognizer: nil)
strongSelf.currentContextController = controller
strongSelf.window?.presentInGlobalOverlay(controller)
})
}
}, addContact: { [weak self] phoneNumber in
if let strongSelf = self {
strongSelf.context.sharedContext.openAddContact(context: strongSelf.context, firstName: "", lastName: "", phoneNumber: phoneNumber, label: defaultContactLabel, present: { [weak self] controller, arguments in
@ -1488,14 +1526,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
}, scheduleCurrentMessage: { [weak self] in
if let strongSelf = self {
if let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer {
let mode: ChatScheduleTimeControllerMode
if case let .peer(peerId) = strongSelf.presentationInterfaceState.chatLocation, peerId == strongSelf.context.account.peerId {
if peer.id == strongSelf.context.account.peerId {
mode = .reminders
} else {
mode = .scheduledMessages
}
let controller = ChatScheduleTimeController(context: strongSelf.context, mode: mode, completion: { [weak self] scheduleTime in
let controller = ChatScheduleTimeController(context: strongSelf.context, mode: mode, minimalTime: strongSelf.presentationInterfaceState.slowmodeState?.timeout, completion: { [weak self] scheduleTime in
if let strongSelf = self {
strongSelf.chatDisplayNode.sendCurrentMessage(scheduleTime: scheduleTime)
if !strongSelf.presentationInterfaceState.isScheduledMessages {
@ -1509,12 +1548,19 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}, sendScheduledMessagesNow: { [weak self] messageIds in
if let strongSelf = self {
let _ = sendScheduledMessageNowInteractively(postbox: strongSelf.context.account.postbox, messageId: messageIds.first!).start()
if let _ = strongSelf.presentationInterfaceState.slowmodeState {
if let rect = strongSelf.chatDisplayNode.frameForInputActionButton() {
strongSelf.interfaceInteraction?.displaySlowmodeTooltip(strongSelf.chatDisplayNode, rect)
}
return
} else {
let _ = sendScheduledMessageNowInteractively(postbox: strongSelf.context.account.postbox, messageId: messageIds.first!).start()
}
}
}, editScheduledMessagesTime: { [weak self] messageIds in
if let strongSelf = self, let messageId = messageIds.first {
if let strongSelf = self, let messageId = messageIds.first, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer {
let mode: ChatScheduleTimeControllerMode
if case let .peer(peerId) = strongSelf.presentationInterfaceState.chatLocation, peerId == strongSelf.context.account.peerId {
if peer.id == strongSelf.context.account.peerId {
mode = .reminders
} else {
mode = .scheduledMessages
@ -1526,7 +1572,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
guard let strongSelf = self, let message = message else {
return
}
let controller = ChatScheduleTimeController(context: strongSelf.context, mode: mode, currentTime: message.timestamp, completion: { [weak self] scheduleTime in
let controller = ChatScheduleTimeController(context: strongSelf.context, mode: mode, currentTime: message.timestamp, minimalTime: strongSelf.presentationInterfaceState.slowmodeState?.timeout, completion: { [weak self] scheduleTime in
if let strongSelf = self {
var entities: TextEntitiesMessageAttribute?
for attribute in message.attributes {
@ -2253,7 +2299,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var slowmodeState: ChatSlowmodeState?
if let cachedData = combinedInitialData.cachedData as? CachedChannelData {
pinnedMessageId = cachedData.pinnedMessageId
if let channel = combinedInitialData.initialData?.peer as? TelegramChannel, channel.isRestrictedBySlowmode, let timeout = cachedData.slowModeTimeout, !strongSelf.presentationInterfaceState.isScheduledMessages {
if let channel = combinedInitialData.initialData?.peer as? TelegramChannel, channel.isRestrictedBySlowmode, let timeout = cachedData.slowModeTimeout {
if let slowmodeUntilTimestamp = calculateSlowmodeActiveUntilTimestamp(account: strongSelf.context.account, untilTimestamp: cachedData.slowModeValidUntilTimestamp) {
slowmodeState = ChatSlowmodeState(timeout: timeout, variant: .timestamp(slowmodeUntilTimestamp))
}
@ -2659,7 +2705,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
guard let strongSelf = self else {
return
}
if strongSelf.presentationInterfaceState.interfaceState.editMessage == nil, let _ = strongSelf.presentationInterfaceState.slowmodeState {
if strongSelf.presentationInterfaceState.interfaceState.editMessage == nil, let _ = strongSelf.presentationInterfaceState.slowmodeState, !strongSelf.presentationInterfaceState.isScheduledMessages {
if let rect = strongSelf.chatDisplayNode.frameForAttachmentButton() {
strongSelf.interfaceInteraction?.displaySlowmodeTooltip(strongSelf.chatDisplayNode, rect)
}
@ -3168,7 +3214,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
guard let strongSelf = self else {
return false
}
if let _ = strongSelf.presentationInterfaceState.slowmodeState {
if let _ = strongSelf.presentationInterfaceState.slowmodeState, !strongSelf.presentationInterfaceState.isScheduledMessages {
strongSelf.interfaceInteraction?.displaySlowmodeTooltip(node, rect)
return false
}
@ -4921,7 +4967,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
return result
}
let controller = legacyAttachmentMenu(context: strongSelf.context, peer: peer, editMediaOptions: menuEditMediaOptions, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, parentController: legacyController, recentlyUsedInlineBots: strongSelf.recentlyUsedInlineBotsValue, initialCaption: inputText.string, openGallery: {
let controller = legacyAttachmentMenu(context: strongSelf.context, peer: peer, editMediaOptions: menuEditMediaOptions, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, hasSchedule: !strongSelf.presentationInterfaceState.isScheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, parentController: legacyController, recentlyUsedInlineBots: strongSelf.recentlyUsedInlineBotsValue, initialCaption: inputText.string, openGallery: {
self?.presentMediaPicker(fileMode: false, editingMedia: editMediaOptions != nil, completion: { signals, silentPosting, scheduleTime in
if !inputText.string.isEmpty {
//strongSelf.clearInputText()
@ -4934,7 +4981,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
}, openCamera: { [weak self] cameraView, menuController in
if let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer {
presentedLegacyCamera(context: strongSelf.context, peer: peer, cameraView: cameraView, menuController: menuController, parentController: strongSelf, editingMedia: editMediaOptions != nil, saveCapturedPhotos: settings.storeEditedPhotos, mediaGrouping: true, initialCaption: inputText.string, sendMessagesWithSignals: { [weak self] signals in
presentedLegacyCamera(context: strongSelf.context, peer: peer, cameraView: cameraView, menuController: menuController, parentController: strongSelf, editingMedia: editMediaOptions != nil, saveCapturedPhotos: settings.storeEditedPhotos, mediaGrouping: true, initialCaption: inputText.string, hasSchedule: !strongSelf.presentationInterfaceState.isScheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat, sendMessagesWithSignals: { [weak self] signals in
if let strongSelf = self {
if editMediaOptions != nil {
strongSelf.editMessageMediaWithLegacySignals(signals!)
@ -4949,17 +4996,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let strongSelf = self, let (host, port, username, password, secret) = parseProxyUrl(code) {
strongSelf.openResolved(ResolvedUrl.proxy(host: host, port: port, username: username, password: password, secret: secret))
}
}, presentScheduleController: { [weak self] done in
}, presentSchedulePicker: { [weak self] done in
guard let strongSelf = self else {
return
}
let mode: ChatScheduleTimeControllerMode
if case let .peer(peerId) = strongSelf.presentationInterfaceState.chatLocation, peerId == strongSelf.context.account.peerId {
if peer.id == strongSelf.context.account.peerId {
mode = .reminders
} else {
mode = .scheduledMessages
}
let controller = ChatScheduleTimeController(context: strongSelf.context, mode: mode, completion: { [weak self] time in
let controller = ChatScheduleTimeController(context: strongSelf.context, mode: mode, minimalTime: strongSelf.presentationInterfaceState.slowmodeState?.timeout, completion: { [weak self] time in
if let strongSelf = self {
done(time)
if !strongSelf.presentationInterfaceState.isScheduledMessages {
@ -4991,17 +5038,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: nil, text: strongSelf.presentationData.strings.Chat_AttachmentMultipleFilesDisabled, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}, presentScheduleController: { [weak self] done in
guard let strongSelf = self else {
}, presentSchedulePicker: { [weak self] done in
guard let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else {
return
}
let mode: ChatScheduleTimeControllerMode
if case let .peer(peerId) = strongSelf.presentationInterfaceState.chatLocation, peerId == strongSelf.context.account.peerId {
if peer.id == strongSelf.context.account.peerId {
mode = .reminders
} else {
mode = .scheduledMessages
}
let controller = ChatScheduleTimeController(context: strongSelf.context, mode: mode, completion: { [weak self] time in
let controller = ChatScheduleTimeController(context: strongSelf.context, mode: mode, minimalTime: strongSelf.presentationInterfaceState.slowmodeState?.timeout, completion: { [weak self] time in
if let strongSelf = self {
done(time)
if !strongSelf.presentationInterfaceState.isScheduledMessages {
@ -5153,7 +5200,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
legacyController.bind(controller: controller)
legacyController.deferScreenEdgeGestures = [.top]
configureLegacyAssetPicker(controller, context: strongSelf.context, peer: peer, initialCaption: inputText.string, presentWebSearch: { [weak self, weak legacyController] in
configureLegacyAssetPicker(controller, context: strongSelf.context, peer: peer, initialCaption: inputText.string, hasSchedule: !strongSelf.presentationInterfaceState.isScheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat, presentWebSearch: { [weak self, weak legacyController] in
if let strongSelf = self {
let controller = WebSearchController(context: strongSelf.context, peer: peer, configuration: searchBotsConfiguration, mode: .media(completion: { results, selectionState, editingState, silentPosting in
if let legacyController = legacyController {
@ -5176,17 +5223,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: nil, text: strongSelf.presentationData.strings.Chat_AttachmentLimitReached, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}, presentScheduleController: { [weak self] done in
guard let strongSelf = self else {
}, presentSchedulePicker: { [weak self] done in
guard let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else {
return
}
let mode: ChatScheduleTimeControllerMode
if case let .peer(peerId) = strongSelf.presentationInterfaceState.chatLocation, peerId == strongSelf.context.account.peerId {
if peer.id == strongSelf.context.account.peerId {
mode = .reminders
} else {
mode = .scheduledMessages
}
let controller = ChatScheduleTimeController(context: strongSelf.context, mode: mode, completion: { [weak self] time in
let controller = ChatScheduleTimeController(context: strongSelf.context, mode: mode, minimalTime: strongSelf.presentationInterfaceState.slowmodeState?.timeout, completion: { [weak self] time in
if let strongSelf = self {
done(time)
if !strongSelf.presentationInterfaceState.isScheduledMessages {
@ -5245,9 +5292,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
})
}
private func presentMapPicker(editingMessage: Bool) {
guard let peer = self.presentationInterfaceState.renderedPeer?.peer else {
return
@ -5468,7 +5513,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} else {
mode = .scheduledMessages
}
let controller = ChatScheduleTimeController(context: self.context, mode: mode, dismissByTapOutside: false, completion: { [weak self] time in
let controller = ChatScheduleTimeController(context: self.context, mode: mode, minimalTime: self.presentationInterfaceState.slowmodeState?.timeout, dismissByTapOutside: false, completion: { [weak self] time in
if let strongSelf = self {
strongSelf.sendMessages(strongSelf.transformEnqueueMessages(messages, silentPosting: false, scheduleTime: time), commit: true)
}
@ -5640,7 +5685,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.recorderFeedback?.prepareImpact(.light)
}
self.videoRecorder.set(.single(legacyInstantVideoController(theme: self.presentationData.theme, panelFrame: currentInputPanelFrame, context: self.context, peerId: peerId, slowmodeState: self.presentationInterfaceState.slowmodeState, send: { [weak self] message in
self.videoRecorder.set(.single(legacyInstantVideoController(theme: self.presentationData.theme, panelFrame: currentInputPanelFrame, context: self.context, peerId: peerId, slowmodeState: !self.presentationInterfaceState.isScheduledMessages ? self.presentationInterfaceState.slowmodeState : nil, send: { [weak self] message in
if let strongSelf = self {
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({
@ -5662,7 +5707,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
private func dismissMediaRecorder(_ action: ChatFinishMediaRecordingAction) {
var updatedAction = action
if let _ = self.presentationInterfaceState.slowmodeState {
if let _ = self.presentationInterfaceState.slowmodeState, !self.presentationInterfaceState.isScheduledMessages {
updatedAction = .preview
}
@ -5786,7 +5831,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
private func sendMediaRecording() {
if let recordedMediaPreview = self.presentationInterfaceState.recordedMediaPreview {
if let _ = self.presentationInterfaceState.slowmodeState {
if let _ = self.presentationInterfaceState.slowmodeState, !self.presentationInterfaceState.isScheduledMessages {
if let rect = self.chatDisplayNode.frameForInputActionButton() {
self.interfaceInteraction?.displaySlowmodeTooltip(self.chatDisplayNode, rect)
}
@ -7157,7 +7202,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if options.contains(.deleteLocally) {
var localOptionText = self.presentationData.strings.Conversation_DeleteMessagesForMe
if self.presentationInterfaceState.isScheduledMessages {
localOptionText = self.presentationData.strings.ScheduledMessages_Delete
localOptionText = messageIds.count > 1 ? self.presentationData.strings.ScheduledMessages_DeleteMany : self.presentationData.strings.ScheduledMessages_Delete
} else {
if options.contains(.unsendPersonal) {
localOptionText = self.presentationData.strings.Chat_DeleteMessagesConfirmation(Int32(messageIds.count))

View File

@ -2041,7 +2041,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
if let _ = effectivePresentationInterfaceState.interfaceState.editMessage {
self.interfaceInteraction?.editMessage()
} else {
if let _ = effectivePresentationInterfaceState.slowmodeState {
if let _ = effectivePresentationInterfaceState.slowmodeState, !effectivePresentationInterfaceState.isScheduledMessages && scheduleTime == nil {
if let rect = self.frameForInputActionButton() {
self.interfaceInteraction?.displaySlowmodeTooltip(self, rect)
}

View File

@ -490,6 +490,11 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
let fixedCombinedReadStates = Atomic<MessageHistoryViewReadState?>(value: nil)
var scheduled = false
if let subject = subject, case .scheduledMessages = subject {
scheduled = true
}
var additionalData: [AdditionalMessageHistoryViewData] = []
if case let .peer(peerId) = chatLocation {
additionalData.append(.cachedPeerData(peerId))
@ -503,13 +508,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
additionalData.append(.peerIsContact(peerId))
}
}
additionalData.append(.totalUnreadState)
var scheduled = false
if let subject = subject, case .scheduledMessages = subject {
scheduled = true
if !scheduled {
additionalData.append(.totalUnreadState)
}
let currentViewVersion = Atomic<Int?>(value: nil)
let historyViewUpdate = self.chatHistoryLocationPromise.get()

View File

@ -33,7 +33,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, account: A
let directionHint: ListViewScrollToItemDirectionHint = sourceIndex > index ? .Down : .Up
chatScrollPosition = .index(index: index, position: position, directionHint: directionHint, animated: animated)
}
return account.viewTracker.scheduledMessagesViewForLocation(chatLocation)
return account.viewTracker.scheduledMessagesViewForLocation(chatLocation, additionalData: additionalData)
|> map { view, updateType, initialData -> ChatHistoryViewUpdate in
let (cachedData, cachedDataMessages, readStateData) = extractAdditionalData(view: view, chatLocation: chatLocation)

View File

@ -149,7 +149,7 @@ final class ChatRecordingPreviewInputPanelNode: ChatInputPanelNode {
transition.updateFrame(node: self.deleteButton, frame: CGRect(origin: CGPoint(x: leftInset, y: -1.0), size: CGSize(width: 48.0, height: panelHeight)))
transition.updateFrame(node: self.sendButton, frame: CGRect(origin: CGPoint(x: width - rightInset - 43.0 - UIScreenPixel, y: -UIScreenPixel), size: CGSize(width: 44.0, height: panelHeight)))
if let slowmodeState = interfaceState.slowmodeState {
if let slowmodeState = interfaceState.slowmodeState, !interfaceState.isScheduledMessages {
let sendButtonRadialStatusNode: ChatSendButtonRadialStatusNode
if let current = self.sendButtonRadialStatusNode {
sendButtonRadialStatusNode = current

View File

@ -22,15 +22,17 @@ final class ChatScheduleTimeController: ViewController {
private let context: AccountContext
private let mode: ChatScheduleTimeControllerMode
private let currentTime: Int32?
private let minimalTime: Int32?
private let dismissByTapOutside: Bool
private let completion: (Int32) -> Void
private var presentationDataDisposable: Disposable?
init(context: AccountContext, mode: ChatScheduleTimeControllerMode, currentTime: Int32? = nil, dismissByTapOutside: Bool = true, completion: @escaping (Int32) -> Void) {
init(context: AccountContext, mode: ChatScheduleTimeControllerMode, currentTime: Int32? = nil, minimalTime: Int32? = nil, dismissByTapOutside: Bool = true, completion: @escaping (Int32) -> Void) {
self.context = context
self.mode = mode
self.currentTime = currentTime
self.minimalTime = minimalTime
self.dismissByTapOutside = dismissByTapOutside
self.completion = completion
@ -55,7 +57,7 @@ final class ChatScheduleTimeController: ViewController {
}
override public func loadDisplayNode() {
self.displayNode = ChatScheduleTimeControllerNode(context: self.context, mode: self.mode, currentTime: self.currentTime, dismissByTapOutside: self.dismissByTapOutside)
self.displayNode = ChatScheduleTimeControllerNode(context: self.context, mode: self.mode, currentTime: self.currentTime, minimalTime: self.minimalTime, dismissByTapOutside: self.dismissByTapOutside)
self.controllerNode.completion = { [weak self] time in
self?.completion(time + 5)
self?.dismiss()

View File

@ -15,6 +15,7 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel
private let mode: ChatScheduleTimeControllerMode
private var presentationData: PresentationData
private let dismissByTapOutside: Bool
private let minimalTime: Int32?
private let dimNode: ASDisplayNode
private let wrappingScrollNode: ASScrollNode
@ -33,11 +34,12 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel
var dismiss: (() -> Void)?
var cancel: (() -> Void)?
init(context: AccountContext, mode: ChatScheduleTimeControllerMode, currentTime: Int32?, dismissByTapOutside: Bool) {
init(context: AccountContext, mode: ChatScheduleTimeControllerMode, currentTime: Int32?, minimalTime: Int32?, dismissByTapOutside: Bool) {
self.context = context
self.mode = mode
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.dismissByTapOutside = dismissByTapOutside
self.minimalTime = minimalTime
self.wrappingScrollNode = ASScrollNode()
self.wrappingScrollNode.view.alwaysBounceVertical = true
@ -131,6 +133,17 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel
self.titleNode.attributedText = NSAttributedString(string: self.titleNode.attributedText?.string ?? "", font: Font.bold(17.0), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
self.pickerView.setValue(self.presentationData.theme.actionSheet.primaryTextColor, forKey: "textColor")
func updatePickerViewSubviews(_ subviews: [UIView]) {
for view in subviews {
if let label = view as? UILabel {
label.textColor = self.presentationData.theme.actionSheet.primaryTextColor
} else {
updatePickerViewSubviews(view.subviews)
}
}
}
updatePickerViewSubviews(self.pickerView.subviews)
self.cancelButton.setTitle(self.presentationData.strings.Common_Cancel, with: Font.regular(17.0), with: self.presentationData.theme.actionSheet.controlAccentColor, for: .normal)
self.doneButton.updateTheme(self.presentationData.theme)
}
@ -152,8 +165,9 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel
}
if let next1MinDate = next1MinDate, let next5MinDate = next5MinDate {
self.pickerView.minimumDate = next1MinDate
if let currentTime = currentTime, Double(currentTime) > currentDate.timeIntervalSince1970 {
let minimalTime = self.minimalTime.flatMap(Double.init) ?? 0.0
self.pickerView.minimumDate = max(next1MinDate, Date(timeIntervalSince1970: minimalTime))
if let currentTime = currentTime, Double(currentTime) > max(currentDate.timeIntervalSince1970, minimalTime) {
self.pickerView.date = Date(timeIntervalSince1970: Double(currentTime))
} else {
self.pickerView.date = next5MinDate

View File

@ -114,10 +114,10 @@ final class ChatSearchInputPanelNode: ChatInputPanelNode {
panelHeight = 45.0
}
transition.updateFrame(node: self.downButton, frame: CGRect(origin: CGPoint(x: leftInset + 12.0, y: 0.0), size: CGSize(width: 40.0, height: panelHeight)))
transition.updateFrame(node: self.upButton, frame: CGRect(origin: CGPoint(x: leftInset + 12.0 + 43.0, y: 0.0), size: CGSize(width: 40.0, height: panelHeight)))
transition.updateFrame(node: self.calendarButton, frame: CGRect(origin: CGPoint(x: width - rightInset - 60.0, y: 0.0), size: CGSize(width: 60.0, height: panelHeight)))
transition.updateFrame(node: self.membersButton, frame: CGRect(origin: CGPoint(x: width - rightInset - 60.0 * 2.0, y: 0.0), size: CGSize(width: 60.0, height: panelHeight)))
transition.updateFrame(node: self.downButton, frame: CGRect(origin: CGPoint(x: width - rightInset - 48.0, y: 0.0), size: CGSize(width: 40.0, height: panelHeight)))
transition.updateFrame(node: self.upButton, frame: CGRect(origin: CGPoint(x: width - rightInset - 48.0 - 43.0, y: 0.0), size: CGSize(width: 40.0, height: panelHeight)))
transition.updateFrame(node: self.calendarButton, frame: CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: 60.0, height: panelHeight)))
transition.updateFrame(node: self.membersButton, frame: CGRect(origin: CGPoint(x: leftInset + 43.0, y: 0.0), size: CGSize(width: 60.0, height: panelHeight)))
var resultIndex: Int?
var resultCount: Int?

View File

@ -89,7 +89,7 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode {
transition.updateFrame(layer: self.sendButton.layer, frame: CGRect(origin: CGPoint(), size: size))
if let slowmodeState = interfaceState.slowmodeState, interfaceState.editMessageState == nil {
if let slowmodeState = interfaceState.slowmodeState, !interfaceState.isScheduledMessages && interfaceState.editMessageState == nil {
let sendButtonRadialStatusNode: ChatSendButtonRadialStatusNode
if let current = self.sendButtonRadialStatusNode {
sendButtonRadialStatusNode = current

View File

@ -654,7 +654,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
}
}
var isSlowmodeActive = false
if interfaceState.slowmodeState != nil {
if interfaceState.slowmodeState != nil && !interfaceState.isScheduledMessages {
isSlowmodeActive = true
if !isEditingMedia {
isMediaEnabled = false
@ -1098,7 +1098,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
}
}
if interfaceState.slowmodeState == nil, let contextPlaceholder = interfaceState.inputTextPanelState.contextPlaceholder {
if interfaceState.slowmodeState == nil || interfaceState.isScheduledMessages, let contextPlaceholder = interfaceState.inputTextPanelState.contextPlaceholder {
let placeholderLayout = TextNode.asyncLayout(self.contextPlaceholderNode)
let (placeholderSize, placeholderApply) = placeholderLayout(TextNodeLayoutArguments(attributedString: contextPlaceholder, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: width - leftInset - rightInset - textFieldInsets.left - textFieldInsets.right - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right - accessoryButtonsWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let contextPlaceholderNode = placeholderApply()
@ -1123,7 +1123,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
self.textPlaceholderNode.alpha = 1.0
}
if let slowmodeState = interfaceState.slowmodeState {
if let slowmodeState = interfaceState.slowmodeState, !interfaceState.isScheduledMessages {
let slowmodePlaceholderNode: ChatTextInputSlowmodePlaceholderNode
if let current = self.slowmodePlaceholderNode {
slowmodePlaceholderNode = current
@ -1146,7 +1146,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
inputHasText = true
}
if (interfaceState.slowmodeState != nil && interfaceState.editMessageState == nil) || interfaceState.inputTextPanelState.contextPlaceholder != nil {
if (interfaceState.slowmodeState != nil && !interfaceState.isScheduledMessages && interfaceState.editMessageState == nil) || interfaceState.inputTextPanelState.contextPlaceholder != nil {
self.textPlaceholderNode.isHidden = true
self.slowmodePlaceholderNode?.isHidden = inputHasText
} else {
@ -1237,7 +1237,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
}
if let interfaceState = self.presentationInterfaceState {
if (interfaceState.slowmodeState != nil && interfaceState.editMessageState == nil) || interfaceState.inputTextPanelState.contextPlaceholder != nil {
if (interfaceState.slowmodeState != nil && !interfaceState.isScheduledMessages && interfaceState.editMessageState == nil) || interfaceState.inputTextPanelState.contextPlaceholder != nil {
self.textPlaceholderNode.isHidden = true
self.slowmodePlaceholderNode?.isHidden = inputHasText
} else {

View File

@ -10,7 +10,7 @@ import ShareController
import LegacyUI
import LegacyMediaPickerUI
func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAttachmentCameraView?, menuController: TGMenuSheetController?, parentController: ViewController, editingMedia: Bool, saveCapturedPhotos: Bool, mediaGrouping: Bool, initialCaption: String, sendMessagesWithSignals: @escaping ([Any]?) -> Void, recognizedQRCode: @escaping (String) -> Void = { _ in }, presentScheduleController: @escaping (@escaping (Int32) -> Void) -> Void) {
func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAttachmentCameraView?, menuController: TGMenuSheetController?, parentController: ViewController, editingMedia: Bool, saveCapturedPhotos: Bool, mediaGrouping: Bool, initialCaption: String, hasSchedule: Bool, sendMessagesWithSignals: @escaping ([Any]?) -> Void, recognizedQRCode: @escaping (String) -> Void = { _ in }, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void) {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme)
legacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .portrait, compactSize: .portrait)
@ -61,11 +61,11 @@ func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAt
controller.recipientName = peer.displayTitle
if peer.id != context.account.peerId {
if peer is TelegramUser {
controller.hasTimer = true
controller.hasTimer = !hasSchedule
}
controller.hasSilentPosting = !isSecretChat
}
controller.hasSchedule = !isSecretChat
controller.hasSchedule = hasSchedule
let screenSize = parentController.view.bounds.size
var startFrame = CGRect(x: 0, y: screenSize.height, width: screenSize.width, height: screenSize.height)