mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-08 17:53:38 +00:00
Stories
This commit is contained in:
parent
cf0cfb5c1e
commit
e5d948d90a
@ -9366,3 +9366,8 @@ Sorry for the inconvenience.";
|
|||||||
"Paint.Flip" = "Flip";
|
"Paint.Flip" = "Flip";
|
||||||
|
|
||||||
"Message.ForwardedStoryShort" = "Forwarded Story\nFrom: %@";
|
"Message.ForwardedStoryShort" = "Forwarded Story\nFrom: %@";
|
||||||
|
|
||||||
|
"Conversation.StoryForwardTooltip.Chat.One" = "Story forwarded to **%@**";
|
||||||
|
"Conversation.StoryForwardTooltip.TwoChats.One" = "Story forwarded to to **%@** and **%@**";
|
||||||
|
"Conversation.StoryForwardTooltip.ManyChats.One" = "Story forwarded to to **%@** and %@ others";
|
||||||
|
"Conversation.StoryForwardTooltip.SavedMessages.One" = "Story forwarded to to **Saved Messages**";
|
||||||
|
|||||||
@ -723,6 +723,19 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
|||||||
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: threadId, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: threadId, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let updatePeerStoryNotifications: (PeerId, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = { peerId, storyNotifications in
|
||||||
|
var isMuted: Bool?
|
||||||
|
switch storyNotifications {
|
||||||
|
case .default:
|
||||||
|
isMuted = nil
|
||||||
|
case .show:
|
||||||
|
isMuted = false
|
||||||
|
case .hide:
|
||||||
|
isMuted = true
|
||||||
|
}
|
||||||
|
return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, isMuted: isMuted) |> deliverOnMainQueue
|
||||||
|
}
|
||||||
|
|
||||||
let defaultSound: PeerMessageSound
|
let defaultSound: PeerMessageSound
|
||||||
|
|
||||||
if case .broadcast = channel.info {
|
if case .broadcast = channel.info {
|
||||||
@ -756,6 +769,9 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
|||||||
|> deliverOnMainQueue).start(next: { _ in
|
|> deliverOnMainQueue).start(next: { _ in
|
||||||
|
|
||||||
})
|
})
|
||||||
|
}, updatePeerStoryNotifications: { peerId, storyNotifications in
|
||||||
|
let _ = (updatePeerStoryNotifications(peerId, storyNotifications)
|
||||||
|
|> deliverOnMainQueue).start()
|
||||||
}, removePeerFromExceptions: {
|
}, removePeerFromExceptions: {
|
||||||
}, modifiedPeer: {
|
}, modifiedPeer: {
|
||||||
})
|
})
|
||||||
|
|||||||
@ -341,6 +341,10 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
}
|
}
|
||||||
strongSelf.selectTab(id: targetTab)
|
strongSelf.selectTab(id: targetTab)
|
||||||
} else {
|
} else {
|
||||||
|
if let componentView = strongSelf.chatListHeaderView(), let storyPeerListView = componentView.storyPeerListView() {
|
||||||
|
storyPeerListView.scrollToTop()
|
||||||
|
}
|
||||||
|
|
||||||
strongSelf.chatListDisplayNode.willScrollToTop()
|
strongSelf.chatListDisplayNode.willScrollToTop()
|
||||||
if let inlineStackContainerNode = strongSelf.chatListDisplayNode.inlineStackContainerNode {
|
if let inlineStackContainerNode = strongSelf.chatListDisplayNode.inlineStackContainerNode {
|
||||||
inlineStackContainerNode.currentItemNode.scrollToPosition(.top)
|
inlineStackContainerNode.currentItemNode.scrollToPosition(.top)
|
||||||
@ -1726,12 +1730,37 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
self.displayNodeDidLoad()
|
self.displayNodeDidLoad()
|
||||||
|
|
||||||
if case .chatList(.root) = self.location {
|
if case .chatList(.root) = self.location {
|
||||||
self.preloadStorySubscriptionsDisposable = (self.context.engine.messages.preloadStorySubscriptions(includeHidden: false)
|
let automaticDownloadNetworkType = context.account.networkType
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] resources in
|
|> map { type -> MediaAutoDownloadNetworkType in
|
||||||
|
switch type {
|
||||||
|
case .none, .wifi:
|
||||||
|
return .wifi
|
||||||
|
case .cellular:
|
||||||
|
return .cellular
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
|
||||||
|
self.preloadStorySubscriptionsDisposable = (combineLatest(queue: .mainQueue(),
|
||||||
|
self.context.engine.messages.preloadStorySubscriptions(includeHidden: false),
|
||||||
|
self.context.sharedContext.automaticMediaDownloadSettings,
|
||||||
|
automaticDownloadNetworkType
|
||||||
|
)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] resources, automaticMediaDownloadSettings, automaticDownloadNetworkType in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var autodownloadEnabled = true
|
||||||
|
if !shouldDownloadMediaAutomatically(settings: automaticMediaDownloadSettings, peerType: .contact, networkType: automaticDownloadNetworkType, authorPeerId: nil, contactsPeerIds: [], media: nil) {
|
||||||
|
autodownloadEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
var resources = resources
|
||||||
|
if !autodownloadEnabled {
|
||||||
|
resources.removeAll()
|
||||||
|
}
|
||||||
|
|
||||||
var validIds: [MediaResourceId] = []
|
var validIds: [MediaResourceId] = []
|
||||||
for (_, info) in resources.sorted(by: { $0.value.priority < $1.value.priority }) {
|
for (_, info) in resources.sorted(by: { $0.value.priority < $1.value.priority }) {
|
||||||
let resource = info.resource
|
let resource = info.resource
|
||||||
|
|||||||
@ -2011,6 +2011,11 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
targetView.layer.removeAnimation(forKey: "opacity")
|
targetView.layer.removeAnimation(forKey: "opacity")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strongSelf.hapticFeedback == nil {
|
||||||
|
strongSelf.hapticFeedback = HapticFeedback()
|
||||||
|
}
|
||||||
|
strongSelf.hapticFeedback?.tap()
|
||||||
|
|
||||||
guard let targetView = targetView as? ReactionIconView else {
|
guard let targetView = targetView as? ReactionIconView else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -2024,11 +2029,6 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
itemNode.frame = selfTargetBounds
|
itemNode.frame = selfTargetBounds
|
||||||
}
|
}
|
||||||
|
|
||||||
if strongSelf.hapticFeedback == nil {
|
|
||||||
strongSelf.hapticFeedback = HapticFeedback()
|
|
||||||
}
|
|
||||||
strongSelf.hapticFeedback?.tap()
|
|
||||||
|
|
||||||
if switchToInlineImmediately {
|
if switchToInlineImmediately {
|
||||||
mainAnimationCompleted = true
|
mainAnimationCompleted = true
|
||||||
intermediateCompletion()
|
intermediateCompletion()
|
||||||
|
|||||||
@ -62,6 +62,10 @@ private final class NotificationExceptionState : Equatable {
|
|||||||
return NotificationExceptionState(mode: mode.withUpdatedPeerDisplayPreviews(peer, displayPreviews), isSearchMode: isSearchMode, revealedPeerId: self.revealedPeerId, editing: self.editing)
|
return NotificationExceptionState(mode: mode.withUpdatedPeerDisplayPreviews(peer, displayPreviews), isSearchMode: isSearchMode, revealedPeerId: self.revealedPeerId, editing: self.editing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withUpdatedPeerStoryNotifications(_ peer: EnginePeer, _ storyNotifications: PeerNotificationDisplayPreviews) -> NotificationExceptionState {
|
||||||
|
return NotificationExceptionState(mode: mode.withUpdatedPeerStoryNotifications(peer, storyNotifications), isSearchMode: isSearchMode, revealedPeerId: self.revealedPeerId, editing: self.editing)
|
||||||
|
}
|
||||||
|
|
||||||
static func == (lhs: NotificationExceptionState, rhs: NotificationExceptionState) -> Bool {
|
static func == (lhs: NotificationExceptionState, rhs: NotificationExceptionState) -> Bool {
|
||||||
return lhs.mode == rhs.mode && lhs.isSearchMode == rhs.isSearchMode && lhs.revealedPeerId == rhs.revealedPeerId && lhs.editing == rhs.editing
|
return lhs.mode == rhs.mode && lhs.isSearchMode == rhs.isSearchMode && lhs.revealedPeerId == rhs.revealedPeerId && lhs.editing == rhs.editing
|
||||||
}
|
}
|
||||||
@ -573,6 +577,19 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
|||||||
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: nil, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: nil, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let updatePeerStoryNotifications: (PeerId, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = { peerId, storyNotifications in
|
||||||
|
var isMuted: Bool?
|
||||||
|
switch storyNotifications {
|
||||||
|
case .default:
|
||||||
|
isMuted = nil
|
||||||
|
case .show:
|
||||||
|
isMuted = false
|
||||||
|
case .hide:
|
||||||
|
isMuted = true
|
||||||
|
}
|
||||||
|
return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, isMuted: isMuted) |> deliverOnMainQueue
|
||||||
|
}
|
||||||
|
|
||||||
self.backgroundColor = presentationData.theme.list.blocksBackgroundColor
|
self.backgroundColor = presentationData.theme.list.blocksBackgroundColor
|
||||||
self.addSubnode(self.listNode)
|
self.addSubnode(self.listNode)
|
||||||
|
|
||||||
@ -642,6 +659,16 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
updateNotificationsView({})
|
updateNotificationsView({})
|
||||||
})
|
})
|
||||||
|
}, updatePeerStoryNotifications: { peerId, displayPreviews in
|
||||||
|
updateNotificationsDisposable.set(nil)
|
||||||
|
_ = combineLatest(updatePeerStoryNotifications(peerId, displayPreviews), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
|
||||||
|
if let peer = peer {
|
||||||
|
updateState { value in
|
||||||
|
return value.withUpdatedPeerStoryNotifications(peer, displayPreviews)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateNotificationsView({})
|
||||||
|
})
|
||||||
}, removePeerFromExceptions: {
|
}, removePeerFromExceptions: {
|
||||||
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: [peerId])
|
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: [peerId])
|
||||||
|> map { _ -> EnginePeer? in }
|
|> map { _ -> EnginePeer? in }
|
||||||
|
|||||||
@ -411,6 +411,10 @@ private final class NotificationExceptionState : Equatable {
|
|||||||
return NotificationExceptionState(mode: mode.withUpdatedPeerDisplayPreviews(peer, displayPreviews), revealedPeerId: self.revealedPeerId, editing: self.editing)
|
return NotificationExceptionState(mode: mode.withUpdatedPeerDisplayPreviews(peer, displayPreviews), revealedPeerId: self.revealedPeerId, editing: self.editing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withUpdatedPeerStoryNotifications(_ peer: EnginePeer, _ storyNotifications: PeerNotificationDisplayPreviews) -> NotificationExceptionState {
|
||||||
|
return NotificationExceptionState(mode: mode.withUpdatedPeerStoryNotifications(peer, storyNotifications), revealedPeerId: self.revealedPeerId, editing: self.editing)
|
||||||
|
}
|
||||||
|
|
||||||
static func == (lhs: NotificationExceptionState, rhs: NotificationExceptionState) -> Bool {
|
static func == (lhs: NotificationExceptionState, rhs: NotificationExceptionState) -> Bool {
|
||||||
return lhs.mode == rhs.mode && lhs.revealedPeerId == rhs.revealedPeerId && lhs.editing == rhs.editing
|
return lhs.mode == rhs.mode && lhs.revealedPeerId == rhs.revealedPeerId && lhs.editing == rhs.editing
|
||||||
}
|
}
|
||||||
@ -450,6 +454,19 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
|
|||||||
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: nil, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: nil, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let updatePeerStoryNotifications: (EnginePeer.Id, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = { peerId, storyNotifications in
|
||||||
|
var isMuted: Bool?
|
||||||
|
switch storyNotifications {
|
||||||
|
case .default:
|
||||||
|
isMuted = nil
|
||||||
|
case .show:
|
||||||
|
isMuted = false
|
||||||
|
case .hide:
|
||||||
|
isMuted = true
|
||||||
|
}
|
||||||
|
return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, isMuted: isMuted) |> deliverOnMainQueue
|
||||||
|
}
|
||||||
|
|
||||||
var peerIds: Set<EnginePeer.Id> = Set(mode.peerIds)
|
var peerIds: Set<EnginePeer.Id> = Set(mode.peerIds)
|
||||||
let updateNotificationsDisposable = MetaDisposable()
|
let updateNotificationsDisposable = MetaDisposable()
|
||||||
let updateNotificationsView: (@escaping () -> Void) -> Void = { completion in
|
let updateNotificationsView: (@escaping () -> Void) -> Void = { completion in
|
||||||
@ -550,6 +567,16 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
|
|||||||
}
|
}
|
||||||
updateNotificationsView({})
|
updateNotificationsView({})
|
||||||
})
|
})
|
||||||
|
}, updatePeerStoryNotifications: { peerId, storyNotifications in
|
||||||
|
updateNotificationsDisposable.set(nil)
|
||||||
|
_ = combineLatest(updatePeerStoryNotifications(peerId, storyNotifications), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
|
||||||
|
if let peer = peer {
|
||||||
|
updateState { value in
|
||||||
|
return value.withUpdatedPeerStoryNotifications(peer, storyNotifications)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateNotificationsView({})
|
||||||
|
})
|
||||||
}, removePeerFromExceptions: {
|
}, removePeerFromExceptions: {
|
||||||
let _ = (
|
let _ = (
|
||||||
context.engine.peers.removeCustomNotificationSettings(peerIds: [peerId])
|
context.engine.peers.removeCustomNotificationSettings(peerIds: [peerId])
|
||||||
|
|||||||
@ -766,8 +766,10 @@ public final class ManagedAudioSession: NSObject {
|
|||||||
managedAudioSessionLog("ManagedAudioSession setting category for \(type) (native: \(nativeCategory)) activateNow: \(activateNow)")
|
managedAudioSessionLog("ManagedAudioSession setting category for \(type) (native: \(nativeCategory)) activateNow: \(activateNow)")
|
||||||
var options: AVAudioSession.CategoryOptions = []
|
var options: AVAudioSession.CategoryOptions = []
|
||||||
switch type {
|
switch type {
|
||||||
case .play, .ambient:
|
case .play:
|
||||||
break
|
break
|
||||||
|
case .ambient:
|
||||||
|
options.insert(.mixWithOthers)
|
||||||
case .playWithPossiblePortOverride:
|
case .playWithPossiblePortOverride:
|
||||||
if case .playAndRecord = nativeCategory {
|
if case .playAndRecord = nativeCategory {
|
||||||
options.insert(.allowBluetoothA2DP)
|
options.insert(.allowBluetoothA2DP)
|
||||||
|
|||||||
@ -213,6 +213,32 @@ func _internal_updatePeerDisplayPreviewsSetting(account: Account, transaction: T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _internal_updatePeerStoriesMutedSetting(account: Account, peerId: PeerId, isMuted: Bool?) -> Signal<Void, NoError> {
|
||||||
|
return account.postbox.transaction { transaction -> Void in
|
||||||
|
_internal_updatePeerStoriesMutedSetting(account: account, transaction: transaction, peerId: peerId, isMuted: isMuted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func _internal_updatePeerStoriesMutedSetting(account: Account, transaction: Transaction, peerId: PeerId, isMuted: Bool?) {
|
||||||
|
if let peer = transaction.getPeer(peerId) {
|
||||||
|
var notificationPeerId = peerId
|
||||||
|
if let associatedPeerId = peer.associatedPeerId {
|
||||||
|
notificationPeerId = associatedPeerId
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentSettings = transaction.getPeerNotificationSettings(id: notificationPeerId) as? TelegramPeerNotificationSettings
|
||||||
|
let previousSettings: TelegramPeerNotificationSettings
|
||||||
|
if let currentSettings = currentSettings {
|
||||||
|
previousSettings = currentSettings
|
||||||
|
} else {
|
||||||
|
previousSettings = TelegramPeerNotificationSettings.defaultSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
let updatedSettings = previousSettings.withUpdatedStoriesMuted(isMuted)
|
||||||
|
transaction.updatePendingPeerNotificationSettings(peerId: peerId, settings: updatedSettings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func _internal_updatePeerNotificationSoundInteractive(account: Account, peerId: PeerId, threadId: Int64?, sound: PeerMessageSound) -> Signal<Void, NoError> {
|
func _internal_updatePeerNotificationSoundInteractive(account: Account, peerId: PeerId, threadId: Int64?, sound: PeerMessageSound) -> Signal<Void, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Void in
|
return account.postbox.transaction { transaction -> Void in
|
||||||
_internal_updatePeerNotificationSoundInteractive(account: account, transaction: transaction, peerId: peerId, threadId: threadId, sound: sound)
|
_internal_updatePeerNotificationSoundInteractive(account: account, transaction: transaction, peerId: peerId, threadId: threadId, sound: sound)
|
||||||
|
|||||||
@ -269,6 +269,10 @@ public extension TelegramEngine {
|
|||||||
return _internal_updatePeerDisplayPreviewsSetting(account: self.account, peerId: peerId, threadId: threadId, displayPreviews: displayPreviews)
|
return _internal_updatePeerDisplayPreviewsSetting(account: self.account, peerId: peerId, threadId: threadId, displayPreviews: displayPreviews)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func updatePeerStoriesMutedSetting(peerId: PeerId, isMuted: Bool?) -> Signal<Void, NoError> {
|
||||||
|
return _internal_updatePeerStoriesMutedSetting(account: self.account, peerId: peerId, isMuted: isMuted)
|
||||||
|
}
|
||||||
|
|
||||||
public func updatePeerNotificationSoundInteractive(peerId: PeerId, threadId: Int64?, sound: PeerMessageSound) -> Signal<Void, NoError> {
|
public func updatePeerNotificationSoundInteractive(peerId: PeerId, threadId: Int64?, sound: PeerMessageSound) -> Signal<Void, NoError> {
|
||||||
return _internal_updatePeerNotificationSoundInteractive(account: self.account, peerId: peerId, threadId: threadId, sound: sound)
|
return _internal_updatePeerNotificationSoundInteractive(account: self.account, peerId: peerId, threadId: threadId, sound: sound)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ public enum MessageContentKindKey {
|
|||||||
case restricted
|
case restricted
|
||||||
case dice
|
case dice
|
||||||
case invoice
|
case invoice
|
||||||
|
case story
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MessageContentKind: Equatable {
|
public enum MessageContentKind: Equatable {
|
||||||
@ -46,6 +47,7 @@ public enum MessageContentKind: Equatable {
|
|||||||
case restricted(String)
|
case restricted(String)
|
||||||
case dice(String)
|
case dice(String)
|
||||||
case invoice(String)
|
case invoice(String)
|
||||||
|
case story
|
||||||
|
|
||||||
public func isSemanticallyEqual(to other: MessageContentKind) -> Bool {
|
public func isSemanticallyEqual(to other: MessageContentKind) -> Bool {
|
||||||
switch self {
|
switch self {
|
||||||
@ -157,6 +159,12 @@ public enum MessageContentKind: Equatable {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
case .story:
|
||||||
|
if case .story = other {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,6 +206,8 @@ public enum MessageContentKind: Equatable {
|
|||||||
return .dice
|
return .dice
|
||||||
case .invoice:
|
case .invoice:
|
||||||
return .invoice
|
return .invoice
|
||||||
|
case .story:
|
||||||
|
return .story
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,6 +342,8 @@ public func mediaContentKind(_ media: EngineMedia, message: EngineMessage? = nil
|
|||||||
} else {
|
} else {
|
||||||
return .invoice(invoice.title)
|
return .invoice(invoice.title)
|
||||||
}
|
}
|
||||||
|
case .story:
|
||||||
|
return .story
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -383,6 +395,9 @@ public func stringForMediaKind(_ kind: MessageContentKind, strings: Presentation
|
|||||||
return (NSAttributedString(string: emoji), true)
|
return (NSAttributedString(string: emoji), true)
|
||||||
case let .invoice(text):
|
case let .invoice(text):
|
||||||
return (NSAttributedString(string: text), true)
|
return (NSAttributedString(string: text), true)
|
||||||
|
case .story:
|
||||||
|
//TODO:localize
|
||||||
|
return (NSAttributedString(string: "Story"), true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -496,6 +496,7 @@ public func threadNotificationExceptionsScreen(context: AccountContext, peerId:
|
|||||||
}
|
}
|
||||||
updated(stateValue.with({ $0 }).notificationExceptions)
|
updated(stateValue.with({ $0 }).notificationExceptions)
|
||||||
})
|
})
|
||||||
|
}, updatePeerStoryNotifications: { _, _ in
|
||||||
}, removePeerFromExceptions: {
|
}, removePeerFromExceptions: {
|
||||||
let _ = context.engine.peers.removeCustomThreadNotificationSettings(peerId: peerId, threadIds: [item.threadId]).start()
|
let _ = context.engine.peers.removeCustomThreadNotificationSettings(peerId: peerId, threadIds: [item.threadId]).start()
|
||||||
updateState { current in
|
updateState { current in
|
||||||
|
|||||||
@ -217,6 +217,52 @@ public enum NotificationExceptionMode : Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func withUpdatedPeerStoryNotifications(_ peer: EnginePeer, _ storyNotifications: PeerNotificationDisplayPreviews) -> NotificationExceptionMode {
|
||||||
|
let apply:([EnginePeer.Id : NotificationExceptionWrapper], EnginePeer.Id, PeerNotificationDisplayPreviews) -> [EnginePeer.Id : NotificationExceptionWrapper] = { values, peerId, storyNotifications in
|
||||||
|
let storiesMuted: Bool?
|
||||||
|
switch storyNotifications {
|
||||||
|
case .default:
|
||||||
|
storiesMuted = nil
|
||||||
|
case .show:
|
||||||
|
storiesMuted = false
|
||||||
|
case .hide:
|
||||||
|
storiesMuted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
var values = values
|
||||||
|
if let value = values[peerId] {
|
||||||
|
switch storyNotifications {
|
||||||
|
case .default:
|
||||||
|
switch value.settings.storiesMuted {
|
||||||
|
case .none:
|
||||||
|
values.removeValue(forKey: peerId)
|
||||||
|
default:
|
||||||
|
values[peerId] = value.updateSettings({$0.withUpdatedStoriesMuted(storiesMuted)}).withUpdatedDate(Date().timeIntervalSince1970)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
values[peerId] = value.updateSettings({$0.withUpdatedStoriesMuted(storiesMuted)}).withUpdatedDate(Date().timeIntervalSince1970)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch storyNotifications {
|
||||||
|
case .default:
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: .unmuted, messageSound: .default, displayPreviews: .default, storiesMuted: storiesMuted), peer: peer, date: Date().timeIntervalSince1970)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
switch self {
|
||||||
|
case let .groups(values):
|
||||||
|
return .groups(apply(values, peer.id, storyNotifications))
|
||||||
|
case let .users(values):
|
||||||
|
return .users(apply(values, peer.id, storyNotifications))
|
||||||
|
case let .channels(values):
|
||||||
|
return .channels(apply(values, peer.id, storyNotifications))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public var peerIds: [EnginePeer.Id] {
|
public var peerIds: [EnginePeer.Id] {
|
||||||
switch self {
|
switch self {
|
||||||
case let .users(settings), let .groups(settings), let .channels(settings):
|
case let .users(settings), let .groups(settings), let .channels(settings):
|
||||||
@ -236,6 +282,7 @@ private enum NotificationPeerExceptionSection: Int32 {
|
|||||||
case remove
|
case remove
|
||||||
case switcher
|
case switcher
|
||||||
case displayPreviews
|
case displayPreviews
|
||||||
|
case storyNotifications
|
||||||
case soundCloud
|
case soundCloud
|
||||||
case soundModern
|
case soundModern
|
||||||
case soundClassic
|
case soundClassic
|
||||||
@ -253,6 +300,8 @@ private enum NotificationPeerExceptionEntryId: Hashable {
|
|||||||
case switcherHeader
|
case switcherHeader
|
||||||
case displayPreviews(NotificationPeerExceptionSwitcher)
|
case displayPreviews(NotificationPeerExceptionSwitcher)
|
||||||
case displayPreviewsHeader
|
case displayPreviewsHeader
|
||||||
|
case storyNotifications(NotificationPeerExceptionSwitcher)
|
||||||
|
case storyNotificationsHeader
|
||||||
case soundModernHeader
|
case soundModernHeader
|
||||||
case soundClassicHeader
|
case soundClassicHeader
|
||||||
case none
|
case none
|
||||||
@ -268,17 +317,19 @@ private final class NotificationPeerExceptionArguments {
|
|||||||
let selectSound: (PeerMessageSound) -> Void
|
let selectSound: (PeerMessageSound) -> Void
|
||||||
let selectMode: (NotificationPeerExceptionSwitcher) -> Void
|
let selectMode: (NotificationPeerExceptionSwitcher) -> Void
|
||||||
let selectDisplayPreviews: (NotificationPeerExceptionSwitcher) -> Void
|
let selectDisplayPreviews: (NotificationPeerExceptionSwitcher) -> Void
|
||||||
|
let selectStoryNotifications: (NotificationPeerExceptionSwitcher) -> Void
|
||||||
let removeFromExceptions: () -> Void
|
let removeFromExceptions: () -> Void
|
||||||
let complete: () -> Void
|
let complete: () -> Void
|
||||||
let cancel: () -> Void
|
let cancel: () -> Void
|
||||||
let upload: () -> Void
|
let upload: () -> Void
|
||||||
let deleteSound: (PeerMessageSound, String) -> Void
|
let deleteSound: (PeerMessageSound, String) -> Void
|
||||||
|
|
||||||
init(account: Account, selectSound: @escaping(PeerMessageSound) -> Void, selectMode: @escaping(NotificationPeerExceptionSwitcher) -> Void, selectDisplayPreviews: @escaping (NotificationPeerExceptionSwitcher) -> Void, removeFromExceptions: @escaping () -> Void, complete: @escaping()->Void, cancel: @escaping() -> Void, upload: @escaping () -> Void, deleteSound: @escaping (PeerMessageSound, String) -> Void) {
|
init(account: Account, selectSound: @escaping(PeerMessageSound) -> Void, selectMode: @escaping(NotificationPeerExceptionSwitcher) -> Void, selectDisplayPreviews: @escaping (NotificationPeerExceptionSwitcher) -> Void, selectStoryNotifications: @escaping (NotificationPeerExceptionSwitcher) -> Void, removeFromExceptions: @escaping () -> Void, complete: @escaping()->Void, cancel: @escaping() -> Void, upload: @escaping () -> Void, deleteSound: @escaping (PeerMessageSound, String) -> Void) {
|
||||||
self.account = account
|
self.account = account
|
||||||
self.selectSound = selectSound
|
self.selectSound = selectSound
|
||||||
self.selectMode = selectMode
|
self.selectMode = selectMode
|
||||||
self.selectDisplayPreviews = selectDisplayPreviews
|
self.selectDisplayPreviews = selectDisplayPreviews
|
||||||
|
self.selectStoryNotifications = selectStoryNotifications
|
||||||
self.removeFromExceptions = removeFromExceptions
|
self.removeFromExceptions = removeFromExceptions
|
||||||
self.complete = complete
|
self.complete = complete
|
||||||
self.cancel = cancel
|
self.cancel = cancel
|
||||||
@ -296,6 +347,8 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
|||||||
case switcherHeader(index:Int32, theme: PresentationTheme, title: String)
|
case switcherHeader(index:Int32, theme: PresentationTheme, title: String)
|
||||||
case displayPreviews(index:Int32, theme: PresentationTheme, strings: PresentationStrings, value: NotificationPeerExceptionSwitcher, selected: Bool)
|
case displayPreviews(index:Int32, theme: PresentationTheme, strings: PresentationStrings, value: NotificationPeerExceptionSwitcher, selected: Bool)
|
||||||
case displayPreviewsHeader(index:Int32, theme: PresentationTheme, title: String)
|
case displayPreviewsHeader(index:Int32, theme: PresentationTheme, title: String)
|
||||||
|
case storyNotifications(index:Int32, theme: PresentationTheme, strings: PresentationStrings, value: NotificationPeerExceptionSwitcher, selected: Bool)
|
||||||
|
case storyNotificationsHeader(index:Int32, theme: PresentationTheme, title: String)
|
||||||
case soundModernHeader(index:Int32, theme: PresentationTheme, title: String)
|
case soundModernHeader(index:Int32, theme: PresentationTheme, title: String)
|
||||||
case soundClassicHeader(index:Int32, theme: PresentationTheme, title: String)
|
case soundClassicHeader(index:Int32, theme: PresentationTheme, title: String)
|
||||||
case none(index:Int32, section: NotificationPeerExceptionSection, theme: PresentationTheme, text: String, selected: Bool)
|
case none(index:Int32, section: NotificationPeerExceptionSection, theme: PresentationTheme, text: String, selected: Bool)
|
||||||
@ -317,6 +370,10 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
|||||||
return index
|
return index
|
||||||
case let .displayPreviews(index, _, _, _, _):
|
case let .displayPreviews(index, _, _, _, _):
|
||||||
return index
|
return index
|
||||||
|
case let .storyNotificationsHeader(index, _, _):
|
||||||
|
return index
|
||||||
|
case let .storyNotifications(index, _, _, _, _):
|
||||||
|
return index
|
||||||
case let .soundModernHeader(index, _, _):
|
case let .soundModernHeader(index, _, _):
|
||||||
return index
|
return index
|
||||||
case let .soundClassicHeader(index, _, _):
|
case let .soundClassicHeader(index, _, _):
|
||||||
@ -344,6 +401,8 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
|||||||
return NotificationPeerExceptionSection.switcher.rawValue
|
return NotificationPeerExceptionSection.switcher.rawValue
|
||||||
case .displayPreviews, .displayPreviewsHeader:
|
case .displayPreviews, .displayPreviewsHeader:
|
||||||
return NotificationPeerExceptionSection.displayPreviews.rawValue
|
return NotificationPeerExceptionSection.displayPreviews.rawValue
|
||||||
|
case .storyNotifications, .storyNotificationsHeader:
|
||||||
|
return NotificationPeerExceptionSection.storyNotifications.rawValue
|
||||||
case .cloudInfo, .cloudHeader, .uploadSound:
|
case .cloudInfo, .cloudHeader, .uploadSound:
|
||||||
return NotificationPeerExceptionSection.soundCloud.rawValue
|
return NotificationPeerExceptionSection.soundCloud.rawValue
|
||||||
case .soundModernHeader:
|
case .soundModernHeader:
|
||||||
@ -371,6 +430,10 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
|||||||
return .displayPreviews(mode)
|
return .displayPreviews(mode)
|
||||||
case .displayPreviewsHeader:
|
case .displayPreviewsHeader:
|
||||||
return .displayPreviewsHeader
|
return .displayPreviewsHeader
|
||||||
|
case let .storyNotifications(_, _, _, mode, _):
|
||||||
|
return .storyNotifications(mode)
|
||||||
|
case .storyNotificationsHeader:
|
||||||
|
return .storyNotificationsHeader
|
||||||
case .soundModernHeader:
|
case .soundModernHeader:
|
||||||
return .soundModernHeader
|
return .soundModernHeader
|
||||||
case .soundClassicHeader:
|
case .soundClassicHeader:
|
||||||
@ -436,6 +499,19 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
|||||||
})
|
})
|
||||||
case let .displayPreviewsHeader(_, _, text):
|
case let .displayPreviewsHeader(_, _, text):
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||||
|
case let .storyNotifications(_, _, strings, value, selected):
|
||||||
|
let title: String
|
||||||
|
switch value {
|
||||||
|
case .alwaysOn:
|
||||||
|
title = strings.Notification_Exceptions_MessagePreviewAlwaysOn
|
||||||
|
case .alwaysOff:
|
||||||
|
title = strings.Notification_Exceptions_MessagePreviewAlwaysOff
|
||||||
|
}
|
||||||
|
return ItemListCheckboxItem(presentationData: presentationData, title: title, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||||
|
arguments.selectStoryNotifications(value)
|
||||||
|
})
|
||||||
|
case let .storyNotificationsHeader(_, _, text):
|
||||||
|
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||||
case let .soundModernHeader(_, _, text):
|
case let .soundModernHeader(_, _, text):
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||||
case let .soundClassicHeader(_, _, text):
|
case let .soundClassicHeader(_, _, text):
|
||||||
@ -459,7 +535,7 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private func notificationPeerExceptionEntries(presentationData: PresentationData, notificationSoundList: NotificationSoundList?, state: NotificationExceptionPeerState) -> [NotificationPeerExceptionEntry] {
|
private func notificationPeerExceptionEntries(presentationData: PresentationData, peer: EnginePeer?, notificationSoundList: NotificationSoundList?, state: NotificationExceptionPeerState) -> [NotificationPeerExceptionEntry] {
|
||||||
let selectedSound = resolvedNotificationSound(sound: state.selectedSound, notificationSoundList: notificationSoundList)
|
let selectedSound = resolvedNotificationSound(sound: state.selectedSound, notificationSoundList: notificationSoundList)
|
||||||
|
|
||||||
var entries: [NotificationPeerExceptionEntry] = []
|
var entries: [NotificationPeerExceptionEntry] = []
|
||||||
@ -488,6 +564,16 @@ private func notificationPeerExceptionEntries(presentationData: PresentationData
|
|||||||
entries.append(.displayPreviews(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOff, selected: state.displayPreviews == .alwaysOff))
|
entries.append(.displayPreviews(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOff, selected: state.displayPreviews == .alwaysOff))
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
|
if case .user = peer {
|
||||||
|
//TODO:localize
|
||||||
|
entries.append(.storyNotificationsHeader(index: index, theme: presentationData.theme, title: "STORY NOTIFICATIONS"))
|
||||||
|
index += 1
|
||||||
|
entries.append(.storyNotifications(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOn, selected: state.storyNotifications == .alwaysOn))
|
||||||
|
index += 1
|
||||||
|
entries.append(.storyNotifications(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOff, selected: state.storyNotifications == .alwaysOff))
|
||||||
|
index += 1
|
||||||
|
}
|
||||||
|
|
||||||
entries.append(.cloudHeader(index: index, text: presentationData.strings.Notifications_TelegramTones))
|
entries.append(.cloudHeader(index: index, text: presentationData.strings.Notifications_TelegramTones))
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
@ -550,6 +636,7 @@ private struct NotificationExceptionPeerState : Equatable {
|
|||||||
var mode: NotificationPeerExceptionSwitcher
|
var mode: NotificationPeerExceptionSwitcher
|
||||||
var defaultSound: PeerMessageSound
|
var defaultSound: PeerMessageSound
|
||||||
var displayPreviews: NotificationPeerExceptionSwitcher
|
var displayPreviews: NotificationPeerExceptionSwitcher
|
||||||
|
var storyNotifications: NotificationPeerExceptionSwitcher
|
||||||
var removedSounds: [PeerMessageSound]
|
var removedSounds: [PeerMessageSound]
|
||||||
|
|
||||||
init(canRemove: Bool, notifications: TelegramPeerNotificationSettings? = nil) {
|
init(canRemove: Bool, notifications: TelegramPeerNotificationSettings? = nil) {
|
||||||
@ -564,27 +651,30 @@ private struct NotificationExceptionPeerState : Equatable {
|
|||||||
self.mode = .alwaysOn
|
self.mode = .alwaysOn
|
||||||
}
|
}
|
||||||
self.displayPreviews = notifications.displayPreviews == .hide ? .alwaysOff : .alwaysOn
|
self.displayPreviews = notifications.displayPreviews == .hide ? .alwaysOff : .alwaysOn
|
||||||
|
self.storyNotifications = notifications.storiesMuted == false ? .alwaysOff : .alwaysOn
|
||||||
} else {
|
} else {
|
||||||
self.selectedSound = .default
|
self.selectedSound = .default
|
||||||
self.mode = .alwaysOn
|
self.mode = .alwaysOn
|
||||||
self.displayPreviews = .alwaysOn
|
self.displayPreviews = .alwaysOn
|
||||||
|
self.storyNotifications = .alwaysOn
|
||||||
}
|
}
|
||||||
|
|
||||||
self.defaultSound = .default
|
self.defaultSound = .default
|
||||||
self.removedSounds = []
|
self.removedSounds = []
|
||||||
}
|
}
|
||||||
|
|
||||||
init(canRemove: Bool, selectedSound: PeerMessageSound, mode: NotificationPeerExceptionSwitcher, defaultSound: PeerMessageSound, displayPreviews: NotificationPeerExceptionSwitcher, removedSounds: [PeerMessageSound]) {
|
init(canRemove: Bool, selectedSound: PeerMessageSound, mode: NotificationPeerExceptionSwitcher, defaultSound: PeerMessageSound, displayPreviews: NotificationPeerExceptionSwitcher, storyNotifications: NotificationPeerExceptionSwitcher, removedSounds: [PeerMessageSound]) {
|
||||||
self.canRemove = canRemove
|
self.canRemove = canRemove
|
||||||
self.selectedSound = selectedSound
|
self.selectedSound = selectedSound
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.defaultSound = defaultSound
|
self.defaultSound = defaultSound
|
||||||
self.displayPreviews = displayPreviews
|
self.displayPreviews = displayPreviews
|
||||||
|
self.storyNotifications = storyNotifications
|
||||||
self.removedSounds = removedSounds
|
self.removedSounds = removedSounds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func notificationPeerExceptionController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer, customTitle: String? = nil, threadId: Int64?, canRemove: Bool, defaultSound: PeerMessageSound, edit: Bool = false, updatePeerSound: @escaping(EnginePeer.Id, PeerMessageSound) -> Void, updatePeerNotificationInterval: @escaping(EnginePeer.Id, Int32?) -> Void, updatePeerDisplayPreviews: @escaping(EnginePeer.Id, PeerNotificationDisplayPreviews) -> Void, removePeerFromExceptions: @escaping () -> Void, modifiedPeer: @escaping () -> Void) -> ViewController {
|
public func notificationPeerExceptionController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer, customTitle: String? = nil, threadId: Int64?, canRemove: Bool, defaultSound: PeerMessageSound, edit: Bool = false, updatePeerSound: @escaping(EnginePeer.Id, PeerMessageSound) -> Void, updatePeerNotificationInterval: @escaping(EnginePeer.Id, Int32?) -> Void, updatePeerDisplayPreviews: @escaping(EnginePeer.Id, PeerNotificationDisplayPreviews) -> Void, updatePeerStoryNotifications: @escaping(EnginePeer.Id, PeerNotificationDisplayPreviews) -> Void, removePeerFromExceptions: @escaping () -> Void, modifiedPeer: @escaping () -> Void) -> ViewController {
|
||||||
let initialState = NotificationExceptionPeerState(canRemove: false)
|
let initialState = NotificationExceptionPeerState(canRemove: false)
|
||||||
let statePromise = Promise(initialState)
|
let statePromise = Promise(initialState)
|
||||||
let stateValue = Atomic(value: initialState)
|
let stateValue = Atomic(value: initialState)
|
||||||
@ -625,6 +715,12 @@ public func notificationPeerExceptionController(context: AccountContext, updated
|
|||||||
state.displayPreviews = value
|
state.displayPreviews = value
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
}, selectStoryNotifications: { value in
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.storyNotifications = value
|
||||||
|
return state
|
||||||
|
}
|
||||||
}, removeFromExceptions: {
|
}, removeFromExceptions: {
|
||||||
removeFromExceptionsImpl?()
|
removeFromExceptionsImpl?()
|
||||||
}, complete: {
|
}, complete: {
|
||||||
@ -686,7 +782,7 @@ public func notificationPeerExceptionController(context: AccountContext, updated
|
|||||||
}
|
}
|
||||||
|
|
||||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(titleString), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(titleString), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
||||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: notificationPeerExceptionEntries(presentationData: presentationData, notificationSoundList: notificationSoundList, state: state), style: .blocks, animateChanges: animated)
|
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: notificationPeerExceptionEntries(presentationData: presentationData, peer: peer, notificationSoundList: notificationSoundList, state: state), style: .blocks, animateChanges: animated)
|
||||||
|
|
||||||
return (controllerState, (listState, arguments))
|
return (controllerState, (listState, arguments))
|
||||||
}
|
}
|
||||||
@ -709,6 +805,7 @@ public func notificationPeerExceptionController(context: AccountContext, updated
|
|||||||
updatePeerSound(peer.id, resolvedNotificationSound(sound: state.selectedSound, notificationSoundList: notificationSoundList))
|
updatePeerSound(peer.id, resolvedNotificationSound(sound: state.selectedSound, notificationSoundList: notificationSoundList))
|
||||||
updatePeerNotificationInterval(peer.id, state.mode == .alwaysOn ? 0 : Int32.max)
|
updatePeerNotificationInterval(peer.id, state.mode == .alwaysOn ? 0 : Int32.max)
|
||||||
updatePeerDisplayPreviews(peer.id, state.displayPreviews == .alwaysOn ? .show : .hide)
|
updatePeerDisplayPreviews(peer.id, state.displayPreviews == .alwaysOn ? .show : .hide)
|
||||||
|
updatePeerStoryNotifications(peer.id, state.storyNotifications == .alwaysOn ? .show : .hide)
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -373,6 +373,8 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
case .began:
|
case .began:
|
||||||
self.verticalPanState = ItemSetPanState(fraction: 0.0, didBegin: true)
|
self.verticalPanState = ItemSetPanState(fraction: 0.0, didBegin: true)
|
||||||
self.state?.updated(transition: .immediate)
|
self.state?.updated(transition: .immediate)
|
||||||
|
|
||||||
|
self.dismissAllTooltips()
|
||||||
case .changed:
|
case .changed:
|
||||||
let translation = recognizer.translation(in: self)
|
let translation = recognizer.translation(in: self)
|
||||||
self.verticalPanState = ItemSetPanState(fraction: max(-1.0, min(1.0, translation.y / self.bounds.height)), didBegin: true)
|
self.verticalPanState = ItemSetPanState(fraction: max(-1.0, min(1.0, translation.y / self.bounds.height)), didBegin: true)
|
||||||
@ -480,6 +482,18 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func dismissAllTooltips() {
|
||||||
|
guard let controller = self.environment?.controller() else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
controller.forEachController { controller in
|
||||||
|
if let controller = controller as? UndoOverlayController {
|
||||||
|
controller.dismissWithCommitAction()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func animateIn() {
|
func animateIn() {
|
||||||
if let component = self.component {
|
if let component = self.component {
|
||||||
component.focusedItemPromise.set(self.focusedItem.get())
|
component.focusedItemPromise.set(self.focusedItem.get())
|
||||||
|
|||||||
@ -229,7 +229,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
let contentContainerView: UIView
|
let contentContainerView: UIView
|
||||||
let topContentGradientLayer: SimpleGradientLayer
|
let topContentGradientLayer: SimpleGradientLayer
|
||||||
let bottomContentGradientLayer: SimpleGradientLayer
|
let bottomContentGradientLayer: SimpleGradientLayer
|
||||||
let contentDimLayer: SimpleLayer
|
let contentDimView: UIView
|
||||||
|
|
||||||
let closeButton: HighlightableButton
|
let closeButton: HighlightableButton
|
||||||
let closeButtonIconView: UIImageView
|
let closeButtonIconView: UIImageView
|
||||||
@ -287,7 +287,9 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
|
|
||||||
self.topContentGradientLayer = SimpleGradientLayer()
|
self.topContentGradientLayer = SimpleGradientLayer()
|
||||||
self.bottomContentGradientLayer = SimpleGradientLayer()
|
self.bottomContentGradientLayer = SimpleGradientLayer()
|
||||||
self.contentDimLayer = SimpleLayer()
|
|
||||||
|
self.contentDimView = UIView()
|
||||||
|
self.contentDimView.isUserInteractionEnabled = false
|
||||||
|
|
||||||
self.closeButton = HighlightableButton()
|
self.closeButton = HighlightableButton()
|
||||||
self.closeButtonIconView = UIImageView()
|
self.closeButtonIconView = UIImageView()
|
||||||
@ -312,7 +314,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
self.scrollView.clipsToBounds = true
|
self.scrollView.clipsToBounds = true
|
||||||
|
|
||||||
self.addSubview(self.contentContainerView)
|
self.addSubview(self.contentContainerView)
|
||||||
self.contentContainerView.layer.addSublayer(self.contentDimLayer)
|
self.contentContainerView.addSubview(self.contentDimView)
|
||||||
self.contentContainerView.layer.addSublayer(self.topContentGradientLayer)
|
self.contentContainerView.layer.addSublayer(self.topContentGradientLayer)
|
||||||
self.layer.addSublayer(self.bottomContentGradientLayer)
|
self.layer.addSublayer(self.bottomContentGradientLayer)
|
||||||
|
|
||||||
@ -970,7 +972,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
self.bottomContentGradientLayer.colors = colors
|
self.bottomContentGradientLayer.colors = colors
|
||||||
self.bottomContentGradientLayer.type = .axial
|
self.bottomContentGradientLayer.type = .axial
|
||||||
|
|
||||||
self.contentDimLayer.backgroundColor = UIColor(white: 0.0, alpha: 0.3).cgColor
|
self.contentDimView.backgroundColor = UIColor(white: 0.0, alpha: 0.3)
|
||||||
}
|
}
|
||||||
|
|
||||||
//self.updatePreloads()
|
//self.updatePreloads()
|
||||||
@ -1767,7 +1769,12 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
|
|
||||||
let centerInfoItemSize = currentCenterInfoItem.view.update(
|
let centerInfoItemSize = currentCenterInfoItem.view.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: currentCenterInfoItem.component,
|
component: AnyComponent(PlainButtonComponent(content: currentCenterInfoItem.component, effectAlignment: .center, action: { [weak self] in
|
||||||
|
guard let self, let component = self.component else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.navigateToPeer(peer: component.slice.peer)
|
||||||
|
})),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: contentFrame.width, height: 44.0)
|
containerSize: CGSize(width: contentFrame.width, height: 44.0)
|
||||||
)
|
)
|
||||||
@ -2125,12 +2132,12 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
dimAlpha = 0.0
|
dimAlpha = 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
transition.setFrame(layer: self.contentDimLayer, frame: CGRect(origin: CGPoint(), size: contentFrame.size))
|
transition.setFrame(view: self.contentDimView, frame: CGRect(origin: CGPoint(), size: contentFrame.size))
|
||||||
|
|
||||||
if transition.animation.isImmediate && forceDimAnimation && self.contentDimLayer.opacity != Float(dimAlpha) {
|
if transition.animation.isImmediate && forceDimAnimation && self.contentDimView.alpha != dimAlpha {
|
||||||
Transition(animation: .curve(duration: 0.25, curve: .easeInOut)).setAlpha(layer: self.contentDimLayer, alpha: dimAlpha)
|
Transition(animation: .curve(duration: 0.25, curve: .easeInOut)).setAlpha(view: self.contentDimView, alpha: dimAlpha)
|
||||||
} else {
|
} else {
|
||||||
transition.setAlpha(layer: self.contentDimLayer, alpha: dimAlpha)
|
transition.setAlpha(view: self.contentDimView, alpha: dimAlpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ignoreScrolling = true
|
self.ignoreScrolling = true
|
||||||
|
|||||||
@ -315,6 +315,61 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
forceTheme: defaultDarkColorPresentationTheme
|
forceTheme: defaultDarkColorPresentationTheme
|
||||||
)
|
)
|
||||||
|
|
||||||
|
shareController.completed = { [weak view] peerIds in
|
||||||
|
guard let view, let component = view.component else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = (component.context.engine.data.get(
|
||||||
|
EngineDataList(
|
||||||
|
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak view] peerList in
|
||||||
|
guard let view, let component = view.component else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let peers = peerList.compactMap { $0 }
|
||||||
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let text: String
|
||||||
|
var savedMessages = false
|
||||||
|
if peerIds.count == 1, let peerId = peerIds.first, peerId == component.context.account.peerId {
|
||||||
|
text = presentationData.strings.Conversation_StoryForwardTooltip_SavedMessages_One
|
||||||
|
savedMessages = true
|
||||||
|
} else {
|
||||||
|
if peers.count == 1, let peer = peers.first {
|
||||||
|
var peerName = peer.id == component.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||||
|
peerName = peerName.replacingOccurrences(of: "**", with: "")
|
||||||
|
text = presentationData.strings.Conversation_StoryForwardTooltip_Chat_One(peerName).string
|
||||||
|
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
|
||||||
|
var firstPeerName = firstPeer.id == component.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||||
|
firstPeerName = firstPeerName.replacingOccurrences(of: "**", with: "")
|
||||||
|
var secondPeerName = secondPeer.id == component.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||||
|
secondPeerName = secondPeerName.replacingOccurrences(of: "**", with: "")
|
||||||
|
text = presentationData.strings.Conversation_StoryForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
|
||||||
|
} else if let peer = peers.first {
|
||||||
|
var peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||||
|
peerName = peerName.replacingOccurrences(of: "**", with: "")
|
||||||
|
text = presentationData.strings.Conversation_StoryForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
|
||||||
|
} else {
|
||||||
|
text = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let controller = component.controller() {
|
||||||
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
controller.present(UndoOverlayController(
|
||||||
|
presentationData: presentationData,
|
||||||
|
content: .forward(savedMessages: savedMessages, text: text),
|
||||||
|
elevatedLayout: false,
|
||||||
|
animateInAsReplacement: false,
|
||||||
|
action: { _ in return false }
|
||||||
|
), in: .current)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
self.shareController = shareController
|
self.shareController = shareController
|
||||||
view.updateIsProgressPaused()
|
view.updateIsProgressPaused()
|
||||||
|
|
||||||
|
|||||||
@ -247,6 +247,10 @@ public final class StoryPeerListComponent: Component {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func scrollToTop() {
|
||||||
|
self.scrollView.setContentOffset(CGPoint(), animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||||
if !self.ignoreScrolling {
|
if !self.ignoreScrolling {
|
||||||
self.updateScrolling(transition: .immediate, keepVisibleUntilCompletion: false)
|
self.updateScrolling(transition: .immediate, keepVisibleUntilCompletion: false)
|
||||||
|
|||||||
@ -676,8 +676,8 @@ public final class StoryPeerListItemComponent: Component {
|
|||||||
if component.peer.id == component.context.account.peerId && !component.hasItems && component.ringAnimation == nil {
|
if component.peer.id == component.context.account.peerId && !component.hasItems && component.ringAnimation == nil {
|
||||||
let cutoutSize: CGFloat = 18.0 + UIScreenPixel * 2.0
|
let cutoutSize: CGFloat = 18.0 + UIScreenPixel * 2.0
|
||||||
avatarPath.addEllipse(in: CGRect(origin: CGPoint(x: avatarSize.width - cutoutSize + UIScreenPixel, y: avatarSize.height - 1.0 - cutoutSize + UIScreenPixel), size: CGSize(width: cutoutSize, height: cutoutSize)))
|
avatarPath.addEllipse(in: CGRect(origin: CGPoint(x: avatarSize.width - cutoutSize + UIScreenPixel, y: avatarSize.height - 1.0 - cutoutSize + UIScreenPixel), size: CGSize(width: cutoutSize, height: cutoutSize)))
|
||||||
} else if let mappedRightCenter {
|
} else if let mappedLeftCenter {
|
||||||
avatarPath.addEllipse(in: CGRect(origin: CGPoint(), size: avatarSize).insetBy(dx: -indicatorLineWidth, dy: -indicatorLineWidth).offsetBy(dx: abs(mappedRightCenter.x - indicatorCenter.x), dy: 0.0))
|
avatarPath.addEllipse(in: CGRect(origin: CGPoint(), size: avatarSize).insetBy(dx: -indicatorLineWidth, dy: -indicatorLineWidth).offsetBy(dx: -abs(indicatorCenter.x - mappedLeftCenter.x), dy: 0.0))
|
||||||
}
|
}
|
||||||
Transition.immediate.setShapeLayerPath(layer: self.avatarShapeLayer, path: avatarPath)
|
Transition.immediate.setShapeLayerPath(layer: self.avatarShapeLayer, path: avatarPath)
|
||||||
|
|
||||||
|
|||||||
@ -700,6 +700,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
var isSticker = false
|
var isSticker = false
|
||||||
var maxDimensions = layoutConstants.image.maxDimensions
|
var maxDimensions = layoutConstants.image.maxDimensions
|
||||||
var maxHeight = layoutConstants.image.maxDimensions.height
|
var maxHeight = layoutConstants.image.maxDimensions.height
|
||||||
|
var isStory = false
|
||||||
|
|
||||||
var unboundSize: CGSize
|
var unboundSize: CGSize
|
||||||
if let _ = media as? TelegramMediaStory {
|
if let _ = media as? TelegramMediaStory {
|
||||||
@ -987,6 +988,8 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let story = media as? TelegramMediaStory {
|
if let story = media as? TelegramMediaStory {
|
||||||
|
isStory = true
|
||||||
|
|
||||||
if hasCurrentVideoNode {
|
if hasCurrentVideoNode {
|
||||||
replaceVideoNode = true
|
replaceVideoNode = true
|
||||||
}
|
}
|
||||||
@ -1058,7 +1061,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
uploading = true
|
uploading = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if file.isVideo && !file.isVideoSticker && !isSecretMedia && automaticPlayback && !uploading {
|
if file.isVideo && !file.isVideoSticker && !isSecretMedia && automaticPlayback && !isStory && !uploading {
|
||||||
updateVideoFile = file
|
updateVideoFile = file
|
||||||
if hasCurrentVideoNode {
|
if hasCurrentVideoNode {
|
||||||
if let currentFile = currentMedia as? TelegramMediaFile {
|
if let currentFile = currentMedia as? TelegramMediaFile {
|
||||||
@ -1194,7 +1197,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
uploading = true
|
uploading = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if file.isVideo && !file.isVideoSticker && !isSecretMedia && automaticPlayback && !uploading {
|
if file.isVideo && !file.isVideoSticker && !isSecretMedia && automaticPlayback && !isStory && !uploading {
|
||||||
updateVideoFile = file
|
updateVideoFile = file
|
||||||
if hasCurrentVideoNode {
|
if hasCurrentVideoNode {
|
||||||
if let currentFile = currentMedia as? TelegramMediaFile {
|
if let currentFile = currentMedia as? TelegramMediaFile {
|
||||||
|
|||||||
@ -466,6 +466,13 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||||||
)
|
)
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|
|
||||||
|
let storyListContext = PeerStoryListContext(account: context.account, peerId: peerId, isArchived: false)
|
||||||
|
let hasStories: Signal<Bool, NoError> = storyListContext.state
|
||||||
|
|> map { state -> Bool in
|
||||||
|
return !state.items.isEmpty
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
|
||||||
return combineLatest(
|
return combineLatest(
|
||||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||||
accountsAndPeers,
|
accountsAndPeers,
|
||||||
@ -487,9 +494,10 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||||||
|> mapToSignal { settings -> Signal<Bool, NoError> in
|
|> mapToSignal { settings -> Signal<Bool, NoError> in
|
||||||
return automaticEnergyUsageShouldBeOn(settings: settings)
|
return automaticEnergyUsageShouldBeOn(settings: settings)
|
||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged,
|
||||||
|
hasStories
|
||||||
)
|
)
|
||||||
|> map { peerView, accountsAndPeers, accountSessions, privacySettings, sharedPreferences, notifications, stickerPacks, hasPassport, hasWatchApp, accountPreferences, suggestions, limits, hasPassword, isPowerSavingEnabled -> PeerInfoScreenData in
|
|> map { peerView, accountsAndPeers, accountSessions, privacySettings, sharedPreferences, notifications, stickerPacks, hasPassport, hasWatchApp, accountPreferences, suggestions, limits, hasPassword, isPowerSavingEnabled, hasStories -> PeerInfoScreenData in
|
||||||
let (notificationExceptions, notificationsAuthorizationStatus, notificationsWarningSuppressed) = notifications
|
let (notificationExceptions, notificationsAuthorizationStatus, notificationsWarningSuppressed) = notifications
|
||||||
let (featuredStickerPacks, archivedStickerPacks) = stickerPacks
|
let (featuredStickerPacks, archivedStickerPacks) = stickerPacks
|
||||||
|
|
||||||
@ -546,7 +554,7 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||||||
groupsInCommon: nil,
|
groupsInCommon: nil,
|
||||||
linkedDiscussionPeer: nil,
|
linkedDiscussionPeer: nil,
|
||||||
members: nil,
|
members: nil,
|
||||||
storyListContext: nil,
|
storyListContext: storyListContext,
|
||||||
encryptionKeyFingerprint: nil,
|
encryptionKeyFingerprint: nil,
|
||||||
globalSettings: globalSettings,
|
globalSettings: globalSettings,
|
||||||
invitations: nil,
|
invitations: nil,
|
||||||
|
|||||||
@ -4685,6 +4685,19 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: threadId, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: threadId, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let updatePeerStoryNotifications: (PeerId, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = { peerId, storyNotifications in
|
||||||
|
var isMuted: Bool?
|
||||||
|
switch storyNotifications {
|
||||||
|
case .default:
|
||||||
|
isMuted = nil
|
||||||
|
case .show:
|
||||||
|
isMuted = false
|
||||||
|
case .hide:
|
||||||
|
isMuted = true
|
||||||
|
}
|
||||||
|
return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, isMuted: isMuted) |> deliverOnMainQueue
|
||||||
|
}
|
||||||
|
|
||||||
let mode: NotificationExceptionMode
|
let mode: NotificationExceptionMode
|
||||||
let defaultSound: PeerMessageSound
|
let defaultSound: PeerMessageSound
|
||||||
if let _ = peer as? TelegramUser {
|
if let _ = peer as? TelegramUser {
|
||||||
@ -4734,6 +4747,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
let _ = (updatePeerDisplayPreviews(peerId, displayPreviews)
|
let _ = (updatePeerDisplayPreviews(peerId, displayPreviews)
|
||||||
|> deliverOnMainQueue).start(next: { _ in
|
|> deliverOnMainQueue).start(next: { _ in
|
||||||
|
|
||||||
|
})
|
||||||
|
}, updatePeerStoryNotifications: { peerId, storyNotifications in
|
||||||
|
let _ = (updatePeerStoryNotifications(peerId, storyNotifications)
|
||||||
|
|> deliverOnMainQueue).start(next: { _ in
|
||||||
|
|
||||||
})
|
})
|
||||||
}, removePeerFromExceptions: {
|
}, removePeerFromExceptions: {
|
||||||
}, modifiedPeer: {
|
}, modifiedPeer: {
|
||||||
|
|||||||
@ -479,7 +479,11 @@ public func effectiveAutodownloadCategories(settings: MediaAutoDownloadSettings,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func categoryAndSizeForMedia(_ media: Media, categories: MediaAutoDownloadCategories) -> (MediaAutoDownloadCategory, Int32?)? {
|
private func categoryAndSizeForMedia(_ media: Media?, categories: MediaAutoDownloadCategories) -> (MediaAutoDownloadCategory, Int32?)? {
|
||||||
|
guard let media = media else {
|
||||||
|
return (categories.photo, 0)
|
||||||
|
}
|
||||||
|
|
||||||
if media is TelegramMediaImage || media is TelegramMediaWebFile {
|
if media is TelegramMediaImage || media is TelegramMediaWebFile {
|
||||||
return (categories.photo, 0)
|
return (categories.photo, 0)
|
||||||
} else if let file = media as? TelegramMediaFile {
|
} else if let file = media as? TelegramMediaFile {
|
||||||
@ -520,7 +524,7 @@ public func isAutodownloadEnabledForAnyPeerType(category: MediaAutoDownloadCateg
|
|||||||
return category.contacts || category.otherPrivate || category.groups || category.channels
|
return category.contacts || category.otherPrivate || category.groups || category.channels
|
||||||
}
|
}
|
||||||
|
|
||||||
public func shouldDownloadMediaAutomatically(settings: MediaAutoDownloadSettings, peerType: MediaAutoDownloadPeerType, networkType: MediaAutoDownloadNetworkType, authorPeerId: PeerId? = nil, contactsPeerIds: Set<PeerId> = Set(), media: Media) -> Bool {
|
public func shouldDownloadMediaAutomatically(settings: MediaAutoDownloadSettings, peerType: MediaAutoDownloadPeerType, networkType: MediaAutoDownloadNetworkType, authorPeerId: PeerId? = nil, contactsPeerIds: Set<PeerId> = Set(), media: Media?) -> Bool {
|
||||||
if (networkType == .cellular && !settings.cellular.enabled) || (networkType == .wifi && !settings.wifi.enabled) {
|
if (networkType == .cellular && !settings.cellular.enabled) || (networkType == .wifi && !settings.wifi.enabled) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -542,7 +546,7 @@ public func shouldDownloadMediaAutomatically(settings: MediaAutoDownloadSettings
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return size <= sizeLimit
|
return size <= sizeLimit
|
||||||
} else if media.id?.namespace == Namespaces.Media.LocalFile {
|
} else if media?.id?.namespace == Namespaces.Media.LocalFile {
|
||||||
return true
|
return true
|
||||||
} else if category.sizeLimit == Int32.max {
|
} else if category.sizeLimit == Int32.max {
|
||||||
return true
|
return true
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user