Various improvements

This commit is contained in:
Isaac 2025-07-29 14:36:00 +02:00
parent 7377b811e1
commit e91809a683
7 changed files with 72 additions and 34 deletions

View File

@ -1424,15 +1424,14 @@ public final class PeerStoryListContext: StoryListContext {
key.setInt64(0, value: peerId.toInt64())
key.setInt8(8, value: 0)
var updatedFolders: [State.Folder] = []
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key))?.get(CachedPeerStoryListHead.self) {
var updatedFolders: [State.Folder] = []
updatedFolders = cached.folders
}
updatedFolders.append(StoryListContextState.Folder(id: Int64(albumId), title: title))
if let entry = CodableEntry(CachedPeerStoryListHead(items: items.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: pinnedIds, totalCount: Int32(totalCount), folders: updatedFolders)) {
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
}
}
let mappedItems = items.map { item in
return item.storyItem.asStoryItem()
@ -1442,7 +1441,7 @@ public final class PeerStoryListContext: StoryListContext {
folderKey.setInt64(0, value: peerId.toInt64())
folderKey.setInt8(8, value: 0)
folderKey.setInt64(8 + 1, value: Int64(albumId))
if let entry = CodableEntry(CachedPeerStoryListHead(items: [], pinnedIds: [], totalCount: Int32(mappedItems.count), folders: [])) {
if let entry = CodableEntry(CachedPeerStoryListHead(items: mappedItems.map { .item($0) }, pinnedIds: [], totalCount: Int32(mappedItems.count), folders: [])) {
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: folderKey), entry: entry)
}
} |> deliverOn(self.queue)).start(completed: {

View File

@ -15,7 +15,8 @@ swift_library(
"//submodules/ComponentFlow",
"//submodules/TelegramPresentationData",
"//submodules/Components/ComponentDisplayAdapters",
"//submodules/Components/SolidRoundedButtonComponent",
"//submodules/Components/MultilineTextComponent",
"//submodules/TelegramUI/Components/ButtonComponent",
],
visibility = [
"//visibility:public",

View File

@ -5,12 +5,14 @@ import AsyncDisplayKit
import ComponentFlow
import ComponentDisplayAdapters
import TelegramPresentationData
import SolidRoundedButtonComponent
import ButtonComponent
import MultilineTextComponent
public final class BottomButtonPanelComponent: Component {
let theme: PresentationTheme
let title: String
let label: String?
let icon: AnyComponentWithIdentity<Empty>?
let isEnabled: Bool
let insets: UIEdgeInsets
let action: () -> Void
@ -19,6 +21,7 @@ public final class BottomButtonPanelComponent: Component {
theme: PresentationTheme,
title: String,
label: String?,
icon: AnyComponentWithIdentity<Empty>? = nil,
isEnabled: Bool,
insets: UIEdgeInsets,
action: @escaping () -> Void
@ -26,6 +29,7 @@ public final class BottomButtonPanelComponent: Component {
self.theme = theme
self.title = title
self.label = label
self.icon = icon
self.isEnabled = isEnabled
self.insets = insets
self.action = action
@ -41,6 +45,9 @@ public final class BottomButtonPanelComponent: Component {
if lhs.label != rhs.label {
return false
}
if lhs.icon != rhs.icon {
return false
}
if lhs.isEnabled != rhs.isEnabled {
return false
}
@ -98,25 +105,39 @@ public final class BottomButtonPanelComponent: Component {
transition.setFrame(layer: self.separatorLayer, frame: CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: availableSize.width, height: UIScreenPixel)))
var buttonTitleVStack: [AnyComponentWithIdentity<Empty>] = []
let titleString = NSMutableAttributedString(string: component.title, font: Font.semibold(17.0), textColor: component.theme.list.itemCheckColors.foregroundColor, paragraphAlignment: .center)
buttonTitleVStack.append(AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(text: .plain(titleString)))))
if let label = component.label {
let labelString = NSMutableAttributedString(string: label, font: Font.semibold(11.0), textColor: component.theme.list.itemCheckColors.foregroundColor.withAlphaComponent(0.7), paragraphAlignment: .center)
buttonTitleVStack.append(AnyComponentWithIdentity(id: AnyHashable(1), component: AnyComponent(MultilineTextComponent(text: .plain(labelString)))))
}
var buttonTitleContent: AnyComponent<Empty> = AnyComponent(VStack(buttonTitleVStack, spacing: 1.0))
if let icon = component.icon {
buttonTitleContent = AnyComponent(HStack([
icon,
AnyComponentWithIdentity(id: "_title", component: buttonTitleContent)
], spacing: 7.0))
}
let actionButtonSize = self.actionButton.update(
transition: transition,
component: AnyComponent(SolidRoundedButtonComponent(
title: component.title,
label: component.label,
theme: SolidRoundedButtonComponent.Theme(
backgroundColor: component.theme.list.itemCheckColors.fillColor,
backgroundColors: [],
foregroundColor: component.theme.list.itemCheckColors.foregroundColor
component: AnyComponent(ButtonComponent(
background: ButtonComponent.Background(
color: component.theme.list.itemCheckColors.fillColor,
foreground: component.theme.list.itemCheckColors.foregroundColor,
pressedColor: component.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.9),
cornerRadius: 10.0
),
content: AnyComponentWithIdentity(
id: 0,
component: buttonTitleContent
),
font: .bold,
fontSize: 17.0,
height: 50.0,
cornerRadius: 10.0,
gloss: false,
isEnabled: component.isEnabled,
animationName: nil,
iconPosition: .right,
iconSpacing: 4.0,
displaysProgress: false,
action: { [weak self] in
guard let self else {
return

View File

@ -46,6 +46,7 @@ import TabSelectorComponent
import LanguageSelectionScreen
import PromptUI
import BottomButtonPanelComponent
import BundleIconComponent
private let mediaBadgeBackgroundColor = UIColor(white: 0.0, alpha: 0.6)
private let mediaBadgeTextColor = UIColor.white
@ -4483,6 +4484,11 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
theme: presentationData.theme,
title: "Add Stories",
label: nil,
icon: AnyComponentWithIdentity(id: 0, component: AnyComponent(BundleIconComponent(
name: "Item List/AddItemIcon",
tintColor: presentationData.theme.list.itemCheckColors.foregroundColor,
maxSize: CGSize(width: 18.0, height: 18.0)
))),
isEnabled: true,
insets: UIEdgeInsets(top: 0.0, left: sideInset + 12.0, bottom: bottomInset, right: sideInset + 12.0),
action: { [weak self] in
@ -5018,14 +5024,11 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
}
if let value {
if let listSource = self.listSource as? PeerStoryListContext {
let _ = listSource.addFolder(title: value, items: [], completion: { [weak self] id in
let _ = listSource.addFolder(title: value, items: addItems, completion: { [weak self] id in
Queue.mainQueue().async {
guard let self, let id, let listSource = self.listSource as? PeerStoryListContext else {
guard let self, let id else {
return
}
if !addItems.isEmpty {
let _ = listSource.addToFolder(id: id, items: addItems)
}
self.isSwitchingToCreatedFolder = true
self.setStoryFolder(id: id, assumeEmpty: addItems.isEmpty)
}
@ -5386,7 +5389,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
let shareController = ShareController(
context: self.context,
subject: .url("https://t.me/\(urlBase)?stories=\(id)"),
subject: .url("https://t.me/\(urlBase)/a/\(id)"),
presetText: nil,
preferredAction: .default,
showInChat: nil,

View File

@ -755,6 +755,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
var text: String?
var profile: Bool = false
var referrer: String?
var albumId: Int64?
if let queryItems = components.queryItems {
for queryItem in queryItems {
if let value = queryItem.value {
@ -790,6 +791,8 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
text = value
} else if queryItem.name == "ref" {
referrer = value
} else if queryItem.name == "album" {
albumId = Int64(value)
}
} else if ["voicechat", "videochat", "livestream"].contains(queryItem.name) {
voiceChat = ""
@ -861,6 +864,8 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
}
} else if let attach = attach {
result += "?attach=\(attach)"
} else if let albumId {
result += "/a/\(albumId)"
}
if let startAttach = startAttach {
if attach == nil {

View File

@ -3992,6 +3992,9 @@ private func peerInfoControllerImpl(context: AccountContext, updatedPresentation
sharedMediaFromForumTopic = (peerId, peer.id.toInt64())
case let .storyAlbum(id):
switchToStoryFolder = id
if peer.id == context.account.peerId {
isMyProfile = true
}
default:
break
}

View File

@ -344,10 +344,12 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, context: Accou
if let id = Int32(value) {
return .peer(.name(peerName), .story(id))
}
} else if queryItem.name == "album" {
if let id = Int64(value) {
return .peer(.name(peerName), .storyFolder(id))
}
} else if queryItem.name == "ref", let referrer = queryItem.value {
return .peer(.name(peerName), .referrer(referrer))
} else if queryItem.name == "stories", let value = queryItem.value, let folderId = Int64(value) {
return .peer(.name(peerName), .storyFolder(folderId))
}
} else if ["voicechat", "videochat", "livestream"].contains(queryItem.name) {
return .peer(.name(peerName), .voiceChat(nil))
@ -404,8 +406,6 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, context: Accou
return .peer(.name(peerName), .appStart("", queryItem.value, mode))
} else if queryItem.name == "ref", let referrer = queryItem.value {
return .peer(.name(peerName), .referrer(referrer))
} else if queryItem.name == "stories", let value = queryItem.value, let folderId = Int64(value) {
return .peer(.name(peerName), .storyFolder(folderId))
}
}
}
@ -658,6 +658,12 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, context: Accou
} else {
return nil
}
} else if pathComponents.count >= 3 && pathComponents[1] == "a" {
if let folderId = Int64(pathComponents[2]) {
return .peer(.name(pathComponents[0]), .storyFolder(folderId))
} else {
return nil
}
} else if let value = Int32(pathComponents[1]) {
var threadId: Int32?
var commentId: Int32?