This commit is contained in:
Isaac 2025-11-04 18:27:13 +04:00
parent b427a8d4ca
commit 07a3a5a2aa
5 changed files with 85 additions and 14 deletions

View file

@ -2597,7 +2597,7 @@ func _internal_exportStoryLink(account: Account, peerId: EnginePeer.Id, id: Int3
func _internal_refreshStories(account: Account, peerId: PeerId, ids: [Int32]) -> Signal<Never, NoError> {
return _internal_getStoriesById(accountPeerId: account.peerId, postbox: account.postbox, source: .network(account.network), peerId: peerId, peerReference: nil, ids: ids, allowFloodWait: true)
|> mapToSignal { result -> Signal<Never, NoError> in
guard let result = result else {
guard let result else {
return .complete()
}
return account.postbox.transaction { transaction -> Void in
@ -2665,6 +2665,20 @@ func _internal_refreshSeenStories(postbox: Postbox, network: Network) -> Signal<
}
}
func _internal_pollAndGetLiveStory(account: Account, peerId: PeerId) -> Signal<Int32?, NoError> {
return _internal_pollPeerStories(postbox: account.postbox, network: account.network, accountPeerId: account.peerId, peerId: peerId)
|> map { _ -> Int32? in }
|> then(account.postbox.transaction { transaction -> Int32? in
for item in transaction.getStoryItems(peerId: peerId) {
if item.isLiveStream {
return item.id
}
}
return nil
})
}
extension Stories.ConfigurationState {
static var `default`: Stories.ConfigurationState {
return Stories.ConfigurationState(

View file

@ -1361,6 +1361,10 @@ public extension TelegramEngine {
return _internal_refreshStories(account: self.account, peerId: peerId, ids: ids)
}
public func pollAndGetLiveStory(peerId: EnginePeer.Id) -> Signal<Int32?, NoError> {
return _internal_pollAndGetLiveStory(account: self.account, peerId: peerId)
}
public func refreshStoryViews(peerId: EnginePeer.Id, ids: [Int32]) -> Signal<Never, NoError> {
if peerId != self.account.peerId && peerId.namespace != Namespaces.Peer.CloudChannel {
return .complete()

View file

@ -8,6 +8,7 @@ import AppBundle
import AccountContext
import HierarchyTrackingLayer
import LokiRng
import SwiftSignalKit
private let gradientColors: [NSArray] = [
[UIColor(rgb: 0xff516a).cgColor, UIColor(rgb: 0xff885e).cgColor],
@ -104,6 +105,28 @@ private func makePeerBadgeImage(engine: TelegramEngine, peer: EnginePeer, count:
textSize.width = ceil(textSize.width)
textSize.height = ceil(textSize.height)
var avatarSourceImage: UIImage?
if let resource = smallestImageRepresentation(peer.profileImageRepresentations)?.resource, let peerReference = PeerReference(peer._asPeer()) {
let disposable = fetchedMediaResource(mediaBox: engine.account.postbox.mediaBox, userLocation: .peer(peer.id), userContentType: .avatar, reference: .avatar(peer: peerReference, resource: resource)).startStrict()
let signal = engine.account.postbox.mediaBox.resourceData(resource)
|> filter { $0.complete }
|> map { value -> Data? in
if value.complete {
return try? Data(contentsOf: URL(fileURLWithPath: value.path))
} else {
return nil
}
}
|> take(1)
|> timeout(0.9, queue: Queue.concurrentDefaultQueue(), alternate: .single(nil))
if let imageData = await signal.get() {
avatarSourceImage = UIImage(data: imageData)
}
disposable.dispose()
}
let size = CGSize(width: avatarInset + avatarSize + avatarIconSpacing + iconSize + iconTextSpacing + textSize.height + rightInset, height: avatarSize + avatarInset * 2.0)
return generateImage(size, rotatedContext: { size, context in
UIGraphicsPushContext(context)
@ -116,8 +139,15 @@ private func makePeerBadgeImage(engine: TelegramEngine, peer: EnginePeer, count:
context.addPath(UIBezierPath(roundedRect: CGRect(origin: CGPoint(), size: size), cornerRadius: size.height * 0.5).cgPath)
context.fillPath()
if let image = avatarViewLettersImage(size: CGSize(width: avatarSize, height: avatarSize), peerId: peer.id, letters: peer.displayLetters, isStory: false) {
image.draw(in: CGRect(origin: CGPoint(x: avatarInset, y: avatarInset), size: CGSize(width: avatarSize, height: avatarSize)))
let avatarRect = CGRect(origin: CGPoint(x: avatarInset, y: avatarInset), size: CGSize(width: avatarSize, height: avatarSize))
if let avatarSourceImage {
context.addEllipse(in: avatarRect)
context.clip()
avatarSourceImage.draw(in: avatarRect)
context.resetClip()
} else if let image = avatarViewLettersImage(size: CGSize(width: avatarSize, height: avatarSize), peerId: peer.id, letters: peer.displayLetters, isStory: false) {
image.draw(in: avatarRect)
}
if let image = generateTintedImage(image: UIImage(bundleImageName: "Premium/Stars/ButtonStar"), color: .white) {

View file

@ -4049,7 +4049,7 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) {
self.commitSendStars(view: view, count: count, delay: false)
} else {
let starsContextState = await component.context.starsContext?.state.get()
/*let starsContextState = await component.context.starsContext?.state.get()
guard let balance = starsContextState?.balance else {
return
}
@ -4080,7 +4080,7 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) {
navigationController.pushViewController(controller)
return
}
}*/
var reactionItem: ReactionItem?
if let availableReactions = await component.context.availableReactions.get() {

View file

@ -67,6 +67,11 @@ extension ResolvedBotAdminRights {
}
public enum ParsedInternalPeerUrlParameter {
public enum Story {
case live
case id(Int32)
}
case botStart(String)
case groupBotStart(String, ResolvedBotAdminRights?)
case channelBotStart(String, ResolvedBotAdminRights?)
@ -76,7 +81,7 @@ public enum ParsedInternalPeerUrlParameter {
case replyThread(Int32, Int32)
case voiceChat(String?)
case appStart(String, String?, ResolvedStartAppMode)
case story(Int32)
case story(Story)
case boost
case text(String)
case profile
@ -342,8 +347,10 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, context: Accou
}
return .peer(.name(peerName), .appStart("", queryItem.value, mode))
} else if queryItem.name == "story" {
if let id = Int32(value) {
return .peer(.name(peerName), .story(id))
if value == "live" {
return .peer(.name(peerName), .story(.live))
} else if let id = Int32(value) {
return .peer(.name(peerName), .story(.id(id)))
}
} else if queryItem.name == "album" {
if let id = Int64(value) {
@ -599,8 +606,10 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, context: Accou
return nil
}
} else if pathComponents.count >= 3 && pathComponents[1] == "s" {
if let storyId = Int32(pathComponents[2]) {
return .peer(.name(pathComponents[0]), .story(storyId))
if pathComponents[2] == "live" {
return .peer(.name(pathComponents[0]), .story(.live))
} else if let storyId = Int32(pathComponents[2]) {
return .peer(.name(pathComponents[0]), .story(.id(storyId)))
} else {
return nil
}
@ -939,11 +948,25 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
}
case let .voiceChat(invite):
return .single(.result(.joinVoiceChat(peer.id, invite)))
case let .story(id):
return .single(.progress) |> then(context.engine.messages.refreshStories(peerId: peer.id, ids: [id])
|> map { _ -> ResolveInternalUrlResult in
case let .story(story):
switch story {
case .live:
return .single(.progress)
|> then(context.engine.messages.pollAndGetLiveStory(peerId: peer.id)
|> map { id -> ResolveInternalUrlResult in
if let id {
return .result(.story(peerId: peer.id, id: id))
} else {
return .result(nil)
}
})
case let .id(id):
return .single(.progress)
|> then(context.engine.messages.refreshStories(peerId: peer.id, ids: [id])
|> map { _ -> ResolveInternalUrlResult in
}
|> then(.single(.result(.story(peerId: peer.id, id: id)))))
}
|> then(.single(.result(.story(peerId: peer.id, id: id)))))
case .boost:
return .single(.progress)
|> then(