Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2022-11-28 00:05:17 +04:00
commit 8766fe93dd
10 changed files with 237 additions and 78 deletions

View File

@ -8338,4 +8338,70 @@ Sorry for the inconvenience.";
"Login.NewNumber" = "New Number";
"ChatList.GeneralHidden" = "General hidden";
"ChatList.GeneralHiddenInfo" = "Pull down to see the general topic.";
"ChatList.GeneralUnhidden" = "General unhidden";
"ChatList.GeneralUnhiddenInfo" = "Swipe left on the general topic to hide it.";
"Autoremove.OptionOff" = "Off";
"Autoremove.SetCustomTime" = "Set Custom Time...";
"CreateGroup.AutoDeleteTitle" = "Auto-Delete Messages";
"CreateGroup.AutoDeleteText" = "Automatically delete messages sent in this group for everyone after a period of time.";
"Settings.AutoDeleteTitle" = "Auto-Delete Messages";
"Settings.AutoDeleteInfo" = "Automatically delete messages for everyone after a period of time in all new chats you start.";
"Time.AfterSeconds_1" = "%@ second";
"Time.AfterSeconds_any" = "%@ seconds";
"Time.AfterMinutes_1" = "%@ minute";
"Time.AfterMinutes_any" = "%@ minutes";
"Time.AfterHours_1" = "%@ hour";
"Time.AfterHours_any" = "%@ hours";
"Time.AfterDays_1" = "%@ day";
"Time.AfterDays_any" = "%@ days";
"Time.AfterWeeks_1" = "%@ week";
"Time.AfterWeeks_any" = "%@ weeks";
"Time.AfterMonths_1" = "%@ month";
"Time.AfterMonths_any" = "%@ months";
"Time.AfterYears_1" = "%@ years";
"Time.AfterYears_any" = "%@ years";
"Time.TimerSeconds_1" = "%@-second";
"Time.TimerSeconds_any" = "%@-second";
"Time.TimerMinutes_1" = "%@-minute";
"Time.TimerMinutes_any" = "%@-minute";
"Time.TimerHours_1" = "%@-hour";
"Time.TimerHours_any" = "%@-hour";
"Time.TimerDays_1" = "%@-day";
"Time.TimerDays_any" = "%@-day";
"Time.TimerWeeks_1" = "%@-week";
"Time.TimerWeeks_any" = "%@-week";
"Time.TimerMonths_1" = "%@-month";
"Time.TimerMonths_any" = "%@-month";
"Time.TimerYears_1" = "%@-year";
"Time.TimerYears_any" = "%@-year";
"ChatList.LabelAutodeleteAfter" = "auto-delete after %@";
"ChatList.LabelAutodeleteDisabled" = "auto-deletion disabled";
"GlobalAutodeleteSettings.Title" = "Auto-Delete Messages";
"GlobalAutodeleteSettings.OptionsHeader" = "SELF-DESTRUCT TIMER";
"GlobalAutodeleteSettings.OptionTitle" = "After %@";
"GlobalAutodeleteSettings.SetCustomTime" = "Set Custom Time...";
"GlobalAutodeleteSettings.InfoDisabled" = "If enabled, all new messages in chats you start will be automatically deleted for everyone at some point after they have been sent. This will not affect your existing chats.";
"GlobalAutodeleteSettings.InfoEnabled" = "All new messages in chats you started will be automatically deleted for everyone %@ after they have been sent. You can also [apply this setting for your existing chats]().";
"GlobalAutodeleteSettings.SetConfirmTitle" = "Self-Destruct Timer";
"GlobalAutodeleteSettings.SetConfirmText" = "Are you sure you want all messages in your new private chats and in new groups you create to be automatically deleted for everyone %@ after they have been sent?";
"GlobalAutodeleteSettings.SetConfirmAction" = "Enable Auto-Deletion";
"GlobalAutodeleteSettings.SetConfirmToastEnabled" = "Messages in all new chats you start will be automatically deleted after %@.";
"GlobalAutodeleteSettings.SetConfirmToastDisabled" = "Messages in all new chats you start will not be automatically deleted.";
"GlobalAutodeleteSettings.ApplyChatsTitle" = "Select Chats";
"GlobalAutodeleteSettings.ApplyChatsPlaceholder" = "Select chats to apply a %@ self-destruct timer";
"GlobalAutodeleteSettings.ApplyChatsToast" = "You applied the %1$@ self-destruct timer to %2$@.";
"GlobalAutodeleteSettings.ApplyChatsSubject_1" = "%@ chat";
"GlobalAutodeleteSettings.ApplyChatsSubject_any" = "%@ chats";
"GlobalAutodeleteSettings.AttemptDisabledGroupSelection" = "You need admin rights in this group to enable auto-delete.";
"GlobalAutodeleteSettings.AttemptDisabledChannelSelection" = "You need admin rights in this channel to enable auto-delete.";
"GlobalAutodeleteSettings.AttemptDisabledGenericSelection" = "You can't enable auto-delete in this chat.";
"EmojiSearch.SearchEmojiPlaceholder" = "Search Emoji";

View File

@ -80,17 +80,19 @@ public final class ContactMultiselectionControllerParams {
public let options: [ContactListAdditionalOption]
public let filters: [ContactListFilter]
public let isPeerEnabled: ((EnginePeer) -> Bool)?
public let attemptDisabledItemSelection: ((EnginePeer) -> Void)?
public let alwaysEnabled: Bool
public let limit: Int32?
public let reachedLimit: ((Int32) -> Void)?
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, mode: ContactMultiselectionControllerMode, options: [ContactListAdditionalOption], filters: [ContactListFilter] = [.excludeSelf], isPeerEnabled: ((EnginePeer) -> Bool)? = nil, alwaysEnabled: Bool = false, limit: Int32? = nil, reachedLimit: ((Int32) -> Void)? = nil) {
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, mode: ContactMultiselectionControllerMode, options: [ContactListAdditionalOption], filters: [ContactListFilter] = [.excludeSelf], isPeerEnabled: ((EnginePeer) -> Bool)? = nil, attemptDisabledItemSelection: ((EnginePeer) -> Void)? = nil, alwaysEnabled: Bool = false, limit: Int32? = nil, reachedLimit: ((Int32) -> Void)? = nil) {
self.context = context
self.updatedPresentationData = updatedPresentationData
self.mode = mode
self.options = options
self.filters = filters
self.isPeerEnabled = isPeerEnabled
self.attemptDisabledItemSelection = attemptDisabledItemSelection
self.alwaysEnabled = alwaysEnabled
self.limit = limit
self.reachedLimit = reachedLimit

View File

@ -3654,8 +3654,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
if isHidden {
//TODO:localize
strongSelf.present(UndoOverlayController(presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, content: .hidArchive(title: "General hidden", text: "Pull down to see the general topic.", undo: false), elevatedLayout: false, animateInAsReplacement: true, action: { [weak self] value in
strongSelf.present(UndoOverlayController(presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, content: .hidArchive(title: strongSelf.presentationData.strings.ChatList_GeneralHidden, text: strongSelf.presentationData.strings.ChatList_GeneralHiddenInfo, undo: false), elevatedLayout: false, animateInAsReplacement: true, action: { [weak self] value in
guard let strongSelf = self else {
return false
}
@ -3666,7 +3665,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return false
}), in: .current)
} else {
strongSelf.present(UndoOverlayController(presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, content: .revealedArchive(title: "General unhidden", text: "Swipe left on the general topic to hide it.", undo: false), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false
strongSelf.present(UndoOverlayController(presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, content: .revealedArchive(title: strongSelf.presentationData.strings.ChatList_GeneralUnhidden, text: strongSelf.presentationData.strings.ChatList_GeneralUnhiddenInfo, undo: false), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false
}), in: .current)
}
}

View File

@ -2972,11 +2972,9 @@ private func statusStringForPeerType(accountPeerId: EnginePeer.Id, strings: Pres
if displayAutoremoveTimeout {
if let autoremoveTimeout = autoremoveTimeout {
//TODO:localize
return ("auto-delete after \(timeIntervalString(strings: strings, value: autoremoveTimeout))", false, true, .autoremove)
return (strings.ChatList_LabelAutodeleteAfter(timeIntervalString(strings: strings, value: autoremoveTimeout, usage: .afterTime)).string, false, true, .autoremove)
} else {
//TODO:localize
return ("auto-deletion disabled", false, false, .autoremove)
return (strings.ChatList_LabelAutodeleteDisabled, false, false, .autoremove)
}
}

View File

@ -149,8 +149,7 @@ private func globalAutoremoveScreenEntries(presentationData: PresentationData, s
let effectiveCurrentValue = state.updatedValue
//TODO:localize
entries.append(.sectionHeader("SELF-DESTRUCT TIMER"))
entries.append(.sectionHeader(presentationData.strings.GlobalAutodeleteSettings_OptionsHeader))
var values: [Int32] = [
0,
@ -170,25 +169,22 @@ private func globalAutoremoveScreenEntries(presentationData: PresentationData, s
values.sort()
//TODO:localize
for value in values {
let text: String
if value == 0 {
text = "Off"
text = presentationData.strings.Autoremove_OptionOff
} else {
text = "After \(timeIntervalString(strings: presentationData.strings, value: value))"
text = presentationData.strings.GlobalAutodeleteSettings_OptionTitle(timeIntervalString(strings: presentationData.strings, value: value, usage: .afterTime)).string
}
entries.append(.timerOption(value: value, text: text, isSelected: effectiveCurrentValue == value))
}
entries.append(.customAction("Set Custom Time..."))
entries.append(.customAction(presentationData.strings.GlobalAutodeleteSettings_SetCustomTime))
//TODO:localize
if effectiveCurrentValue == 0 {
entries.append(.info("If enabled, all new messages in chats you start will be automatically deleted for everyone at some point after they have been sent. This will not affect your existing chats."))
entries.append(.info(presentationData.strings.GlobalAutodeleteSettings_InfoDisabled))
} else {
entries.append(.info("All new messages in chats you started will be automatically deleted for everyone \(timeIntervalString(strings: presentationData.strings, value: effectiveCurrentValue)) after they have been sent. You can also [apply this setting for your existing chats]()."))
entries.append(.info(presentationData.strings.GlobalAutodeleteSettings_InfoEnabled(timeIntervalString(strings: presentationData.strings, value: effectiveCurrentValue, usage: .afterTime)).string))
}
return entries
@ -237,10 +233,10 @@ public func globalAutoremoveScreen(context: AccountContext, initialValue: Int32,
var isOn: Bool = true
var text: String?
if timeout != 0 {
text = "Messages in all new chats you start will be automatically deleted after \(timeIntervalString(strings: presentationData.strings, value: timeout))."
text = presentationData.strings.GlobalAutodeleteSettings_SetConfirmToastEnabled(timeIntervalString(strings: presentationData.strings, value: timeout, usage: .afterTime)).string
} else {
isOn = false
text = "Messages in all new chats you start will not be automatically deleted.";
text = presentationData.strings.GlobalAutodeleteSettings_SetConfirmToastDisabled
}
if let text = text {
var animateAsReplacement = false
@ -264,14 +260,13 @@ public func globalAutoremoveScreen(context: AccountContext, initialValue: Int32,
apply(timeout)
} else {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
let valueText = timeIntervalString(strings: presentationData.strings, value: timeout)
let valueText = timeIntervalString(strings: presentationData.strings, value: timeout, usage: .afterTime)
presentControllerImpl?(standardTextAlertController(
theme: AlertControllerTheme(presentationData: presentationData),
title: "Self-Destruct Timer",
text: "Are you sure you want all messages in your new private chats and in new groups you create to be automatically deleted for everyone \(valueText) after they have been sent?",
title: presentationData.strings.GlobalAutodeleteSettings_SetConfirmTitle,
text: presentationData.strings.GlobalAutodeleteSettings_SetConfirmText(valueText).string,
actions: [
TextAlertAction(type: .defaultAction, title: "Enable Auto-Deletion", action: {
TextAlertAction(type: .defaultAction, title: presentationData.strings.GlobalAutodeleteSettings_SetConfirmAction, action: {
apply(timeout)
}),
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {})
@ -299,16 +294,14 @@ public func globalAutoremoveScreen(context: AccountContext, initialValue: Int32,
return
}
//TODO:localize
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let valueText = timeIntervalString(strings: presentationData.strings, value: value)
let valueText = timeIntervalString(strings: presentationData.strings, value: value, usage: .timer)
//TODO:localize
let selectionController = context.sharedContext.makeContactMultiselectionController(ContactMultiselectionControllerParams(
context: context,
mode: .chatSelection(ContactMultiselectionControllerMode.ChatSelection(
title: "Select Chats",
searchPlaceholder: "Select chats to apply the \(valueText) self-destruct timer",
title: presentationData.strings.GlobalAutodeleteSettings_ApplyChatsTitle,
searchPlaceholder: presentationData.strings.GlobalAutodeleteSettings_ApplyChatsPlaceholder(valueText).string,
selectedChats: Set(),
additionalCategories: nil,
chatListFilters: nil,
@ -333,6 +326,31 @@ public func globalAutoremoveScreen(context: AccountContext, initialValue: Int32,
canManage = channel.hasPermission(.changeInfo)
}
return canManage
},
attemptDisabledItemSelection: { peer in
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let text: String
if case let .channel(channel) = peer {
if case .group = channel.info {
text = presentationData.strings.GlobalAutodeleteSettings_AttemptDisabledGroupSelection
} else {
text = presentationData.strings.GlobalAutodeleteSettings_AttemptDisabledChannelSelection
}
} else if case .legacyGroup = peer {
text = presentationData.strings.GlobalAutodeleteSettings_AttemptDisabledGroupSelection
} else {
text = presentationData.strings.GlobalAutodeleteSettings_AttemptDisabledGenericSelection
}
presentControllerImpl?(standardTextAlertController(
theme: AlertControllerTheme(presentationData: presentationData),
title: nil,
text: text,
actions: [
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})
]
), nil)
}
))
selectionController.navigationPresentation = .modal
@ -362,8 +380,7 @@ public func globalAutoremoveScreen(context: AccountContext, initialValue: Int32,
selectionController?.dismiss()
let isOn: Bool = true
//TODO:localize
let text = "You applied the \(timeIntervalString(strings: presentationData.strings, value: value)) self-destruct timer to \(peerIds.count) \(peerIds.count == 1 ? "chat" : "chats")."
let text = presentationData.strings.GlobalAutodeleteSettings_ApplyChatsToast(timeIntervalString(strings: presentationData.strings, value: value, usage: .timer), presentationData.strings.GlobalAutodeleteSettings_ApplyChatsSubject(Int32(peerIds.count))).string
var animateAsReplacement = false
if let window = getController?()?.window {
@ -390,8 +407,7 @@ public func globalAutoremoveScreen(context: AccountContext, initialValue: Int32,
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let rightNavigationButton: ItemListNavigationButton? = nil
//TODO:localize
let title: ItemListControllerTitle = .text("Auto-Delete Messages")
let title: ItemListControllerTitle = .text(presentationData.strings.GlobalAutodeleteSettings_Title)
let entries: [GlobalAutoremoveEntry] = globalAutoremoveScreenEntries(presentationData: presentationData, state: state)

View File

@ -514,7 +514,6 @@ private func privacyAndSecurityControllerEntries(
}
entries.append(.twoStepVerification(presentationData.theme, presentationData.strings.PrivacySettings_TwoStepAuth, twoStepAuthString, twoStepAuthData))
//TODO:localize
if let privacySettings = privacySettings {
let value: Int32?
if let updatingMessageAutoremoveTimeoutValue = state.updatingMessageAutoremoveTimeoutValue {
@ -526,13 +525,13 @@ private func privacyAndSecurityControllerEntries(
if let value {
valueText = timeIntervalString(strings: presentationData.strings, value: value)
} else {
valueText = "Off"
valueText = presentationData.strings.Autoremove_OptionOff
}
entries.append(.messageAutoremoveTimeout(presentationData.theme, "Auto-Delete Messages", valueText))
entries.append(.messageAutoremoveTimeout(presentationData.theme, presentationData.strings.Settings_AutoDeleteTitle, valueText))
} else {
entries.append(.messageAutoremoveTimeout(presentationData.theme, "Auto-Delete Messages", presentationData.strings.Channel_NotificationLoading))
entries.append(.messageAutoremoveTimeout(presentationData.theme, presentationData.strings.Settings_AutoDeleteTitle, presentationData.strings.Channel_NotificationLoading))
}
entries.append(.messageAutoremoveInfo(presentationData.theme, "Automatically delete messages for everyone after a period of time in all new chats you start."))
entries.append(.messageAutoremoveInfo(presentationData.theme, presentationData.strings.Settings_AutoDeleteInfo))
if loginEmail != nil {
entries.append(.loginEmail(presentationData.theme, presentationData.strings.PrivacySettings_LoginEmail, loginEmail))

View File

@ -50,38 +50,115 @@ public func minutesIntervalString(strings: PresentationStrings, minutes: Int32)
return strings.MessageTimer_Minutes(max(0, minutes))
}
public func timeIntervalString(strings: PresentationStrings, value: Int32, preferLowerValue: Bool = false) -> String {
if preferLowerValue {
if value <= 60 {
return strings.MessageTimer_Seconds(max(1, value))
} else if value <= 60 * 60 {
return strings.MessageTimer_Minutes(max(1, value / 60))
} else if value <= 60 * 60 * 24 {
return strings.MessageTimer_Hours(max(1, value / (60 * 60)))
} else if value <= 60 * 60 * 24 * 7 {
return strings.MessageTimer_Days(max(1, value / (60 * 60 * 24)))
} else if value <= 60 * 60 * 24 * 30 {
return strings.MessageTimer_Weeks(max(1, value / (60 * 60 * 24 * 7)))
} else if value <= 60 * 60 * 24 * 365 {
return strings.MessageTimer_Months(max(1, value / (60 * 60 * 24 * 30)))
public enum TimeIntervalStringUsage {
case generic
case afterTime
case timer
}
public func timeIntervalString(strings: PresentationStrings, value: Int32, usage: TimeIntervalStringUsage = .generic, preferLowerValue: Bool = false) -> String {
switch usage {
case .generic:
if preferLowerValue {
if value <= 60 {
return strings.MessageTimer_Seconds(max(1, value))
} else if value <= 60 * 60 {
return strings.MessageTimer_Minutes(max(1, value / 60))
} else if value <= 60 * 60 * 24 {
return strings.MessageTimer_Hours(max(1, value / (60 * 60)))
} else if value <= 60 * 60 * 24 * 7 {
return strings.MessageTimer_Days(max(1, value / (60 * 60 * 24)))
} else if value <= 60 * 60 * 24 * 30 {
return strings.MessageTimer_Weeks(max(1, value / (60 * 60 * 24 * 7)))
} else if value <= 60 * 60 * 24 * 365 {
return strings.MessageTimer_Months(max(1, value / (60 * 60 * 24 * 30)))
} else {
return strings.MessageTimer_Years(max(1, value / (60 * 60 * 24 * 365)))
}
} else {
return strings.MessageTimer_Years(max(1, value / (60 * 60 * 24 * 365)))
if value < 60 {
return strings.MessageTimer_Seconds(max(1, value))
} else if value < 60 * 60 {
return strings.MessageTimer_Minutes(max(1, value / 60))
} else if value < 60 * 60 * 24 {
return strings.MessageTimer_Hours(max(1, value / (60 * 60)))
} else if value < 60 * 60 * 24 * 7 {
return strings.MessageTimer_Days(max(1, value / (60 * 60 * 24)))
} else if value < 60 * 60 * 24 * 30 {
return strings.MessageTimer_Weeks(max(1, value / (60 * 60 * 24 * 7)))
} else if value < 60 * 60 * 24 * 365 {
return strings.MessageTimer_Months(max(1, value / (60 * 60 * 24 * 30)))
} else {
return strings.MessageTimer_Years(max(1, value / (60 * 60 * 24 * 365)))
}
}
} else {
if value < 60 {
return strings.MessageTimer_Seconds(max(1, value))
} else if value < 60 * 60 {
return strings.MessageTimer_Minutes(max(1, value / 60))
} else if value < 60 * 60 * 24 {
return strings.MessageTimer_Hours(max(1, value / (60 * 60)))
} else if value < 60 * 60 * 24 * 7 {
return strings.MessageTimer_Days(max(1, value / (60 * 60 * 24)))
} else if value < 60 * 60 * 24 * 30 {
return strings.MessageTimer_Weeks(max(1, value / (60 * 60 * 24 * 7)))
} else if value < 60 * 60 * 24 * 365 {
return strings.MessageTimer_Months(max(1, value / (60 * 60 * 24 * 30)))
case .afterTime:
if preferLowerValue {
if value <= 60 {
return strings.Time_AfterSeconds(max(1, value))
} else if value <= 60 * 60 {
return strings.Time_AfterMinutes(max(1, value / 60))
} else if value <= 60 * 60 * 24 {
return strings.Time_AfterHours(max(1, value / (60 * 60)))
} else if value <= 60 * 60 * 24 * 7 {
return strings.Time_AfterDays(max(1, value / (60 * 60 * 24)))
} else if value <= 60 * 60 * 24 * 30 {
return strings.Time_AfterWeeks(max(1, value / (60 * 60 * 24 * 7)))
} else if value <= 60 * 60 * 24 * 365 {
return strings.Time_AfterMonths(max(1, value / (60 * 60 * 24 * 30)))
} else {
return strings.Time_AfterYears(max(1, value / (60 * 60 * 24 * 365)))
}
} else {
return strings.MessageTimer_Years(max(1, value / (60 * 60 * 24 * 365)))
if value < 60 {
return strings.Time_AfterSeconds(max(1, value))
} else if value < 60 * 60 {
return strings.Time_AfterMinutes(max(1, value / 60))
} else if value < 60 * 60 * 24 {
return strings.Time_AfterHours(max(1, value / (60 * 60)))
} else if value < 60 * 60 * 24 * 7 {
return strings.Time_AfterDays(max(1, value / (60 * 60 * 24)))
} else if value < 60 * 60 * 24 * 30 {
return strings.Time_AfterWeeks(max(1, value / (60 * 60 * 24 * 7)))
} else if value < 60 * 60 * 24 * 365 {
return strings.Time_AfterMonths(max(1, value / (60 * 60 * 24 * 30)))
} else {
return strings.Time_AfterYears(max(1, value / (60 * 60 * 24 * 365)))
}
}
case .timer:
if preferLowerValue {
if value <= 60 {
return strings.Time_TimerSeconds(max(1, value))
} else if value <= 60 * 60 {
return strings.Time_TimerMinutes(max(1, value / 60))
} else if value <= 60 * 60 * 24 {
return strings.Time_TimerHours(max(1, value / (60 * 60)))
} else if value <= 60 * 60 * 24 * 7 {
return strings.Time_TimerDays(max(1, value / (60 * 60 * 24)))
} else if value <= 60 * 60 * 24 * 30 {
return strings.Time_TimerWeeks(max(1, value / (60 * 60 * 24 * 7)))
} else if value <= 60 * 60 * 24 * 365 {
return strings.Time_TimerMonths(max(1, value / (60 * 60 * 24 * 30)))
} else {
return strings.Time_TimerYears(max(1, value / (60 * 60 * 24 * 365)))
}
} else {
if value < 60 {
return strings.Time_TimerSeconds(max(1, value))
} else if value < 60 * 60 {
return strings.Time_TimerMinutes(max(1, value / 60))
} else if value < 60 * 60 * 24 {
return strings.Time_TimerHours(max(1, value / (60 * 60)))
} else if value < 60 * 60 * 24 * 7 {
return strings.Time_TimerDays(max(1, value / (60 * 60 * 24)))
} else if value < 60 * 60 * 24 * 30 {
return strings.Time_TimerWeeks(max(1, value / (60 * 60 * 24 * 7)))
} else if value < 60 * 60 * 24 * 365 {
return strings.Time_TimerMonths(max(1, value / (60 * 60 * 24 * 30)))
} else {
return strings.Time_TimerYears(max(1, value / (60 * 60 * 24 * 365)))
}
}
}
}

View File

@ -29,6 +29,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
private let context: AccountContext
private let mode: ContactMultiselectionControllerMode
private let isPeerEnabled: ((EnginePeer) -> Bool)?
private let attemptDisabledItemSelection: ((EnginePeer) -> Void)?
private let titleView: CounterContollerTitleView
@ -85,6 +86,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
self.context = params.context
self.mode = params.mode
self.isPeerEnabled = params.isPeerEnabled
self.attemptDisabledItemSelection = params.attemptDisabledItemSelection
self.options = params.options
self.filters = params.filters
self.limit = params.limit
@ -222,7 +224,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
}
override func loadDisplayNode() {
self.displayNode = ContactMultiselectionControllerNode(navigationBar: self.navigationBar, context: self.context, presentationData: self.presentationData, mode: self.mode, isPeerEnabled: self.isPeerEnabled, options: self.options, filters: self.filters, limit: self.limit, reachedSelectionLimit: self.params.reachedLimit)
self.displayNode = ContactMultiselectionControllerNode(navigationBar: self.navigationBar, context: self.context, presentationData: self.presentationData, mode: self.mode, isPeerEnabled: self.isPeerEnabled, attemptDisabledItemSelection: self.attemptDisabledItemSelection, options: self.options, filters: self.filters, limit: self.limit, reachedSelectionLimit: self.params.reachedLimit)
switch self.contactsNode.contentNode {
case let .contacts(contactsNode):
self._listReady.set(contactsNode.ready)

View File

@ -71,7 +71,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode {
private let animationCache: AnimationCache
private let animationRenderer: MultiAnimationRenderer
init(navigationBar: NavigationBar?, context: AccountContext, presentationData: PresentationData, mode: ContactMultiselectionControllerMode, isPeerEnabled: ((EnginePeer) -> Bool)?, options: [ContactListAdditionalOption], filters: [ContactListFilter], limit: Int32?, reachedSelectionLimit: ((Int32) -> Void)?) {
init(navigationBar: NavigationBar?, context: AccountContext, presentationData: PresentationData, mode: ContactMultiselectionControllerMode, isPeerEnabled: ((EnginePeer) -> Bool)?, attemptDisabledItemSelection: ((EnginePeer) -> Void)?, options: [ContactListAdditionalOption], filters: [ContactListFilter], limit: Int32?, reachedSelectionLimit: ((Int32) -> Void)?) {
self.navigationBar = navigationBar
self.context = context
@ -102,6 +102,9 @@ final class ContactMultiselectionControllerNode: ASDisplayNode {
placeholder = placeholderValue
let chatListNode = ChatListNode(context: context, location: .chatList(groupId: .root), previewing: false, fillPreloadItems: false, mode: .peers(filter: [.excludeSecretChats], isSelecting: true, additionalCategories: additionalCategories?.categories ?? [], chatListFilters: chatListFilters, displayAutoremoveTimeout: chatSelection.displayAutoremoveTimeout), isPeerEnabled: isPeerEnabled, theme: self.presentationData.theme, fontSize: self.presentationData.listsFontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameSortOrder: self.presentationData.nameSortOrder, nameDisplayOrder: self.presentationData.nameDisplayOrder, animationCache: self.animationCache, animationRenderer: self.animationRenderer, disableAnimations: true, isInlineMode: false)
chatListNode.disabledPeerSelected = { peer, _ in
attemptDisabledItemSelection?(peer)
}
if let limit = limit {
chatListNode.selectionLimit = limit
chatListNode.reachedSelectionLimit = reachedSelectionLimit

View File

@ -310,16 +310,15 @@ private func createGroupEntries(presentationData: PresentationData, state: Creat
entries.append(.groupInfo(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, groupInfoState, state.avatar))
//TODO:localize
let autoremoveTimeout = state.autoremoveTimeout ?? globalAutoremoveTimeout
let autoRemoveText: String
if autoremoveTimeout == 0 {
autoRemoveText = "Off"
autoRemoveText = presentationData.strings.Autoremove_OptionOff
} else {
autoRemoveText = timeIntervalString(strings: presentationData.strings, value: autoremoveTimeout)
}
entries.append(.autoDelete(title: "Auto-Delete Messages", value: autoRemoveText))
entries.append(.autoDeleteInfo("Automatically delete messages sent in this group for everyone after a period of time."))
entries.append(.autoDelete(title: presentationData.strings.CreateGroup_AutoDeleteTitle, value: autoRemoveText))
entries.append(.autoDeleteInfo(presentationData.strings.CreateGroup_AutoDeleteText))
var peers: [Peer] = []
for peerId in peerIds {
@ -846,8 +845,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
subItems.append(.action(ContextMenuActionItem(text: "Off", icon: { theme in
subItems.append(.action(ContextMenuActionItem(text: presentationData.strings.Autoremove_OptionOff, icon: { theme in
if currentValue == 0 {
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
} else {
@ -882,8 +880,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
})))
}
//TODO:localize
subItems.append(.action(ContextMenuActionItem(text: "Set Custom Time...", icon: { _ in
subItems.append(.action(ContextMenuActionItem(text: presentationData.strings.Autoremove_SetCustomTime, icon: { _ in
return nil
}, action: { _, f in
f(.default)