mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various Fixes
This commit is contained in:
parent
9f8bd71105
commit
6490f0ba06
@ -166,6 +166,10 @@ public func inviteRequestsController(context: AccountContext, updatedPresentatio
|
||||
|
||||
let actionsDisposable = DisposableSet()
|
||||
|
||||
if let existingContext = existingContext {
|
||||
existingContext.reload()
|
||||
}
|
||||
|
||||
let statePromise = ValuePromise(InviteRequestsControllerState(searchingMembers: false), ignoreRepeated: true)
|
||||
let stateValue = Atomic(value: InviteRequestsControllerState(searchingMembers: false))
|
||||
let updateState: ((InviteRequestsControllerState) -> InviteRequestsControllerState) -> Void = { f in
|
||||
|
@ -236,17 +236,18 @@ private final class InviteRequestsSearchContainerInteraction {
|
||||
}
|
||||
|
||||
private enum InviteRequestsSearchEntryId: Hashable {
|
||||
case placeholder(Int)
|
||||
case request(EnginePeer.Id)
|
||||
}
|
||||
|
||||
private final class InviteRequestsSearchEntry: Comparable, Identifiable {
|
||||
let index: Int
|
||||
let request: PeerInvitationImportersState.Importer
|
||||
let request: PeerInvitationImportersState.Importer?
|
||||
let dateTimeFormat: PresentationDateTimeFormat
|
||||
let nameDisplayOrder: PresentationPersonNameOrder
|
||||
let isGroup: Bool
|
||||
|
||||
init(index: Int, request: PeerInvitationImportersState.Importer, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, isGroup: Bool) {
|
||||
init(index: Int, request: PeerInvitationImportersState.Importer?, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, isGroup: Bool) {
|
||||
self.index = index
|
||||
self.request = request
|
||||
self.dateTimeFormat = dateTimeFormat
|
||||
@ -255,7 +256,11 @@ private final class InviteRequestsSearchEntry: Comparable, Identifiable {
|
||||
}
|
||||
|
||||
var stableId: InviteRequestsSearchEntryId {
|
||||
return .request(self.request.peer.peerId)
|
||||
if let request = self.request {
|
||||
return .request(request.peer.peerId)
|
||||
} else {
|
||||
return .placeholder(self.index)
|
||||
}
|
||||
}
|
||||
|
||||
static func ==(lhs: InviteRequestsSearchEntry, rhs: InviteRequestsSearchEntry) -> Bool {
|
||||
@ -268,19 +273,19 @@ private final class InviteRequestsSearchEntry: Comparable, Identifiable {
|
||||
|
||||
func item(context: AccountContext, presentationData: PresentationData, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, interaction: InviteRequestsSearchContainerInteraction) -> ListViewItem {
|
||||
return ItemListInviteRequestItem(context: context, presentationData: ItemListPresentationData(presentationData), dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, importer: self.request, isGroup: self.isGroup, sectionId: 0, style: .plain, tapAction: {
|
||||
if let peer = self.request.peer.peer.flatMap({ EnginePeer($0) }) {
|
||||
if let peer = self.request?.peer.peer.flatMap({ EnginePeer($0) }) {
|
||||
interaction.openPeer(peer)
|
||||
}
|
||||
}, addAction: {
|
||||
if let peer = self.request.peer.peer.flatMap({ EnginePeer($0) }) {
|
||||
if let peer = self.request?.peer.peer.flatMap({ EnginePeer($0) }) {
|
||||
interaction.approveRequest(peer)
|
||||
}
|
||||
}, dismissAction: {
|
||||
if let peer = self.request.peer.peer.flatMap({ EnginePeer($0) }) {
|
||||
if let peer = self.request?.peer.peer.flatMap({ EnginePeer($0) }) {
|
||||
interaction.denyRequest(peer)
|
||||
}
|
||||
}, contextAction: { node, gesture in
|
||||
if let peer = self.request.peer.peer.flatMap({ EnginePeer($0) }) {
|
||||
if let peer = self.request?.peer.peer.flatMap({ EnginePeer($0) }) {
|
||||
interaction.peerContextAction(peer, node, gesture)
|
||||
}
|
||||
})
|
||||
@ -489,12 +494,16 @@ public final class InviteRequestsSearchContainerNode: SearchDisplayControllerCon
|
||||
|
||||
return combineLatest(requestsContext.state, presentationDataPromise.get(), processedPeerIds.get())
|
||||
|> mapToSignal { state, presentationData, processedPeerIds -> Signal<[InviteRequestsSearchEntry]?, NoError> in
|
||||
if !state.hasLoadedOnce {
|
||||
return .complete()
|
||||
}
|
||||
|
||||
var entries: [InviteRequestsSearchEntry] = []
|
||||
var index = 0
|
||||
if !state.hasLoadedOnce {
|
||||
for _ in 0 ..< 2 {
|
||||
entries.append(InviteRequestsSearchEntry(index: index, request: nil, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, isGroup: isGroup))
|
||||
index += 1
|
||||
}
|
||||
return .single(entries)
|
||||
}
|
||||
|
||||
for importer in state.importers {
|
||||
if processedPeerIds.contains(importer.peer.peerId) {
|
||||
continue
|
||||
|
@ -246,10 +246,10 @@ public class ItemListInviteRequestItemNode: ListViewItemNode, ItemListItemNode {
|
||||
self.dismissButton.addTarget(self, action: #selector(self.dismissPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
self.containerNode.shouldBegin = { [weak self] point in
|
||||
guard let strongSelf = self else {
|
||||
guard let strongSelf = self, let item = strongSelf.layoutParams?.0 else {
|
||||
return false
|
||||
}
|
||||
if strongSelf.addButton.frame.contains(point) || strongSelf.dismissButton.frame.contains(point) {
|
||||
if item.importer == nil || strongSelf.addButton.frame.contains(point) || strongSelf.dismissButton.frame.contains(point) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -742,8 +742,9 @@ public class ItemListInviteRequestItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
var shapes: [ShimmerEffectNode.Shape] = []
|
||||
|
||||
let titleLineWidth: CGFloat = 180.0
|
||||
let subtitleLineWidth: CGFloat = 60.0
|
||||
let titleLineWidth: CGFloat = 120.0
|
||||
let subtitleLineWidth: CGFloat = 180.0
|
||||
let dateLineWidth: CGFloat = 35.0
|
||||
let lineDiameter: CGFloat = 10.0
|
||||
|
||||
let iconFrame = strongSelf.avatarNode.frame
|
||||
@ -755,6 +756,15 @@ public class ItemListInviteRequestItemNode: ListViewItemNode, ItemListItemNode {
|
||||
let subtitleFrame = strongSelf.subtitleNode.frame
|
||||
shapes.append(.roundedRectLine(startPoint: CGPoint(x: subtitleFrame.minX, y: subtitleFrame.minY + floor((subtitleFrame.height - lineDiameter) / 2.0)), width: subtitleLineWidth, diameter: lineDiameter))
|
||||
|
||||
let dateFrame = strongSelf.dateNode.frame
|
||||
shapes.append(.roundedRectLine(startPoint: CGPoint(x: dateFrame.maxX - dateLineWidth, y: dateFrame.minY + floor((dateFrame.height - lineDiameter) / 2.0)), width: dateLineWidth, diameter: lineDiameter))
|
||||
|
||||
let addFrame = strongSelf.addButton.frame
|
||||
shapes.append(.roundedRectLine(startPoint: CGPoint(x: addFrame.minX, y: addFrame.minY + floor((addFrame.height - strongSelf.addButton.frame.height) / 2.0)), width: strongSelf.addButton.frame.width, diameter: strongSelf.addButton.frame.height))
|
||||
|
||||
let dismissFrame = strongSelf.dismissButton.frame
|
||||
shapes.append(.roundedRectLine(startPoint: CGPoint(x: dismissFrame.minX, y: dismissFrame.minY + floor((dismissFrame.height - lineDiameter) / 2.0)), width: 60.0, diameter: lineDiameter))
|
||||
|
||||
shimmerNode.update(backgroundColor: item.presentationData.theme.list.itemBlocksBackgroundColor, foregroundColor: item.presentationData.theme.list.mediaPlaceholderColor, shimmeringColor: item.presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), shapes: shapes, size: layout.contentSize)
|
||||
} else if let shimmerNode = strongSelf.placeholderNode {
|
||||
strongSelf.placeholderNode = nil
|
||||
|
@ -955,6 +955,26 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
||||
if case .modal = mode {
|
||||
controller.navigationPresentation = .modal
|
||||
}
|
||||
|
||||
var alreadyReadIds = Set<ItemCollectionId>()
|
||||
controller.visibleEntriesUpdated = { entries in
|
||||
var unreadIds: [ItemCollectionId] = []
|
||||
for entry in entries {
|
||||
if let entry = entry as? InstalledStickerPacksEntry {
|
||||
if case let .trendingPack(_, _, _, info, _, _, _, unread, _) = entry {
|
||||
if unread && !alreadyReadIds.contains(info.id) {
|
||||
unreadIds.append(info.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !unreadIds.isEmpty {
|
||||
alreadyReadIds.formUnion(Set(unreadIds))
|
||||
|
||||
let _ = context.engine.stickers.markFeaturedStickerPacksAsSeenInteractively(ids: unreadIds).start()
|
||||
}
|
||||
}
|
||||
|
||||
controller.setReorderEntry({ (fromIndex: Int, toIndex: Int, entries: [InstalledStickerPacksEntry]) -> Signal<Bool, NoError> in
|
||||
let fromEntry = entries[fromIndex]
|
||||
guard case let .pack(_, _, _, fromPackInfo, _, _, _, _, _, _) = fromEntry else {
|
||||
|
@ -567,16 +567,17 @@ private struct ThemeCarouselThemeItemNodeTransition {
|
||||
let updates: [ListViewUpdateItem]
|
||||
let crossfade: Bool
|
||||
let entries: [ThemeCarouselThemeEntry]
|
||||
let updatePosition: Bool
|
||||
}
|
||||
|
||||
private func preparedTransition(context: AccountContext, action: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, from fromEntries: [ThemeCarouselThemeEntry], to toEntries: [ThemeCarouselThemeEntry], crossfade: Bool) -> ThemeCarouselThemeItemNodeTransition {
|
||||
private func preparedTransition(context: AccountContext, action: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, from fromEntries: [ThemeCarouselThemeEntry], to toEntries: [ThemeCarouselThemeEntry], crossfade: Bool, updatePosition: Bool) -> ThemeCarouselThemeItemNodeTransition {
|
||||
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
||||
|
||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
||||
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, action: action, contextAction: contextAction), directionHint: .Down) }
|
||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, action: action, contextAction: contextAction), directionHint: nil) }
|
||||
|
||||
return ThemeCarouselThemeItemNodeTransition(deletions: deletions, insertions: insertions, updates: updates, crossfade: crossfade, entries: toEntries)
|
||||
return ThemeCarouselThemeItemNodeTransition(deletions: deletions, insertions: insertions, updates: updates, crossfade: crossfade, entries: toEntries, updatePosition: false)
|
||||
}
|
||||
|
||||
private func ensureThemeVisible(listNode: ListView, themeReference: PresentationThemeReference, animated: Bool) -> Bool {
|
||||
@ -612,6 +613,8 @@ class ThemeCarouselThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
private var item: ThemeCarouselThemeItem?
|
||||
private var layoutParams: ListViewItemLayoutParams?
|
||||
|
||||
private var tapping = false
|
||||
|
||||
var tag: ItemListItemTag? {
|
||||
return self.item?.tag
|
||||
}
|
||||
@ -667,7 +670,7 @@ class ThemeCarouselThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
options.insert(.Synchronous)
|
||||
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
if !self.initialized {
|
||||
if !self.initialized || !self.tapping {
|
||||
if let index = transition.entries.firstIndex(where: { entry in
|
||||
return entry.themeReference.index == item.currentTheme.index
|
||||
}) {
|
||||
@ -775,13 +778,17 @@ class ThemeCarouselThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
let action: (PresentationThemeReference) -> Void = { [weak self] themeReference in
|
||||
if let strongSelf = self {
|
||||
strongSelf.tapping = true
|
||||
strongSelf.item?.updatedTheme(themeReference)
|
||||
let _ = ensureThemeVisible(listNode: strongSelf.listNode, themeReference: themeReference, animated: true)
|
||||
Queue.mainQueue().after(0.2) {
|
||||
strongSelf.tapping = false
|
||||
}
|
||||
}
|
||||
}
|
||||
let previousEntries = strongSelf.entries ?? []
|
||||
let crossfade = previousEntries.count != entries.count
|
||||
let transition = preparedTransition(context: item.context, action: action, contextAction: item.contextAction, from: previousEntries, to: entries, crossfade: crossfade)
|
||||
let transition = preparedTransition(context: item.context, action: action, contextAction: item.contextAction, from: previousEntries, to: entries, crossfade: crossfade, updatePosition: false)
|
||||
strongSelf.enqueueTransition(transition)
|
||||
|
||||
strongSelf.entries = entries
|
||||
|
@ -711,10 +711,12 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
|
||||
private var item: ThemeSettingsAccentColorItem?
|
||||
private var layoutParams: ListViewItemLayoutParams?
|
||||
|
||||
private var tapping = false
|
||||
|
||||
var tag: ItemListItemTag? {
|
||||
return self.item?.tag
|
||||
}
|
||||
|
||||
|
||||
init() {
|
||||
self.containerNode = ASDisplayNode()
|
||||
|
||||
@ -761,7 +763,7 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
let options = ListViewDeleteAndInsertOptions()
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
if !self.initialized || transition.updatePosition {
|
||||
if !self.initialized || transition.updatePosition || !self.tapping {
|
||||
if let index = item.colors.firstIndex(where: { $0.index == item.currentColor?.index }) {
|
||||
scrollToItem = ListViewScrollToItem(index: index, position: .bottom(-70.0), animated: false, curve: .Default(duration: 0.0), directionHint: .Down)
|
||||
self.initialized = true
|
||||
@ -912,7 +914,11 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
|
||||
}
|
||||
item.openColorPicker(create)
|
||||
} else {
|
||||
strongSelf.tapping = true
|
||||
item.updated(color)
|
||||
Queue.mainQueue().after(0.2) {
|
||||
strongSelf.tapping = false
|
||||
}
|
||||
}
|
||||
let _ = ensureColorVisible(listNode: strongSelf.listNode, accentColor: color, animated: true)
|
||||
}
|
||||
|
@ -469,6 +469,8 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
var tag: ItemListItemTag? {
|
||||
return self.item?.tag
|
||||
}
|
||||
|
||||
private var tapping = false
|
||||
|
||||
init() {
|
||||
self.containerNode = ASDisplayNode()
|
||||
@ -521,7 +523,7 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
options.insert(.Synchronous)
|
||||
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
if !self.initialized {
|
||||
if !self.initialized || !self.tapping {
|
||||
if let index = transition.entries.firstIndex(where: { entry in
|
||||
return entry.theme.index == item.currentTheme.index
|
||||
}) {
|
||||
@ -650,8 +652,12 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
let action: (PresentationThemeReference) -> Void = { [weak self] themeReference in
|
||||
if let strongSelf = self {
|
||||
strongSelf.tapping = true
|
||||
strongSelf.item?.updatedTheme(themeReference)
|
||||
let _ = ensureThemeVisible(listNode: strongSelf.listNode, themeReference: themeReference, animated: true)
|
||||
Queue.mainQueue().after(0.2) {
|
||||
strongSelf.tapping = false
|
||||
}
|
||||
}
|
||||
}
|
||||
let previousEntries = strongSelf.entries ?? []
|
||||
|
@ -858,6 +858,12 @@ private final class PeerInvitationImportersContextImpl {
|
||||
self.actionDisposables.dispose()
|
||||
}
|
||||
|
||||
func reload() {
|
||||
self.loadedFromCache = true
|
||||
self.populateCache = true
|
||||
self.loadMore()
|
||||
}
|
||||
|
||||
func loadMore() {
|
||||
if self.isLoadingMore {
|
||||
return
|
||||
@ -1070,6 +1076,12 @@ public final class PeerInvitationImportersContext {
|
||||
}
|
||||
}
|
||||
|
||||
public func reload() {
|
||||
self.impl.with { impl in
|
||||
impl.reload()
|
||||
}
|
||||
}
|
||||
|
||||
public func update(_ peerId: EnginePeer.Id, action: UpdateAction) {
|
||||
self.impl.with { impl in
|
||||
impl.update(peerId, action: action)
|
||||
|
Loading…
x
Reference in New Issue
Block a user