mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various Improvements
This commit is contained in:
parent
6c38a5a68f
commit
d60588b3f1
@ -143,7 +143,6 @@ private final class AuthorizationSequenceCountrySelectionNavigationContentNode:
|
||||
self.addSubnode(self.searchBar)
|
||||
|
||||
self.searchBar.cancel = { [weak self] in
|
||||
//self?.searchBar.deactivate(clear: false)
|
||||
self?.cancel()
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,13 @@ private func searchCountries(items: [((String, String), String, [Int])], query:
|
||||
|
||||
var result: [((String, String), String, Int)] = []
|
||||
for item in items {
|
||||
let string = "\(item.0) \(item.1)"
|
||||
let componentsOne = item.0.0.components(separatedBy: " ")
|
||||
let abbrOne = componentsOne.compactMap { $0.first.flatMap { String($0) } }.reduce(into: String(), { $0.append(contentsOf: $1) }).replacingOccurrences(of: "&", with: "")
|
||||
|
||||
let componentsTwo = item.0.0.components(separatedBy: " ")
|
||||
let abbrTwo = componentsTwo.compactMap { $0.first.flatMap { String($0) } }.reduce(into: String(), { $0.append(contentsOf: $1) }).replacingOccurrences(of: "&", with: "")
|
||||
|
||||
let string = "\(item.0.0) \((item.0.1)) \(item.1) \(abbrOne) \(abbrTwo)"
|
||||
let tokens = stringTokens(string)
|
||||
if matchStringTokens(tokens, with: queryTokens) {
|
||||
for code in item.2 {
|
||||
|
@ -687,6 +687,7 @@ public func readCGFloat(_ index: inout UnsafePointer<UInt8>, end: UnsafePointer<
|
||||
public func drawSvgPath(_ context: CGContext, path: StaticString, strokeOnMove: Bool = false) throws {
|
||||
var index: UnsafePointer<UInt8> = path.utf8Start
|
||||
let end = path.utf8Start.advanced(by: path.utf8CodeUnitCount)
|
||||
var currentPoint = CGPoint()
|
||||
while index < end {
|
||||
let c = index.pointee
|
||||
index = index.successor()
|
||||
@ -696,18 +697,32 @@ public func drawSvgPath(_ context: CGContext, path: StaticString, strokeOnMove:
|
||||
let y = try readCGFloat(&index, end: end, separator: 32)
|
||||
|
||||
//print("Move to \(x), \(y)")
|
||||
context.move(to: CGPoint(x: x, y: y))
|
||||
currentPoint = CGPoint(x: x, y: y)
|
||||
context.move(to: currentPoint)
|
||||
} else if c == 76 { // L
|
||||
let x = try readCGFloat(&index, end: end, separator: 44)
|
||||
let y = try readCGFloat(&index, end: end, separator: 32)
|
||||
|
||||
//print("Line to \(x), \(y)")
|
||||
context.addLine(to: CGPoint(x: x, y: y))
|
||||
currentPoint = CGPoint(x: x, y: y)
|
||||
context.addLine(to: currentPoint)
|
||||
|
||||
if strokeOnMove {
|
||||
context.strokePath()
|
||||
context.move(to: CGPoint(x: x, y: y))
|
||||
context.move(to: currentPoint)
|
||||
}
|
||||
} else if c == 72 { // H
|
||||
let x = try readCGFloat(&index, end: end, separator: 32)
|
||||
|
||||
//print("Move to \(x), \(y)")
|
||||
currentPoint = CGPoint(x: x, y: currentPoint.y)
|
||||
context.addLine(to: currentPoint)
|
||||
} else if c == 86 { // V
|
||||
let y = try readCGFloat(&index, end: end, separator: 32)
|
||||
|
||||
//print("Move to \(x), \(y)")
|
||||
currentPoint = CGPoint(x: currentPoint.x, y: y)
|
||||
context.addLine(to: currentPoint)
|
||||
} else if c == 67 { // C
|
||||
let x1 = try readCGFloat(&index, end: end, separator: 44)
|
||||
let y1 = try readCGFloat(&index, end: end, separator: 32)
|
||||
@ -715,12 +730,14 @@ public func drawSvgPath(_ context: CGContext, path: StaticString, strokeOnMove:
|
||||
let y2 = try readCGFloat(&index, end: end, separator: 32)
|
||||
let x = try readCGFloat(&index, end: end, separator: 44)
|
||||
let y = try readCGFloat(&index, end: end, separator: 32)
|
||||
context.addCurve(to: CGPoint(x: x, y: y), control1: CGPoint(x: x1, y: y1), control2: CGPoint(x: x2, y: y2))
|
||||
|
||||
currentPoint = CGPoint(x: x, y: y)
|
||||
context.addCurve(to: currentPoint, control1: CGPoint(x: x1, y: y1), control2: CGPoint(x: x2, y: y2))
|
||||
|
||||
//print("Line to \(x), \(y)")
|
||||
if strokeOnMove {
|
||||
context.strokePath()
|
||||
context.move(to: CGPoint(x: x, y: y))
|
||||
context.move(to: currentPoint)
|
||||
}
|
||||
} else if c == 90 { // Z
|
||||
if index != end && index.pointee != 32 {
|
||||
|
@ -306,15 +306,15 @@ private enum InviteLinksEditEntry: ItemListNodeEntry {
|
||||
}
|
||||
}
|
||||
|
||||
private func inviteLinkEditControllerEntries(invite: ExportedInvitation?, state: InviteLinkEditControllerState, presentationData: PresentationData) -> [InviteLinksEditEntry] {
|
||||
private func inviteLinkEditControllerEntries(invite: ExportedInvitation?, state: InviteLinkEditControllerState, isGroup: Bool, isPublic: Bool, presentationData: PresentationData) -> [InviteLinksEditEntry] {
|
||||
var entries: [InviteLinksEditEntry] = []
|
||||
|
||||
entries.append(.requestApproval(presentationData.theme, presentationData.strings.InviteLink_Create_RequestApproval, state.requestApproval))
|
||||
var requestApprovalInfoText = presentationData.strings.InviteLink_Create_RequestApprovalOffInfoChannel
|
||||
if state.requestApproval {
|
||||
requestApprovalInfoText = presentationData.strings.InviteLink_Create_RequestApprovalOnInfoChannel
|
||||
requestApprovalInfoText = isGroup ? presentationData.strings.InviteLink_Create_RequestApprovalOnInfoGroup : presentationData.strings.InviteLink_Create_RequestApprovalOnInfoChannel
|
||||
} else {
|
||||
requestApprovalInfoText = presentationData.strings.InviteLink_Create_RequestApprovalOffInfoChannel
|
||||
requestApprovalInfoText = isGroup ? presentationData.strings.InviteLink_Create_RequestApprovalOnInfoGroup : presentationData.strings.InviteLink_Create_RequestApprovalOffInfoChannel
|
||||
}
|
||||
entries.append(.requestApprovalInfo(presentationData.theme, requestApprovalInfoText))
|
||||
|
||||
@ -460,9 +460,14 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio
|
||||
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
|
||||
|
||||
let previousState = Atomic<InviteLinkEditControllerState?>(value: nil)
|
||||
let signal = combineLatest(presentationData, statePromise.get())
|
||||
let signal = combineLatest(
|
||||
presentationData,
|
||||
statePromise.get(),
|
||||
context.engine.data.subscribe(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||
))
|
||||
|> deliverOnMainQueue
|
||||
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
|> map { presentationData, state, peer -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
|
||||
dismissImpl?()
|
||||
})
|
||||
@ -524,8 +529,15 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio
|
||||
animateChanges = true
|
||||
}
|
||||
|
||||
let isGroup: Bool
|
||||
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||
isGroup = false
|
||||
} else {
|
||||
isGroup = true
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(invite == nil ? presentationData.strings.InviteLink_Create_Title : presentationData.strings.InviteLink_Create_EditTitle), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: inviteLinkEditControllerEntries(invite: invite, state: state, presentationData: presentationData), style: .blocks, emptyStateItem: nil, crossfadeState: false, animateChanges: animateChanges)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: inviteLinkEditControllerEntries(invite: invite, state: state, isGroup: isGroup, isPublic: !(peer?.addressName?.isEmpty ?? true), presentationData: presentationData), style: .blocks, emptyStateItem: nil, crossfadeState: false, animateChanges: animateChanges)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
@ -784,7 +784,7 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
|
||||
})))
|
||||
}
|
||||
|
||||
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .extracted(InviteLinkContextExtractedContentSource(controller: controller, sourceNode: node, blurBackground: true)), items: .single(ContextController.Items(items: items)), gesture: gesture)
|
||||
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .extracted(InviteLinkContextExtractedContentSource(controller: controller, sourceNode: node, keepInPlace: false, blurBackground: true)), items: .single(ContextController.Items(items: items)), gesture: gesture)
|
||||
presentInGlobalOverlayImpl?(contextController)
|
||||
}, openAdmin: { admin in
|
||||
let controller = inviteLinkListController(context: context, peerId: peerId, admin: admin)
|
||||
@ -957,10 +957,10 @@ final class InviteLinkContextExtractedContentSource: ContextExtractedContentSour
|
||||
private let controller: ViewController
|
||||
private let sourceNode: ContextExtractedContentContainingNode
|
||||
|
||||
init(controller: ViewController, sourceNode: ContextExtractedContentContainingNode, blurBackground: Bool) {
|
||||
init(controller: ViewController, sourceNode: ContextExtractedContentContainingNode, keepInPlace: Bool, blurBackground: Bool) {
|
||||
self.controller = controller
|
||||
self.sourceNode = sourceNode
|
||||
self.keepInPlace = true
|
||||
self.keepInPlace = keepInPlace
|
||||
self.blurBackground = blurBackground
|
||||
}
|
||||
|
||||
|
@ -808,17 +808,19 @@ public final class InviteLinkViewController: ViewController {
|
||||
}
|
||||
|
||||
let navigationController = parentController.navigationController as? NavigationController
|
||||
self.controller?.dismiss()
|
||||
|
||||
|
||||
|
||||
let invitationsContext = parentController.invitationsContext
|
||||
let revokedInvitationsContext = parentController.revokedInvitationsContext
|
||||
if let navigationController = navigationController {
|
||||
let updatedPresentationData = (self.presentationData, parentController.presentationDataPromise.get())
|
||||
let controller = inviteLinkEditController(context: self.context, updatedPresentationData: updatedPresentationData, peerId: self.peerId, invite: self.invite, completion: { invite in
|
||||
let controller = inviteLinkEditController(context: self.context, updatedPresentationData: updatedPresentationData, peerId: self.peerId, invite: self.invite, completion: { [weak self] invite in
|
||||
if let invite = invite {
|
||||
if invite.isRevoked {
|
||||
invitationsContext?.remove(invite)
|
||||
revokedInvitationsContext?.add(invite.withUpdated(isRevoked: true))
|
||||
|
||||
self?.controller?.dismiss()
|
||||
} else {
|
||||
invitationsContext?.update(invite)
|
||||
}
|
||||
@ -934,7 +936,6 @@ public final class InviteLinkViewController: ViewController {
|
||||
|
||||
var titleText = self.presentationData.strings.InviteLink_InviteLink
|
||||
|
||||
|
||||
var subtitleText = ""
|
||||
var subtitleColor = self.presentationData.theme.list.itemSecondaryTextColor
|
||||
if self.invite.isRevoked {
|
||||
@ -981,11 +982,11 @@ public final class InviteLinkViewController: ViewController {
|
||||
transition.updateFrame(node: self.titleNode, frame: titleFrame)
|
||||
|
||||
let editSize = self.editButton.measure(CGSize(width: layout.size.width, height: headerHeight))
|
||||
let editFrame = CGRect(origin: CGPoint(x: 16.0, y: 18.0), size: editSize)
|
||||
let editFrame = CGRect(origin: CGPoint(x: 16.0 + layout.safeInsets.left, y: 18.0), size: editSize)
|
||||
transition.updateFrame(node: self.editButton, frame: editFrame)
|
||||
|
||||
let doneSize = self.doneButton.measure(CGSize(width: layout.size.width, height: headerHeight))
|
||||
let doneFrame = CGRect(origin: CGPoint(x: layout.size.width - doneSize.width - 16.0, y: 18.0), size: doneSize)
|
||||
let doneFrame = CGRect(origin: CGPoint(x: layout.size.width - doneSize.width - 16.0 - layout.safeInsets.right, y: 18.0), size: doneSize)
|
||||
transition.updateFrame(node: self.doneButton, frame: doneFrame)
|
||||
}
|
||||
|
||||
|
@ -160,6 +160,7 @@ public func inviteRequestsController(context: AccountContext, updatedPresentatio
|
||||
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
|
||||
var presentInGlobalOverlayImpl: ((ViewController) -> Void)?
|
||||
var navigateToProfileImpl: ((EnginePeer) -> Void)?
|
||||
var navigateToChatImpl: ((EnginePeer) -> Void)?
|
||||
var dismissInputImpl: (() -> Void)?
|
||||
var dismissTooltipsImpl: (() -> Void)?
|
||||
|
||||
@ -214,33 +215,56 @@ public func inviteRequestsController(context: AccountContext, updatedPresentatio
|
||||
guard let node = node as? ContextExtractedContentContainingNode else {
|
||||
return
|
||||
}
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
let _ = (context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
guard let peer = peer else {
|
||||
return
|
||||
}
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let addString: String
|
||||
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||
addString = presentationData.strings.MemberRequests_AddToChannel
|
||||
} else {
|
||||
addString = presentationData.strings.MemberRequests_AddToGroup
|
||||
}
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MemberRequests_AddToGroup, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddUser"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
items.append(.action(ContextMenuActionItem(text: addString, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddUser"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
approveRequestImpl(peer)
|
||||
})))
|
||||
|
||||
approveRequestImpl(peer)
|
||||
})))
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MemberRequests_Dismiss, textColor: .destructive, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.destructiveColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.ContactList_Context_SendMessage, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Message"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
navigateToChatImpl?(peer)
|
||||
})))
|
||||
|
||||
denyRequestImpl(peer)
|
||||
})))
|
||||
|
||||
let dismissPromise = ValuePromise<Bool>(false)
|
||||
let source = InviteRequestsContextExtractedContentSource(sourceNode: node, keepInPlace: false, blurBackground: true, centerVertically: true, shouldBeDismissed: dismissPromise.get())
|
||||
// sourceNode.requestDismiss = {
|
||||
// dismissPromise.set(true)
|
||||
// }
|
||||
|
||||
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .extracted(source), items: .single(ContextController.Items(items: items)), gesture: gesture)
|
||||
presentInGlobalOverlayImpl?(contextController)
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MemberRequests_Dismiss, textColor: .destructive, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.destructiveColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
denyRequestImpl(peer)
|
||||
})))
|
||||
|
||||
let dismissPromise = ValuePromise<Bool>(false)
|
||||
let source = InviteRequestsContextExtractedContentSource(sourceNode: node, keepInPlace: false, blurBackground: true, centerVertically: true, shouldBeDismissed: dismissPromise.get())
|
||||
// sourceNode.requestDismiss = {
|
||||
// dismissPromise.set(true)
|
||||
// }
|
||||
|
||||
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .extracted(source), items: .single(ContextController.Items(items: items)), gesture: gesture)
|
||||
presentInGlobalOverlayImpl?(contextController)
|
||||
})
|
||||
})
|
||||
|
||||
let previousEntries = Atomic<[InviteRequestsEntry]>(value: [])
|
||||
@ -298,10 +322,14 @@ public func inviteRequestsController(context: AccountContext, updatedPresentatio
|
||||
arguments.approveRequest(peer)
|
||||
}, denyRequest: { peer in
|
||||
arguments.denyRequest(peer)
|
||||
}, navigateToChat: { peer in
|
||||
navigateToChatImpl?(peer)
|
||||
}, pushController: { c in
|
||||
pushControllerImpl?(c)
|
||||
}, dismissInput: {
|
||||
dismissInputImpl?()
|
||||
}, presentInGlobalOverlay: { c in
|
||||
presentInGlobalOverlayImpl?(c)
|
||||
})
|
||||
}
|
||||
|
||||
@ -347,6 +375,11 @@ public func inviteRequestsController(context: AccountContext, updatedPresentatio
|
||||
navigationController.pushViewController(controller)
|
||||
}
|
||||
}
|
||||
navigateToChatImpl = { [weak controller] peer in
|
||||
if let navigationController = controller?.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer.id)))
|
||||
}
|
||||
}
|
||||
dismissInputImpl = { [weak controller] in
|
||||
controller?.view.endEditing(true)
|
||||
}
|
||||
@ -367,7 +400,7 @@ public func inviteRequestsController(context: AccountContext, updatedPresentatio
|
||||
}
|
||||
|
||||
|
||||
private final class InviteRequestsContextExtractedContentSource: ContextExtractedContentSource {
|
||||
final class InviteRequestsContextExtractedContentSource: ContextExtractedContentSource {
|
||||
var keepInPlace: Bool
|
||||
let ignoreContentTouches: Bool = false
|
||||
let blurBackground: Bool
|
||||
|
@ -15,6 +15,7 @@ import MergeLists
|
||||
import ChatListSearchItemHeader
|
||||
import ItemListUI
|
||||
import SearchUI
|
||||
import ContextUI
|
||||
|
||||
private let searchBarFont = Font.regular(17.0)
|
||||
|
||||
@ -101,22 +102,26 @@ final class InviteRequestsSearchItem: ItemListControllerSearch {
|
||||
let openPeer: (EnginePeer) -> Void
|
||||
let approveRequest: (EnginePeer) -> Void
|
||||
let denyRequest: (EnginePeer) -> Void
|
||||
let navigateToChat: (EnginePeer) -> Void
|
||||
let pushController: (ViewController) -> Void
|
||||
let presentInGlobalOverlay: (ViewController) -> Void
|
||||
let dismissInput: () -> Void
|
||||
|
||||
private var updateActivity: ((Bool) -> Void)?
|
||||
private var activity: ValuePromise<Bool> = ValuePromise(ignoreRepeated: false)
|
||||
private let activityDisposable = MetaDisposable()
|
||||
|
||||
init(context: AccountContext, peerId: PeerId, cancel: @escaping () -> Void, openPeer: @escaping (EnginePeer) -> Void, approveRequest: @escaping (EnginePeer) -> Void, denyRequest: @escaping (EnginePeer) -> Void, pushController: @escaping (ViewController) -> Void, dismissInput: @escaping () -> Void) {
|
||||
init(context: AccountContext, peerId: PeerId, cancel: @escaping () -> Void, openPeer: @escaping (EnginePeer) -> Void, approveRequest: @escaping (EnginePeer) -> Void, denyRequest: @escaping (EnginePeer) -> Void, navigateToChat: @escaping (EnginePeer) -> Void, pushController: @escaping (ViewController) -> Void, dismissInput: @escaping () -> Void, presentInGlobalOverlay: @escaping (ViewController) -> Void) {
|
||||
self.context = context
|
||||
self.peerId = peerId
|
||||
self.cancel = cancel
|
||||
self.openPeer = openPeer
|
||||
self.approveRequest = approveRequest
|
||||
self.denyRequest = denyRequest
|
||||
self.navigateToChat = navigateToChat
|
||||
self.pushController = pushController
|
||||
self.dismissInput = dismissInput
|
||||
self.presentInGlobalOverlay = presentInGlobalOverlay
|
||||
self.activityDisposable.set((activity.get() |> mapToSignal { value -> Signal<Bool, NoError> in
|
||||
if value {
|
||||
return .single(value) |> delay(0.2, queue: Queue.mainQueue())
|
||||
@ -159,25 +164,27 @@ final class InviteRequestsSearchItem: ItemListControllerSearch {
|
||||
}
|
||||
|
||||
func node(current: ItemListControllerSearchNode?, titleContentNode: (NavigationBarContentNode & ItemListControllerSearchNavigationContentNode)?) -> ItemListControllerSearchNode {
|
||||
return InviteRequestsSearchItemNode(context: self.context, peerId: self.peerId, openPeer: self.openPeer, approveRequest: self.approveRequest, denyRequest: self.denyRequest, cancel: self.cancel, updateActivity: { [weak self] value in
|
||||
return InviteRequestsSearchItemNode(context: self.context, peerId: self.peerId, openPeer: self.openPeer, approveRequest: self.approveRequest, denyRequest: self.denyRequest, navigateToChat: self.navigateToChat, cancel: self.cancel, updateActivity: { [weak self] value in
|
||||
self?.activity.set(value)
|
||||
}, pushController: { [weak self] c in
|
||||
self?.pushController(c)
|
||||
}, dismissInput: self.dismissInput)
|
||||
}, dismissInput: self.dismissInput, presentInGlobalOverlay: self.presentInGlobalOverlay)
|
||||
}
|
||||
}
|
||||
|
||||
private final class InviteRequestsSearchItemNode: ItemListControllerSearchNode {
|
||||
private let containerNode: InviteRequestsSearchContainerNode
|
||||
|
||||
init(context: AccountContext, peerId: PeerId, openPeer: @escaping (EnginePeer) -> Void, approveRequest: @escaping (EnginePeer) -> Void, denyRequest: @escaping (EnginePeer) -> Void, cancel: @escaping () -> Void, updateActivity: @escaping(Bool) -> Void, pushController: @escaping (ViewController) -> Void, dismissInput: @escaping () -> Void) {
|
||||
init(context: AccountContext, peerId: PeerId, openPeer: @escaping (EnginePeer) -> Void, approveRequest: @escaping (EnginePeer) -> Void, denyRequest: @escaping (EnginePeer) -> Void, navigateToChat: @escaping (EnginePeer) -> Void, cancel: @escaping () -> Void, updateActivity: @escaping(Bool) -> Void, pushController: @escaping (ViewController) -> Void, dismissInput: @escaping () -> Void, presentInGlobalOverlay: @escaping (ViewController) -> Void) {
|
||||
self.containerNode = InviteRequestsSearchContainerNode(context: context, forceTheme: nil, peerId: peerId, openPeer: { peer in
|
||||
openPeer(peer)
|
||||
}, approveRequest: { peer in
|
||||
approveRequest(peer)
|
||||
}, denyRequest: { peer in
|
||||
denyRequest(peer)
|
||||
}, updateActivity: updateActivity, pushController: pushController)
|
||||
}, navigateToChat: { peer in
|
||||
navigateToChat(peer)
|
||||
}, updateActivity: updateActivity, pushController: pushController, presentInGlobalOverlay: presentInGlobalOverlay)
|
||||
self.containerNode.cancel = {
|
||||
cancel()
|
||||
}
|
||||
@ -335,7 +342,7 @@ public final class InviteRequestsSearchContainerNode: SearchDisplayControllerCon
|
||||
}
|
||||
}
|
||||
|
||||
public init(context: AccountContext, forceTheme: PresentationTheme?, peerId: PeerId, openPeer: @escaping (EnginePeer) -> Void, approveRequest: @escaping (EnginePeer) -> Void, denyRequest: @escaping (EnginePeer) -> Void, updateActivity: @escaping (Bool) -> Void, pushController: @escaping (ViewController) -> Void) {
|
||||
public init(context: AccountContext, forceTheme: PresentationTheme?, peerId: PeerId, openPeer: @escaping (EnginePeer) -> Void, approveRequest: @escaping (EnginePeer) -> Void, denyRequest: @escaping (EnginePeer) -> Void, navigateToChat: @escaping (EnginePeer) -> Void, updateActivity: @escaping (Bool) -> Void, pushController: @escaping (ViewController) -> Void, presentInGlobalOverlay: @escaping (ViewController) -> Void) {
|
||||
self.context = context
|
||||
self.openPeer = openPeer
|
||||
|
||||
@ -391,8 +398,62 @@ public final class InviteRequestsSearchContainerNode: SearchDisplayControllerCon
|
||||
}, denyRequest: { [weak self] peer in
|
||||
denyRequest(peer)
|
||||
self?.processedPeerIds.insert(peer.id)
|
||||
}, peerContextAction: { _, _, _ in
|
||||
}, peerContextAction: { [weak self] peer, node, gesture in
|
||||
guard let node = node as? ContextExtractedContentContainingNode else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let peer = peer else {
|
||||
return
|
||||
}
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let addString: String
|
||||
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||
addString = presentationData.strings.MemberRequests_AddToChannel
|
||||
} else {
|
||||
addString = presentationData.strings.MemberRequests_AddToGroup
|
||||
}
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: addString, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddUser"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
approveRequest(peer)
|
||||
self?.processedPeerIds.insert(peer.id)
|
||||
})))
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.ContactList_Context_SendMessage, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Message"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
navigateToChat(peer)
|
||||
})))
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MemberRequests_Dismiss, textColor: .destructive, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.destructiveColor)
|
||||
}, action: { [weak self] _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
denyRequest(peer)
|
||||
self?.processedPeerIds.insert(peer.id)
|
||||
})))
|
||||
|
||||
let dismissPromise = ValuePromise<Bool>(false)
|
||||
let source = InviteRequestsContextExtractedContentSource(sourceNode: node, keepInPlace: false, blurBackground: true, centerVertically: true, shouldBeDismissed: dismissPromise.get())
|
||||
// sourceNode.requestDismiss = {
|
||||
// dismissPromise.set(true)
|
||||
// }
|
||||
|
||||
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .extracted(source), items: .single(ContextController.Items(items: items)), gesture: gesture)
|
||||
presentInGlobalOverlay(contextController)
|
||||
})
|
||||
})
|
||||
|
||||
let presentationDataPromise = self.presentationDataPromise
|
||||
@ -412,13 +473,20 @@ public final class InviteRequestsSearchContainerNode: SearchDisplayControllerCon
|
||||
|
||||
let foundItems = combineLatest(searchQuery, context.account.postbox.peerView(id: peerId) |> take(1))
|
||||
|> mapToSignal { query, peerView -> Signal<[InviteRequestsSearchEntry]?, NoError> in
|
||||
guard let query = query, !query.isEmpty else {
|
||||
guard let query = query, !query.isEmpty, let peer = peerViewMainPeer(peerView) else {
|
||||
return .single(nil)
|
||||
}
|
||||
updateActivity(true)
|
||||
let requestsContext = context.engine.peers.peerInvitationImporters(peerId: peerId, subject: .requests(query: query))
|
||||
let _ = previousRequestsContext.swap(requestsContext)
|
||||
|
||||
let isGroup: Bool
|
||||
if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
isGroup = false
|
||||
} else {
|
||||
isGroup = true
|
||||
}
|
||||
|
||||
return combineLatest(requestsContext.state, presentationDataPromise.get(), processedPeerIds.get())
|
||||
|> mapToSignal { state, presentationData, processedPeerIds -> Signal<[InviteRequestsSearchEntry]?, NoError> in
|
||||
if !state.hasLoadedOnce {
|
||||
@ -431,7 +499,7 @@ public final class InviteRequestsSearchContainerNode: SearchDisplayControllerCon
|
||||
if processedPeerIds.contains(importer.peer.peerId) {
|
||||
continue
|
||||
}
|
||||
entries.append(InviteRequestsSearchEntry(index: index, request: importer, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, isGroup: false))
|
||||
entries.append(InviteRequestsSearchEntry(index: index, request: importer, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, isGroup: isGroup))
|
||||
index += 1
|
||||
}
|
||||
return .single(entries)
|
||||
|
@ -198,6 +198,7 @@ public class ItemListInviteRequestItemNode: ListViewItemNode, ItemListItemNode {
|
||||
self.subtitleNode.contentsScale = UIScreen.main.scale
|
||||
|
||||
self.expandedSubtitleNode = TextNode()
|
||||
self.expandedSubtitleNode.alpha = 0.0
|
||||
self.expandedSubtitleNode.isUserInteractionEnabled = false
|
||||
self.expandedSubtitleNode.contentMode = .left
|
||||
self.expandedSubtitleNode.contentsScale = UIScreen.main.scale
|
||||
@ -517,7 +518,7 @@ public class ItemListInviteRequestItemNode: ListViewItemNode, ItemListItemNode {
|
||||
let rightInset: CGFloat = 16.0 + params.rightInset
|
||||
let verticalInset: CGFloat = 9.0
|
||||
|
||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset - 44.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: subtitleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
let (expandedSubtitleLayout, expandedSubtitleApply) = makeExpandedSubtitleLayout(TextNodeLayoutArguments(attributedString: subtitleAttributedString, backgroundColor: nil, maximumNumberOfLines: 5, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
let (dateLayout, dateApply) = makeDateLayout(TextNodeLayoutArguments(attributedString: dateAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
@ -307,10 +307,10 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
|
||||
mutableDescriptionText.append(NSAttributedString(string: text + "\n", font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemSecondaryTextColor))
|
||||
}
|
||||
|
||||
let plainUrlString = NSAttributedString(string: content.displayUrl, font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor)
|
||||
let plainUrlString = NSAttributedString(string: content.url.replacingOccurrences(of: "https://", with: ""), font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor)
|
||||
let urlString = NSMutableAttributedString()
|
||||
urlString.append(plainUrlString)
|
||||
urlString.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: content.displayUrl, range: NSMakeRange(0, urlString.length))
|
||||
urlString.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: content.url, range: NSMakeRange(0, urlString.length))
|
||||
linkText = urlString
|
||||
|
||||
descriptionText = mutableDescriptionText
|
||||
@ -395,7 +395,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
|
||||
}
|
||||
|
||||
let urlAttributedString = NSMutableAttributedString()
|
||||
urlAttributedString.append(NSAttributedString(string: urlString, font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor))
|
||||
urlAttributedString.append(NSAttributedString(string: urlString.replacingOccurrences(of: "https://", with: ""), font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor))
|
||||
if item.presentationData.theme.theme.list.itemAccentColor.isEqual(item.presentationData.theme.theme.list.itemPrimaryTextColor) {
|
||||
urlAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: NSMakeRange(0, urlAttributedString.length))
|
||||
}
|
||||
@ -439,7 +439,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
|
||||
}
|
||||
|
||||
let urlAttributedString = NSMutableAttributedString()
|
||||
urlAttributedString.append(NSAttributedString(string: urlString, font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor))
|
||||
urlAttributedString.append(NSAttributedString(string: urlString.replacingOccurrences(of: "https://", with: ""), font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor))
|
||||
if item.presentationData.theme.theme.list.itemAccentColor.isEqual(item.presentationData.theme.theme.list.itemPrimaryTextColor) {
|
||||
urlAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: NSMakeRange(0, urlAttributedString.length))
|
||||
}
|
||||
@ -505,7 +505,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
|
||||
|
||||
let (descriptionNodeLayout, descriptionNodeApply) = descriptionNodeMakeLayout(TextNodeLayoutArguments(attributedString: descriptionText, backgroundColor: nil, maximumNumberOfLines: descriptionMaxNumberOfLines, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 8.0 - params.rightInset - 16.0 - 8.0, height: CGFloat.infinity), alignment: .natural, lineSpacing: 0.3, cutout: nil, insets: UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)))
|
||||
|
||||
let (linkNodeLayout, linkNodeApply) = linkNodeMakeLayout(TextNodeLayoutArguments(attributedString: linkText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 8.0 - params.rightInset - 16.0 - 8.0, height: CGFloat.infinity), alignment: .natural, lineSpacing: 0.3, cutout: isInstantView ? TextNodeCutout(topLeft: CGSize(width: 14.0, height: 8.0)) : nil, insets: UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)))
|
||||
let (linkNodeLayout, linkNodeApply) = linkNodeMakeLayout(TextNodeLayoutArguments(attributedString: linkText, backgroundColor: nil, maximumNumberOfLines: 4, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 8.0 - params.rightInset - 16.0 - 8.0, height: CGFloat.infinity), alignment: .natural, lineSpacing: 0.3, cutout: isInstantView ? TextNodeCutout(topLeft: CGSize(width: 14.0, height: 8.0)) : nil, insets: UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)))
|
||||
var instantViewImage: UIImage?
|
||||
if isInstantView {
|
||||
instantViewImage = PresentationResourcesChat.sharedMediaInstantViewIcon(item.presentationData.theme.theme)
|
||||
|
@ -38,6 +38,7 @@ private struct LocationViewTransaction {
|
||||
let insertions: [ListViewInsertItem]
|
||||
let updates: [ListViewUpdateItem]
|
||||
let gotTravelTimes: Bool
|
||||
let count: Int
|
||||
}
|
||||
|
||||
private enum LocationViewEntryId: Hashable {
|
||||
@ -184,7 +185,7 @@ private func preparedTransition(from fromEntries: [LocationViewEntry], to toEntr
|
||||
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, interaction: interaction), directionHint: nil) }
|
||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, interaction: interaction), directionHint: nil) }
|
||||
|
||||
return LocationViewTransaction(deletions: deletions, insertions: insertions, updates: updates, gotTravelTimes: gotTravelTimes)
|
||||
return LocationViewTransaction(deletions: deletions, insertions: insertions, updates: updates, gotTravelTimes: gotTravelTimes, count: toEntries.count)
|
||||
}
|
||||
|
||||
enum LocationViewLocation: Equatable {
|
||||
@ -453,7 +454,7 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
|
||||
var drivingTime: Double?
|
||||
var transitTime: Double?
|
||||
var walkingTime: Double?
|
||||
if !isLocationView {
|
||||
if !isLocationView && message.author?.id != context.account.peerId {
|
||||
if let (previousTimestamp, maybeDrivingTime, maybeTransitTime, maybeWalkingTime) = travelTimes[message.id] {
|
||||
drivingTime = maybeDrivingTime
|
||||
transitTime = maybeTransitTime
|
||||
@ -704,7 +705,11 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
|
||||
var index: Int = 0
|
||||
var offset: CGFloat = 0.0
|
||||
if transition.gotTravelTimes {
|
||||
index = 1
|
||||
if transition.count > 1 {
|
||||
index = 1
|
||||
} else {
|
||||
index = 0
|
||||
}
|
||||
offset = 0.0
|
||||
} else if transition.insertions.count > 2 {
|
||||
index = 2
|
||||
|
@ -363,7 +363,7 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
var string: String?
|
||||
if let _ = item.themeReference.emoticon {
|
||||
} else {
|
||||
string = "⚙️"
|
||||
string = "🎨"
|
||||
}
|
||||
|
||||
let emojiTitle = NSAttributedString(string: string ?? "", font: Font.regular(20.0), textColor: .black)
|
||||
|
@ -22,9 +22,9 @@ import AnimationUI
|
||||
|
||||
private final class ThemePickerControllerArguments {
|
||||
let context: AccountContext
|
||||
let selectTheme: (PresentationThemeReference) -> Void
|
||||
let selectTheme: (TelegramBaseTheme?, PresentationThemeReference) -> Void
|
||||
let previewTheme: (PresentationThemeReference) -> Void
|
||||
let selectAccentColor: (PresentationThemeAccentColor?) -> Void
|
||||
let selectAccentColor: (TelegramBaseTheme?, PresentationThemeAccentColor?) -> Void
|
||||
let openAccentColorPicker: (PresentationThemeReference, Bool) -> Void
|
||||
let editTheme: (PresentationCloudTheme) -> Void
|
||||
let editCurrentTheme: () -> Void
|
||||
@ -32,7 +32,7 @@ private final class ThemePickerControllerArguments {
|
||||
let themeContextAction: (Bool, PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void
|
||||
let colorContextAction: (Bool, PresentationThemeReference, ThemeSettingsColorOption?, ASDisplayNode, ContextGesture?) -> Void
|
||||
|
||||
init(context: AccountContext, selectTheme: @escaping (PresentationThemeReference) -> Void, previewTheme: @escaping (PresentationThemeReference) -> Void, selectAccentColor: @escaping (PresentationThemeAccentColor?) -> Void, openAccentColorPicker: @escaping (PresentationThemeReference, Bool) -> Void, editTheme: @escaping (PresentationCloudTheme) -> Void, editCurrentTheme: @escaping () -> Void, createNewTheme: @escaping () -> Void, themeContextAction: @escaping (Bool, PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void, colorContextAction: @escaping (Bool, PresentationThemeReference, ThemeSettingsColorOption?, ASDisplayNode, ContextGesture?) -> Void) {
|
||||
init(context: AccountContext, selectTheme: @escaping (TelegramBaseTheme?, PresentationThemeReference) -> Void, previewTheme: @escaping (PresentationThemeReference) -> Void, selectAccentColor: @escaping (TelegramBaseTheme?, PresentationThemeAccentColor?) -> Void, openAccentColorPicker: @escaping (PresentationThemeReference, Bool) -> Void, editTheme: @escaping (PresentationCloudTheme) -> Void, editCurrentTheme: @escaping () -> Void, createNewTheme: @escaping () -> Void, themeContextAction: @escaping (Bool, PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void, colorContextAction: @escaping (Bool, PresentationThemeReference, ThemeSettingsColorOption?, ASDisplayNode, ContextGesture?) -> Void) {
|
||||
self.context = context
|
||||
self.selectTheme = selectTheme
|
||||
self.previewTheme = previewTheme
|
||||
@ -57,7 +57,7 @@ private enum ThemePickerControllerEntry: ItemListNodeEntry {
|
||||
case themes(PresentationTheme, PresentationStrings, [PresentationThemeReference], PresentationThemeReference, Bool, [String: [StickerPackItem]])
|
||||
case customHeader(PresentationTheme, String)
|
||||
case chatPreview(PresentationTheme, TelegramWallpaper, PresentationFontSize, PresentationChatBubbleCorners, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, [ChatPreviewMessageItem])
|
||||
case theme(PresentationTheme, PresentationStrings, [PresentationThemeReference], [PresentationThemeReference], PresentationThemeReference, [Int64: PresentationThemeAccentColor], [Int64: TelegramWallpaper], PresentationThemeAccentColor?)
|
||||
case theme(PresentationTheme, PresentationStrings, [PresentationThemeReference], [PresentationThemeReference], PresentationThemeReference, [Int64: PresentationThemeAccentColor], [Int64: TelegramWallpaper], PresentationThemeAccentColor?, [Int64: TelegramBaseTheme])
|
||||
case accentColor(PresentationTheme, PresentationThemeReference, PresentationThemeReference, [PresentationThemeReference], ThemeSettingsColorOption?)
|
||||
case editTheme(PresentationTheme, String)
|
||||
case createTheme(PresentationTheme, String)
|
||||
@ -120,8 +120,8 @@ private enum ThemePickerControllerEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .theme(lhsTheme, lhsStrings, lhsThemes, lhsAllThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeSpecificChatWallpapers, lhsCurrentColor):
|
||||
if case let .theme(rhsTheme, rhsStrings, rhsThemes, rhsAllThemes, rhsCurrentTheme, rhsThemeAccentColors, rhsThemeSpecificChatWallpapers, rhsCurrentColor) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsThemes == rhsThemes, lhsAllThemes == rhsAllThemes, lhsCurrentTheme == rhsCurrentTheme, lhsThemeAccentColors == rhsThemeAccentColors, lhsThemeSpecificChatWallpapers == rhsThemeSpecificChatWallpapers, lhsCurrentColor == rhsCurrentColor {
|
||||
case let .theme(lhsTheme, lhsStrings, lhsThemes, lhsAllThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeSpecificChatWallpapers, lhsCurrentColor, lhsThemePreferredBaseTheme):
|
||||
if case let .theme(rhsTheme, rhsStrings, rhsThemes, rhsAllThemes, rhsCurrentTheme, rhsThemeAccentColors, rhsThemeSpecificChatWallpapers, rhsCurrentColor, rhsThemePreferredBaseTheme) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsThemes == rhsThemes, lhsAllThemes == rhsAllThemes, lhsCurrentTheme == rhsCurrentTheme, lhsThemeAccentColors == rhsThemeAccentColors, lhsThemeSpecificChatWallpapers == rhsThemeSpecificChatWallpapers, lhsCurrentColor == rhsCurrentColor, lhsThemePreferredBaseTheme == rhsThemePreferredBaseTheme {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -166,14 +166,14 @@ private enum ThemePickerControllerEntry: ItemListNodeEntry {
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .chatPreview(theme, wallpaper, fontSize, chatBubbleCorners, strings, dateTimeFormat, nameDisplayOrder, items):
|
||||
return ThemeSettingsChatPreviewItem(context: arguments.context, theme: theme, componentTheme: theme, strings: strings, sectionId: self.section, fontSize: fontSize, chatBubbleCorners: chatBubbleCorners, wallpaper: wallpaper, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, messageItems: items)
|
||||
case let .theme(theme, strings, themes, allThemes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers, _):
|
||||
return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, allThemes: allThemes, displayUnsupported: true, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in
|
||||
case let .theme(theme, strings, themes, allThemes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers, _, themePreferredBaseTheme):
|
||||
return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, allThemes: allThemes, displayUnsupported: true, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, themePreferredBaseTheme: themePreferredBaseTheme, currentTheme: currentTheme, updatedTheme: { theme in
|
||||
if case let .cloud(theme) = theme, theme.theme.file == nil && theme.theme.settings == nil {
|
||||
if theme.theme.isCreator {
|
||||
arguments.editTheme(theme)
|
||||
}
|
||||
} else {
|
||||
arguments.selectTheme(theme)
|
||||
arguments.selectTheme(nil, theme)
|
||||
}
|
||||
}, contextAction: { theme, node, gesture in
|
||||
arguments.themeContextAction(theme.index == currentTheme.index, theme, node, gesture)
|
||||
@ -246,16 +246,24 @@ private enum ThemePickerControllerEntry: ItemListNodeEntry {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let baseTheme: TelegramBaseTheme?
|
||||
if case let .builtin(theme) = generalThemeReference {
|
||||
baseTheme = theme.baseTheme
|
||||
} else {
|
||||
baseTheme = nil
|
||||
}
|
||||
|
||||
return ThemeSettingsAccentColorItem(theme: theme, sectionId: self.section, generalThemeReference: generalThemeReference, themeReference: currentTheme, colors: colorItems, currentColor: currentColor, updated: { color in
|
||||
if let color = color {
|
||||
switch color {
|
||||
case let .accentColor(color):
|
||||
arguments.selectAccentColor(color)
|
||||
arguments.selectAccentColor(baseTheme, color)
|
||||
case let .theme(theme):
|
||||
arguments.selectTheme(theme)
|
||||
arguments.selectTheme(baseTheme, theme)
|
||||
}
|
||||
} else {
|
||||
arguments.selectAccentColor(nil)
|
||||
arguments.selectAccentColor(nil, nil)
|
||||
}
|
||||
}, contextAction: { isCurrent, theme, color, node, gesture in
|
||||
arguments.colorContextAction(isCurrent, theme, color, node, gesture)
|
||||
@ -263,7 +271,7 @@ private enum ThemePickerControllerEntry: ItemListNodeEntry {
|
||||
arguments.openAccentColorPicker(currentTheme, create)
|
||||
}, tag: ThemeSettingsEntryTag.accentColor)
|
||||
case let .editTheme(theme, text):
|
||||
return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.makeVisibleIcon(theme), title: text, sectionId: self.section, height: .generic, editing: false, action: {
|
||||
return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.makeEditThemeIcon(theme), title: text, sectionId: self.section, height: .generic, editing: false, action: {
|
||||
arguments.editCurrentTheme()
|
||||
})
|
||||
case let .createTheme(theme, text):
|
||||
@ -292,17 +300,23 @@ private func themePickerControllerEntries(presentationData: PresentationData, pr
|
||||
}
|
||||
|
||||
let generalThemeReference: PresentationThemeReference
|
||||
if case let .cloud(theme) = themeReference, let settings = theme.theme.settings?.first {
|
||||
generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme))
|
||||
if case let .cloud(theme) = themeReference, let settings = theme.theme.settings {
|
||||
if let baseTheme = presentationThemeSettings.themePreferredBaseTheme[themeReference.index] {
|
||||
generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: baseTheme))
|
||||
} else if let first = settings.first {
|
||||
generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: first.baseTheme))
|
||||
} else {
|
||||
generalThemeReference = themeReference
|
||||
}
|
||||
} else {
|
||||
generalThemeReference = themeReference
|
||||
}
|
||||
|
||||
entries.append(.theme(presentationData.theme, presentationData.strings, generalThemes, availableThemes, themeReference, presentationThemeSettings.themeSpecificAccentColors, presentationThemeSettings.themeSpecificChatWallpapers, presentationThemeSettings.themeSpecificAccentColors[themeReference.index]))
|
||||
entries.append(.theme(presentationData.theme, presentationData.strings, generalThemes, availableThemes, themeReference, presentationThemeSettings.themeSpecificAccentColors, presentationThemeSettings.themeSpecificChatWallpapers, presentationThemeSettings.themeSpecificAccentColors[themeReference.index], presentationThemeSettings.themePreferredBaseTheme))
|
||||
|
||||
if case let .builtin(builtinTheme) = generalThemeReference {
|
||||
let colorThemes = availableThemes.filter { reference in
|
||||
if case let .cloud(theme) = reference, let settings = theme.theme.settings?.first, settings.baseTheme == builtinTheme.baseTheme {
|
||||
if case let .cloud(theme) = reference, let settings = theme.theme.settings, settings.contains(where: { $0.baseTheme == builtinTheme.baseTheme }) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -344,8 +358,8 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
var getNavigationControllerImpl: (() -> NavigationController?)?
|
||||
var presentCrossfadeControllerImpl: ((Bool) -> Void)?
|
||||
|
||||
var selectThemeImpl: ((PresentationThemeReference) -> Void)?
|
||||
var selectAccentColorImpl: ((PresentationThemeAccentColor?) -> Void)?
|
||||
var selectThemeImpl: ((TelegramBaseTheme?, PresentationThemeReference) -> Void)?
|
||||
var selectAccentColorImpl: ((TelegramBaseTheme?, PresentationThemeAccentColor?) -> Void)?
|
||||
var openAccentColorPickerImpl: ((PresentationThemeReference, Bool) -> Void)?
|
||||
|
||||
let _ = telegramWallpapers(postbox: context.account.postbox, network: context.account.network).start()
|
||||
@ -379,15 +393,15 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
|
||||
let nightModePreviewPromise = ValuePromise<Bool>(false)
|
||||
|
||||
let arguments = ThemePickerControllerArguments(context: context, selectTheme: { theme in
|
||||
selectThemeImpl?(theme)
|
||||
let arguments = ThemePickerControllerArguments(context: context, selectTheme: { baseTheme, theme in
|
||||
selectThemeImpl?(baseTheme, theme)
|
||||
}, previewTheme: { themeReference in
|
||||
if let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference) {
|
||||
let controller = ThemePreviewController(context: context, previewTheme: theme, source: .settings(themeReference, nil, false))
|
||||
pushControllerImpl?(controller)
|
||||
}
|
||||
}, selectAccentColor: { accentColor in
|
||||
selectAccentColorImpl?(accentColor)
|
||||
}, selectAccentColor: { currentBaseTheme, accentColor in
|
||||
selectAccentColorImpl?(currentBaseTheme, accentColor)
|
||||
}, openAccentColorPicker: { themeReference, create in
|
||||
openAccentColorPickerImpl?(themeReference, create)
|
||||
}, editTheme: { theme in
|
||||
@ -398,7 +412,30 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
})
|
||||
pushControllerImpl?(controller)
|
||||
}, editCurrentTheme: {
|
||||
|
||||
let _ = (context.sharedContext.accountManager.transaction { transaction -> PresentationThemeReference in
|
||||
let settings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.presentationThemeSettings)?.get(PresentationThemeSettings.self) ?? PresentationThemeSettings.defaultSettings
|
||||
|
||||
let themeReference: PresentationThemeReference
|
||||
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
|
||||
if autoNightModeTriggered {
|
||||
themeReference = settings.automaticThemeSwitchSetting.theme
|
||||
} else {
|
||||
themeReference = settings.theme
|
||||
}
|
||||
|
||||
return themeReference
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { themeReference in
|
||||
guard case let .cloud(cloudTheme) = themeReference else {
|
||||
return
|
||||
}
|
||||
let controller = editThemeController(context: context, mode: .edit(cloudTheme), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
}
|
||||
})
|
||||
pushControllerImpl?(controller)
|
||||
})
|
||||
}, createNewTheme: {
|
||||
let _ = (context.sharedContext.accountManager.transaction { transaction -> PresentationThemeReference in
|
||||
let settings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.presentationThemeSettings)?.get(PresentationThemeSettings.self) ?? PresentationThemeSettings.defaultSettings
|
||||
@ -558,9 +595,9 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
if isCurrent, let currentThemeIndex = themes.firstIndex(where: { $0.id == theme.theme.id }) {
|
||||
if let settings = theme.theme.settings?.first {
|
||||
if settings.baseTheme == .night {
|
||||
selectAccentColorImpl?(PresentationThemeAccentColor(baseColor: .blue))
|
||||
selectAccentColorImpl?(nil, PresentationThemeAccentColor(baseColor: .blue))
|
||||
} else {
|
||||
selectAccentColorImpl?(nil)
|
||||
selectAccentColorImpl?(nil, nil)
|
||||
}
|
||||
} else {
|
||||
let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil })
|
||||
@ -571,7 +608,7 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
} else {
|
||||
newTheme = .builtin(.nightAccent)
|
||||
}
|
||||
selectThemeImpl?(newTheme)
|
||||
selectThemeImpl?(nil, newTheme)
|
||||
}
|
||||
}
|
||||
|
||||
@ -808,12 +845,12 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil })
|
||||
if let previousThemeIndex = previousThemeIndex {
|
||||
let theme = themes[themes.index(before: previousThemeIndex.base)]
|
||||
selectThemeImpl?(.cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: nil, creatorAccountId: theme.isCreator ? context.account.id : nil)))
|
||||
selectThemeImpl?(nil, .cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: nil, creatorAccountId: theme.isCreator ? context.account.id : nil)))
|
||||
} else {
|
||||
if settings.baseTheme == .night {
|
||||
selectAccentColorImpl?(PresentationThemeAccentColor(baseColor: .blue))
|
||||
selectAccentColorImpl?(nil, PresentationThemeAccentColor(baseColor: .blue))
|
||||
} else {
|
||||
selectAccentColorImpl?(nil)
|
||||
selectAccentColorImpl?(nil, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -863,10 +900,10 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
themeReference = settings.theme
|
||||
// }
|
||||
|
||||
let rightNavigationButton = ItemListNavigationButton(content: .node(switchNode), style: .regular, enabled: true, action: {
|
||||
// nightModePreviewPromise.set(!nightModePreview)
|
||||
// switchNode?.play(isDark: presentationData.theme.overallDarkAppearance, theme: presentationData.theme)
|
||||
// presentCrossfadeControllerImpl?(false)
|
||||
let rightNavigationButton = ItemListNavigationButton(content: .node(switchNode), style: .regular, enabled: true, action: { [weak switchNode] in
|
||||
nightModePreviewPromise.set(!nightModePreview)
|
||||
switchNode?.play(isDark: presentationData.theme.overallDarkAppearance, theme: presentationData.theme)
|
||||
presentCrossfadeControllerImpl?(false)
|
||||
})
|
||||
|
||||
var defaultThemes: [PresentationThemeReference] = []
|
||||
@ -985,7 +1022,7 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
context.sharedContext.presentGlobalController(crossfadeController, nil)
|
||||
}
|
||||
}
|
||||
selectThemeImpl = { theme in
|
||||
selectThemeImpl = { baseTheme, theme in
|
||||
guard let presentationTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: theme) else {
|
||||
return
|
||||
}
|
||||
@ -1029,9 +1066,14 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
|
||||
var baseThemeIndex: Int64?
|
||||
var updatedThemeBaseIndex: Int64?
|
||||
var updatedBaseTheme: TelegramBaseTheme?
|
||||
if case let .cloud(info) = theme {
|
||||
updatedTheme = .cloud(PresentationCloudTheme(theme: info.theme, resolvedWallpaper: resolvedWallpaper, creatorAccountId: info.theme.isCreator ? context.account.id : nil))
|
||||
if let settings = info.theme.settings?.first {
|
||||
if let baseTheme = baseTheme, let settings = info.theme.settings?.first(where: { $0.baseTheme == baseTheme }) {
|
||||
updatedBaseTheme = baseTheme
|
||||
baseThemeIndex = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)).index
|
||||
updatedThemeBaseIndex = baseThemeIndex
|
||||
} else if let settings = info.theme.settings?.first {
|
||||
baseThemeIndex = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)).index
|
||||
updatedThemeBaseIndex = baseThemeIndex
|
||||
}
|
||||
@ -1040,6 +1082,10 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
}
|
||||
|
||||
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
var updatedThemePreferredBaseTheme = current.themePreferredBaseTheme
|
||||
if let updatedBaseTheme = updatedBaseTheme {
|
||||
updatedThemePreferredBaseTheme[updatedTheme.index] = updatedBaseTheme
|
||||
}
|
||||
var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting
|
||||
if case let .cloud(info) = updatedTheme, info.theme.settings?.contains(where: { $0.baseTheme == .night || $0.baseTheme == .tinted }) ?? false {
|
||||
updatedAutomaticThemeSwitchSetting.theme = updatedTheme
|
||||
@ -1050,7 +1096,7 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
updatedAutomaticThemeSwitchSetting.theme = updatedTheme
|
||||
}
|
||||
}
|
||||
return current.withUpdatedTheme(updatedTheme).withUpdatedAutomaticThemeSwitchSetting(updatedAutomaticThemeSwitchSetting)
|
||||
return current.withUpdatedTheme(updatedTheme).withUpdatedThemePreferredBaseTheme(updatedThemePreferredBaseTheme).withUpdatedAutomaticThemeSwitchSetting(updatedAutomaticThemeSwitchSetting)
|
||||
// var updatedThemeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
// if let baseThemeIndex = baseThemeIndex {
|
||||
// updatedThemeSpecificAccentColors[baseThemeIndex] = PresentationThemeAccentColor(themeIndex: updatedTheme.index)
|
||||
@ -1078,73 +1124,93 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
let controller = ThemeAccentColorController(context: context, mode: .colors(themeReference: themeReference, create: create))
|
||||
pushControllerImpl?(controller)
|
||||
}
|
||||
selectAccentColorImpl = { accentColor in
|
||||
var wallpaperSignal: Signal<TelegramWallpaper?, NoError> = .single(nil)
|
||||
if let colorWallpaper = accentColor?.wallpaper, case let .file(file) = colorWallpaper {
|
||||
wallpaperSignal = cachedWallpaper(account: context.account, slug: file.slug, settings: colorWallpaper.settings)
|
||||
|> mapToSignal { cachedWallpaper in
|
||||
if let wallpaper = cachedWallpaper?.wallpaper, case let .file(file) = wallpaper {
|
||||
let _ = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)).start()
|
||||
|
||||
return .single(wallpaper)
|
||||
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
selectAccentColorImpl = { currentBaseTheme, accentColor in
|
||||
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
return current
|
||||
// var currentTheme = current.theme
|
||||
// let currentPreferredBaseTheme = currentBaseTheme
|
||||
// if case let .cloud(theme) = currentTheme, let _ = theme.theme.settings, currentBaseTheme != nil {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// return PresentationThemeSettings(theme: updatedTheme, themePreferredBaseTheme: themePreferredBaseTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
}).start()
|
||||
|
||||
let _ = (wallpaperSignal
|
||||
|> deliverOnMainQueue).start(next: { presetWallpaper in
|
||||
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
|
||||
var currentTheme = current.theme
|
||||
if autoNightModeTriggered {
|
||||
currentTheme = current.automaticThemeSwitchSetting.theme
|
||||
}
|
||||
|
||||
let generalThemeReference: PresentationThemeReference
|
||||
if case let .cloud(theme) = currentTheme, let settings = theme.theme.settings?.first {
|
||||
generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme))
|
||||
} else {
|
||||
generalThemeReference = currentTheme
|
||||
}
|
||||
|
||||
currentTheme = generalThemeReference
|
||||
var updatedTheme = current.theme
|
||||
var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting
|
||||
|
||||
if autoNightModeTriggered {
|
||||
updatedAutomaticThemeSwitchSetting.theme = generalThemeReference
|
||||
} else {
|
||||
updatedTheme = generalThemeReference
|
||||
}
|
||||
|
||||
guard let _ = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.color, wallpaper: presetWallpaper, baseColor: accentColor?.baseColor) else {
|
||||
return current
|
||||
}
|
||||
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
var themeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
themeSpecificAccentColors[generalThemeReference.index] = accentColor?.withUpdatedWallpaper(presetWallpaper)
|
||||
|
||||
if case .builtin = generalThemeReference {
|
||||
let index = coloredThemeIndex(reference: currentTheme, accentColor: accentColor)
|
||||
if let wallpaper = current.themeSpecificChatWallpapers[index] {
|
||||
if wallpaper.isColorOrGradient || wallpaper.isPattern || wallpaper.isBuiltin {
|
||||
themeSpecificChatWallpapers[index] = presetWallpaper
|
||||
}
|
||||
} else {
|
||||
themeSpecificChatWallpapers[index] = presetWallpaper
|
||||
}
|
||||
}
|
||||
|
||||
return PresentationThemeSettings(theme: updatedTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
}).start()
|
||||
|
||||
presentCrossfadeControllerImpl?(true)
|
||||
})
|
||||
presentCrossfadeControllerImpl?(true)
|
||||
}
|
||||
|
||||
|
||||
// var wallpaperSignal: Signal<TelegramWallpaper?, NoError> = .single(nil)
|
||||
// if let colorWallpaper = accentColor?.wallpaper, case let .file(file) = colorWallpaper {
|
||||
// wallpaperSignal = cachedWallpaper(account: context.account, slug: file.slug, settings: colorWallpaper.settings)
|
||||
// |> mapToSignal { cachedWallpaper in
|
||||
// if let wallpaper = cachedWallpaper?.wallpaper, case let .file(file) = wallpaper {
|
||||
// let _ = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)).start()
|
||||
//
|
||||
// return .single(wallpaper)
|
||||
//
|
||||
// } else {
|
||||
// return .single(nil)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// let _ = (wallpaperSignal
|
||||
// |> deliverOnMainQueue).start(next: { presetWallpaper in
|
||||
// let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
// let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
|
||||
// var currentTheme = current.theme
|
||||
// let currentPreferredBaseTheme = currentBaseTheme
|
||||
//
|
||||
// if autoNightModeTriggered {
|
||||
// currentTheme = current.automaticThemeSwitchSetting.theme
|
||||
// }
|
||||
//
|
||||
// let generalThemeReference: PresentationThemeReference
|
||||
// if case let .cloud(theme) = currentTheme, let settings = theme.theme.settings, currentBaseTheme != nil && {
|
||||
// generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme))
|
||||
// } else {
|
||||
// generalThemeReference = currentTheme
|
||||
// }
|
||||
//
|
||||
// currentTheme = generalThemeReference
|
||||
// var updatedTheme = current.theme
|
||||
// var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting
|
||||
//
|
||||
// if autoNightModeTriggered {
|
||||
// updatedAutomaticThemeSwitchSetting.theme = generalThemeReference
|
||||
// } else {
|
||||
// updatedTheme = generalThemeReference
|
||||
// }
|
||||
//
|
||||
// guard let _ = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.color, wallpaper: presetWallpaper, baseColor: accentColor?.baseColor) else {
|
||||
// return current
|
||||
// }
|
||||
//
|
||||
// var themePreferredBaseTheme = current.themePreferredBaseTheme
|
||||
// if up
|
||||
//
|
||||
// var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
// var themeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
// themeSpecificAccentColors[generalThemeReference.index] = accentColor?.withUpdatedWallpaper(presetWallpaper)
|
||||
//
|
||||
// if case .builtin = generalThemeReference {
|
||||
// let index = coloredThemeIndex(reference: currentTheme, accentColor: accentColor)
|
||||
// if let wallpaper = current.themeSpecificChatWallpapers[index] {
|
||||
// if wallpaper.isColorOrGradient || wallpaper.isPattern || wallpaper.isBuiltin {
|
||||
// themeSpecificChatWallpapers[index] = presetWallpaper
|
||||
// }
|
||||
// } else {
|
||||
// themeSpecificChatWallpapers[index] = presetWallpaper
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return PresentationThemeSettings(theme: updatedTheme, themePreferredBaseTheme: themePreferredBaseTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
// }).start()
|
||||
//
|
||||
// presentCrossfadeControllerImpl?(true)
|
||||
// })
|
||||
// }
|
||||
return controller
|
||||
}
|
||||
|
||||
|
@ -288,11 +288,11 @@ private func editThemeControllerEntries(presentationData: PresentationData, stat
|
||||
entries.append(.changeColors(presentationData.theme, presentationData.strings.EditTheme_ChangeColors))
|
||||
if hasSettings {
|
||||
if previewTheme.overallDarkAppearance {
|
||||
entries.append(.toggleDark(presentationData.theme, "Toggle Base Theme"))
|
||||
// entries.append(.toggleDark(presentationData.theme, "Toggle Base Theme"))
|
||||
}
|
||||
} else {
|
||||
if !isCreate {
|
||||
entries.append(.convertToPresetTheme(presentationData.theme, "Convert to Preset Theme"))
|
||||
// entries.append(.convertToPresetTheme(presentationData.theme, "Convert to Preset Theme"))
|
||||
}
|
||||
entries.append(.uploadTheme(presentationData.theme, uploadText))
|
||||
entries.append(.uploadInfo(presentationData.theme, uploadInfo))
|
||||
@ -643,7 +643,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
||||
|
||||
return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
return PresentationThemeSettings(theme: themeReference, themePreferredBaseTheme: current.themePreferredBaseTheme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
}) |> deliverOnMainQueue).start(completed: {
|
||||
if !hasCustomFile {
|
||||
saveThemeTemplateFile(state.title, themeResource, {
|
||||
@ -677,7 +677,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
||||
|
||||
return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
return PresentationThemeSettings(theme: themeReference, themePreferredBaseTheme: current.themePreferredBaseTheme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
}) |> deliverOnMainQueue).start(completed: {
|
||||
if let themeResource = themeResource, !hasCustomFile {
|
||||
saveThemeTemplateFile(state.title, themeResource, {
|
||||
|
@ -249,13 +249,14 @@ final class ThemeAccentColorController: ViewController {
|
||||
updatedTheme = themeReference
|
||||
}
|
||||
|
||||
let themePreferredBaseTheme = current.themePreferredBaseTheme
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
||||
|
||||
var themeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
themeSpecificAccentColors[baseThemeReference.index] = PresentationThemeAccentColor(themeIndex: themeReference.index)
|
||||
|
||||
return PresentationThemeSettings(theme: updatedTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
return PresentationThemeSettings(theme: updatedTheme, themePreferredBaseTheme: themePreferredBaseTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
})
|
||||
|> castError(CreateThemeError.self)
|
||||
} else {
|
||||
@ -278,13 +279,14 @@ final class ThemeAccentColorController: ViewController {
|
||||
updatedTheme = themeReference
|
||||
}
|
||||
|
||||
let themePreferredBaseTheme = current.themePreferredBaseTheme
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
||||
|
||||
var themeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
themeSpecificAccentColors[baseThemeReference.index] = PresentationThemeAccentColor(themeIndex: themeReference.index)
|
||||
|
||||
return PresentationThemeSettings(theme: updatedTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
return PresentationThemeSettings(theme: updatedTheme, themePreferredBaseTheme: themePreferredBaseTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
})
|
||||
|> castError(CreateThemeError.self)
|
||||
} else {
|
||||
|
@ -245,7 +245,7 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry {
|
||||
case let .themeHeader(_, title):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section)
|
||||
case let .themeItem(theme, strings, themes, allThemes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers):
|
||||
return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, allThemes: allThemes, displayUnsupported: false, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in
|
||||
return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, allThemes: allThemes, displayUnsupported: false, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, themePreferredBaseTheme: [:], currentTheme: currentTheme, updatedTheme: { theme in
|
||||
arguments.updateTheme(theme)
|
||||
}, contextAction: nil)
|
||||
}
|
||||
|
@ -1230,6 +1230,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
return current
|
||||
}
|
||||
|
||||
let themePreferredBaseTheme = current.themePreferredBaseTheme
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
var themeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
themeSpecificAccentColors[generalThemeReference.index] = accentColor?.withUpdatedWallpaper(presetWallpaper)
|
||||
@ -1245,7 +1246,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
}
|
||||
}
|
||||
|
||||
return PresentationThemeSettings(theme: updatedTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
return PresentationThemeSettings(theme: updatedTheme, themePreferredBaseTheme: themePreferredBaseTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
}).start()
|
||||
|
||||
presentCrossfadeControllerImpl?(true)
|
||||
|
@ -358,12 +358,13 @@ class ThemeSettingsThemeItem: ListViewItem, ItemListItem {
|
||||
let displayUnsupported: Bool
|
||||
let themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
||||
let themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
|
||||
let themePreferredBaseTheme: [Int64: TelegramBaseTheme]
|
||||
let currentTheme: PresentationThemeReference
|
||||
let updatedTheme: (PresentationThemeReference) -> Void
|
||||
let contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?
|
||||
let tag: ItemListItemTag?
|
||||
|
||||
init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, themes: [PresentationThemeReference], allThemes: [PresentationThemeReference], displayUnsupported: Bool, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], currentTheme: PresentationThemeReference, updatedTheme: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, tag: ItemListItemTag? = nil) {
|
||||
init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, themes: [PresentationThemeReference], allThemes: [PresentationThemeReference], displayUnsupported: Bool, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], themePreferredBaseTheme: [Int64: TelegramBaseTheme], currentTheme: PresentationThemeReference, updatedTheme: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, tag: ItemListItemTag? = nil) {
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
@ -372,6 +373,7 @@ class ThemeSettingsThemeItem: ListViewItem, ItemListItem {
|
||||
self.displayUnsupported = displayUnsupported
|
||||
self.themeSpecificAccentColors = themeSpecificAccentColors
|
||||
self.themeSpecificChatWallpapers = themeSpecificChatWallpapers
|
||||
self.themePreferredBaseTheme = themePreferredBaseTheme
|
||||
self.currentTheme = currentTheme
|
||||
self.updatedTheme = updatedTheme
|
||||
self.contextAction = contextAction
|
||||
@ -636,7 +638,12 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
let wallpaper = accentColor?.wallpaper ?? customWallpaper ?? themeWallpaper
|
||||
|
||||
let selected = item.currentTheme.index == theme.index || item.currentTheme.generalThemeReference == theme
|
||||
var baseThemeReference = item.currentTheme.generalThemeReference
|
||||
if let baseTheme = item.themePreferredBaseTheme[item.currentTheme.index] {
|
||||
baseThemeReference = PresentationThemeReference.builtin(.init(baseTheme: baseTheme))
|
||||
}
|
||||
|
||||
let selected = item.currentTheme.index == theme.index || baseThemeReference == theme
|
||||
entries.append(ThemeSettingsThemeEntry(index: index, themeReference: theme, title: title, accentColor: accentColor, selected: selected, theme: item.theme, wallpaper: wallpaper))
|
||||
index += 1
|
||||
}
|
||||
|
@ -155,7 +155,10 @@ public final class SolidRoundedButtonNode: ASDisplayNode {
|
||||
|
||||
self.isUserInteractionEnabled = false
|
||||
|
||||
let progressFrame = CGRect(origin: CGPoint(x: (self.frame.width - self.buttonHeight) / 2.0, y: 0.0), size: CGSize(width: self.buttonHeight, height: self.buttonHeight))
|
||||
let buttonOffset = self.buttonBackgroundNode.frame.minX
|
||||
let buttonWidth = self.buttonBackgroundNode.frame.width
|
||||
|
||||
let progressFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(buttonOffset + (buttonWidth - self.buttonHeight) / 2.0), y: 0.0), size: CGSize(width: self.buttonHeight, height: self.buttonHeight))
|
||||
let progressNode = ASImageNode()
|
||||
progressNode.displaysAsynchronously = false
|
||||
progressNode.frame = progressFrame
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
|
||||
public enum TelegramBaseTheme: Int32 {
|
||||
public enum TelegramBaseTheme: Int32, Codable {
|
||||
case classic
|
||||
case day
|
||||
case night
|
||||
|
@ -9,6 +9,10 @@ public extension TelegramEngine {
|
||||
self.account = account
|
||||
}
|
||||
|
||||
// public func getThemes(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<[TelegramTheme], NoError> {
|
||||
// return _internal_getThemes(accountManager: accountManager, postbox: self.account.postbox, network: self.account.network)
|
||||
// }
|
||||
|
||||
public func getChatThemes(accountManager: AccountManager<TelegramAccountManagerTypes>, forceUpdate: Bool = false, onlyCached: Bool = false) -> Signal<[TelegramTheme], NoError> {
|
||||
return _internal_getChatThemes(accountManager: accountManager, network: self.account.network, forceUpdate: forceUpdate, onlyCached: onlyCached)
|
||||
}
|
||||
|
@ -623,9 +623,16 @@ public func updatedPresentationData(accountManager: AccountManager<TelegramAccou
|
||||
switchedToNightModeWallpaper = true
|
||||
}
|
||||
effectiveTheme = automaticTheme
|
||||
preferredBaseTheme = .night
|
||||
if let baseTheme = themeSettings.themePreferredBaseTheme[effectiveTheme.index], [.night, .tinted].contains(baseTheme) {
|
||||
preferredBaseTheme = baseTheme
|
||||
} else {
|
||||
preferredBaseTheme = .night
|
||||
}
|
||||
} else {
|
||||
effectiveTheme = themeSettings.theme
|
||||
if let baseTheme = themeSettings.themePreferredBaseTheme[effectiveTheme.index], [.classic, .day].contains(baseTheme) {
|
||||
preferredBaseTheme = baseTheme
|
||||
}
|
||||
}
|
||||
|
||||
if let colors = effectiveColors, colors.baseColor == .theme {
|
||||
|
@ -55,6 +55,7 @@ public enum PresentationResourceKey: Int32 {
|
||||
case itemListCloseIconImage
|
||||
case itemListMakeVisibleIcon
|
||||
case itemListMakeInvisibleIcon
|
||||
case itemListEditThemeIcon
|
||||
case itemListCornersTop
|
||||
case itemListCornersBottom
|
||||
case itemListCornersBoth
|
||||
|
@ -181,6 +181,12 @@ public struct PresentationResourcesItemList {
|
||||
})
|
||||
}
|
||||
|
||||
public static func makeEditThemeIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.itemListEditThemeIcon.rawValue, { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Settings/EditTheme"), color: theme.list.itemAccentColor)
|
||||
})
|
||||
}
|
||||
|
||||
public static func cornersImage(_ theme: PresentationTheme, top: Bool, bottom: Bool) -> UIImage? {
|
||||
if !top && !bottom {
|
||||
return nil
|
||||
|
12
submodules/TelegramUI/Images.xcassets/Settings/EditTheme.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/EditTheme.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "colors_30.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
212
submodules/TelegramUI/Images.xcassets/Settings/EditTheme.imageset/colors_30.pdf
vendored
Normal file
212
submodules/TelegramUI/Images.xcassets/Settings/EditTheme.imageset/colors_30.pdf
vendored
Normal file
@ -0,0 +1,212 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 5.107361 3.162231 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.136919 4.618919 m
|
||||
-0.347895 4.163717 l
|
||||
-0.344284 4.159932 l
|
||||
0.136919 4.618919 l
|
||||
h
|
||||
0.099977 5.143885 m
|
||||
-0.349349 5.634120 l
|
||||
-0.360017 5.624343 l
|
||||
-0.370249 5.614110 l
|
||||
0.099977 5.143885 l
|
||||
h
|
||||
1.511918 5.861061 m
|
||||
1.044556 6.334151 l
|
||||
1.041692 6.331286 l
|
||||
1.511918 5.861061 l
|
||||
h
|
||||
3.736765 10.227889 m
|
||||
4.133279 9.693956 l
|
||||
4.140501 9.699474 l
|
||||
3.736765 10.227889 l
|
||||
h
|
||||
8.166384 8.960043 m
|
||||
8.685057 9.376224 l
|
||||
8.683912 9.377643 l
|
||||
8.166384 8.960043 l
|
||||
h
|
||||
7.604795 3.599786 m
|
||||
7.210793 4.135567 l
|
||||
7.203959 4.130404 l
|
||||
7.604795 3.599786 l
|
||||
h
|
||||
0.621717 5.074106 m
|
||||
0.611081 5.085433 0.666412 5.028751 0.664974 4.909222 c
|
||||
0.663605 4.795333 0.611284 4.714740 0.570203 4.673659 c
|
||||
-0.370249 5.614110 l
|
||||
-0.527953 5.456407 -0.661392 5.219398 -0.664930 4.925216 c
|
||||
-0.668535 4.625394 -0.536423 4.364540 -0.347880 4.163732 c
|
||||
0.621717 5.074106 l
|
||||
h
|
||||
0.549303 4.653649 m
|
||||
0.473747 4.584398 0.413424 4.579663 0.524168 4.615534 c
|
||||
0.558581 4.626680 0.765894 4.687963 0.879854 4.726777 c
|
||||
1.190154 4.832462 1.603420 5.012111 1.982144 5.390835 c
|
||||
1.041692 6.331286 l
|
||||
0.863218 6.152813 0.661790 6.057532 0.451056 5.985758 c
|
||||
0.304500 5.935842 0.274712 5.932763 0.114334 5.880815 c
|
||||
0.030287 5.853591 -0.182517 5.787030 -0.349349 5.634120 c
|
||||
0.549303 4.653649 l
|
||||
h
|
||||
1.979271 5.387979 m
|
||||
2.762335 6.161561 2.983588 7.179695 3.183573 7.926414 c
|
||||
3.398847 8.730222 3.596982 9.295764 4.133242 9.694006 c
|
||||
3.340288 10.761772 l
|
||||
2.396795 10.061108 2.111542 9.064655 1.898849 8.270485 c
|
||||
1.670867 7.419226 1.519574 6.803399 1.044565 6.334142 c
|
||||
1.979271 5.387979 l
|
||||
h
|
||||
4.140501 9.699474 m
|
||||
4.938049 10.308843 6.388459 10.104443 7.648856 8.542443 c
|
||||
8.683912 9.377643 l
|
||||
7.236722 11.171134 4.988924 12.021493 3.333029 10.756304 c
|
||||
4.140501 9.699474 l
|
||||
h
|
||||
7.647713 8.543863 m
|
||||
8.319628 7.706477 8.550738 6.867272 8.466406 6.134995 c
|
||||
8.382251 5.404262 7.974833 4.697357 7.210826 4.135523 c
|
||||
7.998764 3.064050 l
|
||||
9.019373 3.814583 9.655708 4.836955 9.787673 5.982832 c
|
||||
9.919460 7.127166 9.539057 8.311907 8.685055 9.376223 c
|
||||
7.647713 8.543863 l
|
||||
h
|
||||
7.203959 4.130404 m
|
||||
5.516191 2.855444 2.559140 3.042942 0.618121 5.077906 c
|
||||
-0.344284 4.159932 l
|
||||
1.998385 1.703878 5.707231 1.332929 8.005630 3.069168 c
|
||||
7.203959 4.130404 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 10.981171 8.944946 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
13.737684 13.620637 m
|
||||
13.159714 13.949536 l
|
||||
13.159714 13.949536 l
|
||||
13.737684 13.620637 l
|
||||
h
|
||||
6.273577 2.774412 m
|
||||
5.766509 3.204652 l
|
||||
5.766508 3.204652 l
|
||||
6.273577 2.774412 l
|
||||
h
|
||||
12.043029 15.315296 m
|
||||
11.714130 15.893268 l
|
||||
11.714130 15.893268 l
|
||||
12.043029 15.315296 l
|
||||
h
|
||||
1.196800 7.851189 m
|
||||
1.627041 7.344121 l
|
||||
1.627041 7.344121 l
|
||||
1.196800 7.851189 l
|
||||
h
|
||||
13.159714 13.949536 m
|
||||
11.531315 11.087968 8.957198 6.965113 5.766509 3.204652 c
|
||||
6.780646 2.344172 l
|
||||
10.045283 6.191786 12.665783 10.392434 14.315655 13.291738 c
|
||||
13.159714 13.949536 l
|
||||
h
|
||||
11.714130 15.893268 m
|
||||
8.814823 14.243399 4.614170 11.622902 0.766559 8.358257 c
|
||||
1.627041 7.344121 l
|
||||
5.387496 10.534817 9.510356 13.108930 12.371927 14.737325 c
|
||||
11.714130 15.893268 l
|
||||
h
|
||||
14.315655 13.291738 m
|
||||
14.798453 14.140153 14.637612 15.061581 14.060793 15.638401 c
|
||||
13.483974 16.215221 12.562547 16.376064 11.714130 15.893268 c
|
||||
12.371927 14.737325 l
|
||||
12.713542 14.931723 12.978041 14.840251 13.120340 14.697950 c
|
||||
13.262640 14.555650 13.354112 14.291151 13.159714 13.949536 c
|
||||
14.315655 13.291738 l
|
||||
h
|
||||
5.766508 3.204652 m
|
||||
5.189209 2.524261 4.373246 2.208553 3.548578 2.245499 c
|
||||
3.489053 0.916832 l
|
||||
4.697387 0.862698 5.919904 1.329725 6.780646 2.344172 c
|
||||
5.766508 3.204652 l
|
||||
h
|
||||
0.766559 8.358257 m
|
||||
-0.261784 7.485722 -0.727416 6.241713 -0.658290 5.017560 c
|
||||
0.669595 5.092544 l
|
||||
0.622377 5.928712 0.937552 6.759100 1.627041 7.344121 c
|
||||
0.766559 8.358257 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
0.707107 -0.707107 0.707107 0.707107 8.940246 12.901031 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
6.514392 6.283155 m
|
||||
4.446240 7.179288 1.798525 7.192235 -0.262776 6.305544 c
|
||||
0.262776 5.083785 l
|
||||
1.983177 5.823833 4.249412 5.815088 5.985608 5.062792 c
|
||||
6.514392 6.283155 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
4016
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Type /Catalog
|
||||
/Pages 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000004106 00000 n
|
||||
0000004129 00000 n
|
||||
0000004302 00000 n
|
||||
0000004376 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
4435
|
||||
%%EOF
|
@ -138,7 +138,7 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager {
|
||||
theme = updatedTheme
|
||||
}
|
||||
|
||||
return PreferencesEntry(PresentationThemeSettings(theme: theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion))
|
||||
return PreferencesEntry(PresentationThemeSettings(theme: theme, themePreferredBaseTheme: current.themePreferredBaseTheme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion))
|
||||
})
|
||||
}).start()
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager {
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
themeSpecificChatWallpapers[themeReference.index] = updatedWallpaper
|
||||
themeSpecificChatWallpapers[coloredThemeIndex(reference: themeReference, accentColor: current.themeSpecificAccentColors[themeReference.index])] = updatedWallpaper
|
||||
return PresentationThemeSettings(theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
return PresentationThemeSettings(theme: current.theme, themePreferredBaseTheme: current.themePreferredBaseTheme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)
|
||||
})).start()
|
||||
}
|
||||
|
||||
|
@ -591,6 +591,7 @@ public struct PresentationThemeSettings: Codable {
|
||||
}
|
||||
|
||||
public var theme: PresentationThemeReference
|
||||
public var themePreferredBaseTheme: [Int64: TelegramBaseTheme]
|
||||
public var themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
||||
public var themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
|
||||
public var useSystemFont: Bool
|
||||
@ -637,11 +638,12 @@ public struct PresentationThemeSettings: Codable {
|
||||
}
|
||||
|
||||
public static var defaultSettings: PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: .builtin(.dayClassic), themeSpecificAccentColors: [:], themeSpecificChatWallpapers: [:], useSystemFont: true, fontSize: .regular, listsFontSize: .regular, chatBubbleSettings: .default, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting(force: false, trigger: .system, theme: .builtin(.night)), largeEmoji: true, reduceMotion: false)
|
||||
return PresentationThemeSettings(theme: .builtin(.dayClassic), themePreferredBaseTheme: [:], themeSpecificAccentColors: [:], themeSpecificChatWallpapers: [:], useSystemFont: true, fontSize: .regular, listsFontSize: .regular, chatBubbleSettings: .default, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting(force: false, trigger: .system, theme: .builtin(.night)), largeEmoji: true, reduceMotion: false)
|
||||
}
|
||||
|
||||
public init(theme: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], useSystemFont: Bool, fontSize: PresentationFontSize, listsFontSize: PresentationFontSize, chatBubbleSettings: PresentationChatBubbleSettings, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting, largeEmoji: Bool, reduceMotion: Bool) {
|
||||
public init(theme: PresentationThemeReference, themePreferredBaseTheme: [Int64: TelegramBaseTheme], themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], useSystemFont: Bool, fontSize: PresentationFontSize, listsFontSize: PresentationFontSize, chatBubbleSettings: PresentationChatBubbleSettings, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting, largeEmoji: Bool, reduceMotion: Bool) {
|
||||
self.theme = theme
|
||||
self.themePreferredBaseTheme = themePreferredBaseTheme
|
||||
self.themeSpecificAccentColors = themeSpecificAccentColors
|
||||
self.themeSpecificChatWallpapers = themeSpecificChatWallpapers
|
||||
self.useSystemFont = useSystemFont
|
||||
@ -661,6 +663,15 @@ public struct PresentationThemeSettings: Codable {
|
||||
} else {
|
||||
self.theme = .builtin(.dayClassic)
|
||||
}
|
||||
|
||||
var mappedThemePreferredBaseTheme: [Int64: TelegramBaseTheme] = [:]
|
||||
let themePreferredBaseThemeDict = try container.decode([Int64: Int64].self, forKey: "themePreferredBaseTheme")
|
||||
for (key, value) in themePreferredBaseThemeDict {
|
||||
if let baseTheme = TelegramBaseTheme(rawValue: Int32(clamping: value)) {
|
||||
mappedThemePreferredBaseTheme[key] = baseTheme
|
||||
}
|
||||
}
|
||||
self.themePreferredBaseTheme = mappedThemePreferredBaseTheme
|
||||
|
||||
let themeSpecificChatWallpapersDict = try container.decode([DictionaryKey: TelegramWallpaperNativeCodable].self, forKey: "themeSpecificChatWallpapers")
|
||||
var mappedThemeSpecificChatWallpapers: [Int64: TelegramWallpaper] = [:]
|
||||
@ -695,6 +706,12 @@ public struct PresentationThemeSettings: Codable {
|
||||
|
||||
try container.encode(PostboxEncoder().encodeObjectToRawData(self.theme), forKey: "t")
|
||||
|
||||
var mappedThemePreferredBaseTheme: [Int64: Int64] = [:]
|
||||
for (key, value) in self.themePreferredBaseTheme {
|
||||
mappedThemePreferredBaseTheme[key] = Int64(value.rawValue)
|
||||
}
|
||||
try container.encode(mappedThemePreferredBaseTheme, forKey: "themePreferredBaseTheme")
|
||||
|
||||
var mappedThemeSpecificAccentColors: [DictionaryKey: AdaptedPostboxEncoder.RawObjectData] = [:]
|
||||
for (key, value) in self.themeSpecificAccentColors {
|
||||
mappedThemeSpecificAccentColors[DictionaryKey(key)] = PostboxEncoder().encodeObjectToRawData(value)
|
||||
@ -717,43 +734,47 @@ public struct PresentationThemeSettings: Codable {
|
||||
}
|
||||
|
||||
public static func ==(lhs: PresentationThemeSettings, rhs: PresentationThemeSettings) -> Bool {
|
||||
return lhs.theme == rhs.theme && lhs.themeSpecificAccentColors == rhs.themeSpecificAccentColors && lhs.themeSpecificChatWallpapers == rhs.themeSpecificChatWallpapers && lhs.useSystemFont == rhs.useSystemFont && lhs.fontSize == rhs.fontSize && lhs.listsFontSize == rhs.listsFontSize && lhs.chatBubbleSettings == rhs.chatBubbleSettings && lhs.automaticThemeSwitchSetting == rhs.automaticThemeSwitchSetting && lhs.largeEmoji == rhs.largeEmoji && lhs.reduceMotion == rhs.reduceMotion
|
||||
return lhs.theme == rhs.theme && lhs.themePreferredBaseTheme == rhs.themePreferredBaseTheme && lhs.themeSpecificAccentColors == rhs.themeSpecificAccentColors && lhs.themeSpecificChatWallpapers == rhs.themeSpecificChatWallpapers && lhs.useSystemFont == rhs.useSystemFont && lhs.fontSize == rhs.fontSize && lhs.listsFontSize == rhs.listsFontSize && lhs.chatBubbleSettings == rhs.chatBubbleSettings && lhs.automaticThemeSwitchSetting == rhs.automaticThemeSwitchSetting && lhs.largeEmoji == rhs.largeEmoji && lhs.reduceMotion == rhs.reduceMotion
|
||||
}
|
||||
|
||||
public func withUpdatedTheme(_ theme: PresentationThemeReference) -> PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
return PresentationThemeSettings(theme: theme, themePreferredBaseTheme: self.themePreferredBaseTheme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
}
|
||||
|
||||
public func withUpdatedThemePreferredBaseTheme(_ themePreferredBaseTheme: [Int64: TelegramBaseTheme]) -> PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: self.theme, themePreferredBaseTheme: themePreferredBaseTheme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
}
|
||||
|
||||
public func withUpdatedThemeSpecificAccentColors(_ themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]) -> PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
return PresentationThemeSettings(theme: self.theme, themePreferredBaseTheme: self.themePreferredBaseTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
}
|
||||
|
||||
public func withUpdatedThemeSpecificChatWallpapers(_ themeSpecificChatWallpapers: [Int64: TelegramWallpaper]) -> PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
return PresentationThemeSettings(theme: self.theme, themePreferredBaseTheme: self.themePreferredBaseTheme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
}
|
||||
|
||||
public func withUpdatedUseSystemFont(_ useSystemFont: Bool) -> PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
return PresentationThemeSettings(theme: self.theme, themePreferredBaseTheme: self.themePreferredBaseTheme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
}
|
||||
|
||||
public func withUpdatedFontSizes(fontSize: PresentationFontSize, listsFontSize: PresentationFontSize) -> PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: fontSize, listsFontSize: listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
return PresentationThemeSettings(theme: self.theme, themePreferredBaseTheme: self.themePreferredBaseTheme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: fontSize, listsFontSize: listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
}
|
||||
|
||||
public func withUpdatedChatBubbleSettings(_ chatBubbleSettings: PresentationChatBubbleSettings) -> PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
return PresentationThemeSettings(theme: self.theme, themePreferredBaseTheme: self.themePreferredBaseTheme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
}
|
||||
|
||||
public func withUpdatedAutomaticThemeSwitchSetting(_ automaticThemeSwitchSetting: AutomaticThemeSwitchSetting) -> PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
return PresentationThemeSettings(theme: self.theme, themePreferredBaseTheme: self.themePreferredBaseTheme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: self.reduceMotion)
|
||||
}
|
||||
|
||||
public func withUpdatedLargeEmoji(_ largeEmoji: Bool) -> PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: largeEmoji, reduceMotion: self.reduceMotion)
|
||||
return PresentationThemeSettings(theme: self.theme, themePreferredBaseTheme: self.themePreferredBaseTheme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: largeEmoji, reduceMotion: self.reduceMotion)
|
||||
}
|
||||
|
||||
public func withUpdatedReduceMotion(_ reduceMotion: Bool) -> PresentationThemeSettings {
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: reduceMotion)
|
||||
return PresentationThemeSettings(theme: self.theme, themePreferredBaseTheme: self.themePreferredBaseTheme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, listsFontSize: self.listsFontSize, chatBubbleSettings: self.chatBubbleSettings, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, reduceMotion: reduceMotion)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1308,7 +1308,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager<Tele
|
||||
}
|
||||
|
||||
let themeSignal: Signal<PresentationTheme?, NoError>
|
||||
if case let .cloud(theme) = theme, let nightMode = nightMode {
|
||||
if case let .cloud(theme) = theme, theme.theme.settings != nil, let nightMode = nightMode {
|
||||
themeSignal = .single(makePresentationTheme(cloudTheme: theme.theme, dark: nightMode))
|
||||
} else if case let .builtin(theme) = theme {
|
||||
themeSignal = .single(makeDefaultPresentationTheme(reference: theme, serviceBackgroundColor: nil))
|
||||
@ -1485,12 +1485,12 @@ public func themeIconImage(account: Account, accountManager: AccountManager<Tele
|
||||
if large {
|
||||
c.saveGState()
|
||||
|
||||
c.translateBy(x: 5.0, y: 25.0)
|
||||
c.translateBy(x: 7.0, y: 27.0)
|
||||
c.translateBy(x: 114.0, y: 32.0)
|
||||
c.scaleBy(x: 1.0, y: -1.0)
|
||||
c.translateBy(x: -114.0, y: -32.0)
|
||||
|
||||
let _ = try? drawSvgPath(c, path: "M98.0061174,0 C106.734138,0 113.82927,6.99200411 113.996965,15.6850616 L114,16 C114,24.836556 106.830179,32 98.0061174,32 L21.9938826,32 C18.2292665,32 14.7684355,30.699197 12.0362474,28.5221601 C8.56516444,32.1765452 -1.77635684e-15,31.9985981 -1.77635684e-15,31.9985981 C5.69252399,28.6991366 5.98604874,24.4421608 5.99940747,24.1573436 L6,24.1422468 L6,16 C6,7.163444 13.1698213,0 21.9938826,0 L98.0061174,0 ")
|
||||
let _ = try? drawSvgPath(c, path: "M12.8304,29.8712 C10.0551,31.8416 6.6628,33 2.99998,33 C1.98426,33 0.989361,32.9109 0.022644,32.7402 C2.97318,31.9699 5.24596,29.5785 5.84625,26.5607 C5.99996,25.7879 5.99996,24.8586 5.99996,23 V16.0 H6.00743 C6.27176,7.11861 13.5546,0 22.5,0 H61.5 C70.6127,0 78,7.3873 78,16.5 C78,25.6127 70.6127,33 61.5,33 H22.5 C18.8883,33 15.5476,31.8396 12.8304,29.8712 ")
|
||||
if Set(incomingColors.map(\.rgb)).count > 1 {
|
||||
c.clip()
|
||||
|
||||
@ -1504,7 +1504,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager<Tele
|
||||
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as NSArray, locations: &locations)!
|
||||
c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: 32.0), options: CGGradientDrawingOptions())
|
||||
c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: 34.0), options: CGGradientDrawingOptions())
|
||||
} else {
|
||||
c.setFillColor(incomingColors[0].cgColor)
|
||||
c.fillPath()
|
||||
@ -1517,7 +1517,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager<Tele
|
||||
c.clip()
|
||||
|
||||
if incomingColors.count >= 2 {
|
||||
let gradientColors = incomingColors.map { $0.cgColor } as CFArray
|
||||
let gradientColors = incomingColors.reversed().map { $0.cgColor } as CFArray
|
||||
|
||||
var locations: [CGFloat] = []
|
||||
for i in 0 ..< incomingColors.count {
|
||||
@ -1551,12 +1551,12 @@ public func themeIconImage(account: Account, accountManager: AccountManager<Tele
|
||||
if large {
|
||||
c.saveGState()
|
||||
|
||||
c.translateBy(x: drawingRect.width - 114.0 - 5.0, y: 65.0)
|
||||
c.translateBy(x: -71.0, y: 66.0)
|
||||
c.translateBy(x: 114.0, y: 32.0)
|
||||
c.scaleBy(x: -1.0, y: -1.0)
|
||||
c.translateBy(x: 0, y: -32.0)
|
||||
c.scaleBy(x: 1.0, y: -1.0)
|
||||
c.translateBy(x: 0.0, y: -32.0)
|
||||
|
||||
let _ = try? drawSvgPath(c, path: "M98.0061174,0 C106.734138,0 113.82927,6.99200411 113.996965,15.6850616 L114,16 C114,24.836556 106.830179,32 98.0061174,32 L21.9938826,32 C18.2292665,32 14.7684355,30.699197 12.0362474,28.5221601 C8.56516444,32.1765452 -1.77635684e-15,31.9985981 -1.77635684e-15,31.9985981 C5.69252399,28.6991366 5.98604874,24.4421608 5.99940747,24.1573436 L6,24.1422468 L6,16 C6,7.163444 13.1698213,0 21.9938826,0 L98.0061174,0 ")
|
||||
let _ = try? drawSvgPath(c, path: "M57.1696,29.8712 C59.9449,31.8416 63.3372,33 67,33 C68.0157,33 69.0106,32.9109 69.9773,32.7402 C67.0268,31.9699 64.754,29.5786 64.1537,26.5607 C64,25.7879 64,24.8586 64,23 V16.5 V16 H63.9926 C63.7282,7.11861 56.4454,0 47.5,0 H16.5 C7.3873,0 0,7.3873 0,16.5 C0,25.6127 7.3873,33 16.5,33 H47.5 C51.1117,33 54.4524,31.8396 57.1696,29.8712 ")
|
||||
if Set(outgoingColors.map(\.rgb)).count > 1 {
|
||||
c.clip()
|
||||
|
||||
@ -1570,7 +1570,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager<Tele
|
||||
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as NSArray, locations: &locations)!
|
||||
c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: 32.0), options: CGGradientDrawingOptions())
|
||||
c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: 34.0), options: CGGradientDrawingOptions())
|
||||
} else {
|
||||
c.setFillColor(outgoingColors[0].cgColor)
|
||||
c.fillPath()
|
||||
@ -1583,7 +1583,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager<Tele
|
||||
c.clip()
|
||||
|
||||
if outgoingColors.count >= 2 {
|
||||
let gradientColors = outgoingColors.map { $0.cgColor } as CFArray
|
||||
let gradientColors = outgoingColors.reversed().map { $0.cgColor } as CFArray
|
||||
|
||||
var locations: [CGFloat] = []
|
||||
for i in 0 ..< outgoingColors.count {
|
||||
|
Loading…
x
Reference in New Issue
Block a user