mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various Voice Chats improvements
This commit is contained in:
parent
556002df68
commit
13fd591ee0
@ -6221,3 +6221,8 @@ Sorry for the inconvenience.";
|
||||
"VoiceChat.InviteLink.InviteListeners_any" = "[%@] Invite Listeners";
|
||||
|
||||
"Conversation.JoinVoiceChat" = "JOIN VOICE CHAT";
|
||||
|
||||
"Conversation.CancelForwardTitle" = "Cancel Forwarding";
|
||||
"Conversation.CancelForwardText" = "Do you want to cancel this forwarding or would like to send this messages to another chat?";
|
||||
"Conversation.CancelForwardCancelForward" = "Cancel Forwarding";
|
||||
"Conversation.CancelForwardSelectChat" = "Select Chat";
|
||||
|
@ -34,10 +34,11 @@ private struct ArchivedStickersNoticeEntry: Comparable, Identifiable {
|
||||
}
|
||||
|
||||
func item(account: Account, presentationData: PresentationData) -> ListViewItem {
|
||||
return ItemListStickerPackItem(presentationData: ItemListPresentationData(presentationData), account: account, packInfo: info, itemCount: self.count, topItem: topItem, unread: false, control: .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false), enabled: true, playAnimatedStickers: true, sectionId: 0, action: {
|
||||
return ItemListStickerPackItem(presentationData: ItemListPresentationData(presentationData), account: account, packInfo: info, itemCount: self.count, topItem: topItem, unread: false, control: .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: true, sectionId: 0, action: {
|
||||
}, setPackIdWithRevealedOptions: { current, previous in
|
||||
}, addPack: {
|
||||
}, removePack: {
|
||||
}, toggleSelected: {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -296,8 +296,6 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
return .like
|
||||
case .unlike:
|
||||
return .unlike
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if strongSelf.highlightedReaction != highlightedReaction {
|
||||
@ -431,8 +429,6 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
reactionSelected(.like)
|
||||
case .unlike:
|
||||
reactionSelected(.unlike)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -632,7 +628,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
|
||||
if let contentNode = self.contentContainerNode.contentNode {
|
||||
switch contentNode {
|
||||
case let .reference(referenceNode):
|
||||
case .reference:
|
||||
let springDuration: Double = 0.42 * animationDurationFactor
|
||||
let springDamping: CGFloat = 104.0
|
||||
|
||||
@ -758,10 +754,6 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
|
||||
self.scrollNode.view.setContentOffset(self.scrollNode.view.contentOffset, animated: false)
|
||||
|
||||
var completedEffect = false
|
||||
var completedContentNode = false
|
||||
var completedActionsNode = false
|
||||
|
||||
if let transitionInfo = transitionInfo, let parentSupernode = referenceNode.supernode {
|
||||
self.originalProjectedContentViewFrame = (convertFrame(referenceNode.frame, from: parentSupernode.view, to: self.view), convertFrame(referenceNode.bounds, from: referenceNode.view, to: self.view))
|
||||
|
||||
@ -794,8 +786,6 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
|
||||
if animateOutToItem, let originalProjectedContentViewFrame = self.originalProjectedContentViewFrame {
|
||||
let localSourceFrame = self.view.convert(originalProjectedContentViewFrame.1, to: self.scrollNode.view)
|
||||
let localContentSourceFrame = self.view.convert(originalProjectedContentViewFrame.1, to: self.contentContainerNode.view.superview)
|
||||
|
||||
self.actionsContainerNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: localSourceFrame.center.x - self.actionsContainerNode.position.x, y: localSourceFrame.center.y - self.actionsContainerNode.position.y), duration: transitionDuration * animationDurationFactor, timingFunction: transitionCurve.timingFunction, removeOnCompletion: false, additive: true)
|
||||
}
|
||||
case let .extracted(source):
|
||||
@ -864,7 +854,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
let propertyAnimator = propertyAnimator as? UIViewPropertyAnimator
|
||||
propertyAnimator?.stopAnimation(true)
|
||||
}
|
||||
self.propertyAnimator = UIViewPropertyAnimator(duration: transitionDuration * UIView.animationDurationFactor(), curve: .easeInOut, animations: { [weak self] in
|
||||
self.propertyAnimator = UIViewPropertyAnimator(duration: transitionDuration * UIView.animationDurationFactor(), curve: .easeInOut, animations: {
|
||||
//self?.effectView.effect = nil
|
||||
})
|
||||
}
|
||||
|
@ -446,7 +446,7 @@ public func inviteLinkListController(context: AccountContext, peerId: PeerId, ad
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
}, mainLinkContextAction: { invite, node, gesture in
|
||||
guard let node = node as? ContextExtractedContentContainingNode, let controller = getControllerImpl?(), let invite = invite else {
|
||||
guard let node = node as? ContextReferenceContentNode, let controller = getControllerImpl?(), let invite = invite else {
|
||||
return
|
||||
}
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
@ -551,7 +551,7 @@ public func inviteLinkListController(context: AccountContext, peerId: PeerId, ad
|
||||
})))
|
||||
}
|
||||
|
||||
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .extracted(InviteLinkContextExtractedContentSource(controller: controller, sourceNode: node, blurBackground: false)), items: .single(items), reactionItems: [], gesture: gesture)
|
||||
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .reference(InviteLinkContextReferenceContentSource(controller: controller, sourceNode: node)), items: .single(items), reactionItems: [], gesture: gesture)
|
||||
presentInGlobalOverlayImpl?(contextController)
|
||||
}, createLink: {
|
||||
let controller = inviteLinkEditController(context: context, peerId: peerId, invite: nil, completion: { invite in
|
||||
@ -899,3 +899,17 @@ final class InviteLinkContextExtractedContentSource: ContextExtractedContentSour
|
||||
return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds)
|
||||
}
|
||||
}
|
||||
|
||||
final class InviteLinkContextReferenceContentSource: ContextReferenceContentSource {
|
||||
private let controller: ViewController
|
||||
private let sourceNode: ContextReferenceContentNode
|
||||
|
||||
init(controller: ViewController, sourceNode: ContextReferenceContentNode) {
|
||||
self.controller = controller
|
||||
self.sourceNode = sourceNode
|
||||
}
|
||||
|
||||
func transitionInfo() -> ContextControllerReferenceViewInfo? {
|
||||
return ContextControllerReferenceViewInfo(referenceNode: self.sourceNode, contentAreaInScreenSpace: UIScreen.main.bounds)
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
||||
private let fieldNode: ASImageNode
|
||||
private let addressNode: TextNode
|
||||
private let fieldButtonNode: HighlightTrackingButtonNode
|
||||
private let extractedContainerNode: ContextExtractedContentContainingNode
|
||||
private let referenceContainerNode: ContextReferenceContentNode
|
||||
private let containerNode: ContextControllerSourceNode
|
||||
private let addressButtonNode: HighlightTrackingButtonNode
|
||||
private let addressButtonIconNode: ASImageNode
|
||||
@ -172,7 +172,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
||||
self.fieldButtonNode = HighlightTrackingButtonNode()
|
||||
|
||||
self.addressButtonNode = HighlightTrackingButtonNode()
|
||||
self.extractedContainerNode = ContextExtractedContentContainingNode()
|
||||
self.referenceContainerNode = ContextReferenceContentNode()
|
||||
self.containerNode = ContextControllerSourceNode()
|
||||
self.containerNode.isGestureEnabled = false
|
||||
self.addressButtonIconNode = ASImageNode()
|
||||
@ -196,9 +196,8 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
||||
self.addSubnode(self.invitedPeersNode)
|
||||
self.addSubnode(self.avatarsButtonNode)
|
||||
|
||||
self.containerNode.addSubnode(self.extractedContainerNode)
|
||||
self.extractedContainerNode.contentNode.addSubnode(self.addressButtonIconNode)
|
||||
self.containerNode.targetNodeForActivationProgress = self.extractedContainerNode.contentNode
|
||||
self.containerNode.addSubnode(self.referenceContainerNode)
|
||||
self.referenceContainerNode.addSubnode(self.addressButtonIconNode)
|
||||
self.addressButtonNode.addSubnode(self.containerNode)
|
||||
self.addSubnode(self.addressButtonNode)
|
||||
|
||||
@ -260,7 +259,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
||||
|
||||
@objc private func addressButtonPressed() {
|
||||
if let item = self.item {
|
||||
item.contextAction?(self.extractedContainerNode)
|
||||
item.contextAction?(self.referenceContainerNode)
|
||||
}
|
||||
}
|
||||
|
||||
@ -432,8 +431,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
|
||||
strongSelf.addressNode.frame = CGRect(origin: CGPoint(x: fieldFrame.minX + (alignCentrally ? floorToScreenPixels((fieldFrame.width - addressLayout.size.width) / 2.0) : 14.0), y: fieldFrame.minY + floorToScreenPixels((fieldFrame.height - addressLayout.size.height) / 2.0) + 1.0), size: addressLayout.size)
|
||||
|
||||
strongSelf.addressButtonNode.frame = CGRect(origin: CGPoint(x: params.width - rightInset - 38.0 - 14.0, y: verticalInset), size: CGSize(width: 52.0, height: 52.0))
|
||||
strongSelf.extractedContainerNode.frame = strongSelf.addressButtonNode.bounds
|
||||
strongSelf.extractedContainerNode.contentRect = strongSelf.addressButtonNode.bounds
|
||||
strongSelf.referenceContainerNode.frame = strongSelf.addressButtonNode.bounds
|
||||
strongSelf.addressButtonIconNode.frame = strongSelf.addressButtonNode.bounds
|
||||
|
||||
let shareButtonNode: SolidRoundedButtonNode
|
||||
|
@ -19,12 +19,14 @@ public struct ItemListStickerPackItemEditing: Equatable {
|
||||
public var editing: Bool
|
||||
public var revealed: Bool
|
||||
public var reorderable: Bool
|
||||
public var selectable: Bool
|
||||
|
||||
public init(editable: Bool, editing: Bool, revealed: Bool, reorderable: Bool) {
|
||||
public init(editable: Bool, editing: Bool, revealed: Bool, reorderable: Bool, selectable: Bool) {
|
||||
self.editable = editable
|
||||
self.editing = editing
|
||||
self.revealed = revealed
|
||||
self.reorderable = reorderable
|
||||
self.selectable = selectable
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,8 +53,9 @@ public final class ItemListStickerPackItem: ListViewItem, ItemListItem {
|
||||
let setPackIdWithRevealedOptions: (ItemCollectionId?, ItemCollectionId?) -> Void
|
||||
let addPack: () -> Void
|
||||
let removePack: () -> Void
|
||||
let toggleSelected: () -> Void
|
||||
|
||||
public init(presentationData: ItemListPresentationData, account: Account, packInfo: StickerPackCollectionInfo, itemCount: String, topItem: StickerPackItem?, unread: Bool, control: ItemListStickerPackItemControl, editing: ItemListStickerPackItemEditing, enabled: Bool, playAnimatedStickers: Bool, sectionId: ItemListSectionId, action: (() -> Void)?, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, addPack: @escaping () -> Void, removePack: @escaping () -> Void) {
|
||||
public init(presentationData: ItemListPresentationData, account: Account, packInfo: StickerPackCollectionInfo, itemCount: String, topItem: StickerPackItem?, unread: Bool, control: ItemListStickerPackItemControl, editing: ItemListStickerPackItemEditing, enabled: Bool, playAnimatedStickers: Bool, sectionId: ItemListSectionId, action: (() -> Void)?, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, addPack: @escaping () -> Void, removePack: @escaping () -> Void, toggleSelected: @escaping () -> Void) {
|
||||
self.presentationData = presentationData
|
||||
self.account = account
|
||||
self.packInfo = packInfo
|
||||
@ -68,6 +71,7 @@ public final class ItemListStickerPackItem: ListViewItem, ItemListItem {
|
||||
self.setPackIdWithRevealedOptions = setPackIdWithRevealedOptions
|
||||
self.addPack = addPack
|
||||
self.removePack = removePack
|
||||
self.toggleSelected = toggleSelected
|
||||
}
|
||||
|
||||
public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||
@ -160,6 +164,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
private var layoutParams: (ItemListStickerPackItem, ListViewItemLayoutParams, ItemListNeighbors)?
|
||||
|
||||
private var selectableControlNode: ItemListSelectableControlNode?
|
||||
private var editableControlNode: ItemListEditableControlNode?
|
||||
private var reorderControlNode: ItemListEditableReorderControlNode?
|
||||
|
||||
@ -168,7 +173,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
private let fetchDisposable = MetaDisposable()
|
||||
|
||||
override var canBeSelected: Bool {
|
||||
if self.editableControlNode != nil || self.disabledOverlayNode != nil {
|
||||
if self.selectableControlNode != nil || self.editableControlNode != nil || self.disabledOverlayNode != nil {
|
||||
return false
|
||||
}
|
||||
if let item = self.layoutParams?.0, item.action != nil {
|
||||
@ -309,12 +314,20 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
override func tapped() {
|
||||
guard let item = self.layoutParams?.0, item.editing.editing && item.editing.selectable else {
|
||||
return
|
||||
}
|
||||
item.toggleSelected()
|
||||
}
|
||||
|
||||
func asyncLayout() -> (_ item: ItemListStickerPackItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, (Bool) -> Void) {
|
||||
let makeImageLayout = self.imageNode.asyncLayout()
|
||||
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
|
||||
let makeStatusLayout = TextNode.asyncLayout(self.statusNode)
|
||||
let editableControlLayout = ItemListEditableControlNode.asyncLayout(self.editableControlNode)
|
||||
let reorderControlLayout = ItemListEditableReorderControlNode.asyncLayout(self.reorderControlNode)
|
||||
let selectableControlLayout = ItemListSelectableControlNode.asyncLayout(self.selectableControlNode)
|
||||
|
||||
let previousThumbnailItem = self.currentThumbnailItem
|
||||
var currentDisabledOverlayNode = self.disabledOverlayNode
|
||||
@ -358,8 +371,8 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
case .selection:
|
||||
rightInset += 16.0
|
||||
checkImage = PresentationResourcesItemList.checkIconImage(item.presentationData.theme)
|
||||
case .check:
|
||||
rightInset += 16.0
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
var unreadImage: UIImage?
|
||||
@ -380,14 +393,25 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
var editableControlSizeAndApply: (CGFloat, (CGFloat) -> ItemListEditableControlNode)?
|
||||
var reorderControlSizeAndApply: (CGFloat, (CGFloat, Bool, ContainedViewLayoutTransition) -> ItemListEditableReorderControlNode)?
|
||||
var selectableControlSizeAndApply: (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode)?
|
||||
|
||||
var editingOffset: CGFloat = 0.0
|
||||
var reorderInset: CGFloat = 0.0
|
||||
|
||||
if item.editing.editing {
|
||||
let sizeAndApply = editableControlLayout(item.presentationData.theme, false)
|
||||
editableControlSizeAndApply = sizeAndApply
|
||||
editingOffset = sizeAndApply.0
|
||||
if item.editing.selectable {
|
||||
var selected = false
|
||||
if case let .check(checked) = item.control {
|
||||
selected = checked
|
||||
}
|
||||
let sizeAndApply = selectableControlLayout(item.presentationData.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.list.itemCheckColors.fillColor, item.presentationData.theme.list.itemCheckColors.foregroundColor, selected, true)
|
||||
selectableControlSizeAndApply = sizeAndApply
|
||||
editingOffset = sizeAndApply.0
|
||||
} else {
|
||||
let sizeAndApply = editableControlLayout(item.presentationData.theme, false)
|
||||
editableControlSizeAndApply = sizeAndApply
|
||||
editingOffset = sizeAndApply.0
|
||||
}
|
||||
|
||||
if item.editing.reorderable {
|
||||
let sizeAndApply = reorderControlLayout(item.presentationData.theme)
|
||||
@ -547,6 +571,31 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
})
|
||||
}
|
||||
|
||||
if let selectableControlSizeAndApply = selectableControlSizeAndApply {
|
||||
let selectableControlSize = CGSize(width: selectableControlSizeAndApply.0, height: layout.contentSize.height)
|
||||
let selectableControlFrame = CGRect(origin: CGPoint(x: params.leftInset + revealOffset, y: 0.0), size: selectableControlSize)
|
||||
if strongSelf.selectableControlNode == nil {
|
||||
let selectableControlNode = selectableControlSizeAndApply.1(selectableControlSize, false)
|
||||
strongSelf.selectableControlNode = selectableControlNode
|
||||
strongSelf.addSubnode(selectableControlNode)
|
||||
selectableControlNode.frame = selectableControlFrame
|
||||
transition.animatePosition(node: selectableControlNode, from: CGPoint(x: -selectableControlFrame.size.width / 2.0, y: selectableControlFrame.midY))
|
||||
selectableControlNode.alpha = 0.0
|
||||
transition.updateAlpha(node: selectableControlNode, alpha: 1.0)
|
||||
} else if let selectableControlNode = strongSelf.selectableControlNode {
|
||||
transition.updateFrame(node: selectableControlNode, frame: selectableControlFrame)
|
||||
let _ = selectableControlSizeAndApply.1(selectableControlSize, transition.isAnimated)
|
||||
}
|
||||
} else if let selectableControlNode = strongSelf.selectableControlNode {
|
||||
var selectableControlFrame = selectableControlNode.frame
|
||||
selectableControlFrame.origin.x = -selectableControlFrame.size.width
|
||||
strongSelf.selectableControlNode = nil
|
||||
transition.updateAlpha(node: selectableControlNode, alpha: 0.0)
|
||||
transition.updateFrame(node: selectableControlNode, frame: selectableControlFrame, completion: { [weak selectableControlNode] _ in
|
||||
selectableControlNode?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
|
||||
if let reorderControlSizeAndApply = reorderControlSizeAndApply {
|
||||
if strongSelf.reorderControlNode == nil {
|
||||
let reorderControlNode = reorderControlSizeAndApply.1(layout.contentSize.height, false, .immediate)
|
||||
|
@ -76,10 +76,20 @@ public struct ItemListToolbarItem {
|
||||
public let title: String
|
||||
public let isEnabled: Bool
|
||||
public let action: () -> Void
|
||||
|
||||
public init(title: String, isEnabled: Bool, action: @escaping () -> Void) {
|
||||
self.title = title
|
||||
self.isEnabled = isEnabled
|
||||
self.action = action
|
||||
}
|
||||
}
|
||||
|
||||
let actions: [Action]
|
||||
|
||||
public init(actions: [Action]) {
|
||||
self.actions = actions
|
||||
}
|
||||
|
||||
var toolbar: Toolbar {
|
||||
var leftAction: ToolbarAction?
|
||||
var middleAction: ToolbarAction?
|
||||
@ -644,9 +654,25 @@ open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
return transition.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
let toolbarFrame = CGRect()
|
||||
let layoutTransition: ContainedViewLayoutTransition = .immediate
|
||||
if let toolbarItem = transition.toolbarItem, let (layout, _) = self.validLayout {
|
||||
var options: ContainerViewLayoutInsetOptions = []
|
||||
if layout.metrics.widthClass == .regular {
|
||||
options.insert(.input)
|
||||
}
|
||||
var tabBarHeight: CGFloat
|
||||
let bottomInset: CGFloat = layout.insets(options: options).bottom
|
||||
if !layout.safeInsets.left.isZero {
|
||||
tabBarHeight = 34.0 + bottomInset
|
||||
// insets.bottom += 34.0
|
||||
} else {
|
||||
tabBarHeight = 49.0 + bottomInset
|
||||
// insets.bottom += 49.0
|
||||
}
|
||||
|
||||
let toolbarFrame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - tabBarHeight), size: CGSize(width: layout.size.width, height: tabBarHeight))
|
||||
|
||||
|
||||
if let toolbarNode = self.toolbarNode {
|
||||
layoutTransition.updateFrame(node: toolbarNode, frame: toolbarFrame)
|
||||
toolbarNode.updateLayout(size: toolbarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, additionalSideInsets: layout.additionalInsets, bottomInset: layout.intrinsicInsets.bottom, toolbar: toolbarItem.toolbar, transition: layoutTransition)
|
||||
|
@ -228,7 +228,7 @@ private enum GroupStickerPackEntry: ItemListNodeEntry {
|
||||
case let .packsTitle(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .pack(_, _, _, info, topItem, count, playAnimatedStickers, selected):
|
||||
return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: selected ? .selection : .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: {
|
||||
return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: selected ? .selection : .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: {
|
||||
if selected {
|
||||
arguments.openStickerPack(info)
|
||||
} else {
|
||||
@ -237,6 +237,7 @@ private enum GroupStickerPackEntry: ItemListNodeEntry {
|
||||
}, setPackIdWithRevealedOptions: { _, _ in
|
||||
}, addPack: {
|
||||
}, removePack: {
|
||||
}, toggleSelected: {
|
||||
})
|
||||
case let .currentPack(_, theme, strings, content):
|
||||
return GroupStickerPackCurrentItem(theme: theme, strings: strings, account: arguments.account, content: content, sectionId: self.section, action: {
|
||||
|
@ -169,6 +169,7 @@ private enum ArchivedStickerPacksEntry: ItemListNodeEntry {
|
||||
arguments.addPack(info)
|
||||
}, removePack: {
|
||||
arguments.removePack(info)
|
||||
}, toggleSelected: {
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -232,7 +233,7 @@ private func archivedStickerPacksControllerEntries(presentationData: Presentatio
|
||||
var index: Int32 = 0
|
||||
for item in packs {
|
||||
if !installedIds.contains(item.info.id) {
|
||||
entries.append(.pack(index, presentationData.theme, presentationData.strings, item.info, item.topItems.first, presentationData.strings.StickerPack_StickerCount(item.info.count), stickerSettings.loopAnimatedStickers, !state.removingPackIds.contains(item.info.id), ItemListStickerPackItemEditing(editable: true, editing: state.editing, revealed: state.packIdWithRevealedOptions == item.info.id, reorderable: false)))
|
||||
entries.append(.pack(index, presentationData.theme, presentationData.strings, item.info, item.topItems.first, presentationData.strings.StickerPack_StickerCount(item.info.count), stickerSettings.loopAnimatedStickers, !state.removingPackIds.contains(item.info.id), ItemListStickerPackItemEditing(editable: true, editing: state.editing, revealed: state.packIdWithRevealedOptions == item.info.id, reorderable: false, selectable: true)))
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
|
@ -121,12 +121,13 @@ private enum FeaturedStickerPacksEntry: ItemListNodeEntry {
|
||||
let arguments = arguments as! FeaturedStickerPacksControllerArguments
|
||||
switch self {
|
||||
case let .pack(_, theme, strings, info, unread, topItem, count, playAnimatedStickers, installed):
|
||||
return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: unread, control: .installation(installed: installed), editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: {
|
||||
return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: unread, control: .installation(installed: installed), editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: {
|
||||
arguments.openStickerPack(info)
|
||||
}, setPackIdWithRevealedOptions: { _, _ in
|
||||
}, addPack: {
|
||||
arguments.addPack(info)
|
||||
}, removePack: {
|
||||
}, toggleSelected: {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import AccountContext
|
||||
import StickerPackPreviewUI
|
||||
import ItemListStickerPackItem
|
||||
import UndoUI
|
||||
import ShareController
|
||||
|
||||
private final class InstalledStickerPacksControllerArguments {
|
||||
let account: Account
|
||||
@ -27,8 +28,9 @@ private final class InstalledStickerPacksControllerArguments {
|
||||
let openArchived: ([ArchivedStickerPackItem]?) -> Void
|
||||
let openSuggestOptions: () -> Void
|
||||
let toggleAnimatedStickers: (Bool) -> Void
|
||||
let togglePackSelected: (ItemCollectionId) -> Void
|
||||
|
||||
init(account: Account, openStickerPack: @escaping (StickerPackCollectionInfo) -> Void, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, removePack: @escaping (ArchivedStickerPackItem) -> Void, openStickersBot: @escaping () -> Void, openMasks: @escaping () -> Void, openFeatured: @escaping () -> Void, openArchived: @escaping ([ArchivedStickerPackItem]?) -> Void, openSuggestOptions: @escaping () -> Void, toggleAnimatedStickers: @escaping (Bool) -> Void) {
|
||||
init(account: Account, openStickerPack: @escaping (StickerPackCollectionInfo) -> Void, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, removePack: @escaping (ArchivedStickerPackItem) -> Void, openStickersBot: @escaping () -> Void, openMasks: @escaping () -> Void, openFeatured: @escaping () -> Void, openArchived: @escaping ([ArchivedStickerPackItem]?) -> Void, openSuggestOptions: @escaping () -> Void, toggleAnimatedStickers: @escaping (Bool) -> Void, togglePackSelected: @escaping (ItemCollectionId) -> Void) {
|
||||
self.account = account
|
||||
self.openStickerPack = openStickerPack
|
||||
self.setPackIdWithRevealedOptions = setPackIdWithRevealedOptions
|
||||
@ -39,6 +41,7 @@ private final class InstalledStickerPacksControllerArguments {
|
||||
self.openArchived = openArchived
|
||||
self.openSuggestOptions = openSuggestOptions
|
||||
self.toggleAnimatedStickers = toggleAnimatedStickers
|
||||
self.togglePackSelected = togglePackSelected
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,7 +102,7 @@ private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry {
|
||||
case animatedStickers(PresentationTheme, String, Bool)
|
||||
case animatedStickersInfo(PresentationTheme, String)
|
||||
case packsTitle(PresentationTheme, String)
|
||||
case pack(Int32, PresentationTheme, PresentationStrings, StickerPackCollectionInfo, StickerPackItem?, String, Bool, Bool, ItemListStickerPackItemEditing)
|
||||
case pack(Int32, PresentationTheme, PresentationStrings, StickerPackCollectionInfo, StickerPackItem?, String, Bool, Bool, ItemListStickerPackItemEditing, Bool?)
|
||||
case packsInfo(PresentationTheme, String)
|
||||
|
||||
var section: ItemListSectionId {
|
||||
@ -127,7 +130,7 @@ private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry {
|
||||
return .index(5)
|
||||
case .packsTitle:
|
||||
return .index(6)
|
||||
case let .pack(_, _, _, info, _, _, _, _, _):
|
||||
case let .pack(_, _, _, info, _, _, _, _, _, _):
|
||||
return .pack(info.id)
|
||||
case .packsInfo:
|
||||
return .index(7)
|
||||
@ -178,8 +181,8 @@ private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .pack(lhsIndex, lhsTheme, lhsStrings, lhsInfo, lhsTopItem, lhsCount, lhsAnimatedStickers, lhsEnabled, lhsEditing):
|
||||
if case let .pack(rhsIndex, rhsTheme, rhsStrings, rhsInfo, rhsTopItem, rhsCount, rhsAnimatedStickers, rhsEnabled, rhsEditing) = rhs {
|
||||
case let .pack(lhsIndex, lhsTheme, lhsStrings, lhsInfo, lhsTopItem, lhsCount, lhsAnimatedStickers, lhsEnabled, lhsEditing, lhsSelected):
|
||||
if case let .pack(rhsIndex, rhsTheme, rhsStrings, rhsInfo, rhsTopItem, rhsCount, rhsAnimatedStickers, rhsEnabled, rhsEditing, rhsSelected) = rhs {
|
||||
if lhsIndex != rhsIndex {
|
||||
return false
|
||||
}
|
||||
@ -207,6 +210,9 @@ private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry {
|
||||
if lhsEditing != rhsEditing {
|
||||
return false
|
||||
}
|
||||
if lhsSelected != rhsSelected {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -271,9 +277,9 @@ private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry {
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case let .pack(lhsIndex, _, _, _, _, _, _, _, _):
|
||||
case let .pack(lhsIndex, _, _, _, _, _, _, _, _, _):
|
||||
switch rhs {
|
||||
case let .pack(rhsIndex, _, _, _, _, _, _, _, _):
|
||||
case let .pack(rhsIndex, _, _, _, _, _, _, _, _, _):
|
||||
return lhsIndex < rhsIndex
|
||||
case .packsInfo:
|
||||
return true
|
||||
@ -317,14 +323,16 @@ private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry {
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||
case let .packsTitle(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .pack(_, _, strings, info, topItem, count, animatedStickers, enabled, editing):
|
||||
return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: .none, editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: {
|
||||
case let .pack(_, _, _, info, topItem, count, animatedStickers, enabled, editing, selected):
|
||||
return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: editing.editing ? .check(checked: selected ?? false) : .none, editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: {
|
||||
arguments.openStickerPack(info)
|
||||
}, setPackIdWithRevealedOptions: { current, previous in
|
||||
arguments.setPackIdWithRevealedOptions(current, previous)
|
||||
}, addPack: {
|
||||
}, removePack: {
|
||||
arguments.removePack(ArchivedStickerPackItem(info: info, topItems: topItem != nil ? [topItem!] : []))
|
||||
}, toggleSelected: {
|
||||
arguments.togglePackSelected(info.id)
|
||||
})
|
||||
case let .packsInfo(_, text):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section, linkAction: { _ in
|
||||
@ -336,7 +344,7 @@ private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry {
|
||||
|
||||
private struct InstalledStickerPacksControllerState: Equatable {
|
||||
let editing: Bool
|
||||
let selectedPackIds: Set<Int64>?
|
||||
let selectedPackIds: Set<ItemCollectionId>?
|
||||
let packIdWithRevealedOptions: ItemCollectionId?
|
||||
|
||||
init() {
|
||||
@ -345,7 +353,7 @@ private struct InstalledStickerPacksControllerState: Equatable {
|
||||
self.packIdWithRevealedOptions = nil
|
||||
}
|
||||
|
||||
init(editing: Bool, selectedPackIds: Set<Int64>?, packIdWithRevealedOptions: ItemCollectionId?) {
|
||||
init(editing: Bool, selectedPackIds: Set<ItemCollectionId>?, packIdWithRevealedOptions: ItemCollectionId?) {
|
||||
self.editing = editing
|
||||
self.selectedPackIds = selectedPackIds
|
||||
self.packIdWithRevealedOptions = packIdWithRevealedOptions
|
||||
@ -369,7 +377,7 @@ private struct InstalledStickerPacksControllerState: Equatable {
|
||||
return InstalledStickerPacksControllerState(editing: editing, selectedPackIds: self.selectedPackIds, packIdWithRevealedOptions: self.packIdWithRevealedOptions)
|
||||
}
|
||||
|
||||
func withUpdatedSelectedPackIds(_ selectedPackIds: Set<Int64>) -> InstalledStickerPacksControllerState {
|
||||
func withUpdatedSelectedPackIds(_ selectedPackIds: Set<ItemCollectionId>?) -> InstalledStickerPacksControllerState {
|
||||
return InstalledStickerPacksControllerState(editing: editing, selectedPackIds: selectedPackIds, packIdWithRevealedOptions: self.packIdWithRevealedOptions)
|
||||
}
|
||||
|
||||
@ -454,7 +462,7 @@ private func installedStickerPacksControllerEntries(presentationData: Presentati
|
||||
var index: Int32 = 0
|
||||
for entry in sortedPacks {
|
||||
if let info = entry.info as? StickerPackCollectionInfo {
|
||||
entries.append(.pack(index, presentationData.theme, presentationData.strings, info, entry.firstItem as? StickerPackItem, presentationData.strings.StickerPack_StickerCount(info.count == 0 ? entry.count : info.count), stickerSettings.loopAnimatedStickers, true, ItemListStickerPackItemEditing(editable: true, editing: state.editing, revealed: state.packIdWithRevealedOptions == entry.id, reorderable: true)))
|
||||
entries.append(.pack(index, presentationData.theme, presentationData.strings, info, entry.firstItem as? StickerPackItem, presentationData.strings.StickerPack_StickerCount(info.count == 0 ? entry.count : info.count), stickerSettings.loopAnimatedStickers, true, ItemListStickerPackItemEditing(editable: true, editing: state.editing, revealed: state.packIdWithRevealedOptions == entry.id, reorderable: true, selectable: true), state.selectedPackIds?.contains(info.id)))
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
@ -485,7 +493,7 @@ public enum InstalledStickerPacksControllerMode {
|
||||
}
|
||||
|
||||
public func installedStickerPacksController(context: AccountContext, mode: InstalledStickerPacksControllerMode, archivedPacks: [ArchivedStickerPackItem]? = nil, updatedPacks: @escaping ([ArchivedStickerPackItem]?) -> Void = { _ in }, focusOnItemTag: InstalledStickerPacksEntryTag? = nil) -> ViewController {
|
||||
let initialState = InstalledStickerPacksControllerState().withUpdatedEditing(mode == .modal)
|
||||
let initialState = InstalledStickerPacksControllerState().withUpdatedEditing(mode == .modal).withUpdatedSelectedPackIds(mode == .modal ? Set() : nil)
|
||||
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
||||
let stateValue = Atomic(value: initialState)
|
||||
let updateState: ((InstalledStickerPacksControllerState) -> InstalledStickerPacksControllerState) -> Void = { f in
|
||||
@ -624,6 +632,19 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
||||
let _ = updateStickerSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
return current.withUpdatedLoopAnimatedStickers(value)
|
||||
}).start()
|
||||
}, togglePackSelected: { packId in
|
||||
updateState { state in
|
||||
if var selectedPackIds = state.selectedPackIds {
|
||||
if selectedPackIds.contains(packId) {
|
||||
selectedPackIds.remove(packId)
|
||||
} else {
|
||||
selectedPackIds.insert(packId)
|
||||
}
|
||||
return state.withUpdatedSelectedPackIds(selectedPackIds)
|
||||
} else {
|
||||
return state
|
||||
}
|
||||
}
|
||||
})
|
||||
let stickerPacks = Promise<CombinedView>()
|
||||
stickerPacks.set(context.account.postbox.combinedView(keys: [.itemCollectionInfos(namespaces: [namespaceForMode(mode)])]))
|
||||
@ -669,16 +690,32 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
||||
if state.editing {
|
||||
rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: {
|
||||
updateState {
|
||||
$0.withUpdatedEditing(false)
|
||||
$0.withUpdatedEditing(false).withUpdatedSelectedPackIds(nil)
|
||||
}
|
||||
if case .modal = mode {
|
||||
dismissImpl?()
|
||||
}
|
||||
})
|
||||
let enabled = (state.selectedPackIds?.count ?? 0) > 0
|
||||
toolbarItem = ItemListToolbarItem(actions: [.init(title: "Delete", isEnabled: enabled, action: {
|
||||
updateState {
|
||||
$0.withUpdatedEditing(false).withUpdatedSelectedPackIds(nil)
|
||||
}
|
||||
}), .init(title: "Archive", isEnabled: enabled, action: {
|
||||
updateState {
|
||||
$0.withUpdatedEditing(false).withUpdatedSelectedPackIds(nil)
|
||||
}
|
||||
}), .init(title: "Share", isEnabled: enabled, action: {
|
||||
updateState {
|
||||
$0.withUpdatedEditing(false).withUpdatedSelectedPackIds(nil)
|
||||
}
|
||||
let shareController = ShareController(context: context, subject: .text("test"), externalShare: true)
|
||||
presentControllerImpl?(shareController, nil)
|
||||
})])
|
||||
} else {
|
||||
rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Edit), style: .regular, enabled: true, action: {
|
||||
updateState {
|
||||
$0.withUpdatedEditing(true)
|
||||
$0.withUpdatedEditing(true).withUpdatedSelectedPackIds(Set())
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -711,7 +748,7 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
||||
}
|
||||
controller.setReorderEntry({ (fromIndex: Int, toIndex: Int, entries: [InstalledStickerPacksEntry]) -> Signal<Bool, NoError> in
|
||||
let fromEntry = entries[fromIndex]
|
||||
guard case let .pack(_, _, _, fromPackInfo, _, _, _, _, _) = fromEntry else {
|
||||
guard case let .pack(_, _, _, fromPackInfo, _, _, _, _, _, _) = fromEntry else {
|
||||
return .single(false)
|
||||
}
|
||||
var referenceId: ItemCollectionId?
|
||||
@ -719,7 +756,7 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
||||
var afterAll = false
|
||||
if toIndex < entries.count {
|
||||
switch entries[toIndex] {
|
||||
case let .pack(_, _, _, toPackInfo, _, _, _, _, _):
|
||||
case let .pack(_, _, _, toPackInfo, _, _, _, _, _, _):
|
||||
referenceId = toPackInfo.id
|
||||
default:
|
||||
if entries[toIndex] < fromEntry {
|
||||
|
@ -743,7 +743,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
activityRank: nil,
|
||||
muteState: GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: false),
|
||||
volume: nil,
|
||||
about: about
|
||||
about: about,
|
||||
raiseHandRating: nil
|
||||
))
|
||||
participants.sort()
|
||||
}
|
||||
@ -901,7 +902,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
strongSelf.requestDisposable.set((joinGroupCall(
|
||||
account: strongSelf.account,
|
||||
peerId: strongSelf.peerId,
|
||||
joinAs: strongSelf.joinAsPeerId == strongSelf.account.peerId ? nil : strongSelf.joinAsPeerId,
|
||||
joinAs: strongSelf.joinAsPeerId,
|
||||
callId: callInfo.id,
|
||||
accessHash: callInfo.accessHash,
|
||||
preferMuted: true,
|
||||
@ -1456,7 +1457,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
if id == peerId {
|
||||
self.callContext?.setVolume(ssrc: ssrc, volume: Double(volume) / 10000.0)
|
||||
if sync {
|
||||
self.participantsContext?.updateMuteState(peerId: peerId, muteState: nil, volume: volume)
|
||||
self.participantsContext?.updateMuteState(peerId: peerId, muteState: nil, volume: volume, raiseHand: nil)
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -1564,19 +1565,19 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
canThenUnmute = true
|
||||
}
|
||||
let muteState = isMuted ? GroupCallParticipantsContext.Participant.MuteState(canUnmute: canThenUnmute, mutedByYou: mutedByYou) : nil
|
||||
self.participantsContext?.updateMuteState(peerId: peerId, muteState: muteState, volume: nil)
|
||||
self.participantsContext?.updateMuteState(peerId: peerId, muteState: muteState, volume: nil, raiseHand: nil)
|
||||
return muteState
|
||||
} else {
|
||||
if peerId == self.joinAsPeerId {
|
||||
self.participantsContext?.updateMuteState(peerId: peerId, muteState: nil, volume: nil)
|
||||
self.participantsContext?.updateMuteState(peerId: peerId, muteState: nil, volume: nil, raiseHand: nil)
|
||||
return nil
|
||||
} else if self.stateValue.canManageCall || self.stateValue.adminIds.contains(self.accountContext.account.peerId) {
|
||||
let muteState = GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: false)
|
||||
self.participantsContext?.updateMuteState(peerId: peerId, muteState: muteState, volume: nil)
|
||||
self.participantsContext?.updateMuteState(peerId: peerId, muteState: muteState, volume: nil, raiseHand: nil)
|
||||
return muteState
|
||||
} else {
|
||||
self.setVolume(peerId: peerId, volume: 10000, sync: true)
|
||||
self.participantsContext?.updateMuteState(peerId: peerId, muteState: nil, volume: nil)
|
||||
self.participantsContext?.updateMuteState(peerId: peerId, muteState: nil, volume: nil, raiseHand: nil)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -1769,7 +1769,11 @@ public func cachedGroupCallDisplayAsAvailablePeers(account: Account) -> Signal<[
|
||||
var peers: [FoundPeer] = []
|
||||
for peerId in cached.peerIds {
|
||||
if let peer = transaction.getPeer(peerId) {
|
||||
peers.append(FoundPeer(peer: peer, subscribers: nil))
|
||||
var subscribers: Int32?
|
||||
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData {
|
||||
subscribers = cachedData.participantsSummary.memberCount
|
||||
}
|
||||
peers.append(FoundPeer(peer: peer, subscribers: subscribers))
|
||||
}
|
||||
}
|
||||
return (peers, cached.timestamp)
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -563,7 +563,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
statusController?.dismiss()
|
||||
}
|
||||
strongSelf.present(statusController, in: .window(.root))
|
||||
strongSelf.createVoiceChatDisposable.set((createGroupCall(account: strongSelf.context.account, peerId: message.id.peerId, joinAs: nil)
|
||||
strongSelf.createVoiceChatDisposable.set((createGroupCall(account: strongSelf.context.account, peerId: message.id.peerId, joinAs: strongSelf.context.account.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] info in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
|
@ -9,6 +9,8 @@ import Display
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import LocalizedPeerData
|
||||
import AlertUI
|
||||
import PresentationDataUtils
|
||||
|
||||
func textStringForForwardedMessage(_ message: Message, strings: PresentationStrings) -> (String, Bool) {
|
||||
for media in message.media {
|
||||
@ -81,11 +83,15 @@ final class ForwardAccessoryPanelNode: AccessoryPanelNode {
|
||||
|
||||
private let actionArea: AccessibilityAreaNode
|
||||
|
||||
let context: AccountContext
|
||||
var theme: PresentationTheme
|
||||
var strings: PresentationStrings
|
||||
|
||||
init(context: AccountContext, messageIds: [MessageId], theme: PresentationTheme, strings: PresentationStrings) {
|
||||
self.context = context
|
||||
self.messageIds = messageIds
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
|
||||
self.closeButton = ASButtonNode()
|
||||
self.closeButton.accessibilityLabel = strings.VoiceOver_DiscardPreparedContent
|
||||
@ -167,8 +173,9 @@ final class ForwardAccessoryPanelNode: AccessoryPanelNode {
|
||||
}
|
||||
|
||||
override func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) {
|
||||
if self.theme !== theme {
|
||||
if self.theme !== theme || self.strings !== strings {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
|
||||
self.closeButton.setImage(PresentationResourcesChat.chatInputPanelCloseIconImage(theme), for: [])
|
||||
|
||||
@ -215,9 +222,12 @@ final class ForwardAccessoryPanelNode: AccessoryPanelNode {
|
||||
}
|
||||
|
||||
@objc func closePressed() {
|
||||
if let dismiss = self.dismiss {
|
||||
dismiss()
|
||||
}
|
||||
let alertController = textAlertController(context: self.context, title: self.strings.Conversation_CancelForwardTitle, text: self.strings.Conversation_CancelForwardText, actions: [TextAlertAction(type: .genericAction, title: self.strings.Conversation_CancelForwardSelectChat, action: { [weak self] in
|
||||
self?.interfaceInteraction?.forwardCurrentForwardMessages()
|
||||
}), TextAlertAction(type: .defaultAction, title: self.strings.Conversation_CancelForwardCancelForward, action: { [weak self] in
|
||||
self?.dismiss?()
|
||||
})], actionLayout: .vertical)
|
||||
self.interfaceInteraction?.presentController(alertController, nil)
|
||||
}
|
||||
|
||||
@objc func tapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||
|
@ -3828,7 +3828,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
||||
statusController?.dismiss()
|
||||
}
|
||||
strongSelf.controller?.present(statusController, in: .window(.root))
|
||||
strongSelf.activeActionDisposable.set((createGroupCall(account: strongSelf.context.account, peerId: peerId, joinAs: joinAsPeerId)
|
||||
strongSelf.activeActionDisposable.set((createGroupCall(account: strongSelf.context.account, peerId: peerId, joinAs: joinAsPeerId ?? strongSelf.context.account.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] info in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
|
@ -28,6 +28,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
private let animationNode: AnimationNode?
|
||||
private var animatedStickerNode: AnimatedStickerNode?
|
||||
private var slotMachineNode: SlotMachineAnimationNode?
|
||||
private var recordingIconNode: RecordingIconNode?
|
||||
private var stillStickerNode: TransformImageNode?
|
||||
private var stickerImageSize: CGSize?
|
||||
private var stickerOffset: CGPoint?
|
||||
@ -555,9 +556,11 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
self.avatarNode = nil
|
||||
self.iconNode = nil
|
||||
self.iconCheckNode = nil
|
||||
self.animationNode = AnimationNode(animation: "anim_linkrevoked", colors: [:], scale: 0.066)
|
||||
self.animationNode = nil
|
||||
self.animatedStickerNode = nil
|
||||
|
||||
self.recordingIconNode = RecordingIconNode()
|
||||
|
||||
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white)
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white)
|
||||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in return nil }), textAlignment: .natural)
|
||||
@ -609,6 +612,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
self.animatedStickerNode.flatMap(self.panelWrapperNode.addSubnode)
|
||||
self.slotMachineNode.flatMap(self.panelWrapperNode.addSubnode)
|
||||
self.avatarNode.flatMap(self.panelWrapperNode.addSubnode)
|
||||
self.recordingIconNode.flatMap(self.panelWrapperNode.addSubnode)
|
||||
self.panelWrapperNode.addSubnode(self.titleNode)
|
||||
self.panelWrapperNode.addSubnode(self.textNode)
|
||||
self.panelWrapperNode.addSubnode(self.buttonNode)
|
||||
@ -834,6 +838,12 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
let iconFrame = CGRect(origin: CGPoint(x: floor((leftInset - iconSize.width) / 2.0), y: floor((contentHeight - iconSize.height) / 2.0)), size: iconSize)
|
||||
transition.updateFrame(node: slotMachineNode, frame: iconFrame)
|
||||
}
|
||||
|
||||
if let recordingIconNode = self.recordingIconNode {
|
||||
let iconSize = CGSize(width: 24.0, height: 24.0)
|
||||
let iconFrame = CGRect(origin: CGPoint(x: floor((leftInset - iconSize.width) / 2.0), y: floor((contentHeight - iconSize.height) / 2.0) + verticalOffset), size: iconSize)
|
||||
transition.updateFrame(node: recordingIconNode, frame: iconFrame)
|
||||
}
|
||||
|
||||
let timerTextSize = self.timerTextNode.updateLayout(CGSize(width: 100.0, height: 100.0))
|
||||
transition.updateFrame(node: self.timerTextNode, frame: CGRect(origin: CGPoint(x: floor((leftInset - timerTextSize.width) / 2.0), y: floor((contentHeight - timerTextSize.height) / 2.0)), size: timerTextSize))
|
||||
@ -909,3 +919,46 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
return super.hitTest(point, with: event)
|
||||
}
|
||||
}
|
||||
|
||||
private class RecordingIconNode: ASDisplayNode {
|
||||
private let backgroundNode: ASImageNode
|
||||
private let dotNode: ASImageNode
|
||||
|
||||
override init() {
|
||||
let iconSize: CGFloat = 24.0
|
||||
self.backgroundNode = ASImageNode()
|
||||
self.backgroundNode.displaysAsynchronously = false
|
||||
self.backgroundNode.displayWithoutProcessing = true
|
||||
self.backgroundNode.image = generateCircleImage(diameter: iconSize, lineWidth: 1.0 + UIScreenPixel, color: UIColor.white, backgroundColor: nil)
|
||||
|
||||
self.dotNode = ASImageNode()
|
||||
self.dotNode.displaysAsynchronously = false
|
||||
self.dotNode.displayWithoutProcessing = true
|
||||
self.dotNode.image = generateFilledCircleImage(diameter: 12.0, color: UIColor(rgb: 0xff3b30))
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.backgroundNode)
|
||||
self.addSubnode(self.dotNode)
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
let animation = CAKeyframeAnimation(keyPath: "opacity")
|
||||
animation.values = [1.0 as NSNumber, 1.0 as NSNumber, 0.0 as NSNumber]
|
||||
animation.keyTimes = [0.0 as NSNumber, 0.4546 as NSNumber, 0.9091 as NSNumber, 1 as NSNumber]
|
||||
animation.duration = 0.5
|
||||
animation.autoreverses = true
|
||||
animation.repeatCount = Float.infinity
|
||||
self.dotNode.layer.add(animation, forKey: "recording")
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
|
||||
self.backgroundNode.frame = self.bounds
|
||||
let dotSize = CGSize(width: 12.0, height: 12.0)
|
||||
self.dotNode.frame = CGRect(origin: CGPoint(x: (self.bounds.width - dotSize.width) / 2.0, y: (self.bounds.height - dotSize.height) / 2.0), size: dotSize)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user