chore: prerelease 0.1.0
This commit is contained in:
parent
6e370e06d1
commit
c37205ebc7
37 changed files with 56411 additions and 110 deletions
|
|
@ -4,8 +4,8 @@ import TelegramCore
|
|||
import TelegramUIPreferences
|
||||
import AccountContext
|
||||
|
||||
public let maximumNumberOfAccounts = 3
|
||||
public let maximumPremiumNumberOfAccounts = 4
|
||||
public let maximumNumberOfAccounts = 100
|
||||
public let maximumPremiumNumberOfAccounts = 100
|
||||
|
||||
public func activeAccountsAndPeers(context: AccountContext, includePrimary: Bool = false) -> Signal<((AccountContext, EnginePeer)?, [(AccountContext, EnginePeer, Int32)]), NoError> {
|
||||
let sharedContext = context.sharedContext
|
||||
|
|
|
|||
607
submodules/SettingsUI/Sources/WinterGramSettingsController.swift
Normal file
607
submodules/SettingsUI/Sources/WinterGramSettingsController.swift
Normal file
|
|
@ -0,0 +1,607 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
|
||||
private final class WinterGramSettingsArguments {
|
||||
let updateSettings: (@escaping (WinterGramSettings) -> WinterGramSettings) -> Void
|
||||
let presentSendWithoutSound: () -> Void
|
||||
let presentPeerId: () -> Void
|
||||
let presentTranslationProvider: () -> Void
|
||||
let presentWebviewPlatform: () -> Void
|
||||
let presentIconPack: () -> Void
|
||||
|
||||
init(
|
||||
updateSettings: @escaping (@escaping (WinterGramSettings) -> WinterGramSettings) -> Void,
|
||||
presentSendWithoutSound: @escaping () -> Void,
|
||||
presentPeerId: @escaping () -> Void,
|
||||
presentTranslationProvider: @escaping () -> Void,
|
||||
presentWebviewPlatform: @escaping () -> Void,
|
||||
presentIconPack: @escaping () -> Void
|
||||
) {
|
||||
self.updateSettings = updateSettings
|
||||
self.presentSendWithoutSound = presentSendWithoutSound
|
||||
self.presentPeerId = presentPeerId
|
||||
self.presentTranslationProvider = presentTranslationProvider
|
||||
self.presentWebviewPlatform = presentWebviewPlatform
|
||||
self.presentIconPack = presentIconPack
|
||||
}
|
||||
}
|
||||
|
||||
private enum WinterGramSettingsSection: Int32 {
|
||||
case ghost
|
||||
case history
|
||||
case stash
|
||||
case antiFeatures
|
||||
case confirmations
|
||||
case chat
|
||||
case appearance
|
||||
case liquidGlass
|
||||
}
|
||||
|
||||
private enum WinterGramSettingsEntry: ItemListNodeEntry {
|
||||
case ghostHeader
|
||||
case ghostEnabled(Bool)
|
||||
case ghostReadReceipts(Bool)
|
||||
case ghostReadStories(Bool)
|
||||
case ghostOnlineStatus(Bool)
|
||||
case ghostUploadProgress(Bool)
|
||||
case ghostOfflineAfterOnline(Bool)
|
||||
case ghostMarkReadAfterAction(Bool)
|
||||
case ghostUseScheduled(Bool)
|
||||
case ghostSendWithoutSound(String)
|
||||
case ghostSuggestBeforeStory(Bool)
|
||||
case ghostFooter
|
||||
|
||||
case historyHeader
|
||||
case historySaveDeleted(Bool)
|
||||
case historySaveEdits(Bool)
|
||||
case historySemiTransparent(Bool)
|
||||
case historyFooter
|
||||
|
||||
case stashHeader
|
||||
case stashMute(Bool)
|
||||
case stashAutoRead(Bool)
|
||||
case stashFooter
|
||||
|
||||
case antiHeader
|
||||
case antiDisableAds(Bool)
|
||||
case antiLocalPremium(Bool)
|
||||
case antiDisableStories(Bool)
|
||||
case antiHidePremiumStatuses(Bool)
|
||||
case antiDisableLinkWarning(Bool)
|
||||
case antiFooter
|
||||
|
||||
case confirmHeader
|
||||
case confirmStickers(Bool)
|
||||
case confirmGif(Bool)
|
||||
case confirmVoice(Bool)
|
||||
|
||||
case chatHeader
|
||||
case chatShowSeconds(Bool)
|
||||
case chatShowPeerId(String)
|
||||
case chatTranslate(Bool)
|
||||
case chatTranslateProvider(String)
|
||||
case chatWebviewPlatform(String)
|
||||
case chatWebviewHeight(Bool)
|
||||
case chatOnlyAddedEmoji(Bool)
|
||||
|
||||
case appearanceHeader
|
||||
case appearanceMaterial(Bool)
|
||||
case appearanceSingleCorner(Bool)
|
||||
case appearanceIconPack(String)
|
||||
|
||||
case glassHeader
|
||||
case glassEnabled(Bool)
|
||||
case glassVibrancy(Bool)
|
||||
case glassChatList(Bool)
|
||||
case glassNavBars(Bool)
|
||||
case glassTabBar(Bool)
|
||||
case glassBubbles(Bool)
|
||||
case glassFooter
|
||||
|
||||
var section: ItemListSectionId {
|
||||
switch self {
|
||||
case .ghostHeader, .ghostEnabled, .ghostReadReceipts, .ghostReadStories, .ghostOnlineStatus, .ghostUploadProgress, .ghostOfflineAfterOnline, .ghostMarkReadAfterAction, .ghostUseScheduled, .ghostSendWithoutSound, .ghostSuggestBeforeStory, .ghostFooter:
|
||||
return WinterGramSettingsSection.ghost.rawValue
|
||||
case .historyHeader, .historySaveDeleted, .historySaveEdits, .historySemiTransparent, .historyFooter:
|
||||
return WinterGramSettingsSection.history.rawValue
|
||||
case .stashHeader, .stashMute, .stashAutoRead, .stashFooter:
|
||||
return WinterGramSettingsSection.stash.rawValue
|
||||
case .antiHeader, .antiDisableAds, .antiLocalPremium, .antiDisableStories, .antiHidePremiumStatuses, .antiDisableLinkWarning, .antiFooter:
|
||||
return WinterGramSettingsSection.antiFeatures.rawValue
|
||||
case .confirmHeader, .confirmStickers, .confirmGif, .confirmVoice:
|
||||
return WinterGramSettingsSection.confirmations.rawValue
|
||||
case .chatHeader, .chatShowSeconds, .chatShowPeerId, .chatTranslate, .chatTranslateProvider, .chatWebviewPlatform, .chatWebviewHeight, .chatOnlyAddedEmoji:
|
||||
return WinterGramSettingsSection.chat.rawValue
|
||||
case .appearanceHeader, .appearanceMaterial, .appearanceSingleCorner, .appearanceIconPack:
|
||||
return WinterGramSettingsSection.appearance.rawValue
|
||||
case .glassHeader, .glassEnabled, .glassVibrancy, .glassChatList, .glassNavBars, .glassTabBar, .glassBubbles, .glassFooter:
|
||||
return WinterGramSettingsSection.liquidGlass.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
var stableId: Int32 {
|
||||
switch self {
|
||||
case .ghostHeader: return 0
|
||||
case .ghostEnabled: return 1
|
||||
case .ghostReadReceipts: return 2
|
||||
case .ghostReadStories: return 3
|
||||
case .ghostOnlineStatus: return 4
|
||||
case .ghostUploadProgress: return 5
|
||||
case .ghostOfflineAfterOnline: return 6
|
||||
case .ghostMarkReadAfterAction: return 7
|
||||
case .ghostUseScheduled: return 8
|
||||
case .ghostSendWithoutSound: return 9
|
||||
case .ghostSuggestBeforeStory: return 10
|
||||
case .ghostFooter: return 11
|
||||
case .historyHeader: return 12
|
||||
case .historySaveDeleted: return 13
|
||||
case .historySaveEdits: return 14
|
||||
case .historySemiTransparent: return 15
|
||||
case .historyFooter: return 16
|
||||
case .stashHeader: return 17
|
||||
case .stashMute: return 18
|
||||
case .stashAutoRead: return 19
|
||||
case .stashFooter: return 20
|
||||
case .antiHeader: return 21
|
||||
case .antiDisableAds: return 22
|
||||
case .antiLocalPremium: return 23
|
||||
case .antiDisableStories: return 24
|
||||
case .antiHidePremiumStatuses: return 25
|
||||
case .antiDisableLinkWarning: return 26
|
||||
case .antiFooter: return 27
|
||||
case .confirmHeader: return 28
|
||||
case .confirmStickers: return 29
|
||||
case .confirmGif: return 30
|
||||
case .confirmVoice: return 31
|
||||
case .chatHeader: return 32
|
||||
case .chatShowSeconds: return 33
|
||||
case .chatShowPeerId: return 34
|
||||
case .chatTranslate: return 35
|
||||
case .chatTranslateProvider: return 36
|
||||
case .chatWebviewPlatform: return 37
|
||||
case .chatWebviewHeight: return 38
|
||||
case .chatOnlyAddedEmoji: return 39
|
||||
case .appearanceHeader: return 40
|
||||
case .appearanceMaterial: return 41
|
||||
case .appearanceSingleCorner: return 42
|
||||
case .appearanceIconPack: return 43
|
||||
case .glassHeader: return 44
|
||||
case .glassEnabled: return 45
|
||||
case .glassVibrancy: return 46
|
||||
case .glassChatList: return 47
|
||||
case .glassNavBars: return 48
|
||||
case .glassTabBar: return 49
|
||||
case .glassBubbles: return 50
|
||||
case .glassFooter: return 51
|
||||
}
|
||||
}
|
||||
|
||||
static func <(lhs: WinterGramSettingsEntry, rhs: WinterGramSettingsEntry) -> Bool {
|
||||
return lhs.stableId < rhs.stableId
|
||||
}
|
||||
|
||||
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
|
||||
let arguments = arguments as! WinterGramSettingsArguments
|
||||
switch self {
|
||||
case .ghostHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "GHOST MODE", sectionId: self.section)
|
||||
case let .ghostEnabled(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Ghost Mode", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.ghostModeEnabled = value; return s }
|
||||
})
|
||||
case let .ghostReadReceipts(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Send Read Receipts", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.sendReadReceipts = value; return s }
|
||||
})
|
||||
case let .ghostReadStories(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Send Story Views", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.sendReadStories = value; return s }
|
||||
})
|
||||
case let .ghostOnlineStatus(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Send Online Status", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.sendOnlineStatus = value; return s }
|
||||
})
|
||||
case let .ghostUploadProgress(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Send Typing & Upload Status", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.sendUploadProgress = value; return s }
|
||||
})
|
||||
case let .ghostOfflineAfterOnline(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Go Offline After Online", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.sendOfflineAfterOnline = value; return s }
|
||||
})
|
||||
case let .ghostMarkReadAfterAction(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Mark Read After Action", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.markReadAfterAction = value; return s }
|
||||
})
|
||||
case let .ghostUseScheduled(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Use Scheduled Messages", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.useScheduledMessages = value; return s }
|
||||
})
|
||||
case let .ghostSendWithoutSound(value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: "Send Without Sound", label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.presentSendWithoutSound()
|
||||
})
|
||||
case let .ghostSuggestBeforeStory(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Ask Before Viewing Stories", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.suggestGhostBeforeStory = value; return s }
|
||||
})
|
||||
case .ghostFooter:
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain("When Ghost Mode is on, WinterGram stops sending read receipts, online status and typing activity."), sectionId: self.section)
|
||||
|
||||
case .historyHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "HISTORY", sectionId: self.section)
|
||||
case let .historySaveDeleted(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Save Deleted Messages", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.saveDeletedMessages = value; return s }
|
||||
})
|
||||
case let .historySaveEdits(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Save Edit History", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.saveMessagesHistory = value; return s }
|
||||
})
|
||||
case let .historySemiTransparent(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Dim Deleted Messages", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.semiTransparentDeletedMessages = value; return s }
|
||||
})
|
||||
case .historyFooter:
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain("Deleted and edited messages are kept locally on this device only."), sectionId: self.section)
|
||||
|
||||
case .stashHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "HIDDEN ARCHIVE", sectionId: self.section)
|
||||
case let .stashMute(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Mute Notifications", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.stashMuteNotifications = value; return s }
|
||||
})
|
||||
case let .stashAutoRead(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Auto Mark as Read", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.stashAutoMarkRead = value; return s }
|
||||
})
|
||||
case .stashFooter:
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain("Stashed chats are hidden from the main list and accessible only here."), sectionId: self.section)
|
||||
|
||||
case .antiHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "FEATURES", sectionId: self.section)
|
||||
case let .antiDisableAds(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Disable Ads", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.disableAds = value; return s }
|
||||
})
|
||||
case let .antiLocalPremium(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Local Premium", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.localPremium = value; return s }
|
||||
})
|
||||
case let .antiDisableStories(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Hide Stories", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.disableStories = value; return s }
|
||||
})
|
||||
case let .antiHidePremiumStatuses(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Hide Premium Statuses", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.hidePremiumStatuses = value; return s }
|
||||
})
|
||||
case let .antiDisableLinkWarning(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Disable Open Link Warning", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.disableOpenLinkWarning = value; return s }
|
||||
})
|
||||
case .antiFooter:
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain("Local Premium unlocks Premium-only UI on this device; it does not grant server-side Premium."), sectionId: self.section)
|
||||
|
||||
case .confirmHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "SEND CONFIRMATIONS", sectionId: self.section)
|
||||
case let .confirmStickers(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Confirm Stickers", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.stickerConfirmation = value; return s }
|
||||
})
|
||||
case let .confirmGif(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Confirm GIFs", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.gifConfirmation = value; return s }
|
||||
})
|
||||
case let .confirmVoice(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Confirm Voice Messages", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.voiceConfirmation = value; return s }
|
||||
})
|
||||
|
||||
case .chatHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "CHAT", sectionId: self.section)
|
||||
case let .chatShowSeconds(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Show Message Seconds", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.showMessageSeconds = value; return s }
|
||||
})
|
||||
case let .chatShowPeerId(value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: "Show Peer ID", label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.presentPeerId()
|
||||
})
|
||||
case let .chatTranslate(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Message Translation", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.translateMessages = value; return s }
|
||||
})
|
||||
case let .chatTranslateProvider(value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: "Translation Provider", label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.presentTranslationProvider()
|
||||
})
|
||||
case let .chatWebviewPlatform(value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: "WebView Platform", label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.presentWebviewPlatform()
|
||||
})
|
||||
case let .chatWebviewHeight(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Increase WebView Height", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.increaseWebviewHeight = value; return s }
|
||||
})
|
||||
case let .chatOnlyAddedEmoji(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Only Added Emoji & Stickers", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.showOnlyAddedEmojisAndStickers = value; return s }
|
||||
})
|
||||
|
||||
case .appearanceHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "APPEARANCE", sectionId: self.section)
|
||||
case let .appearanceMaterial(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Material Design", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.materialDesign = value; return s }
|
||||
})
|
||||
case let .appearanceSingleCorner(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Single Corner Radius", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.singleCornerRadius = value; return s }
|
||||
})
|
||||
case let .appearanceIconPack(value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: "Icon Pack", label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.presentIconPack()
|
||||
})
|
||||
|
||||
case .glassHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "LIQUID GLASS", sectionId: self.section)
|
||||
case let .glassEnabled(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Liquid Glass", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.liquidGlass.enabled = value; return s }
|
||||
})
|
||||
case let .glassVibrancy(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Vibrancy", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.liquidGlass.vibrancy = value; return s }
|
||||
})
|
||||
case let .glassChatList(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Apply to Chat List", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.liquidGlass.applyToChatList = value; return s }
|
||||
})
|
||||
case let .glassNavBars(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Apply to Navigation Bars", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.liquidGlass.applyToNavigationBars = value; return s }
|
||||
})
|
||||
case let .glassTabBar(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Apply to Tab Bar", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.liquidGlass.applyToTabBar = value; return s }
|
||||
})
|
||||
case let .glassBubbles(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Apply to Bubbles", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateSettings { var s = $0; s.liquidGlass.applyToBubbles = value; return s }
|
||||
})
|
||||
case .glassFooter:
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain("Transparency, blur and tint can be fine-tuned per surface. Turn Liquid Glass off for the standard opaque look."), sectionId: self.section)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func sendWithoutSoundLabel(_ value: WinterGramSendWithoutSound) -> String {
|
||||
switch value {
|
||||
case .never: return "Never"
|
||||
case .inGhostMode: return "In Ghost Mode"
|
||||
case .always: return "Always"
|
||||
}
|
||||
}
|
||||
|
||||
private func peerIdLabel(_ value: WinterGramPeerIdDisplay) -> String {
|
||||
switch value {
|
||||
case .hidden: return "Hidden"
|
||||
case .telegramApi: return "Telegram API"
|
||||
case .botApi: return "Bot API"
|
||||
}
|
||||
}
|
||||
|
||||
private func translationProviderLabel(_ value: WinterGramTranslationProvider) -> String {
|
||||
switch value {
|
||||
case .telegram: return "Telegram"
|
||||
case .google: return "Google"
|
||||
case .yandex: return "Yandex"
|
||||
case .system: return "System"
|
||||
}
|
||||
}
|
||||
|
||||
private func webviewPlatformLabel(_ value: WinterGramWebviewPlatform) -> String {
|
||||
switch value {
|
||||
case .auto: return "Automatic"
|
||||
case .ios: return "iOS"
|
||||
case .android: return "Android"
|
||||
case .macos: return "macOS"
|
||||
case .desktop: return "Desktop"
|
||||
}
|
||||
}
|
||||
|
||||
private func iconPackLabel(_ value: WinterGramIconPack) -> String {
|
||||
switch value {
|
||||
case .wintergram: return "WinterGram"
|
||||
case .ayugram: return "AyuGram"
|
||||
case .exteragram: return "exteraGram"
|
||||
case .telegram: return "Telegram"
|
||||
}
|
||||
}
|
||||
|
||||
private func winterGramSettingsEntries(settings: WinterGramSettings) -> [WinterGramSettingsEntry] {
|
||||
var entries: [WinterGramSettingsEntry] = []
|
||||
|
||||
entries.append(.ghostHeader)
|
||||
entries.append(.ghostEnabled(settings.ghostModeEnabled))
|
||||
entries.append(.ghostReadReceipts(settings.sendReadReceipts))
|
||||
entries.append(.ghostReadStories(settings.sendReadStories))
|
||||
entries.append(.ghostOnlineStatus(settings.sendOnlineStatus))
|
||||
entries.append(.ghostUploadProgress(settings.sendUploadProgress))
|
||||
entries.append(.ghostOfflineAfterOnline(settings.sendOfflineAfterOnline))
|
||||
entries.append(.ghostMarkReadAfterAction(settings.markReadAfterAction))
|
||||
entries.append(.ghostUseScheduled(settings.useScheduledMessages))
|
||||
entries.append(.ghostSendWithoutSound(sendWithoutSoundLabel(settings.sendWithoutSound)))
|
||||
entries.append(.ghostSuggestBeforeStory(settings.suggestGhostBeforeStory))
|
||||
entries.append(.ghostFooter)
|
||||
|
||||
entries.append(.historyHeader)
|
||||
entries.append(.historySaveDeleted(settings.saveDeletedMessages))
|
||||
entries.append(.historySaveEdits(settings.saveMessagesHistory))
|
||||
entries.append(.historySemiTransparent(settings.semiTransparentDeletedMessages))
|
||||
entries.append(.historyFooter)
|
||||
|
||||
entries.append(.stashHeader)
|
||||
entries.append(.stashMute(settings.stashMuteNotifications))
|
||||
entries.append(.stashAutoRead(settings.stashAutoMarkRead))
|
||||
entries.append(.stashFooter)
|
||||
|
||||
entries.append(.antiHeader)
|
||||
entries.append(.antiDisableAds(settings.disableAds))
|
||||
entries.append(.antiLocalPremium(settings.localPremium))
|
||||
entries.append(.antiDisableStories(settings.disableStories))
|
||||
entries.append(.antiHidePremiumStatuses(settings.hidePremiumStatuses))
|
||||
entries.append(.antiDisableLinkWarning(settings.disableOpenLinkWarning))
|
||||
entries.append(.antiFooter)
|
||||
|
||||
entries.append(.confirmHeader)
|
||||
entries.append(.confirmStickers(settings.stickerConfirmation))
|
||||
entries.append(.confirmGif(settings.gifConfirmation))
|
||||
entries.append(.confirmVoice(settings.voiceConfirmation))
|
||||
|
||||
entries.append(.chatHeader)
|
||||
entries.append(.chatShowSeconds(settings.showMessageSeconds))
|
||||
entries.append(.chatShowPeerId(peerIdLabel(settings.showPeerId)))
|
||||
entries.append(.chatTranslate(settings.translateMessages))
|
||||
entries.append(.chatTranslateProvider(translationProviderLabel(settings.translationProvider)))
|
||||
entries.append(.chatWebviewPlatform(webviewPlatformLabel(settings.webviewSpoofPlatform)))
|
||||
entries.append(.chatWebviewHeight(settings.increaseWebviewHeight))
|
||||
entries.append(.chatOnlyAddedEmoji(settings.showOnlyAddedEmojisAndStickers))
|
||||
|
||||
entries.append(.appearanceHeader)
|
||||
entries.append(.appearanceMaterial(settings.materialDesign))
|
||||
entries.append(.appearanceSingleCorner(settings.singleCornerRadius))
|
||||
entries.append(.appearanceIconPack(iconPackLabel(settings.iconPack)))
|
||||
|
||||
entries.append(.glassHeader)
|
||||
entries.append(.glassEnabled(settings.liquidGlass.enabled))
|
||||
entries.append(.glassVibrancy(settings.liquidGlass.vibrancy))
|
||||
entries.append(.glassChatList(settings.liquidGlass.applyToChatList))
|
||||
entries.append(.glassNavBars(settings.liquidGlass.applyToNavigationBars))
|
||||
entries.append(.glassTabBar(settings.liquidGlass.applyToTabBar))
|
||||
entries.append(.glassBubbles(settings.liquidGlass.applyToBubbles))
|
||||
entries.append(.glassFooter)
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
public func winterGramSettingsController(context: AccountContext) -> ViewController {
|
||||
let accountManager = context.sharedContext.accountManager
|
||||
|
||||
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
||||
|
||||
let updateSettings: (@escaping (WinterGramSettings) -> WinterGramSettings) -> Void = { f in
|
||||
let _ = updateWinterGramSettingsInteractively(accountManager: accountManager, f).start()
|
||||
}
|
||||
|
||||
func presentChoice<T>(title: String, options: [(String, T)], apply: @escaping (T, WinterGramSettings) -> WinterGramSettings) {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let controller = ActionSheetController(presentationData: presentationData)
|
||||
var items: [ActionSheetItem] = []
|
||||
items.append(ActionSheetTextItem(title: title))
|
||||
for (label, value) in options {
|
||||
items.append(ActionSheetButtonItem(title: label, action: { [weak controller] in
|
||||
controller?.dismissAnimated()
|
||||
updateSettings { apply(value, $0) }
|
||||
}))
|
||||
}
|
||||
controller.setItemGroups([
|
||||
ActionSheetItemGroup(items: items),
|
||||
ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak controller] in
|
||||
controller?.dismissAnimated()
|
||||
})
|
||||
])
|
||||
])
|
||||
presentControllerImpl?(controller, nil)
|
||||
}
|
||||
|
||||
let arguments = WinterGramSettingsArguments(
|
||||
updateSettings: updateSettings,
|
||||
presentSendWithoutSound: {
|
||||
presentChoice(title: "Send Without Sound", options: [
|
||||
("Never", WinterGramSendWithoutSound.never),
|
||||
("In Ghost Mode", WinterGramSendWithoutSound.inGhostMode),
|
||||
("Always", WinterGramSendWithoutSound.always)
|
||||
], apply: { value, settings in
|
||||
var settings = settings
|
||||
settings.sendWithoutSound = value
|
||||
return settings
|
||||
})
|
||||
},
|
||||
presentPeerId: {
|
||||
presentChoice(title: "Show Peer ID", options: [
|
||||
("Hidden", WinterGramPeerIdDisplay.hidden),
|
||||
("Telegram API", WinterGramPeerIdDisplay.telegramApi),
|
||||
("Bot API", WinterGramPeerIdDisplay.botApi)
|
||||
], apply: { value, settings in
|
||||
var settings = settings
|
||||
settings.showPeerId = value
|
||||
return settings
|
||||
})
|
||||
},
|
||||
presentTranslationProvider: {
|
||||
presentChoice(title: "Translation Provider", options: [
|
||||
("Telegram", WinterGramTranslationProvider.telegram),
|
||||
("Google", WinterGramTranslationProvider.google),
|
||||
("Yandex", WinterGramTranslationProvider.yandex),
|
||||
("System", WinterGramTranslationProvider.system)
|
||||
], apply: { value, settings in
|
||||
var settings = settings
|
||||
settings.translationProvider = value
|
||||
return settings
|
||||
})
|
||||
},
|
||||
presentWebviewPlatform: {
|
||||
presentChoice(title: "WebView Platform", options: [
|
||||
("Automatic", WinterGramWebviewPlatform.auto),
|
||||
("iOS", WinterGramWebviewPlatform.ios),
|
||||
("Android", WinterGramWebviewPlatform.android),
|
||||
("macOS", WinterGramWebviewPlatform.macos),
|
||||
("Desktop", WinterGramWebviewPlatform.desktop)
|
||||
], apply: { value, settings in
|
||||
var settings = settings
|
||||
settings.webviewSpoofPlatform = value
|
||||
return settings
|
||||
})
|
||||
},
|
||||
presentIconPack: {
|
||||
presentChoice(title: "Icon Pack", options: [
|
||||
("WinterGram", WinterGramIconPack.wintergram),
|
||||
("AyuGram", WinterGramIconPack.ayugram),
|
||||
("exteraGram", WinterGramIconPack.exteragram),
|
||||
("Telegram", WinterGramIconPack.telegram)
|
||||
], apply: { value, settings in
|
||||
var settings = settings
|
||||
settings.iconPack = value
|
||||
return settings
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
let signal = combineLatest(queue: .mainQueue(),
|
||||
context.sharedContext.presentationData,
|
||||
winterGramSettings(accountManager: accountManager)
|
||||
)
|
||||
|> deliverOnMainQueue
|
||||
|> map { presentationData, settings -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text("WinterGram"), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: winterGramSettingsEntries(settings: settings), style: .blocks, animateChanges: true)
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
||||
let controller = ItemListController(context: context, state: signal)
|
||||
presentControllerImpl = { [weak controller] c, a in
|
||||
controller?.present(c, in: .window(.root), with: a)
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
|
@ -279,8 +279,10 @@ public func performAppGroupUpgrades(appGroupPath: String, rootPath: String) {
|
|||
}
|
||||
|
||||
do {
|
||||
// WinterGram: include account data in the device's iCloud/iTunes backup so accounts
|
||||
// survive a restore. Tradeoff: session auth keys are then part of the iCloud backup.
|
||||
var resourceValues = URLResourceValues()
|
||||
resourceValues.isExcludedFromBackup = true
|
||||
resourceValues.isExcludedFromBackup = false
|
||||
var mutableUrl = URL(fileURLWithPath: rootPath)
|
||||
try mutableUrl.setResourceValues(resourceValues)
|
||||
} catch let e {
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@ public struct PresentationResourcesSettings {
|
|||
public static let powerSaving = renderSettingsIcon(name: "Item List/Icons/PowerSaving", backgroundColors: [colorOrange])
|
||||
public static let business = renderSettingsIcon(name: "Item List/Icons/Business", backgroundColors: [UIColor(rgb: 0xA95CE3), UIColor(rgb: 0xF16B80)])
|
||||
public static let myProfile = renderSettingsIcon(name: "Item List/Icons/Profile", backgroundColors: [colorRed])
|
||||
|
||||
public static let winterGram = renderSettingsIcon(name: "Item List/Icons/WinterGram", backgroundColors: [colorLightBlue])
|
||||
|
||||
public static let birthday = renderSettingsIcon(name: "Item List/Icons/Cake", backgroundColors: [colorBlue])
|
||||
public static let aiTools = renderSettingsIcon(name: "Item List/Icons/AITools", backgroundColors: [colorPurple])
|
||||
public static let yourColor = renderSettingsIcon(name: "Item List/Icons/Brush", backgroundColors: [colorLightBlue])
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ swift_library(
|
|||
"//submodules/OverlayStatusController",
|
||||
"//submodules/UrlWhitelist",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/TelegramUIPreferences",
|
||||
"//submodules/TelegramUI/Components/AlertComponent",
|
||||
"//submodules/TelegramUI/Components/AlertComponent/AlertCheckComponent",
|
||||
"//submodules/TelegramUI/Components/AlertComponent/AlertWebpagePreviewComponent",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import AccountContext
|
|||
import OverlayStatusController
|
||||
import UrlWhitelist
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import AlertComponent
|
||||
import AlertCheckComponent
|
||||
import AlertWebpagePreviewComponent
|
||||
|
|
@ -111,7 +112,7 @@ public func openUserGeneratedUrl(
|
|||
}
|
||||
}
|
||||
|
||||
if concealed && !skipConcealedAlert {
|
||||
if concealed && !skipConcealedAlert && !currentWinterGramSettings.disableOpenLinkWarning {
|
||||
var rawDisplayUrl: String = parsedString
|
||||
let maxLength = 180
|
||||
if rawDisplayUrl.count > maxLength {
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ enum PeerInfoSettingsSection {
|
|||
case premiumManagement
|
||||
case stars
|
||||
case ton
|
||||
case winterGram
|
||||
}
|
||||
|
||||
enum PeerInfoReportType {
|
||||
|
|
|
|||
|
|
@ -217,15 +217,15 @@ extension PeerInfoScreenNode {
|
|||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
var maximumAvailableAccounts: Int = 3
|
||||
var maximumAvailableAccounts: Int = maximumNumberOfAccounts
|
||||
if accountAndPeer?.1.isPremium == true && !strongSelf.context.account.testingEnvironment {
|
||||
maximumAvailableAccounts = 4
|
||||
maximumAvailableAccounts = maximumPremiumNumberOfAccounts
|
||||
}
|
||||
var count: Int = 1
|
||||
for (accountContext, peer, _) in accountsAndPeers {
|
||||
if !accountContext.account.testingEnvironment {
|
||||
if peer.isPremium {
|
||||
maximumAvailableAccounts = 4
|
||||
maximumAvailableAccounts = maximumPremiumNumberOfAccounts
|
||||
}
|
||||
count += 1
|
||||
}
|
||||
|
|
@ -271,6 +271,8 @@ extension PeerInfoScreenNode {
|
|||
self.interaction.editingOpenNameColorSetup()
|
||||
case .powerSaving:
|
||||
push(energySavingSettingsScreen(context: self.context))
|
||||
case .winterGram:
|
||||
push(winterGramSettingsController(context: self.context))
|
||||
case .businessSetup:
|
||||
guard let controller = self.controller, !controller.presentAccountFrozenInfoIfNeeded() else {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import TelegramStringFormatting
|
|||
import PeerNameColorItem
|
||||
|
||||
enum SettingsSection: Int, CaseIterable {
|
||||
case winterGram
|
||||
case edit
|
||||
case phone
|
||||
case accounts
|
||||
|
|
@ -36,7 +37,11 @@ func settingsItems(data: PeerInfoScreenData?, context: AccountContext, presentat
|
|||
for section in SettingsSection.allCases {
|
||||
items[section] = []
|
||||
}
|
||||
|
||||
|
||||
items[.winterGram]!.append(PeerInfoScreenDisclosureItem(id: 0, text: "WinterGram", icon: PresentationResourcesSettings.winterGram, action: {
|
||||
interaction.openSettings(.winterGram)
|
||||
}))
|
||||
|
||||
let setPhotoTitle: String
|
||||
if let peer = data.peer, !peer.profileImageRepresentations.isEmpty {
|
||||
setPhotoTitle = presentationData.strings.Settings_ChangeProfilePhoto
|
||||
|
|
@ -239,7 +244,7 @@ func settingsItems(data: PeerInfoScreenData?, context: AccountContext, presentat
|
|||
items[.advanced]!.append(PeerInfoScreenDisclosureItem(id: 3, text: presentationData.strings.Settings_Appearance, icon: PresentationResourcesSettings.appearance, action: {
|
||||
interaction.openSettings(.appearance)
|
||||
}))
|
||||
|
||||
|
||||
items[.advanced]!.append(PeerInfoScreenDisclosureItem(id: 6, label: .text(data.isPowerSavingEnabled == true ? presentationData.strings.Settings_PowerSavingOn : presentationData.strings.Settings_PowerSavingOff), text: presentationData.strings.Settings_PowerSaving, icon: PresentationResourcesSettings.powerSaving, action: {
|
||||
interaction.openSettings(.powerSaving)
|
||||
}))
|
||||
|
|
|
|||
12
submodules/TelegramUI/Images.xcassets/Item List/Icons/WinterGram.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Item List/Icons/WinterGram.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "wintergram_snowball_30.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
submodules/TelegramUI/Images.xcassets/Item List/Icons/WinterGram.imageset/wintergram_snowball_30.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Item List/Icons/WinterGram.imageset/wintergram_snowball_30.pdf
vendored
Normal file
Binary file not shown.
|
|
@ -56,6 +56,17 @@ private let handleVoipNotifications = false
|
|||
|
||||
private var testIsLaunched = false
|
||||
|
||||
func normalizeWinterGramUrlScheme(_ url: URL) -> URL {
|
||||
guard let scheme = url.scheme, scheme.lowercased() == "wnt" else {
|
||||
return url
|
||||
}
|
||||
guard var components = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
|
||||
return url
|
||||
}
|
||||
components.scheme = "tg"
|
||||
return components.url ?? url
|
||||
}
|
||||
|
||||
private func isKeyboardWindow(window: NSObject) -> Bool {
|
||||
let typeName = NSStringFromClass(type(of: window))
|
||||
if #available(iOS 9.0, *) {
|
||||
|
|
@ -248,7 +259,8 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||
private let openNotificationSettingsWhenReadyDisposable = MetaDisposable()
|
||||
private let openChatWhenReadyDisposable = MetaDisposable()
|
||||
private let openUrlWhenReadyDisposable = MetaDisposable()
|
||||
|
||||
private let winterGramSettingsDisposable = MetaDisposable()
|
||||
|
||||
private let badgeDisposable = MetaDisposable()
|
||||
private let quickActionsDisposable = MetaDisposable()
|
||||
|
||||
|
|
@ -1191,6 +1203,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||
})
|
||||
let sharedApplicationContext = SharedApplicationContext(sharedContext: sharedContext, notificationManager: notificationManager, wakeupManager: wakeupManager)
|
||||
sharedApplicationContext.sharedContext.mediaManager.overlayMediaManager.attachOverlayMediaController(sharedApplicationContext.overlayMediaController)
|
||||
self.winterGramSettingsDisposable.set(observeWinterGramSettings(accountManager: accountManager))
|
||||
|
||||
return accountManager.transaction { transaction -> (SharedApplicationContext, LoggingSettings) in
|
||||
return (sharedApplicationContext, transaction.getSharedData(SharedDataKeys.loggingSettings)?.get(LoggingSettings.self) ?? LoggingSettings.defaultSettings)
|
||||
|
|
@ -1513,10 +1526,10 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||
})
|
||||
|
||||
if let url = launchOptions?[.url] {
|
||||
if let url = url as? URL, url.scheme == "tg" || url.scheme == buildConfig.appSpecificUrlScheme {
|
||||
self.openUrlWhenReady(url: url, external: true)
|
||||
} else if let urlString = url as? String, urlString.lowercased().hasPrefix("tg:") || urlString.lowercased().hasPrefix("\(buildConfig.appSpecificUrlScheme):"), let url = URL(string: urlString) {
|
||||
self.openUrlWhenReady(url: url, external: true)
|
||||
if let url = url as? URL, url.scheme == "tg" || url.scheme == "wnt" || url.scheme == buildConfig.appSpecificUrlScheme {
|
||||
self.openUrlWhenReady(url: normalizeWinterGramUrlScheme(url), external: true)
|
||||
} else if let urlString = url as? String, urlString.lowercased().hasPrefix("tg:") || urlString.lowercased().hasPrefix("wnt:") || urlString.lowercased().hasPrefix("\(buildConfig.appSpecificUrlScheme):"), let url = URL(string: urlString) {
|
||||
self.openUrlWhenReady(url: normalizeWinterGramUrlScheme(url), external: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2500,6 +2513,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||
}
|
||||
|
||||
private func openUrl(url: URL) {
|
||||
let url = normalizeWinterGramUrlScheme(url)
|
||||
let _ = (self.sharedContextPromise.get()
|
||||
|> take(1)
|
||||
|> mapToSignal { sharedApplicationContext -> Signal<(SharedAccountContextImpl, AuthorizedApplicationContext?, UnauthorizedApplicationContext?), NoError> in
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import TemporaryCachedPeerDataManager
|
|||
import Emoji
|
||||
import AccountContext
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import ChatHistoryEntry
|
||||
import ChatMessageItemCommon
|
||||
import TextFormat
|
||||
|
|
@ -687,7 +688,7 @@ func chatHistoryEntriesForView(
|
|||
}
|
||||
|
||||
if view.laterId == nil && !view.isLoading {
|
||||
if !entries.isEmpty, case let .MessageEntry(lastMessage, _, _, _, _, _) = entries[entries.count - 1], let message = adMessage {
|
||||
if !entries.isEmpty, !currentWinterGramSettings.disableAds, case let .MessageEntry(lastMessage, _, _, _, _, _) = entries[entries.count - 1], let message = adMessage {
|
||||
var nextAdMessageId: Int32 = 10000
|
||||
let updatedMessage = Message(
|
||||
stableId: ChatHistoryListNodeImpl.fixedAdMessageStableId,
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ private enum ApplicationSpecificSharedDataKeyValues: Int32 {
|
|||
case mediaDisplaySettings = 20
|
||||
case updateSettings = 21
|
||||
case chatSettings = 22
|
||||
case winterGramSettings = 23
|
||||
}
|
||||
|
||||
public struct ApplicationSpecificSharedDataKeys {
|
||||
|
|
@ -77,6 +78,7 @@ public struct ApplicationSpecificSharedDataKeys {
|
|||
public static let mediaDisplaySettings: EngineDataBuffer = applicationSpecificPreferencesKey(ApplicationSpecificSharedDataKeyValues.mediaDisplaySettings.rawValue)
|
||||
public static let updateSettings: EngineDataBuffer = applicationSpecificPreferencesKey(ApplicationSpecificSharedDataKeyValues.updateSettings.rawValue)
|
||||
public static let chatSettings: EngineDataBuffer = applicationSpecificPreferencesKey(ApplicationSpecificSharedDataKeyValues.chatSettings.rawValue)
|
||||
public static let winterGramSettings: EngineDataBuffer = applicationSpecificSharedDataKey(ApplicationSpecificSharedDataKeyValues.winterGramSettings.rawValue)
|
||||
}
|
||||
|
||||
private enum ApplicationSpecificItemCacheCollectionIdValues: Int8 {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,491 @@
|
|||
import Foundation
|
||||
import TelegramCore
|
||||
import SwiftSignalKit
|
||||
|
||||
public enum WinterGramSendWithoutSound: Int32, Codable {
|
||||
case never = 0
|
||||
case inGhostMode = 1
|
||||
case always = 2
|
||||
}
|
||||
|
||||
public enum WinterGramPeerIdDisplay: Int32, Codable {
|
||||
case hidden = 0
|
||||
case telegramApi = 1
|
||||
case botApi = 2
|
||||
}
|
||||
|
||||
public enum WinterGramTranslationProvider: Int32, Codable {
|
||||
case telegram = 0
|
||||
case google = 1
|
||||
case yandex = 2
|
||||
case system = 3
|
||||
}
|
||||
|
||||
public enum WinterGramWebviewPlatform: Int32, Codable {
|
||||
case auto = 0
|
||||
case ios = 1
|
||||
case android = 2
|
||||
case macos = 3
|
||||
case desktop = 4
|
||||
}
|
||||
|
||||
public enum WinterGramIconPack: Int32, Codable {
|
||||
case wintergram = 0
|
||||
case ayugram = 1
|
||||
case exteragram = 2
|
||||
case telegram = 3
|
||||
}
|
||||
|
||||
public struct WinterGramLiquidGlass: Codable, Equatable {
|
||||
public var enabled: Bool
|
||||
public var transparency: Double
|
||||
public var blurRadius: Double
|
||||
public var tintColor: Int32?
|
||||
public var vibrancy: Bool
|
||||
public var applyToChatList: Bool
|
||||
public var applyToBubbles: Bool
|
||||
public var applyToNavigationBars: Bool
|
||||
public var applyToTabBar: Bool
|
||||
|
||||
public static var defaultSettings: WinterGramLiquidGlass {
|
||||
return WinterGramLiquidGlass(
|
||||
enabled: true,
|
||||
transparency: 0.75,
|
||||
blurRadius: 30.0,
|
||||
tintColor: nil,
|
||||
vibrancy: true,
|
||||
applyToChatList: true,
|
||||
applyToBubbles: false,
|
||||
applyToNavigationBars: true,
|
||||
applyToTabBar: true
|
||||
)
|
||||
}
|
||||
|
||||
public init(
|
||||
enabled: Bool,
|
||||
transparency: Double,
|
||||
blurRadius: Double,
|
||||
tintColor: Int32?,
|
||||
vibrancy: Bool,
|
||||
applyToChatList: Bool,
|
||||
applyToBubbles: Bool,
|
||||
applyToNavigationBars: Bool,
|
||||
applyToTabBar: Bool
|
||||
) {
|
||||
self.enabled = enabled
|
||||
self.transparency = transparency
|
||||
self.blurRadius = blurRadius
|
||||
self.tintColor = tintColor
|
||||
self.vibrancy = vibrancy
|
||||
self.applyToChatList = applyToChatList
|
||||
self.applyToBubbles = applyToBubbles
|
||||
self.applyToNavigationBars = applyToNavigationBars
|
||||
self.applyToTabBar = applyToTabBar
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||
self.enabled = try container.decodeIfPresent(Bool.self, forKey: "enabled") ?? true
|
||||
self.transparency = try container.decodeIfPresent(Double.self, forKey: "transparency") ?? 0.75
|
||||
self.blurRadius = try container.decodeIfPresent(Double.self, forKey: "blurRadius") ?? 30.0
|
||||
self.tintColor = try container.decodeIfPresent(Int32.self, forKey: "tintColor")
|
||||
self.vibrancy = try container.decodeIfPresent(Bool.self, forKey: "vibrancy") ?? true
|
||||
self.applyToChatList = try container.decodeIfPresent(Bool.self, forKey: "applyToChatList") ?? true
|
||||
self.applyToBubbles = try container.decodeIfPresent(Bool.self, forKey: "applyToBubbles") ?? false
|
||||
self.applyToNavigationBars = try container.decodeIfPresent(Bool.self, forKey: "applyToNavigationBars") ?? true
|
||||
self.applyToTabBar = try container.decodeIfPresent(Bool.self, forKey: "applyToTabBar") ?? true
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||
try container.encode(self.enabled, forKey: "enabled")
|
||||
try container.encode(self.transparency, forKey: "transparency")
|
||||
try container.encode(self.blurRadius, forKey: "blurRadius")
|
||||
try container.encodeIfPresent(self.tintColor, forKey: "tintColor")
|
||||
try container.encode(self.vibrancy, forKey: "vibrancy")
|
||||
try container.encode(self.applyToChatList, forKey: "applyToChatList")
|
||||
try container.encode(self.applyToBubbles, forKey: "applyToBubbles")
|
||||
try container.encode(self.applyToNavigationBars, forKey: "applyToNavigationBars")
|
||||
try container.encode(self.applyToTabBar, forKey: "applyToTabBar")
|
||||
}
|
||||
}
|
||||
|
||||
public struct WinterGramSettings: Codable, Equatable {
|
||||
// Ghost mode & privacy
|
||||
public var ghostModeEnabled: Bool
|
||||
public var sendReadReceipts: Bool
|
||||
public var sendReadStories: Bool
|
||||
public var sendOnlineStatus: Bool
|
||||
public var sendUploadProgress: Bool
|
||||
public var sendOfflineAfterOnline: Bool
|
||||
public var markReadAfterAction: Bool
|
||||
public var useScheduledMessages: Bool
|
||||
public var sendWithoutSound: WinterGramSendWithoutSound
|
||||
public var suggestGhostBeforeStory: Bool
|
||||
|
||||
// Local history
|
||||
public var saveDeletedMessages: Bool
|
||||
public var saveMessagesHistory: Bool
|
||||
public var saveForBots: Bool
|
||||
public var hideFromBlocked: Bool
|
||||
public var semiTransparentDeletedMessages: Bool
|
||||
|
||||
// Hidden archive ("ААрхив")
|
||||
public var stashedPeerIds: [Int64]
|
||||
public var stashMuteNotifications: Bool
|
||||
public var stashAutoMarkRead: Bool
|
||||
|
||||
// Anti-features
|
||||
public var disableAds: Bool
|
||||
public var localPremium: Bool
|
||||
public var shadowBanIds: [Int64]
|
||||
public var disableStories: Bool
|
||||
public var hidePremiumStatuses: Bool
|
||||
public var disableOpenLinkWarning: Bool
|
||||
|
||||
// Confirmations
|
||||
public var stickerConfirmation: Bool
|
||||
public var gifConfirmation: Bool
|
||||
public var voiceConfirmation: Bool
|
||||
|
||||
// Message decorations
|
||||
public var showMessageSeconds: Bool
|
||||
public var showPeerId: WinterGramPeerIdDisplay
|
||||
public var deletedMark: String
|
||||
public var editedMark: String
|
||||
public var recentStickersCount: Int32
|
||||
|
||||
// Translation
|
||||
public var translateMessages: Bool
|
||||
public var translationProvider: WinterGramTranslationProvider
|
||||
|
||||
// Webview / platform spoofing
|
||||
public var webviewSpoofPlatform: WinterGramWebviewPlatform
|
||||
public var increaseWebviewHeight: Bool
|
||||
|
||||
// Appearance & customization
|
||||
public var liquidGlass: WinterGramLiquidGlass
|
||||
public var materialDesign: Bool
|
||||
public var avatarCornerRadius: Int32
|
||||
public var singleCornerRadius: Bool
|
||||
public var messageBubbleRadius: Int32
|
||||
public var removeMessageTail: Bool
|
||||
public var customFont: String?
|
||||
public var monoFont: String?
|
||||
public var appIcon: String
|
||||
public var iconPack: WinterGramIconPack
|
||||
public var showOnlyAddedEmojisAndStickers: Bool
|
||||
|
||||
public static var defaultSettings: WinterGramSettings {
|
||||
return WinterGramSettings(
|
||||
ghostModeEnabled: false,
|
||||
sendReadReceipts: true,
|
||||
sendReadStories: true,
|
||||
sendOnlineStatus: true,
|
||||
sendUploadProgress: true,
|
||||
sendOfflineAfterOnline: false,
|
||||
markReadAfterAction: true,
|
||||
useScheduledMessages: false,
|
||||
sendWithoutSound: .never,
|
||||
suggestGhostBeforeStory: true,
|
||||
saveDeletedMessages: true,
|
||||
saveMessagesHistory: true,
|
||||
saveForBots: false,
|
||||
hideFromBlocked: false,
|
||||
semiTransparentDeletedMessages: false,
|
||||
stashedPeerIds: [],
|
||||
stashMuteNotifications: true,
|
||||
stashAutoMarkRead: false,
|
||||
disableAds: true,
|
||||
localPremium: false,
|
||||
shadowBanIds: [],
|
||||
disableStories: false,
|
||||
hidePremiumStatuses: false,
|
||||
disableOpenLinkWarning: false,
|
||||
stickerConfirmation: false,
|
||||
gifConfirmation: false,
|
||||
voiceConfirmation: false,
|
||||
showMessageSeconds: false,
|
||||
showPeerId: .botApi,
|
||||
deletedMark: "🧹",
|
||||
editedMark: "",
|
||||
recentStickersCount: 100,
|
||||
translateMessages: false,
|
||||
translationProvider: .telegram,
|
||||
webviewSpoofPlatform: .auto,
|
||||
increaseWebviewHeight: false,
|
||||
liquidGlass: .defaultSettings,
|
||||
materialDesign: true,
|
||||
avatarCornerRadius: 50,
|
||||
singleCornerRadius: false,
|
||||
messageBubbleRadius: 16,
|
||||
removeMessageTail: false,
|
||||
customFont: nil,
|
||||
monoFont: nil,
|
||||
appIcon: "WinterGramDark",
|
||||
iconPack: .wintergram,
|
||||
showOnlyAddedEmojisAndStickers: false
|
||||
)
|
||||
}
|
||||
|
||||
public init(
|
||||
ghostModeEnabled: Bool,
|
||||
sendReadReceipts: Bool,
|
||||
sendReadStories: Bool,
|
||||
sendOnlineStatus: Bool,
|
||||
sendUploadProgress: Bool,
|
||||
sendOfflineAfterOnline: Bool,
|
||||
markReadAfterAction: Bool,
|
||||
useScheduledMessages: Bool,
|
||||
sendWithoutSound: WinterGramSendWithoutSound,
|
||||
suggestGhostBeforeStory: Bool,
|
||||
saveDeletedMessages: Bool,
|
||||
saveMessagesHistory: Bool,
|
||||
saveForBots: Bool,
|
||||
hideFromBlocked: Bool,
|
||||
semiTransparentDeletedMessages: Bool,
|
||||
stashedPeerIds: [Int64],
|
||||
stashMuteNotifications: Bool,
|
||||
stashAutoMarkRead: Bool,
|
||||
disableAds: Bool,
|
||||
localPremium: Bool,
|
||||
shadowBanIds: [Int64],
|
||||
disableStories: Bool,
|
||||
hidePremiumStatuses: Bool,
|
||||
disableOpenLinkWarning: Bool,
|
||||
stickerConfirmation: Bool,
|
||||
gifConfirmation: Bool,
|
||||
voiceConfirmation: Bool,
|
||||
showMessageSeconds: Bool,
|
||||
showPeerId: WinterGramPeerIdDisplay,
|
||||
deletedMark: String,
|
||||
editedMark: String,
|
||||
recentStickersCount: Int32,
|
||||
translateMessages: Bool,
|
||||
translationProvider: WinterGramTranslationProvider,
|
||||
webviewSpoofPlatform: WinterGramWebviewPlatform,
|
||||
increaseWebviewHeight: Bool,
|
||||
liquidGlass: WinterGramLiquidGlass,
|
||||
materialDesign: Bool,
|
||||
avatarCornerRadius: Int32,
|
||||
singleCornerRadius: Bool,
|
||||
messageBubbleRadius: Int32,
|
||||
removeMessageTail: Bool,
|
||||
customFont: String?,
|
||||
monoFont: String?,
|
||||
appIcon: String,
|
||||
iconPack: WinterGramIconPack,
|
||||
showOnlyAddedEmojisAndStickers: Bool
|
||||
) {
|
||||
self.ghostModeEnabled = ghostModeEnabled
|
||||
self.sendReadReceipts = sendReadReceipts
|
||||
self.sendReadStories = sendReadStories
|
||||
self.sendOnlineStatus = sendOnlineStatus
|
||||
self.sendUploadProgress = sendUploadProgress
|
||||
self.sendOfflineAfterOnline = sendOfflineAfterOnline
|
||||
self.markReadAfterAction = markReadAfterAction
|
||||
self.useScheduledMessages = useScheduledMessages
|
||||
self.sendWithoutSound = sendWithoutSound
|
||||
self.suggestGhostBeforeStory = suggestGhostBeforeStory
|
||||
self.saveDeletedMessages = saveDeletedMessages
|
||||
self.saveMessagesHistory = saveMessagesHistory
|
||||
self.saveForBots = saveForBots
|
||||
self.hideFromBlocked = hideFromBlocked
|
||||
self.semiTransparentDeletedMessages = semiTransparentDeletedMessages
|
||||
self.stashedPeerIds = stashedPeerIds
|
||||
self.stashMuteNotifications = stashMuteNotifications
|
||||
self.stashAutoMarkRead = stashAutoMarkRead
|
||||
self.disableAds = disableAds
|
||||
self.localPremium = localPremium
|
||||
self.shadowBanIds = shadowBanIds
|
||||
self.disableStories = disableStories
|
||||
self.hidePremiumStatuses = hidePremiumStatuses
|
||||
self.disableOpenLinkWarning = disableOpenLinkWarning
|
||||
self.stickerConfirmation = stickerConfirmation
|
||||
self.gifConfirmation = gifConfirmation
|
||||
self.voiceConfirmation = voiceConfirmation
|
||||
self.showMessageSeconds = showMessageSeconds
|
||||
self.showPeerId = showPeerId
|
||||
self.deletedMark = deletedMark
|
||||
self.editedMark = editedMark
|
||||
self.recentStickersCount = recentStickersCount
|
||||
self.translateMessages = translateMessages
|
||||
self.translationProvider = translationProvider
|
||||
self.webviewSpoofPlatform = webviewSpoofPlatform
|
||||
self.increaseWebviewHeight = increaseWebviewHeight
|
||||
self.liquidGlass = liquidGlass
|
||||
self.materialDesign = materialDesign
|
||||
self.avatarCornerRadius = avatarCornerRadius
|
||||
self.singleCornerRadius = singleCornerRadius
|
||||
self.messageBubbleRadius = messageBubbleRadius
|
||||
self.removeMessageTail = removeMessageTail
|
||||
self.customFont = customFont
|
||||
self.monoFont = monoFont
|
||||
self.appIcon = appIcon
|
||||
self.iconPack = iconPack
|
||||
self.showOnlyAddedEmojisAndStickers = showOnlyAddedEmojisAndStickers
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||
let defaults = WinterGramSettings.defaultSettings
|
||||
|
||||
self.ghostModeEnabled = try container.decodeIfPresent(Bool.self, forKey: "ghostModeEnabled") ?? defaults.ghostModeEnabled
|
||||
self.sendReadReceipts = try container.decodeIfPresent(Bool.self, forKey: "sendReadReceipts") ?? defaults.sendReadReceipts
|
||||
self.sendReadStories = try container.decodeIfPresent(Bool.self, forKey: "sendReadStories") ?? defaults.sendReadStories
|
||||
self.sendOnlineStatus = try container.decodeIfPresent(Bool.self, forKey: "sendOnlineStatus") ?? defaults.sendOnlineStatus
|
||||
self.sendUploadProgress = try container.decodeIfPresent(Bool.self, forKey: "sendUploadProgress") ?? defaults.sendUploadProgress
|
||||
self.sendOfflineAfterOnline = try container.decodeIfPresent(Bool.self, forKey: "sendOfflineAfterOnline") ?? defaults.sendOfflineAfterOnline
|
||||
self.markReadAfterAction = try container.decodeIfPresent(Bool.self, forKey: "markReadAfterAction") ?? defaults.markReadAfterAction
|
||||
self.useScheduledMessages = try container.decodeIfPresent(Bool.self, forKey: "useScheduledMessages") ?? defaults.useScheduledMessages
|
||||
self.sendWithoutSound = try container.decodeIfPresent(WinterGramSendWithoutSound.self, forKey: "sendWithoutSound") ?? defaults.sendWithoutSound
|
||||
self.suggestGhostBeforeStory = try container.decodeIfPresent(Bool.self, forKey: "suggestGhostBeforeStory") ?? defaults.suggestGhostBeforeStory
|
||||
self.saveDeletedMessages = try container.decodeIfPresent(Bool.self, forKey: "saveDeletedMessages") ?? defaults.saveDeletedMessages
|
||||
self.saveMessagesHistory = try container.decodeIfPresent(Bool.self, forKey: "saveMessagesHistory") ?? defaults.saveMessagesHistory
|
||||
self.saveForBots = try container.decodeIfPresent(Bool.self, forKey: "saveForBots") ?? defaults.saveForBots
|
||||
self.hideFromBlocked = try container.decodeIfPresent(Bool.self, forKey: "hideFromBlocked") ?? defaults.hideFromBlocked
|
||||
self.semiTransparentDeletedMessages = try container.decodeIfPresent(Bool.self, forKey: "semiTransparentDeletedMessages") ?? defaults.semiTransparentDeletedMessages
|
||||
self.stashedPeerIds = try container.decodeIfPresent([Int64].self, forKey: "stashedPeerIds") ?? defaults.stashedPeerIds
|
||||
self.stashMuteNotifications = try container.decodeIfPresent(Bool.self, forKey: "stashMuteNotifications") ?? defaults.stashMuteNotifications
|
||||
self.stashAutoMarkRead = try container.decodeIfPresent(Bool.self, forKey: "stashAutoMarkRead") ?? defaults.stashAutoMarkRead
|
||||
self.disableAds = try container.decodeIfPresent(Bool.self, forKey: "disableAds") ?? defaults.disableAds
|
||||
self.localPremium = try container.decodeIfPresent(Bool.self, forKey: "localPremium") ?? defaults.localPremium
|
||||
self.shadowBanIds = try container.decodeIfPresent([Int64].self, forKey: "shadowBanIds") ?? defaults.shadowBanIds
|
||||
self.disableStories = try container.decodeIfPresent(Bool.self, forKey: "disableStories") ?? defaults.disableStories
|
||||
self.hidePremiumStatuses = try container.decodeIfPresent(Bool.self, forKey: "hidePremiumStatuses") ?? defaults.hidePremiumStatuses
|
||||
self.disableOpenLinkWarning = try container.decodeIfPresent(Bool.self, forKey: "disableOpenLinkWarning") ?? defaults.disableOpenLinkWarning
|
||||
self.stickerConfirmation = try container.decodeIfPresent(Bool.self, forKey: "stickerConfirmation") ?? defaults.stickerConfirmation
|
||||
self.gifConfirmation = try container.decodeIfPresent(Bool.self, forKey: "gifConfirmation") ?? defaults.gifConfirmation
|
||||
self.voiceConfirmation = try container.decodeIfPresent(Bool.self, forKey: "voiceConfirmation") ?? defaults.voiceConfirmation
|
||||
self.showMessageSeconds = try container.decodeIfPresent(Bool.self, forKey: "showMessageSeconds") ?? defaults.showMessageSeconds
|
||||
self.showPeerId = try container.decodeIfPresent(WinterGramPeerIdDisplay.self, forKey: "showPeerId") ?? defaults.showPeerId
|
||||
self.deletedMark = try container.decodeIfPresent(String.self, forKey: "deletedMark") ?? defaults.deletedMark
|
||||
self.editedMark = try container.decodeIfPresent(String.self, forKey: "editedMark") ?? defaults.editedMark
|
||||
self.recentStickersCount = try container.decodeIfPresent(Int32.self, forKey: "recentStickersCount") ?? defaults.recentStickersCount
|
||||
self.translateMessages = try container.decodeIfPresent(Bool.self, forKey: "translateMessages") ?? defaults.translateMessages
|
||||
self.translationProvider = try container.decodeIfPresent(WinterGramTranslationProvider.self, forKey: "translationProvider") ?? defaults.translationProvider
|
||||
self.webviewSpoofPlatform = try container.decodeIfPresent(WinterGramWebviewPlatform.self, forKey: "webviewSpoofPlatform") ?? defaults.webviewSpoofPlatform
|
||||
self.increaseWebviewHeight = try container.decodeIfPresent(Bool.self, forKey: "increaseWebviewHeight") ?? defaults.increaseWebviewHeight
|
||||
self.liquidGlass = try container.decodeIfPresent(WinterGramLiquidGlass.self, forKey: "liquidGlass") ?? defaults.liquidGlass
|
||||
self.materialDesign = try container.decodeIfPresent(Bool.self, forKey: "materialDesign") ?? defaults.materialDesign
|
||||
self.avatarCornerRadius = try container.decodeIfPresent(Int32.self, forKey: "avatarCornerRadius") ?? defaults.avatarCornerRadius
|
||||
self.singleCornerRadius = try container.decodeIfPresent(Bool.self, forKey: "singleCornerRadius") ?? defaults.singleCornerRadius
|
||||
self.messageBubbleRadius = try container.decodeIfPresent(Int32.self, forKey: "messageBubbleRadius") ?? defaults.messageBubbleRadius
|
||||
self.removeMessageTail = try container.decodeIfPresent(Bool.self, forKey: "removeMessageTail") ?? defaults.removeMessageTail
|
||||
self.customFont = try container.decodeIfPresent(String.self, forKey: "customFont")
|
||||
self.monoFont = try container.decodeIfPresent(String.self, forKey: "monoFont")
|
||||
self.appIcon = try container.decodeIfPresent(String.self, forKey: "appIcon") ?? defaults.appIcon
|
||||
self.iconPack = try container.decodeIfPresent(WinterGramIconPack.self, forKey: "iconPack") ?? defaults.iconPack
|
||||
self.showOnlyAddedEmojisAndStickers = try container.decodeIfPresent(Bool.self, forKey: "showOnlyAddedEmojisAndStickers") ?? defaults.showOnlyAddedEmojisAndStickers
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||
try container.encode(self.ghostModeEnabled, forKey: "ghostModeEnabled")
|
||||
try container.encode(self.sendReadReceipts, forKey: "sendReadReceipts")
|
||||
try container.encode(self.sendReadStories, forKey: "sendReadStories")
|
||||
try container.encode(self.sendOnlineStatus, forKey: "sendOnlineStatus")
|
||||
try container.encode(self.sendUploadProgress, forKey: "sendUploadProgress")
|
||||
try container.encode(self.sendOfflineAfterOnline, forKey: "sendOfflineAfterOnline")
|
||||
try container.encode(self.markReadAfterAction, forKey: "markReadAfterAction")
|
||||
try container.encode(self.useScheduledMessages, forKey: "useScheduledMessages")
|
||||
try container.encode(self.sendWithoutSound, forKey: "sendWithoutSound")
|
||||
try container.encode(self.suggestGhostBeforeStory, forKey: "suggestGhostBeforeStory")
|
||||
try container.encode(self.saveDeletedMessages, forKey: "saveDeletedMessages")
|
||||
try container.encode(self.saveMessagesHistory, forKey: "saveMessagesHistory")
|
||||
try container.encode(self.saveForBots, forKey: "saveForBots")
|
||||
try container.encode(self.hideFromBlocked, forKey: "hideFromBlocked")
|
||||
try container.encode(self.semiTransparentDeletedMessages, forKey: "semiTransparentDeletedMessages")
|
||||
try container.encode(self.stashedPeerIds, forKey: "stashedPeerIds")
|
||||
try container.encode(self.stashMuteNotifications, forKey: "stashMuteNotifications")
|
||||
try container.encode(self.stashAutoMarkRead, forKey: "stashAutoMarkRead")
|
||||
try container.encode(self.disableAds, forKey: "disableAds")
|
||||
try container.encode(self.localPremium, forKey: "localPremium")
|
||||
try container.encode(self.shadowBanIds, forKey: "shadowBanIds")
|
||||
try container.encode(self.disableStories, forKey: "disableStories")
|
||||
try container.encode(self.hidePremiumStatuses, forKey: "hidePremiumStatuses")
|
||||
try container.encode(self.disableOpenLinkWarning, forKey: "disableOpenLinkWarning")
|
||||
try container.encode(self.stickerConfirmation, forKey: "stickerConfirmation")
|
||||
try container.encode(self.gifConfirmation, forKey: "gifConfirmation")
|
||||
try container.encode(self.voiceConfirmation, forKey: "voiceConfirmation")
|
||||
try container.encode(self.showMessageSeconds, forKey: "showMessageSeconds")
|
||||
try container.encode(self.showPeerId, forKey: "showPeerId")
|
||||
try container.encode(self.deletedMark, forKey: "deletedMark")
|
||||
try container.encode(self.editedMark, forKey: "editedMark")
|
||||
try container.encode(self.recentStickersCount, forKey: "recentStickersCount")
|
||||
try container.encode(self.translateMessages, forKey: "translateMessages")
|
||||
try container.encode(self.translationProvider, forKey: "translationProvider")
|
||||
try container.encode(self.webviewSpoofPlatform, forKey: "webviewSpoofPlatform")
|
||||
try container.encode(self.increaseWebviewHeight, forKey: "increaseWebviewHeight")
|
||||
try container.encode(self.liquidGlass, forKey: "liquidGlass")
|
||||
try container.encode(self.materialDesign, forKey: "materialDesign")
|
||||
try container.encode(self.avatarCornerRadius, forKey: "avatarCornerRadius")
|
||||
try container.encode(self.singleCornerRadius, forKey: "singleCornerRadius")
|
||||
try container.encode(self.messageBubbleRadius, forKey: "messageBubbleRadius")
|
||||
try container.encode(self.removeMessageTail, forKey: "removeMessageTail")
|
||||
try container.encodeIfPresent(self.customFont, forKey: "customFont")
|
||||
try container.encodeIfPresent(self.monoFont, forKey: "monoFont")
|
||||
try container.encode(self.appIcon, forKey: "appIcon")
|
||||
try container.encode(self.iconPack, forKey: "iconPack")
|
||||
try container.encode(self.showOnlyAddedEmojisAndStickers, forKey: "showOnlyAddedEmojisAndStickers")
|
||||
}
|
||||
|
||||
public func isShadowBanned(_ peerId: Int64) -> Bool {
|
||||
return self.shadowBanIds.contains(peerId)
|
||||
}
|
||||
|
||||
public func isStashed(_ peerId: Int64) -> Bool {
|
||||
return self.stashedPeerIds.contains(peerId)
|
||||
}
|
||||
|
||||
public var shouldSendWithoutSound: Bool {
|
||||
switch self.sendWithoutSound {
|
||||
case .never:
|
||||
return false
|
||||
case .inGhostMode:
|
||||
return self.ghostModeEnabled
|
||||
case .always:
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func updateWinterGramSettingsInteractively(accountManager: AccountManager<TelegramAccountManagerTypes>, _ f: @escaping (WinterGramSettings) -> WinterGramSettings) -> Signal<Void, NoError> {
|
||||
return accountManager.transaction { transaction -> Void in
|
||||
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.winterGramSettings, { entry in
|
||||
let currentSettings: WinterGramSettings
|
||||
if let entry = entry?.get(WinterGramSettings.self) {
|
||||
currentSettings = entry
|
||||
} else {
|
||||
currentSettings = .defaultSettings
|
||||
}
|
||||
return SharedPreferencesEntry(f(currentSettings))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public func winterGramSettings(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<WinterGramSettings, NoError> {
|
||||
return accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.winterGramSettings])
|
||||
|> map { sharedData -> WinterGramSettings in
|
||||
return sharedData.entries[ApplicationSpecificSharedDataKeys.winterGramSettings]?.get(WinterGramSettings.self) ?? .defaultSettings
|
||||
}
|
||||
}
|
||||
|
||||
private let currentWinterGramSettingsValue = Atomic<WinterGramSettings>(value: .defaultSettings)
|
||||
|
||||
// Synchronous snapshot of the latest settings, for hook points that cannot subscribe to a Signal.
|
||||
// Kept up to date by observeWinterGramSettings(accountManager:) at app startup.
|
||||
public var currentWinterGramSettings: WinterGramSettings {
|
||||
return currentWinterGramSettingsValue.with { $0 }
|
||||
}
|
||||
|
||||
public func setCurrentWinterGramSettings(_ settings: WinterGramSettings) {
|
||||
let _ = currentWinterGramSettingsValue.swap(settings)
|
||||
}
|
||||
|
||||
public func observeWinterGramSettings(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Disposable {
|
||||
return (winterGramSettings(accountManager: accountManager)
|
||||
|> deliverOnMainQueue).start(next: { settings in
|
||||
setCurrentWinterGramSettings(settings)
|
||||
})
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue