UI improvements

This commit is contained in:
Ali 2023-03-01 21:25:32 +04:00
parent 9525b92aac
commit 0102433f8b
12 changed files with 150 additions and 43 deletions

View File

@ -604,11 +604,11 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
},
tomorrowFormatString: { value in
//TODO:localize
return PresentationStrings.FormattedString(string: "at \(value)", ranges: [])
return PresentationStrings.FormattedString(string: "today at \(value)", ranges: [])
},
todayFormatString: { value in
//TODO:localize
return PresentationStrings.FormattedString(string: "at \(value)", ranges: [])
return PresentationStrings.FormattedString(string: "today at \(value)", ranges: [])
},
yesterdayFormatString: { value in
//TODO:localize

View File

@ -839,6 +839,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[347227392] = { return Api.Update.parse_updateGroupCall($0) }
dict[192428418] = { return Api.Update.parse_updateGroupCallConnection($0) }
dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) }
dict[-856651050] = { return Api.Update.parse_updateGroupInvitePrivacyForbidden($0) }
dict[1763610706] = { return Api.Update.parse_updateInlineBotCallbackQuery($0) }
dict[1442983757] = { return Api.Update.parse_updateLangPack($0) }
dict[1180041828] = { return Api.Update.parse_updateLangPackTooLong($0) }

View File

@ -777,6 +777,7 @@ public extension Api {
case updateGroupCall(chatId: Int64, call: Api.GroupCall)
case updateGroupCallConnection(flags: Int32, params: Api.DataJSON)
case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32)
case updateGroupInvitePrivacyForbidden(userId: Int64)
case updateInlineBotCallbackQuery(flags: Int32, queryId: Int64, userId: Int64, msgId: Api.InputBotInlineMessageID, chatInstance: Int64, data: Buffer?, gameShortName: String?)
case updateLangPack(difference: Api.LangPackDifference)
case updateLangPackTooLong(langCode: String)
@ -1324,6 +1325,12 @@ public extension Api {
}
serializeInt32(version, buffer: buffer, boxed: false)
break
case .updateGroupInvitePrivacyForbidden(let userId):
if boxed {
buffer.appendInt32(-856651050)
}
serializeInt64(userId, buffer: buffer, boxed: false)
break
case .updateInlineBotCallbackQuery(let flags, let queryId, let userId, let msgId, let chatInstance, let data, let gameShortName):
if boxed {
buffer.appendInt32(1763610706)
@ -1900,6 +1907,8 @@ public extension Api {
return ("updateGroupCallConnection", [("flags", flags as Any), ("params", params as Any)])
case .updateGroupCallParticipants(let call, let participants, let version):
return ("updateGroupCallParticipants", [("call", call as Any), ("participants", participants as Any), ("version", version as Any)])
case .updateGroupInvitePrivacyForbidden(let userId):
return ("updateGroupInvitePrivacyForbidden", [("userId", userId as Any)])
case .updateInlineBotCallbackQuery(let flags, let queryId, let userId, let msgId, let chatInstance, let data, let gameShortName):
return ("updateInlineBotCallbackQuery", [("flags", flags as Any), ("queryId", queryId as Any), ("userId", userId as Any), ("msgId", msgId as Any), ("chatInstance", chatInstance as Any), ("data", data as Any), ("gameShortName", gameShortName as Any)])
case .updateLangPack(let difference):
@ -3031,6 +3040,17 @@ public extension Api {
return nil
}
}
public static func parse_updateGroupInvitePrivacyForbidden(_ reader: BufferReader) -> Update? {
var _1: Int64?
_1 = reader.readInt64()
let _c1 = _1 != nil
if _c1 {
return Api.Update.updateGroupInvitePrivacyForbidden(userId: _1!)
}
else {
return nil
}
}
public static func parse_updateInlineBotCallbackQuery(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()

View File

@ -13,8 +13,21 @@ public enum CreateGroupError {
case serverProvided(String)
}
func _internal_createGroup(account: Account, title: String, peerIds: [PeerId], ttlPeriod: Int32?) -> Signal<PeerId?, CreateGroupError> {
return account.postbox.transaction { transaction -> Signal<PeerId?, CreateGroupError> in
public struct CreateGroupResult {
public var peerId: EnginePeer.Id
public var failedToInvitePeerIds: [EnginePeer.Id]
public init(
peerId: EnginePeer.Id,
failedToInvitePeerIds: [EnginePeer.Id]
) {
self.peerId = peerId
self.failedToInvitePeerIds = failedToInvitePeerIds
}
}
func _internal_createGroup(account: Account, title: String, peerIds: [PeerId], ttlPeriod: Int32?) -> Signal<CreateGroupResult?, CreateGroupError> {
return account.postbox.transaction { transaction -> Signal<CreateGroupResult?, CreateGroupError> in
var inputUsers: [Api.InputUser] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId), let inputUser = apiInputUser(peer) {
@ -36,7 +49,20 @@ func _internal_createGroup(account: Account, title: String, peerIds: [PeerId], t
}
return .generic
}
|> mapToSignal { updates -> Signal<PeerId?, CreateGroupError> in
|> mapToSignal { updates -> Signal<CreateGroupResult?, CreateGroupError> in
var failedToInvitePeerIds: [EnginePeer.Id] = []
failedToInvitePeerIds = []
switch updates {
case let .updates(updates, _, _, _, _):
for update in updates {
if case let .updateGroupInvitePrivacyForbidden(userId) = update {
failedToInvitePeerIds.append(EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(userId)))
}
}
default:
break
}
account.stateManager.addUpdates(updates)
if let message = updates.messages.first, let peerId = apiMessagePeerId(message) {
return account.postbox.multiplePeersView([peerId])
@ -45,8 +71,11 @@ func _internal_createGroup(account: Account, title: String, peerIds: [PeerId], t
}
|> take(1)
|> castError(CreateGroupError.self)
|> map { _ in
return peerId
|> map { _ -> CreateGroupResult in
return CreateGroupResult(
peerId: peerId,
failedToInvitePeerIds: failedToInvitePeerIds
)
}
} else {
return .single(nil)

View File

@ -138,7 +138,7 @@ public extension TelegramEngine {
return _internal_convertGroupToSupergroup(account: self.account, peerId: peerId)
}
public func createGroup(title: String, peerIds: [PeerId], ttlPeriod: Int32?) -> Signal<PeerId?, CreateGroupError> {
public func createGroup(title: String, peerIds: [PeerId], ttlPeriod: Int32?) -> Signal<CreateGroupResult?, CreateGroupError> {
return _internal_createGroup(account: self.account, title: title, peerIds: peerIds, ttlPeriod: ttlPeriod)
}

View File

@ -459,10 +459,12 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
actions.append(.action(ContextMenuActionItem(text: presentationData.strings.SponsoredMessageMenu_Info, textColor: .primary, textLayout: .twoLinesMax, textFont: .custom(font: Font.regular(presentationData.listsFontSize.baseDisplaySize - 1.0), height: nil, verticalOffset: nil), badge: nil, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.actionSheet.primaryTextColor)
}, iconSource: nil, action: { c, _ in
c.dismiss(completion: {
}, iconSource: nil, action: { _, f in
/*c.dismiss(completion: {
controllerInteraction.navigationController()?.pushViewController(AdInfoScreen(context: context))
})*/
f(.dismissWithoutContent)
controllerInteraction.navigationController()?.pushViewController(AdInfoScreen(context: context))
})
})))
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })

View File

@ -562,6 +562,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
strongSelf.videoFrame = displayVideoFrame
strongSelf.appliedForwardInfo = (forwardSource, forwardAuthorSignature)
strongSelf.secretProgressIcon = secretProgressIcon
strongSelf.automaticDownload = automaticDownload
var updatedReplyBackgroundNode: NavigationBackgroundNode?
@ -689,7 +690,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
}
}
}
}), content: NativeVideoContent(id: .message(item.message.stableId, telegramFile.fileId), userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile), streamVideo: streamVideo ? .conservative : .none, enableSound: false, fetchAutomatically: false, captureProtected: item.message.isCopyProtected(), storeAfterDownload: nil), priority: .embedded, autoplay: true)
}), content: NativeVideoContent(id: .message(item.message.stableId, telegramFile.fileId), userLocation: .peer(item.message.id.peerId), fileReference: .message(message: MessageReference(item.message), media: telegramFile), streamVideo: streamVideo ? .conservative : .none, enableSound: false, fetchAutomatically: false, captureProtected: item.message.isCopyProtected(), storeAfterDownload: nil), priority: .embedded, autoplay: item.context.sharedContext.energyUsageSettings.autoplayVideo)
if let previousVideoNode = previousVideoNode {
videoNode.bounds = previousVideoNode.bounds
videoNode.position = previousVideoNode.position

View File

@ -31,6 +31,7 @@ import ChatTimerScreen
import AsyncDisplayKit
import TextFormat
import AvatarEditorScreen
import SendInviteLinkScreen
private struct CreateGroupArguments {
let context: AccountContext
@ -606,13 +607,15 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
let autoremoveTimeout = stateValue.with({ $0 }).autoremoveTimeout ?? globalAutoremoveTimeout
let ttlPeriod: Int32? = autoremoveTimeout == 0 ? nil : autoremoveTimeout
var createSignal: Signal<PeerId?, CreateGroupError>
var createSignal: Signal<CreateGroupResult?, CreateGroupError>
switch mode {
case .generic:
createSignal = context.engine.peers.createGroup(title: title, peerIds: peerIds, ttlPeriod: ttlPeriod)
case .supergroup:
createSignal = context.engine.peers.createSupergroup(title: title, description: nil)
|> map(Optional.init)
|> map { peerId -> CreateGroupResult? in
return CreateGroupResult(peerId: peerId, failedToInvitePeerIds: [])
}
|> mapError { error -> CreateGroupError in
switch error {
case .generic:
@ -634,12 +637,14 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
createSignal = addressPromise.get()
|> castError(CreateGroupError.self)
|> mapToSignal { address -> Signal<PeerId?, CreateGroupError> in
|> mapToSignal { address -> Signal<CreateGroupResult?, CreateGroupError> in
guard let address = address else {
return .complete()
}
return context.engine.peers.createSupergroup(title: title, description: nil, location: (location.latitude, location.longitude, address))
|> map(Optional.init)
|> map { peerId -> CreateGroupResult? in
return CreateGroupResult(peerId: peerId, failedToInvitePeerIds: [])
}
|> mapError { error -> CreateGroupError in
switch error {
case .generic:
@ -661,9 +666,11 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
isForum = true
}
let createGroupSignal: (Bool) -> Signal<PeerId?, CreateGroupError> = { isForum in
let createGroupSignal: (Bool) -> Signal<CreateGroupResult?, CreateGroupError> = { isForum in
return context.engine.peers.createSupergroup(title: title, description: nil, isForum: isForum)
|> map(Optional.init)
|> map { peerId -> CreateGroupResult? in
return CreateGroupResult(peerId: peerId, failedToInvitePeerIds: [])
}
|> mapError { error -> CreateGroupError in
switch error {
case .generic:
@ -681,14 +688,14 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
}
if let publicLink, !publicLink.isEmpty {
createSignal = createGroupSignal(isForum)
|> mapToSignal { peerId in
if let peerId = peerId {
return context.engine.peers.updateAddressName(domain: .peer(peerId), name: publicLink)
|> mapToSignal { result in
if let result = result {
return context.engine.peers.updateAddressName(domain: .peer(result.peerId), name: publicLink)
|> mapError { _ in
return .generic
}
|> map { _ in
return peerId
|> map { _ -> CreateGroupResult? in
return result
}
} else {
return .fail(.generic)
@ -702,14 +709,14 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
if group.userAdminRights?.rights.contains(.canBeAnonymous) == true {
createSignal = createSignal
|> mapToSignal { peerId in
if let peerId = peerId {
return context.engine.peers.updateChannelAdminRights(peerId: peerId, adminId: context.account.peerId, rights: TelegramChatAdminRights(rights: .canBeAnonymous), rank: nil)
|> mapToSignal { result in
if let result = result {
return context.engine.peers.updateChannelAdminRights(peerId: result.peerId, adminId: context.account.peerId, rights: TelegramChatAdminRights(rights: .canBeAnonymous), rank: nil)
|> mapError { _ in
return .generic
}
|> map { _ in
return peerId
return result
}
} else {
return .fail(.generic)
@ -718,27 +725,32 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
}
}
let _ = createSignal
let _ = replaceControllerImpl
let _ = dismissImpl
let _ = uploadedVideoAvatar
actionsDisposable.add((createSignal
|> mapToSignal { peerId -> Signal<PeerId?, CreateGroupError> in
guard let peerId = peerId else {
|> mapToSignal { result -> Signal<CreateGroupResult?, CreateGroupError> in
guard let result = result else {
return .single(nil)
}
let updatingAvatar = stateValue.with {
return $0.avatar
}
if let _ = updatingAvatar {
return context.engine.peers.updatePeerPhoto(peerId: peerId, photo: uploadedAvatar.get(), video: uploadedVideoAvatar?.0.get(), videoStartTimestamp: uploadedVideoAvatar?.1, mapResourceToAvatarSizes: { resource, representations in
return context.engine.peers.updatePeerPhoto(peerId: result.peerId, photo: uploadedAvatar.get(), video: uploadedVideoAvatar?.0.get(), videoStartTimestamp: uploadedVideoAvatar?.1, mapResourceToAvatarSizes: { resource, representations in
return mapResourceToAvatarSizes(postbox: context.account.postbox, resource: resource, representations: representations)
})
|> ignoreValues
|> `catch` { _ -> Signal<Never, CreateGroupError> in
return .complete()
}
|> mapToSignal { _ -> Signal<PeerId?, CreateGroupError> in
|> mapToSignal { _ -> Signal<CreateGroupResult?, CreateGroupError> in
}
|> then(.single(peerId))
|> then(.single(result))
} else {
return .single(peerId)
return .single(result)
}
}
|> deliverOnMainQueue
@ -750,15 +762,48 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
return current
}
}
}).start(next: { peerId in
if let peerId = peerId {
}).start(next: { result in
if let result = result {
if let completion = completion {
completion(peerId, {
completion(result.peerId, {
dismissImpl?()
})
} else {
let controller = ChatControllerImpl(context: context, chatLocation: .peer(id: peerId))
let controller = ChatControllerImpl(context: context, chatLocation: .peer(id: result.peerId))
replaceControllerImpl?(controller)
if !result.failedToInvitePeerIds.isEmpty {
context.account.viewTracker.forceUpdateCachedPeerData(peerId: result.peerId)
let _ = (context.engine.data.subscribe(
TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: result.peerId)
)
|> filter { $0 != nil }
|> take(1)
|> timeout(1.0, queue: .mainQueue(), alternate: .single(nil))
|> deliverOnMainQueue).start(next: { [weak controller] exportedInvitation in
let _ = controller
let _ = exportedInvitation
if let exportedInvitation, let link = exportedInvitation.link {
let _ = (context.engine.data.get(
EngineDataList(result.failedToInvitePeerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
)
|> deliverOnMainQueue).start(next: { peerItems in
guard let controller else {
return
}
let _ = controller
let _ = peerItems
let peers = peerItems.compactMap { $0 }
if !peers.isEmpty {
let inviteScreen = SendInviteLinkScreen(context: context, link: link, peers: peers)
controller.push(inviteScreen)
}
})
}
})
}
}
}
}, error: { error in

View File

@ -496,7 +496,12 @@ public final class MediaManagerImpl: NSObject, MediaManager {
strongSelf.musicMediaPlayer?.control(.playback(.pause))
strongSelf.voiceMediaPlayer?.stop()
if let (account, playlist, settings, storedState) = inputData {
let voiceMediaPlayer = SharedMediaPlayer(mediaManager: strongSelf, inForeground: strongSelf.inForeground, account: account, audioSession: strongSelf.audioSession, overlayMediaManager: strongSelf.overlayMediaManager, playlist: playlist, initialOrder: .reversed, initialLooping: .none, initialPlaybackRate: settings.voicePlaybackRate, playerIndex: nextPlayerIndex, controlPlaybackWithProximity: true, type: type)
var continueInstantVideoLoopAfterFinish: Bool = true
if let playlist = playlist as? PeerMessagesMediaPlaylist {
continueInstantVideoLoopAfterFinish = playlist.context.sharedContext.energyUsageSettings.autoplayVideo
}
let voiceMediaPlayer = SharedMediaPlayer(mediaManager: strongSelf, inForeground: strongSelf.inForeground, account: account, audioSession: strongSelf.audioSession, overlayMediaManager: strongSelf.overlayMediaManager, playlist: playlist, initialOrder: .reversed, initialLooping: .none, initialPlaybackRate: settings.voicePlaybackRate, playerIndex: nextPlayerIndex, controlPlaybackWithProximity: true, type: type, continueInstantVideoLoopAfterFinish: continueInstantVideoLoopAfterFinish)
strongSelf.voiceMediaPlayer = voiceMediaPlayer
voiceMediaPlayer.playedToEnd = { [weak voiceMediaPlayer] in
if let strongSelf = self, let voiceMediaPlayer = voiceMediaPlayer, voiceMediaPlayer === strongSelf.voiceMediaPlayer {
@ -523,7 +528,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
strongSelf.musicMediaPlayer?.stop()
strongSelf.voiceMediaPlayer?.control(.playback(.pause))
if let (account, playlist, settings, storedState) = inputData {
let musicMediaPlayer = SharedMediaPlayer(mediaManager: strongSelf, inForeground: strongSelf.inForeground, account: account, audioSession: strongSelf.audioSession, overlayMediaManager: strongSelf.overlayMediaManager, playlist: playlist, initialOrder: settings.order, initialLooping: settings.looping, initialPlaybackRate: storedState?.playbackRate ?? .x1, playerIndex: nextPlayerIndex, controlPlaybackWithProximity: false, type: type)
let musicMediaPlayer = SharedMediaPlayer(mediaManager: strongSelf, inForeground: strongSelf.inForeground, account: account, audioSession: strongSelf.audioSession, overlayMediaManager: strongSelf.overlayMediaManager, playlist: playlist, initialOrder: settings.order, initialLooping: settings.looping, initialPlaybackRate: storedState?.playbackRate ?? .x1, playerIndex: nextPlayerIndex, controlPlaybackWithProximity: false, type: type, continueInstantVideoLoopAfterFinish: true)
strongSelf.musicMediaPlayer = musicMediaPlayer
musicMediaPlayer.cancelled = { [weak musicMediaPlayer] in
if let strongSelf = self, let musicMediaPlayer = musicMediaPlayer, musicMediaPlayer === strongSelf.musicMediaPlayer {

View File

@ -290,7 +290,7 @@ private final class VisualMediaItemNode: ASDisplayNode {
}
}
if let file = media as? TelegramMediaFile, file.isAnimated {
if let file = media as? TelegramMediaFile, file.isAnimated, self.context.sharedContext.energyUsageSettings.autoplayGif {
if self.videoLayerFrameManager == nil {
let sampleBufferLayer: SampleBufferLayer
if let current = self.sampleBufferLayer {

View File

@ -355,7 +355,7 @@ private struct PlaybackStack {
}
final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
private let context: AccountContext
let context: AccountContext
private let messagesLocation: PeerMessagesPlaylistLocation
private let chatLocationContextHolder: Atomic<ChatLocationContextHolder?>?

View File

@ -182,7 +182,7 @@ final class SharedMediaPlayer {
let type: MediaManagerPlayerType
init(mediaManager: MediaManager, inForeground: Signal<Bool, NoError>, account: Account, audioSession: ManagedAudioSession, overlayMediaManager: OverlayMediaManager, playlist: SharedMediaPlaylist, initialOrder: MusicPlaybackSettingsOrder, initialLooping: MusicPlaybackSettingsLooping, initialPlaybackRate: AudioPlaybackRate, playerIndex: Int32, controlPlaybackWithProximity: Bool, type: MediaManagerPlayerType) {
init(mediaManager: MediaManager, inForeground: Signal<Bool, NoError>, account: Account, audioSession: ManagedAudioSession, overlayMediaManager: OverlayMediaManager, playlist: SharedMediaPlaylist, initialOrder: MusicPlaybackSettingsOrder, initialLooping: MusicPlaybackSettingsLooping, initialPlaybackRate: AudioPlaybackRate, playerIndex: Int32, controlPlaybackWithProximity: Bool, type: MediaManagerPlayerType, continueInstantVideoLoopAfterFinish: Bool) {
self.mediaManager = mediaManager
self.account = account
self.audioSession = audioSession
@ -310,7 +310,11 @@ final class SharedMediaPlayer {
case let .audio(player):
player.pause()
case let .instantVideo(node):
if continueInstantVideoLoopAfterFinish {
node.setSoundEnabled(false)
} else {
node.pause()
}
}
}
strongSelf.playedToEnd?()