mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-06 21:22:44 +00:00
no message
This commit is contained in:
@@ -30,11 +30,9 @@ enum ChatMediaGalleryThumbnail: Equatable {
|
||||
final class ChatMediaGalleryThumbnailItem: GalleryThumbnailItem {
|
||||
private let account: Account
|
||||
private let thumbnail: ChatMediaGalleryThumbnail
|
||||
private let requestForIndex: () -> Int?
|
||||
|
||||
init?(account: Account, mediaReference: AnyMediaReference, requestForIndex: @escaping () -> Int?) {
|
||||
init?(account: Account, mediaReference: AnyMediaReference) {
|
||||
self.account = account
|
||||
self.requestForIndex = requestForIndex
|
||||
if let imageReference = mediaReference.concrete(TelegramMediaImage.self) {
|
||||
self.thumbnail = .image(imageReference)
|
||||
} else if let fileReference = mediaReference.concrete(TelegramMediaFile.self), fileReference.media.isVideo {
|
||||
@@ -68,10 +66,6 @@ final class ChatMediaGalleryThumbnailItem: GalleryThumbnailItem {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var index: Int? {
|
||||
return self.requestForIndex()
|
||||
}
|
||||
}
|
||||
|
||||
class ChatImageGalleryItem: GalleryItem {
|
||||
@@ -136,7 +130,7 @@ class ChatImageGalleryItem: GalleryItem {
|
||||
}
|
||||
}
|
||||
if let mediaReference = mediaReference {
|
||||
if let item = ChatMediaGalleryThumbnailItem(account: self.account, mediaReference: mediaReference, requestForIndex: { return 0 }) {
|
||||
if let item = ChatMediaGalleryThumbnailItem(account: self.account, mediaReference: mediaReference) {
|
||||
return (Int64(id), item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,11 +96,15 @@ class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGestureRecog
|
||||
if let (updatedItems, index, progress) = itemsIndexAndProgress {
|
||||
if let (centralId, centralItem) = strongSelf.pager.items[index].thumbnailItem() {
|
||||
var items: [GalleryThumbnailItem]
|
||||
var indexes: [Int]?
|
||||
|
||||
if updatedItems != nil || strongSelf.currentThumbnailContainerNode == nil {
|
||||
items = [centralItem]
|
||||
indexes = [index]
|
||||
for i in (0 ..< index).reversed() {
|
||||
if let (id, item) = strongSelf.pager.items[i].thumbnailItem(), id == centralId {
|
||||
items.insert(item, at: 0)
|
||||
indexes?.insert(i, at: 0)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
@@ -108,6 +112,7 @@ class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGestureRecog
|
||||
for i in (index + 1) ..< strongSelf.pager.items.count {
|
||||
if let (id, item) = strongSelf.pager.items[i].thumbnailItem(), id == centralId {
|
||||
items.append(item)
|
||||
indexes?.append(i)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
@@ -123,15 +128,17 @@ class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGestureRecog
|
||||
let convertedIndex = (index, progress)
|
||||
if strongSelf.currentThumbnailContainerNode?.groupId != centralId {
|
||||
node = GalleryThumbnailContainerNode(groupId: centralId)
|
||||
node?.itemChanged = { [weak self] index in
|
||||
if let strongSelf = self {
|
||||
//strongSelf.pager.transaction(GalleryPagerTransaction(deleteItems: [], insertItems: [], updateItems: [], focusOnItem: index))
|
||||
}
|
||||
}
|
||||
node?.updateItems(items, centralIndex: convertedIndex.0, progress: convertedIndex.1)
|
||||
} else {
|
||||
node = strongSelf.currentThumbnailContainerNode
|
||||
node?.updateItems(items, centralIndex: convertedIndex.0, progress: convertedIndex.1)
|
||||
}
|
||||
node?.updateItems(items, centralIndex: convertedIndex.0, progress: convertedIndex.1)
|
||||
if let indexes = indexes {
|
||||
node?.itemChanged = { [weak self] index in
|
||||
if let strongSelf = self {
|
||||
let pagerIndex = indexes[index]
|
||||
strongSelf.pager.transaction(GalleryPagerTransaction(deleteItems: [], insertItems: [], updateItems: [], focusOnItem: pagerIndex))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,6 +214,12 @@ final class GalleryPagerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
self.updateItemNodes(transition: .immediate)
|
||||
}
|
||||
else if let focusOnItem = transaction.focusOnItem {
|
||||
self.ignoreCentralItemIndexUpdate = true
|
||||
self.centralItemIndex = focusOnItem
|
||||
self.ignoreCentralItemIndexUpdate = false
|
||||
self.updateItemNodes(transition: .immediate, forceOffsetReset: true)
|
||||
}
|
||||
}
|
||||
|
||||
private func makeNodeForItem(at index: Int) -> GalleryItemNode {
|
||||
@@ -255,12 +261,17 @@ final class GalleryPagerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.itemNodes.remove(at: internalIndex)
|
||||
}
|
||||
|
||||
private func updateItemNodes(transition: ContainedViewLayoutTransition) {
|
||||
private func updateItemNodes(transition: ContainedViewLayoutTransition, forceOffsetReset: Bool = false) {
|
||||
if self.items.isEmpty || self.containerLayout == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var resetOffsetToCentralItem = false
|
||||
var resetOffsetToCentralItem = forceOffsetReset
|
||||
if let centralItemIndex = self.centralItemIndex, self.visibleItemNode(at: centralItemIndex) == nil, !self.itemNodes.isEmpty {
|
||||
repeat {
|
||||
self.removeVisibleItemNode(internalIndex: self.itemNodes.count - 1)
|
||||
} while self.itemNodes.count > 0
|
||||
}
|
||||
if self.itemNodes.isEmpty {
|
||||
let node = self.makeNodeForItem(at: self.centralItemIndex ?? 0)
|
||||
node.frame = CGRect(origin: CGPoint(), size: scrollView.bounds.size)
|
||||
@@ -272,7 +283,7 @@ final class GalleryPagerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
resetOffsetToCentralItem = true
|
||||
}
|
||||
|
||||
var notifyCentralItemUpdated = false
|
||||
var notifyCentralItemUpdated = forceOffsetReset
|
||||
|
||||
if let centralItemIndex = self.centralItemIndex, let centralItemNode = self.visibleItemNode(at: centralItemIndex) {
|
||||
if centralItemIndex != 0 {
|
||||
|
||||
@@ -10,7 +10,6 @@ private let maxWidth: CGFloat = 75.0
|
||||
protocol GalleryThumbnailItem {
|
||||
func isEqual(to: GalleryThumbnailItem) -> Bool
|
||||
var image: (Signal<(TransformImageArguments) -> DrawingContext?, NoError>, CGSize) { get }
|
||||
var index: Int? { get }
|
||||
}
|
||||
|
||||
private final class GalleryThumbnailItemNode: ASDisplayNode {
|
||||
@@ -73,14 +72,13 @@ final class GalleryThumbnailContainerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.addSubnode(self.scrollNode)
|
||||
}
|
||||
|
||||
@objc private func tapGesture(_ recognizer: UITapGestureRecognizer)
|
||||
{
|
||||
@objc private func tapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||
let location = recognizer.location(in: recognizer.view)
|
||||
for i in 0 ..< self.itemNodes.count {
|
||||
let view = self.itemNodes[i]
|
||||
if view.frame.contains(location) {
|
||||
self.updateCentralIndexAndProgress(centralIndex: i, progress: 0.0)
|
||||
self.itemChanged?(self.items[i].index!)
|
||||
self.updateCentralIndexAndProgress(centralIndex: i, progress: 0.0, transition: .animated(duration: 0.4, curve: .spring))
|
||||
self.itemChanged?(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -128,10 +126,10 @@ final class GalleryThumbnailContainerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func updateCentralIndexAndProgress(centralIndex: Int, progress: CGFloat) {
|
||||
func updateCentralIndexAndProgress(centralIndex: Int, progress: CGFloat, transition: ContainedViewLayoutTransition = .immediate) {
|
||||
self.centralIndexAndProgress = (centralIndex, progress)
|
||||
if let size = self.currentLayout {
|
||||
self.updateLayout(size: size, transition: .immediate)
|
||||
self.updateLayout(size: size, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +164,9 @@ final class GalleryThumbnailContainerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
|
||||
if updated || !self.isPanning {
|
||||
self.scrollNode.view.contentOffset = contentOffsetToCenterItem(index: centralIndex, progress: progress, contentInset: contentInset)
|
||||
transition.animateView {
|
||||
self.scrollNode.view.contentOffset = self.contentOffsetToCenterItem(index: centralIndex, progress: progress, contentInset: contentInset)
|
||||
}
|
||||
}
|
||||
|
||||
let progress = progress ?? 0.0
|
||||
@@ -186,9 +186,14 @@ final class GalleryThumbnailContainerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
let itemSpacing = itemProgress * centralSpacing + (1.0 - itemProgress) * spacing
|
||||
let itemWidth = self.itemNodes[i].updateLayout(height: itemBaseSize.height, progress: itemProgress, transition: transition)
|
||||
if i == centralIndex {
|
||||
xOffset = -itemWidth / 2.0
|
||||
|
||||
if itemWidth > itemBaseSize.width {
|
||||
xOffset -= (itemWidth - itemBaseSize.width) / 2.0
|
||||
if itemSpacing > spacing && i > 0 {
|
||||
xOffset -= (itemSpacing - spacing) / 2.0
|
||||
}
|
||||
}
|
||||
|
||||
let itemX: CGFloat
|
||||
if i == 0 {
|
||||
itemX = 0.0
|
||||
@@ -254,7 +259,7 @@ final class GalleryThumbnailContainerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
if let (currentCentralIndex, _) = self.centralIndexAndProgress, currentCentralIndex != index {
|
||||
self.centralIndexAndProgress = (index, nil)
|
||||
self.itemChanged?(self.items[index].index!)
|
||||
self.itemChanged?(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,9 +277,9 @@ final class GalleryThumbnailContainerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.isPanning = false
|
||||
self.updateLayout(size: currentLayout, transition: transition)
|
||||
}
|
||||
transition.animateView {
|
||||
self.scrollNode.view.contentOffset = contentOffset
|
||||
}
|
||||
// transition.animateView {
|
||||
// self.scrollNode.view.contentOffset = contentOffset
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import TelegramCore
|
||||
private struct InstantImageGalleryThumbnailItem: GalleryThumbnailItem {
|
||||
let account: Account
|
||||
let mediaReference: AnyMediaReference
|
||||
let requestForIndex: () -> Int?
|
||||
|
||||
var image: (Signal<(TransformImageArguments) -> DrawingContext?, NoError>, CGSize) {
|
||||
if let imageReferene = mediaReference.concrete(TelegramMediaImage.self), let representation = largestImageRepresentation(imageReferene.media.representations) {
|
||||
@@ -27,10 +26,6 @@ private struct InstantImageGalleryThumbnailItem: GalleryThumbnailItem {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var index: Int? {
|
||||
return self.requestForIndex()
|
||||
}
|
||||
}
|
||||
|
||||
class InstantImageGalleryItem: GalleryItem {
|
||||
@@ -69,13 +64,7 @@ class InstantImageGalleryItem: GalleryItem {
|
||||
}
|
||||
|
||||
func thumbnailItem() -> (Int64, GalleryThumbnailItem)? {
|
||||
return (0, InstantImageGalleryThumbnailItem(account: self.account, mediaReference: imageReference.abstract, requestForIndex: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
return 0 //return strongSelf..index
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}))
|
||||
return (0, InstantImageGalleryThumbnailItem(account: self.account, mediaReference: imageReference.abstract))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ private func allOpenInOptions(applicationContext: TelegramApplicationContext, it
|
||||
return .openUrl(url: url)
|
||||
}))
|
||||
|
||||
options.append(OpenInOption(application: .other(title: "Chrome", identifier: 535886823, scheme: "chrome"), action: {
|
||||
options.append(OpenInOption(application: .other(title: "Chrome", identifier: 535886823, scheme: "googlechrome"), action: {
|
||||
if let url = URL(string: url), var components = URLComponents(url: url, resolvingAgainstBaseURL: true) {
|
||||
components.scheme = components.scheme == "https" ? "googlechromes" : "googlechrome"
|
||||
if let url = components.string {
|
||||
|
||||
@@ -23,13 +23,11 @@ private struct PeerAvatarImageGalleryThumbnailItem: GalleryThumbnailItem {
|
||||
let account: Account
|
||||
let peer: Peer
|
||||
let content: PeerAvatarImageGalleryThumbnailContent
|
||||
private let requestForIndex: () -> Int?
|
||||
|
||||
init(account: Account, peer: Peer, content: PeerAvatarImageGalleryThumbnailContent, requestForIndex: @escaping () -> Int?) {
|
||||
init(account: Account, peer: Peer, content: PeerAvatarImageGalleryThumbnailContent) {
|
||||
self.account = account
|
||||
self.peer = peer
|
||||
self.content = content
|
||||
self.requestForIndex = requestForIndex
|
||||
}
|
||||
|
||||
var image: (Signal<(TransformImageArguments) -> DrawingContext?, NoError>, CGSize) {
|
||||
@@ -52,10 +50,6 @@ private struct PeerAvatarImageGalleryThumbnailItem: GalleryThumbnailItem {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var index: Int? {
|
||||
return self.requestForIndex()
|
||||
}
|
||||
}
|
||||
|
||||
class PeerAvatarImageGalleryItem: GalleryItem {
|
||||
@@ -110,7 +104,7 @@ class PeerAvatarImageGalleryItem: GalleryItem {
|
||||
content = .standaloneImage(image.representations)
|
||||
}
|
||||
|
||||
return (0, PeerAvatarImageGalleryThumbnailItem(account: self.account, peer: self.peer, content: content, requestForIndex: { return 0 }))
|
||||
return (0, PeerAvatarImageGalleryThumbnailItem(account: self.account, peer: self.peer, content: content))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -368,7 +368,10 @@ extension SecureIdDocumentFormDocumentState {
|
||||
}
|
||||
}
|
||||
if details.countryCode.isEmpty {
|
||||
details.countryCode = data.issuingCountry ?? ""
|
||||
details.countryCode = data.nationality ?? ""
|
||||
}
|
||||
if details.residenceCountryCode.isEmpty {
|
||||
details.residenceCountryCode = data.issuingCountry ?? ""
|
||||
}
|
||||
state.details = details
|
||||
}
|
||||
|
||||
@@ -71,25 +71,13 @@ class UniversalVideoGalleryItem: GalleryItem {
|
||||
}
|
||||
}
|
||||
if let mediaReference = mediaReference {
|
||||
if let item = ChatMediaGalleryThumbnailItem(account: self.account, mediaReference: mediaReference, requestForIndex: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
return 0 //strongSelf.index
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}) {
|
||||
if let item = ChatMediaGalleryThumbnailItem(account: self.account, mediaReference: mediaReference) {
|
||||
return (Int64(id), item)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if case let .webPage(webPage, file) = contentInfo {
|
||||
if let item = ChatMediaGalleryThumbnailItem(account: self.account, mediaReference: .webPage(webPage: WebpageReference(webPage), media: file), requestForIndex: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
return 0 //strongSelf.index
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}) {
|
||||
if let item = ChatMediaGalleryThumbnailItem(account: self.account, mediaReference: .webPage(webPage: WebpageReference(webPage), media: file)) {
|
||||
return (0, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,28 +19,50 @@ func extractVimeoVideoIdAndTimestamp(url: String) -> (String, Int)? {
|
||||
var timestamp = 0
|
||||
|
||||
if let components = URLComponents(url: url, resolvingAgainstBaseURL: false) {
|
||||
// if let queryItems = components.queryItems {
|
||||
// for queryItem in queryItems {
|
||||
// if let value = queryItem.value {
|
||||
// if queryItem.name == "v" {
|
||||
// videoId = value
|
||||
// } else if queryItem.name == "t" || queryItem.name == "time_continue" {
|
||||
// if value.contains("s") {
|
||||
//
|
||||
// } else {
|
||||
// timestamp = Int(value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if let queryItems = components.queryItems {
|
||||
for queryItem in queryItems {
|
||||
if let value = queryItem.value {
|
||||
if queryItem.name == "t" {
|
||||
if value.contains("s") {
|
||||
var range = value.startIndex..<value.endIndex
|
||||
if let hoursRange = value.range(of: "h", options: .caseInsensitive, range: range, locale: nil) {
|
||||
let subvalue = String(value[range.lowerBound ..< hoursRange.lowerBound])
|
||||
if let hours = Int(subvalue) {
|
||||
timestamp = timestamp + hours * 3600
|
||||
}
|
||||
range = hoursRange.upperBound..<value.endIndex
|
||||
}
|
||||
|
||||
if let minutesRange = value.range(of: "m", options: .caseInsensitive, range: range, locale: nil) {
|
||||
let subvalue = String(value[range.lowerBound ..< minutesRange.lowerBound])
|
||||
if let minutes = Int(subvalue) {
|
||||
timestamp = timestamp + minutes * 60
|
||||
}
|
||||
range = minutesRange.upperBound..<value.endIndex
|
||||
}
|
||||
|
||||
if let secondsRange = value.range(of: "s", options: .caseInsensitive, range: range, locale: nil) {
|
||||
let subvalue = String(value[range.lowerBound ..< secondsRange.lowerBound])
|
||||
if let seconds = Int(subvalue) {
|
||||
timestamp = timestamp + seconds
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let seconds = Int(value) {
|
||||
timestamp = seconds
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if videoId == nil {
|
||||
let pathComponents = components.path.components(separatedBy: "/")
|
||||
var nextComponentIsVideoId = false
|
||||
|
||||
for component in pathComponents {
|
||||
if CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: component)) || nextComponentIsVideoId {
|
||||
if !component.isEmpty && (CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: component)) || nextComponentIsVideoId) {
|
||||
videoId = component
|
||||
break
|
||||
} else if component == "video" {
|
||||
@@ -73,7 +95,7 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
init(videoId: String, timestamp: Int = 0) {
|
||||
self.videoId = videoId
|
||||
self.timestamp = timestamp
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true))
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: Double(timestamp), baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true))
|
||||
}
|
||||
|
||||
func setup(_ webView: WKWebView, userContentController: WKUserContentController, evaluateJavaScript: @escaping (String) -> Void, updateStatus: @escaping (MediaPlayerStatus) -> Void, onPlaybackStarted: @escaping () -> Void) {
|
||||
@@ -156,7 +178,7 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
var position: Double?
|
||||
var duration: Double?
|
||||
var download: Float?
|
||||
var failed: Bool?
|
||||
//var failed: Bool?
|
||||
|
||||
if let queryItems = components.queryItems {
|
||||
for queryItem in queryItems {
|
||||
|
||||
@@ -25,8 +25,8 @@ enum WebEmbedType {
|
||||
func webEmbedType(content: TelegramMediaWebpageLoadedContent) -> WebEmbedType {
|
||||
if let (videoId, timestamp) = extractYoutubeVideoIdAndTimestamp(url: content.url) {
|
||||
return .youtube(videoId: videoId, timestamp: timestamp)
|
||||
} else if let (videoId, timestamp) = extractVimeoVideoIdAndTimestamp(url: content.url) {
|
||||
return .vimeo(videoId: videoId, timestamp: timestamp)
|
||||
// } else if let (videoId, timestamp) = extractVimeoVideoIdAndTimestamp(url: content.url) {
|
||||
// return .vimeo(videoId: videoId, timestamp: timestamp)
|
||||
} else {
|
||||
return .iframe(url: content.embedUrl ?? content.url)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user