mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Stories
This commit is contained in:
parent
cf0cfb5c1e
commit
e5d948d90a
@ -9366,3 +9366,8 @@ Sorry for the inconvenience.";
|
||||
"Paint.Flip" = "Flip";
|
||||
|
||||
"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
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if case .broadcast = channel.info {
|
||||
@ -756,6 +769,9 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
|
||||
})
|
||||
}, updatePeerStoryNotifications: { peerId, storyNotifications in
|
||||
let _ = (updatePeerStoryNotifications(peerId, storyNotifications)
|
||||
|> deliverOnMainQueue).start()
|
||||
}, removePeerFromExceptions: {
|
||||
}, modifiedPeer: {
|
||||
})
|
||||
|
@ -341,6 +341,10 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
strongSelf.selectTab(id: targetTab)
|
||||
} else {
|
||||
if let componentView = strongSelf.chatListHeaderView(), let storyPeerListView = componentView.storyPeerListView() {
|
||||
storyPeerListView.scrollToTop()
|
||||
}
|
||||
|
||||
strongSelf.chatListDisplayNode.willScrollToTop()
|
||||
if let inlineStackContainerNode = strongSelf.chatListDisplayNode.inlineStackContainerNode {
|
||||
inlineStackContainerNode.currentItemNode.scrollToPosition(.top)
|
||||
@ -1726,12 +1730,37 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
self.displayNodeDidLoad()
|
||||
|
||||
if case .chatList(.root) = self.location {
|
||||
self.preloadStorySubscriptionsDisposable = (self.context.engine.messages.preloadStorySubscriptions(includeHidden: false)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] resources in
|
||||
let automaticDownloadNetworkType = context.account.networkType
|
||||
|> 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 {
|
||||
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] = []
|
||||
for (_, info) in resources.sorted(by: { $0.value.priority < $1.value.priority }) {
|
||||
let resource = info.resource
|
||||
|
@ -2011,6 +2011,11 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
targetView.layer.removeAnimation(forKey: "opacity")
|
||||
}
|
||||
|
||||
if strongSelf.hapticFeedback == nil {
|
||||
strongSelf.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
strongSelf.hapticFeedback?.tap()
|
||||
|
||||
guard let targetView = targetView as? ReactionIconView else {
|
||||
return
|
||||
}
|
||||
@ -2024,11 +2029,6 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
itemNode.frame = selfTargetBounds
|
||||
}
|
||||
|
||||
if strongSelf.hapticFeedback == nil {
|
||||
strongSelf.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
strongSelf.hapticFeedback?.tap()
|
||||
|
||||
if switchToInlineImmediately {
|
||||
mainAnimationCompleted = true
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
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.addSubnode(self.listNode)
|
||||
|
||||
@ -642,6 +659,16 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
||||
}
|
||||
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: {
|
||||
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: [peerId])
|
||||
|> 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)
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
let updateNotificationsDisposable = MetaDisposable()
|
||||
let updateNotificationsView: (@escaping () -> Void) -> Void = { completion in
|
||||
@ -550,6 +567,16 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
|
||||
}
|
||||
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: {
|
||||
let _ = (
|
||||
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)")
|
||||
var options: AVAudioSession.CategoryOptions = []
|
||||
switch type {
|
||||
case .play, .ambient:
|
||||
case .play:
|
||||
break
|
||||
case .ambient:
|
||||
options.insert(.mixWithOthers)
|
||||
case .playWithPossiblePortOverride:
|
||||
if case .playAndRecord = nativeCategory {
|
||||
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> {
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
_internal_updatePeerNotificationSoundInteractive(account: account, transaction: transaction, peerId: peerId, threadId: threadId, sound: sound)
|
||||
|
@ -268,6 +268,10 @@ public extension TelegramEngine {
|
||||
public func updatePeerDisplayPreviewsSetting(peerId: PeerId, threadId: Int64?, displayPreviews: PeerNotificationDisplayPreviews) -> Signal<Void, NoError> {
|
||||
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> {
|
||||
return _internal_updatePeerNotificationSoundInteractive(account: self.account, peerId: peerId, threadId: threadId, sound: sound)
|
||||
|
@ -25,6 +25,7 @@ public enum MessageContentKindKey {
|
||||
case restricted
|
||||
case dice
|
||||
case invoice
|
||||
case story
|
||||
}
|
||||
|
||||
public enum MessageContentKind: Equatable {
|
||||
@ -46,6 +47,7 @@ public enum MessageContentKind: Equatable {
|
||||
case restricted(String)
|
||||
case dice(String)
|
||||
case invoice(String)
|
||||
case story
|
||||
|
||||
public func isSemanticallyEqual(to other: MessageContentKind) -> Bool {
|
||||
switch self {
|
||||
@ -157,6 +159,12 @@ public enum MessageContentKind: Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .story:
|
||||
if case .story = other {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,6 +206,8 @@ public enum MessageContentKind: Equatable {
|
||||
return .dice
|
||||
case .invoice:
|
||||
return .invoice
|
||||
case .story:
|
||||
return .story
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -332,6 +342,8 @@ public func mediaContentKind(_ media: EngineMedia, message: EngineMessage? = nil
|
||||
} else {
|
||||
return .invoice(invoice.title)
|
||||
}
|
||||
case .story:
|
||||
return .story
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
@ -383,6 +395,9 @@ public func stringForMediaKind(_ kind: MessageContentKind, strings: Presentation
|
||||
return (NSAttributedString(string: emoji), true)
|
||||
case let .invoice(text):
|
||||
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)
|
||||
})
|
||||
}, updatePeerStoryNotifications: { _, _ in
|
||||
}, removePeerFromExceptions: {
|
||||
let _ = context.engine.peers.removeCustomThreadNotificationSettings(peerId: peerId, threadIds: [item.threadId]).start()
|
||||
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] {
|
||||
switch self {
|
||||
case let .users(settings), let .groups(settings), let .channels(settings):
|
||||
@ -236,6 +282,7 @@ private enum NotificationPeerExceptionSection: Int32 {
|
||||
case remove
|
||||
case switcher
|
||||
case displayPreviews
|
||||
case storyNotifications
|
||||
case soundCloud
|
||||
case soundModern
|
||||
case soundClassic
|
||||
@ -253,6 +300,8 @@ private enum NotificationPeerExceptionEntryId: Hashable {
|
||||
case switcherHeader
|
||||
case displayPreviews(NotificationPeerExceptionSwitcher)
|
||||
case displayPreviewsHeader
|
||||
case storyNotifications(NotificationPeerExceptionSwitcher)
|
||||
case storyNotificationsHeader
|
||||
case soundModernHeader
|
||||
case soundClassicHeader
|
||||
case none
|
||||
@ -268,17 +317,19 @@ private final class NotificationPeerExceptionArguments {
|
||||
let selectSound: (PeerMessageSound) -> Void
|
||||
let selectMode: (NotificationPeerExceptionSwitcher) -> Void
|
||||
let selectDisplayPreviews: (NotificationPeerExceptionSwitcher) -> Void
|
||||
let selectStoryNotifications: (NotificationPeerExceptionSwitcher) -> Void
|
||||
let removeFromExceptions: () -> Void
|
||||
let complete: () -> Void
|
||||
let cancel: () -> Void
|
||||
let upload: () -> 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.selectSound = selectSound
|
||||
self.selectMode = selectMode
|
||||
self.selectDisplayPreviews = selectDisplayPreviews
|
||||
self.selectStoryNotifications = selectStoryNotifications
|
||||
self.removeFromExceptions = removeFromExceptions
|
||||
self.complete = complete
|
||||
self.cancel = cancel
|
||||
@ -296,6 +347,8 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
||||
case switcherHeader(index:Int32, theme: PresentationTheme, title: String)
|
||||
case displayPreviews(index:Int32, theme: PresentationTheme, strings: PresentationStrings, value: NotificationPeerExceptionSwitcher, selected: Bool)
|
||||
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 soundClassicHeader(index:Int32, theme: PresentationTheme, title: String)
|
||||
case none(index:Int32, section: NotificationPeerExceptionSection, theme: PresentationTheme, text: String, selected: Bool)
|
||||
@ -317,6 +370,10 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
||||
return index
|
||||
case let .displayPreviews(index, _, _, _, _):
|
||||
return index
|
||||
case let .storyNotificationsHeader(index, _, _):
|
||||
return index
|
||||
case let .storyNotifications(index, _, _, _, _):
|
||||
return index
|
||||
case let .soundModernHeader(index, _, _):
|
||||
return index
|
||||
case let .soundClassicHeader(index, _, _):
|
||||
@ -344,6 +401,8 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
||||
return NotificationPeerExceptionSection.switcher.rawValue
|
||||
case .displayPreviews, .displayPreviewsHeader:
|
||||
return NotificationPeerExceptionSection.displayPreviews.rawValue
|
||||
case .storyNotifications, .storyNotificationsHeader:
|
||||
return NotificationPeerExceptionSection.storyNotifications.rawValue
|
||||
case .cloudInfo, .cloudHeader, .uploadSound:
|
||||
return NotificationPeerExceptionSection.soundCloud.rawValue
|
||||
case .soundModernHeader:
|
||||
@ -371,6 +430,10 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
||||
return .displayPreviews(mode)
|
||||
case .displayPreviewsHeader:
|
||||
return .displayPreviewsHeader
|
||||
case let .storyNotifications(_, _, _, mode, _):
|
||||
return .storyNotifications(mode)
|
||||
case .storyNotificationsHeader:
|
||||
return .storyNotificationsHeader
|
||||
case .soundModernHeader:
|
||||
return .soundModernHeader
|
||||
case .soundClassicHeader:
|
||||
@ -436,6 +499,19 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
||||
})
|
||||
case let .displayPreviewsHeader(_, _, text):
|
||||
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):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
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)
|
||||
|
||||
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))
|
||||
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))
|
||||
index += 1
|
||||
|
||||
@ -550,6 +636,7 @@ private struct NotificationExceptionPeerState : Equatable {
|
||||
var mode: NotificationPeerExceptionSwitcher
|
||||
var defaultSound: PeerMessageSound
|
||||
var displayPreviews: NotificationPeerExceptionSwitcher
|
||||
var storyNotifications: NotificationPeerExceptionSwitcher
|
||||
var removedSounds: [PeerMessageSound]
|
||||
|
||||
init(canRemove: Bool, notifications: TelegramPeerNotificationSettings? = nil) {
|
||||
@ -564,27 +651,30 @@ private struct NotificationExceptionPeerState : Equatable {
|
||||
self.mode = .alwaysOn
|
||||
}
|
||||
self.displayPreviews = notifications.displayPreviews == .hide ? .alwaysOff : .alwaysOn
|
||||
self.storyNotifications = notifications.storiesMuted == false ? .alwaysOff : .alwaysOn
|
||||
} else {
|
||||
self.selectedSound = .default
|
||||
self.mode = .alwaysOn
|
||||
self.displayPreviews = .alwaysOn
|
||||
self.storyNotifications = .alwaysOn
|
||||
}
|
||||
|
||||
self.defaultSound = .default
|
||||
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.selectedSound = selectedSound
|
||||
self.mode = mode
|
||||
self.defaultSound = defaultSound
|
||||
self.displayPreviews = displayPreviews
|
||||
self.storyNotifications = storyNotifications
|
||||
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 statePromise = Promise(initialState)
|
||||
let stateValue = Atomic(value: initialState)
|
||||
@ -625,6 +715,12 @@ public func notificationPeerExceptionController(context: AccountContext, updated
|
||||
state.displayPreviews = value
|
||||
return state
|
||||
}
|
||||
}, selectStoryNotifications: { value in
|
||||
updateState { state in
|
||||
var state = state
|
||||
state.storyNotifications = value
|
||||
return state
|
||||
}
|
||||
}, removeFromExceptions: {
|
||||
removeFromExceptionsImpl?()
|
||||
}, 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 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))
|
||||
}
|
||||
@ -709,6 +805,7 @@ public func notificationPeerExceptionController(context: AccountContext, updated
|
||||
updatePeerSound(peer.id, resolvedNotificationSound(sound: state.selectedSound, notificationSoundList: notificationSoundList))
|
||||
updatePeerNotificationInterval(peer.id, state.mode == .alwaysOn ? 0 : Int32.max)
|
||||
updatePeerDisplayPreviews(peer.id, state.displayPreviews == .alwaysOn ? .show : .hide)
|
||||
updatePeerStoryNotifications(peer.id, state.storyNotifications == .alwaysOn ? .show : .hide)
|
||||
return state
|
||||
}
|
||||
})
|
||||
|
@ -373,6 +373,8 @@ private final class StoryContainerScreenComponent: Component {
|
||||
case .began:
|
||||
self.verticalPanState = ItemSetPanState(fraction: 0.0, didBegin: true)
|
||||
self.state?.updated(transition: .immediate)
|
||||
|
||||
self.dismissAllTooltips()
|
||||
case .changed:
|
||||
let translation = recognizer.translation(in: self)
|
||||
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
|
||||
}
|
||||
|
||||
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() {
|
||||
if let component = self.component {
|
||||
component.focusedItemPromise.set(self.focusedItem.get())
|
||||
|
@ -229,7 +229,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
let contentContainerView: UIView
|
||||
let topContentGradientLayer: SimpleGradientLayer
|
||||
let bottomContentGradientLayer: SimpleGradientLayer
|
||||
let contentDimLayer: SimpleLayer
|
||||
let contentDimView: UIView
|
||||
|
||||
let closeButton: HighlightableButton
|
||||
let closeButtonIconView: UIImageView
|
||||
@ -287,7 +287,9 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
|
||||
self.topContentGradientLayer = SimpleGradientLayer()
|
||||
self.bottomContentGradientLayer = SimpleGradientLayer()
|
||||
self.contentDimLayer = SimpleLayer()
|
||||
|
||||
self.contentDimView = UIView()
|
||||
self.contentDimView.isUserInteractionEnabled = false
|
||||
|
||||
self.closeButton = HighlightableButton()
|
||||
self.closeButtonIconView = UIImageView()
|
||||
@ -312,7 +314,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
self.scrollView.clipsToBounds = true
|
||||
|
||||
self.addSubview(self.contentContainerView)
|
||||
self.contentContainerView.layer.addSublayer(self.contentDimLayer)
|
||||
self.contentContainerView.addSubview(self.contentDimView)
|
||||
self.contentContainerView.layer.addSublayer(self.topContentGradientLayer)
|
||||
self.layer.addSublayer(self.bottomContentGradientLayer)
|
||||
|
||||
@ -970,7 +972,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
self.bottomContentGradientLayer.colors = colors
|
||||
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()
|
||||
@ -1767,7 +1769,12 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
|
||||
let centerInfoItemSize = currentCenterInfoItem.view.update(
|
||||
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: {},
|
||||
containerSize: CGSize(width: contentFrame.width, height: 44.0)
|
||||
)
|
||||
@ -2125,12 +2132,12 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
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) {
|
||||
Transition(animation: .curve(duration: 0.25, curve: .easeInOut)).setAlpha(layer: self.contentDimLayer, alpha: dimAlpha)
|
||||
if transition.animation.isImmediate && forceDimAnimation && self.contentDimView.alpha != dimAlpha {
|
||||
Transition(animation: .curve(duration: 0.25, curve: .easeInOut)).setAlpha(view: self.contentDimView, alpha: dimAlpha)
|
||||
} else {
|
||||
transition.setAlpha(layer: self.contentDimLayer, alpha: dimAlpha)
|
||||
transition.setAlpha(view: self.contentDimView, alpha: dimAlpha)
|
||||
}
|
||||
|
||||
self.ignoreScrolling = true
|
||||
|
@ -315,6 +315,61 @@ final class StoryItemSetContainerSendMessage {
|
||||
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
|
||||
view.updateIsProgressPaused()
|
||||
|
||||
|
@ -247,6 +247,10 @@ public final class StoryPeerListComponent: Component {
|
||||
return nil
|
||||
}
|
||||
|
||||
public func scrollToTop() {
|
||||
self.scrollView.setContentOffset(CGPoint(), animated: true)
|
||||
}
|
||||
|
||||
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
if !self.ignoreScrolling {
|
||||
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 {
|
||||
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)))
|
||||
} else if let mappedRightCenter {
|
||||
avatarPath.addEllipse(in: CGRect(origin: CGPoint(), size: avatarSize).insetBy(dx: -indicatorLineWidth, dy: -indicatorLineWidth).offsetBy(dx: abs(mappedRightCenter.x - indicatorCenter.x), dy: 0.0))
|
||||
} else if let mappedLeftCenter {
|
||||
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)
|
||||
|
||||
|
@ -700,6 +700,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
var isSticker = false
|
||||
var maxDimensions = layoutConstants.image.maxDimensions
|
||||
var maxHeight = layoutConstants.image.maxDimensions.height
|
||||
var isStory = false
|
||||
|
||||
var unboundSize: CGSize
|
||||
if let _ = media as? TelegramMediaStory {
|
||||
@ -987,6 +988,8 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
}
|
||||
|
||||
if let story = media as? TelegramMediaStory {
|
||||
isStory = true
|
||||
|
||||
if hasCurrentVideoNode {
|
||||
replaceVideoNode = true
|
||||
}
|
||||
@ -1058,7 +1061,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
uploading = true
|
||||
}
|
||||
|
||||
if file.isVideo && !file.isVideoSticker && !isSecretMedia && automaticPlayback && !uploading {
|
||||
if file.isVideo && !file.isVideoSticker && !isSecretMedia && automaticPlayback && !isStory && !uploading {
|
||||
updateVideoFile = file
|
||||
if hasCurrentVideoNode {
|
||||
if let currentFile = currentMedia as? TelegramMediaFile {
|
||||
@ -1194,7 +1197,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
uploading = true
|
||||
}
|
||||
|
||||
if file.isVideo && !file.isVideoSticker && !isSecretMedia && automaticPlayback && !uploading {
|
||||
if file.isVideo && !file.isVideoSticker && !isSecretMedia && automaticPlayback && !isStory && !uploading {
|
||||
updateVideoFile = file
|
||||
if hasCurrentVideoNode {
|
||||
if let currentFile = currentMedia as? TelegramMediaFile {
|
||||
|
@ -466,6 +466,13 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
||||
)
|
||||
|> 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(
|
||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||
accountsAndPeers,
|
||||
@ -487,9 +494,10 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
||||
|> mapToSignal { settings -> Signal<Bool, NoError> in
|
||||
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 (featuredStickerPacks, archivedStickerPacks) = stickerPacks
|
||||
|
||||
@ -546,7 +554,7 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
||||
groupsInCommon: nil,
|
||||
linkedDiscussionPeer: nil,
|
||||
members: nil,
|
||||
storyListContext: nil,
|
||||
storyListContext: storyListContext,
|
||||
encryptionKeyFingerprint: nil,
|
||||
globalSettings: globalSettings,
|
||||
invitations: nil,
|
||||
|
@ -4685,6 +4685,19 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
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 defaultSound: PeerMessageSound
|
||||
if let _ = peer as? TelegramUser {
|
||||
@ -4734,6 +4747,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
let _ = (updatePeerDisplayPreviews(peerId, displayPreviews)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
|
||||
})
|
||||
}, updatePeerStoryNotifications: { peerId, storyNotifications in
|
||||
let _ = (updatePeerStoryNotifications(peerId, storyNotifications)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
|
||||
})
|
||||
}, removePeerFromExceptions: {
|
||||
}, 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 {
|
||||
return (categories.photo, 0)
|
||||
} 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
|
||||
}
|
||||
|
||||
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) {
|
||||
return false
|
||||
}
|
||||
@ -542,7 +546,7 @@ public func shouldDownloadMediaAutomatically(settings: MediaAutoDownloadSettings
|
||||
return false
|
||||
}
|
||||
return size <= sizeLimit
|
||||
} else if media.id?.namespace == Namespaces.Media.LocalFile {
|
||||
} else if media?.id?.namespace == Namespaces.Media.LocalFile {
|
||||
return true
|
||||
} else if category.sizeLimit == Int32.max {
|
||||
return true
|
||||
|
Loading…
x
Reference in New Issue
Block a user