mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 08:31:13 +00:00
223 lines
9.5 KiB
Swift
223 lines
9.5 KiB
Swift
import Foundation
|
|
import Postbox
|
|
import TelegramCore
|
|
import SwiftSignalKit
|
|
|
|
struct PeerMessageHistoryAudioPlaylistItemId: AudioPlaylistItemId {
|
|
let id: MessageId
|
|
|
|
var hashValue: Int {
|
|
return self.id.hashValue
|
|
}
|
|
|
|
func isEqual(to: AudioPlaylistItemId) -> Bool {
|
|
if let other = to as? PeerMessageHistoryAudioPlaylistItemId {
|
|
return self.id == other.id
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
final class PeerMessageHistoryAudioPlaylistItem: AudioPlaylistItem {
|
|
let entry: MessageHistoryEntry
|
|
|
|
var id: AudioPlaylistItemId {
|
|
return PeerMessageHistoryAudioPlaylistItemId(id: self.entry.index.id)
|
|
}
|
|
|
|
var resource: MediaResource? {
|
|
switch self.entry {
|
|
case let .MessageEntry(message, _, _, _):
|
|
for media in message.media {
|
|
if let file = media as? TelegramMediaFile {
|
|
return file.resource
|
|
} else if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content, let file = content.file {
|
|
return file.resource
|
|
}
|
|
}
|
|
return nil
|
|
case .HoleEntry:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
var streamable: Bool {
|
|
switch self.entry {
|
|
case let .MessageEntry(message, _, _, _):
|
|
for media in message.media {
|
|
if let file = media as? TelegramMediaFile {
|
|
if file.isMusic {
|
|
return true
|
|
} else if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content, let file = content.file {
|
|
if file.isMusic {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
case .HoleEntry:
|
|
return false
|
|
}
|
|
}
|
|
|
|
var info: AudioPlaylistItemInfo? {
|
|
switch self.entry {
|
|
case let .MessageEntry(message, _, _, _):
|
|
for media in message.media {
|
|
if let file = media as? TelegramMediaFile {
|
|
for attribute in file.attributes {
|
|
switch attribute {
|
|
case let .Audio(isVoice, duration, title, performer, _):
|
|
if isVoice {
|
|
return AudioPlaylistItemInfo(duration: Double(duration), labelInfo: .voice)
|
|
} else {
|
|
return AudioPlaylistItemInfo(duration: Double(duration), labelInfo: .music(title: title, performer: performer))
|
|
}
|
|
case let .Video(duration, _, flags):
|
|
if flags.contains(.instantRoundVideo) {
|
|
return AudioPlaylistItemInfo(duration: Double(duration), labelInfo: .video)
|
|
}
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
return nil
|
|
} else if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content, let file = content.file {
|
|
for attribute in file.attributes {
|
|
switch attribute {
|
|
case let .Audio(isVoice, duration, title, performer, _):
|
|
if isVoice {
|
|
return AudioPlaylistItemInfo(duration: Double(duration), labelInfo: .voice)
|
|
} else {
|
|
return AudioPlaylistItemInfo(duration: Double(duration), labelInfo: .music(title: title, performer: performer))
|
|
}
|
|
case let .Video(duration, _, flags):
|
|
if flags.contains(.instantRoundVideo) {
|
|
return AudioPlaylistItemInfo(duration: Double(duration), labelInfo: .video)
|
|
}
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
case .HoleEntry:
|
|
break
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
init(entry: MessageHistoryEntry) {
|
|
self.entry = entry
|
|
}
|
|
|
|
func isEqual(to: AudioPlaylistItem) -> Bool {
|
|
if let other = to as? PeerMessageHistoryAudioPlaylistItem {
|
|
return self.entry == other.entry
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
struct PeerMessageHistoryAudioPlaylistId: AudioPlaylistId {
|
|
let peerId: PeerId
|
|
|
|
func isEqual(to: AudioPlaylistId) -> Bool {
|
|
if let other = to as? PeerMessageHistoryAudioPlaylistId {
|
|
if self.peerId != other.peerId {
|
|
return false
|
|
}
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
func peerMessageAudioPlaylistAndItemIds(_ message: Message) -> (AudioPlaylistId, AudioPlaylistItemId)? {
|
|
return (PeerMessageHistoryAudioPlaylistId(peerId: message.id.peerId), PeerMessageHistoryAudioPlaylistItemId(id: message.id))
|
|
}
|
|
|
|
func peerMessageHistoryAudioPlaylist(account: Account, messageId: MessageId) -> AudioPlaylist {
|
|
return AudioPlaylist(id: PeerMessageHistoryAudioPlaylistId(peerId: messageId.peerId), navigate: { item, navigation in
|
|
if let item = item as? PeerMessageHistoryAudioPlaylistItem {
|
|
var tagMask: MessageTags?
|
|
switch item.entry {
|
|
case let .MessageEntry(message, _, _, _):
|
|
for media in message.media {
|
|
if let file = media as? TelegramMediaFile {
|
|
inner: for attribute in file.attributes {
|
|
switch attribute {
|
|
case let .Video(_, _, flags):
|
|
if flags.contains(.instantRoundVideo) {
|
|
tagMask = .voiceOrInstantVideo
|
|
break inner
|
|
}
|
|
case let .Audio(isVoice, _, _, _, _):
|
|
if isVoice {
|
|
tagMask = .voiceOrInstantVideo
|
|
} else {
|
|
tagMask = .music
|
|
}
|
|
break inner
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
break
|
|
}
|
|
}
|
|
case .HoleEntry:
|
|
break
|
|
}
|
|
if let tagMask = tagMask {
|
|
return account.postbox.aroundMessageHistoryViewForLocation(.peer(item.entry.index.id.peerId), index: .message(item.entry.index), anchorIndex: .message(item.entry.index), count: 10, clipHoles: false, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: tagMask, orderStatistics: [])
|
|
|> take(1)
|
|
|> map { (view, _, _) -> AudioPlaylistItem? in
|
|
var index = 0
|
|
for entry in view.entries {
|
|
if entry.index.id == item.entry.index.id {
|
|
switch navigation {
|
|
case .previous:
|
|
if index != 0 {
|
|
return PeerMessageHistoryAudioPlaylistItem(entry: view.entries[index - 1])
|
|
} else {
|
|
return PeerMessageHistoryAudioPlaylistItem(entry: view.entries.first!)
|
|
}
|
|
case .next:
|
|
if index + 1 < view.entries.count {
|
|
return PeerMessageHistoryAudioPlaylistItem(entry: view.entries[index + 1])
|
|
} else {
|
|
return nil//PeerMessageHistoryAudioPlaylistItem(entry: view.entries.last!)
|
|
}
|
|
}
|
|
}
|
|
index += 1
|
|
}
|
|
if !view.entries.isEmpty {
|
|
return PeerMessageHistoryAudioPlaylistItem(entry: view.entries.first!)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
} else {
|
|
return .single(nil)
|
|
}
|
|
} else {
|
|
return account.postbox.messageAtId(messageId)
|
|
|> map { message -> AudioPlaylistItem? in
|
|
if let message = message {
|
|
return PeerMessageHistoryAudioPlaylistItem(entry: .MessageEntry(message, false, nil, nil))
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|