Various Fixes

This commit is contained in:
Ilya Laktyushin 2021-10-28 17:49:57 +04:00
parent 9f8bd71105
commit 6490f0ba06
8 changed files with 96 additions and 22 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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)
}

View File

@ -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 ?? []

View File

@ -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)