mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Merge commit '37e752c78f1fc0e83eb20a2063145939112be167'
# Conflicts: # submodules/ChatListUI/Sources/Node/ChatListItem.swift # submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift # submodules/TelegramCore/Sources/ForumChannels.swift
This commit is contained in:
@@ -49,6 +49,7 @@ public final class EmojiStatusComponent: Component {
|
||||
case text(color: UIColor, string: String)
|
||||
case animation(content: AnimationContent, size: CGSize, placeholderColor: UIColor, themeColor: UIColor?, loopMode: LoopMode)
|
||||
case topic(title: String, color: Int32, size: CGSize)
|
||||
case image(image: UIImage?)
|
||||
}
|
||||
|
||||
public let context: AccountContext
|
||||
@@ -230,6 +231,8 @@ public final class EmojiStatusComponent: Component {
|
||||
} else {
|
||||
iconImage = nil
|
||||
}
|
||||
case let .image(image):
|
||||
iconImage = image
|
||||
case let .verified(fillColor, foregroundColor, sizeType):
|
||||
let imageNamePrefix: String
|
||||
switch sizeType {
|
||||
|
||||
@@ -261,23 +261,33 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
||||
}
|
||||
}
|
||||
|
||||
private func updateTopicInfo(topicInfo: EngineMessageHistoryThread.Info) {
|
||||
func generateTopicColors(_ color: Int32) -> ([UInt32], [UInt32]) {
|
||||
return ([0x6FB9F0, 0x0261E4], [0x026CB5, 0x064BB7])
|
||||
}
|
||||
|
||||
let topicColors: [Int32: ([UInt32], [UInt32])] = [
|
||||
0x6FB9F0: ([0x6FB9F0, 0x0261E4], [0x026CB5, 0x064BB7]),
|
||||
0xFFD67E: ([0xFFD67E, 0xFC8601], [0xDA9400, 0xFA5F00]),
|
||||
0xCB86DB: ([0xCB86DB, 0x9338AF], [0x812E98, 0x6F2B87]),
|
||||
0x8EEE98: ([0x8EEE98, 0x02B504], [0x02A01B, 0x009716]),
|
||||
0xFF93B2: ([0xFF93B2, 0xE23264], [0xFC447A, 0xC80C46]),
|
||||
0xFB6F5F: ([0xFB6F5F, 0xD72615], [0xDC1908, 0xB61506])
|
||||
]
|
||||
let colors = topicColors[topicInfo.iconColor] ?? generateTopicColors(topicInfo.iconColor)
|
||||
|
||||
if let image = generateTopicIcon(title: String(topicInfo.title.prefix(1)), backgroundColors: colors.0.map(UIColor.init(rgb:)), strokeColors: colors.1.map(UIColor.init(rgb:)), size: CGSize(width: 32.0, height: 32.0)) {
|
||||
self.contents = image.cgImage
|
||||
private func updateTopicInfo(topicInfo: (Int64, EngineMessageHistoryThread.Info)) {
|
||||
if topicInfo.0 == 1 {
|
||||
let image = generateImage(CGSize(width: 18.0, height: 18.0), contextGenerator: { size, context in
|
||||
context.clear(CGRect(origin: .zero, size: size))
|
||||
if let cgImage = generateTintedImage(image: UIImage(bundleImageName: "Chat List/GeneralTopicIcon"), color: .white)?.cgImage {
|
||||
context.draw(cgImage, in: CGRect(origin: .zero, size: size))
|
||||
}
|
||||
})
|
||||
self.contents = image?.cgImage
|
||||
} else {
|
||||
func generateTopicColors(_ color: Int32) -> ([UInt32], [UInt32]) {
|
||||
return ([0x6FB9F0, 0x0261E4], [0x026CB5, 0x064BB7])
|
||||
}
|
||||
|
||||
let topicColors: [Int32: ([UInt32], [UInt32])] = [
|
||||
0x6FB9F0: ([0x6FB9F0, 0x0261E4], [0x026CB5, 0x064BB7]),
|
||||
0xFFD67E: ([0xFFD67E, 0xFC8601], [0xDA9400, 0xFA5F00]),
|
||||
0xCB86DB: ([0xCB86DB, 0x9338AF], [0x812E98, 0x6F2B87]),
|
||||
0x8EEE98: ([0x8EEE98, 0x02B504], [0x02A01B, 0x009716]),
|
||||
0xFF93B2: ([0xFF93B2, 0xE23264], [0xFC447A, 0xC80C46]),
|
||||
0xFB6F5F: ([0xFB6F5F, 0xD72615], [0xDC1908, 0xB61506])
|
||||
]
|
||||
let colors = topicColors[topicInfo.1.iconColor] ?? generateTopicColors(topicInfo.1.iconColor)
|
||||
|
||||
if let image = generateTopicIcon(title: String(topicInfo.1.title.prefix(1)), backgroundColors: colors.0.map(UIColor.init(rgb:)), strokeColors: colors.1.map(UIColor.init(rgb:)), size: CGSize(width: 32.0, height: 32.0)) {
|
||||
self.contents = image.cgImage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ private final class TitleFieldComponent: Component {
|
||||
let textColor: UIColor
|
||||
let accentColor: UIColor
|
||||
let placeholderColor: UIColor
|
||||
let isGeneral: Bool
|
||||
let fileId: Int64
|
||||
let iconColor: Int32
|
||||
let text: String
|
||||
@@ -36,6 +37,7 @@ private final class TitleFieldComponent: Component {
|
||||
textColor: UIColor,
|
||||
accentColor: UIColor,
|
||||
placeholderColor: UIColor,
|
||||
isGeneral: Bool,
|
||||
fileId: Int64,
|
||||
iconColor: Int32,
|
||||
text: String,
|
||||
@@ -47,6 +49,7 @@ private final class TitleFieldComponent: Component {
|
||||
self.textColor = textColor
|
||||
self.accentColor = accentColor
|
||||
self.placeholderColor = placeholderColor
|
||||
self.isGeneral = isGeneral
|
||||
self.fileId = fileId
|
||||
self.iconColor = iconColor
|
||||
self.text = text
|
||||
@@ -68,6 +71,9 @@ private final class TitleFieldComponent: Component {
|
||||
if lhs.placeholderColor != rhs.placeholderColor {
|
||||
return false
|
||||
}
|
||||
if lhs.isGeneral != rhs.isGeneral {
|
||||
return false
|
||||
}
|
||||
if lhs.fileId != rhs.fileId {
|
||||
return false
|
||||
}
|
||||
@@ -140,7 +146,10 @@ private final class TitleFieldComponent: Component {
|
||||
self.state = state
|
||||
|
||||
let iconContent: EmojiStatusComponent.Content
|
||||
if component.fileId == 0 {
|
||||
if component.isGeneral {
|
||||
iconContent = .image(image: generateTintedImage(image: UIImage(bundleImageName: "Chat List/GeneralTopicIcon"), color: component.placeholderColor))
|
||||
self.iconButton.isUserInteractionEnabled = false
|
||||
} else if component.fileId == 0 {
|
||||
iconContent = .topic(title: String(component.text.prefix(1)), color: component.iconColor, size: CGSize(width: 32.0, height: 32.0))
|
||||
self.iconButton.isUserInteractionEnabled = true
|
||||
} else {
|
||||
@@ -413,6 +422,7 @@ private final class ForumCreateTopicScreenComponent: CombinedComponent {
|
||||
private var defaultIconFilesDisposable: Disposable?
|
||||
private var defaultIconFiles = Set<Int64>()
|
||||
|
||||
let isGeneral: Bool
|
||||
var title: String
|
||||
var fileId: Int64
|
||||
var iconColor: Int32
|
||||
@@ -427,11 +437,13 @@ private final class ForumCreateTopicScreenComponent: CombinedComponent {
|
||||
|
||||
switch mode {
|
||||
case .create:
|
||||
self.isGeneral = false
|
||||
self.title = ""
|
||||
self.fileId = 0
|
||||
|
||||
self.iconColor = ForumCreateTopicScreen.iconColors.randomElement() ?? 0x0
|
||||
case let .edit(info):
|
||||
case let .edit(threadId, info):
|
||||
self.isGeneral = threadId == 1
|
||||
self.title = info.title
|
||||
self.fileId = info.icon ?? 0
|
||||
self.iconColor = info.iconColor
|
||||
@@ -638,6 +650,7 @@ private final class ForumCreateTopicScreenComponent: CombinedComponent {
|
||||
textColor: environment.theme.list.itemPrimaryTextColor,
|
||||
accentColor: environment.theme.list.itemAccentColor,
|
||||
placeholderColor: environment.theme.list.disclosureArrowColor,
|
||||
isGeneral: state.isGeneral,
|
||||
fileId: state.fileId,
|
||||
iconColor: state.iconColor,
|
||||
text: state.title,
|
||||
@@ -658,124 +671,128 @@ private final class ForumCreateTopicScreenComponent: CombinedComponent {
|
||||
|
||||
contentHeight += titleBackground.size.height + sectionSpacing
|
||||
|
||||
let iconHeader = iconHeader.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: environment.strings.CreateTopic_SelectTopicIcon,
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor,
|
||||
paragraphAlignment: .natural)
|
||||
),
|
||||
horizontalAlignment: .natural,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
availableSize: CGSize(
|
||||
width: context.availableSize.width - sideInset * 2.0,
|
||||
height: CGFloat.greatestFiniteMagnitude
|
||||
),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(iconHeader
|
||||
.position(CGPoint(x: sideInset * 2.0 + iconHeader.size.width / 2.0, y: contentHeight + iconHeader.size.height / 2.0))
|
||||
)
|
||||
contentHeight += iconHeader.size.height + headerSpacing
|
||||
|
||||
let bottomInset = max(environment.safeInsets.bottom, 12.0)
|
||||
|
||||
let iconBackground = iconBackground.update(
|
||||
component: RoundedRectangle(
|
||||
color: environment.theme.list.itemBlocksBackgroundColor,
|
||||
cornerRadius: 10.0
|
||||
),
|
||||
availableSize: CGSize(
|
||||
width: context.availableSize.width - sideInset * 2.0,
|
||||
height: context.availableSize.height - contentHeight - bottomInset
|
||||
),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(iconBackground
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentHeight + iconBackground.size.height / 2.0))
|
||||
)
|
||||
|
||||
if let emojiContent = state.emojiContent {
|
||||
let availableHeight = context.availableSize.height - contentHeight - max(bottomInset, environment.inputHeight)
|
||||
if case let .edit(threadId, _) = context.component.mode, threadId == 1 {
|
||||
|
||||
let iconSelector = iconSelector.update(
|
||||
component: TopicIconSelectionComponent(
|
||||
theme: environment.theme,
|
||||
strings: environment.strings,
|
||||
deviceMetrics: environment.deviceMetrics,
|
||||
emojiContent: emojiContent,
|
||||
backgroundColor: environment.theme.list.itemBlocksBackgroundColor,
|
||||
separatorColor: environment.theme.list.blocksBackgroundColor
|
||||
} else {
|
||||
let iconHeader = iconHeader.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: environment.strings.CreateTopic_SelectTopicIcon,
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor,
|
||||
paragraphAlignment: .natural)
|
||||
),
|
||||
horizontalAlignment: .natural,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
availableSize: CGSize(
|
||||
width: context.availableSize.width - sideInset * 2.0,
|
||||
height: CGFloat.greatestFiniteMagnitude
|
||||
),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(iconHeader
|
||||
.position(CGPoint(x: sideInset * 2.0 + iconHeader.size.width / 2.0, y: contentHeight + iconHeader.size.height / 2.0))
|
||||
)
|
||||
contentHeight += iconHeader.size.height + headerSpacing
|
||||
|
||||
let bottomInset = max(environment.safeInsets.bottom, 12.0)
|
||||
|
||||
let iconBackground = iconBackground.update(
|
||||
component: RoundedRectangle(
|
||||
color: environment.theme.list.itemBlocksBackgroundColor,
|
||||
cornerRadius: 10.0
|
||||
),
|
||||
availableSize: CGSize(
|
||||
width: context.availableSize.width - sideInset * 2.0,
|
||||
height: context.availableSize.height - contentHeight - bottomInset
|
||||
),
|
||||
environment: {},
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: availableHeight),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(iconSelector
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentHeight + iconSelector.size.height / 2.0))
|
||||
.cornerRadius(10.0)
|
||||
.clipsToBounds(true)
|
||||
context.add(iconBackground
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentHeight + iconBackground.size.height / 2.0))
|
||||
)
|
||||
|
||||
let accountContext = context.component.context
|
||||
emojiContent.inputInteractionHolder.inputInteraction = EmojiPagerContentComponent.InputInteraction(
|
||||
performItemAction: { [weak state] groupId, item, _, _, _, _ in
|
||||
state?.applyItem(groupId: groupId, item: item)
|
||||
},
|
||||
deleteBackwards: {
|
||||
},
|
||||
openStickerSettings: {
|
||||
},
|
||||
openFeatured: {
|
||||
},
|
||||
addGroupAction: { groupId, isPremiumLocked in
|
||||
guard let collectionId = groupId.base as? ItemCollectionId else {
|
||||
return
|
||||
}
|
||||
|
||||
let viewKey = PostboxViewKey.orderedItemList(id: Namespaces.OrderedItemList.CloudFeaturedEmojiPacks)
|
||||
let _ = (accountContext.account.postbox.combinedView(keys: [viewKey])
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { views in
|
||||
guard let view = views.views[viewKey] as? OrderedItemListView else {
|
||||
if let emojiContent = state.emojiContent {
|
||||
let availableHeight = context.availableSize.height - contentHeight - max(bottomInset, environment.inputHeight)
|
||||
|
||||
let iconSelector = iconSelector.update(
|
||||
component: TopicIconSelectionComponent(
|
||||
theme: environment.theme,
|
||||
strings: environment.strings,
|
||||
deviceMetrics: environment.deviceMetrics,
|
||||
emojiContent: emojiContent,
|
||||
backgroundColor: environment.theme.list.itemBlocksBackgroundColor,
|
||||
separatorColor: environment.theme.list.blocksBackgroundColor
|
||||
),
|
||||
environment: {},
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: availableHeight),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(iconSelector
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentHeight + iconSelector.size.height / 2.0))
|
||||
.cornerRadius(10.0)
|
||||
.clipsToBounds(true)
|
||||
)
|
||||
|
||||
let accountContext = context.component.context
|
||||
emojiContent.inputInteractionHolder.inputInteraction = EmojiPagerContentComponent.InputInteraction(
|
||||
performItemAction: { [weak state] groupId, item, _, _, _, _ in
|
||||
state?.applyItem(groupId: groupId, item: item)
|
||||
},
|
||||
deleteBackwards: {
|
||||
},
|
||||
openStickerSettings: {
|
||||
},
|
||||
openFeatured: {
|
||||
},
|
||||
addGroupAction: { groupId, isPremiumLocked in
|
||||
guard let collectionId = groupId.base as? ItemCollectionId else {
|
||||
return
|
||||
}
|
||||
for featuredEmojiPack in view.items.lazy.map({ $0.contents.get(FeaturedStickerPackItem.self)! }) {
|
||||
if featuredEmojiPack.info.id == collectionId {
|
||||
// if let strongSelf = self {
|
||||
// strongSelf.scheduledEmojiContentAnimationHint = EmojiPagerContentComponent.ContentAnimation(type: .groupInstalled(id: collectionId))
|
||||
// }
|
||||
let _ = accountContext.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info, items: featuredEmojiPack.topItems).start()
|
||||
|
||||
break
|
||||
|
||||
let viewKey = PostboxViewKey.orderedItemList(id: Namespaces.OrderedItemList.CloudFeaturedEmojiPacks)
|
||||
let _ = (accountContext.account.postbox.combinedView(keys: [viewKey])
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { views in
|
||||
guard let view = views.views[viewKey] as? OrderedItemListView else {
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
clearGroup: { _ in
|
||||
},
|
||||
pushController: { c in
|
||||
},
|
||||
presentController: { c in
|
||||
},
|
||||
presentGlobalOverlayController: { c in
|
||||
},
|
||||
navigationController: {
|
||||
return nil
|
||||
},
|
||||
requestUpdate: { _ in
|
||||
},
|
||||
updateSearchQuery: { _, _ in
|
||||
},
|
||||
chatPeerId: nil,
|
||||
peekBehavior: nil,
|
||||
customLayout: nil,
|
||||
externalBackground: nil,
|
||||
externalExpansionView: nil,
|
||||
useOpaqueTheme: true
|
||||
)
|
||||
for featuredEmojiPack in view.items.lazy.map({ $0.contents.get(FeaturedStickerPackItem.self)! }) {
|
||||
if featuredEmojiPack.info.id == collectionId {
|
||||
// if let strongSelf = self {
|
||||
// strongSelf.scheduledEmojiContentAnimationHint = EmojiPagerContentComponent.ContentAnimation(type: .groupInstalled(id: collectionId))
|
||||
// }
|
||||
let _ = accountContext.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info, items: featuredEmojiPack.topItems).start()
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
clearGroup: { _ in
|
||||
},
|
||||
pushController: { c in
|
||||
},
|
||||
presentController: { c in
|
||||
},
|
||||
presentGlobalOverlayController: { c in
|
||||
},
|
||||
navigationController: {
|
||||
return nil
|
||||
},
|
||||
requestUpdate: { _ in
|
||||
},
|
||||
updateSearchQuery: { _, _ in
|
||||
},
|
||||
chatPeerId: nil,
|
||||
peekBehavior: nil,
|
||||
customLayout: nil,
|
||||
externalBackground: nil,
|
||||
externalExpansionView: nil,
|
||||
useOpaqueTheme: true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return context.availableSize
|
||||
@@ -788,7 +805,7 @@ public class ForumCreateTopicScreen: ViewControllerComponentContainer {
|
||||
|
||||
public enum Mode: Equatable {
|
||||
case create
|
||||
case edit(topic: EngineMessageHistoryThread.Info)
|
||||
case edit(threadId: Int64, threadInfo: EngineMessageHistoryThread.Info)
|
||||
}
|
||||
|
||||
private let context: AccountContext
|
||||
@@ -835,9 +852,9 @@ public class ForumCreateTopicScreen: ViewControllerComponentContainer {
|
||||
case .create:
|
||||
title = presentationData.strings.CreateTopic_CreateTitle
|
||||
doneTitle = presentationData.strings.CreateTopic_Create
|
||||
case let .edit(topic):
|
||||
case let .edit(_, topic):
|
||||
title = presentationData.strings.CreateTopic_EditTitle
|
||||
doneTitle = presentationData.strings.Common_Done
|
||||
doneTitle = presentationData.strings.Common_Done
|
||||
|
||||
self.state = (topic.title, topic.icon)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user