Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2023-07-07 13:32:25 +02:00
commit 965d3fe392
6 changed files with 57 additions and 25 deletions

View File

@ -1967,17 +1967,29 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
self.rawStoryArchiveSubscriptions = rawStoryArchiveSubscriptions self.rawStoryArchiveSubscriptions = rawStoryArchiveSubscriptions
let hasUnseenArchive: Bool? let archiveStoryState: ChatListNodeState.StoryState?
if rawStoryArchiveSubscriptions.items.isEmpty { if rawStoryArchiveSubscriptions.items.isEmpty {
hasUnseenArchive = nil archiveStoryState = nil
} else { } else {
hasUnseenArchive = rawStoryArchiveSubscriptions.items.contains(where: { $0.hasUnseen }) var unseenCount = 0
for item in rawStoryArchiveSubscriptions.items {
if item.hasUnseen {
unseenCount += 1
}
}
archiveStoryState = ChatListNodeState.StoryState(
stats: EngineChatList.StoryStats(
totalCount: rawStoryArchiveSubscriptions.items.count,
unseenCount: unseenCount
),
hasUnseenCloseFriends: rawStoryArchiveSubscriptions.items.contains(where: { $0.hasUnseenCloseFriends })
)
} }
self.chatListDisplayNode.mainContainerNode.currentItemNode.updateState { chatListState in self.chatListDisplayNode.mainContainerNode.currentItemNode.updateState { chatListState in
var chatListState = chatListState var chatListState = chatListState
chatListState.hasUnseenArchiveStories = hasUnseenArchive chatListState.archiveStoryState = archiveStoryState
return chatListState return chatListState
} }

View File

@ -251,7 +251,7 @@ public struct ChatListNodeState: Equatable {
public var foundPeers: [(EnginePeer, EnginePeer?)] public var foundPeers: [(EnginePeer, EnginePeer?)]
public var selectedPeerMap: [EnginePeer.Id: EnginePeer] public var selectedPeerMap: [EnginePeer.Id: EnginePeer]
public var selectedThreadIds: Set<Int64> public var selectedThreadIds: Set<Int64>
public var hasUnseenArchiveStories: Bool? public var archiveStoryState: StoryState?
public init( public init(
presentationData: ChatListPresentationData, presentationData: ChatListPresentationData,
@ -267,7 +267,7 @@ public struct ChatListNodeState: Equatable {
hiddenItemShouldBeTemporaryRevealed: Bool, hiddenItemShouldBeTemporaryRevealed: Bool,
hiddenPsaPeerId: EnginePeer.Id?, hiddenPsaPeerId: EnginePeer.Id?,
selectedThreadIds: Set<Int64>, selectedThreadIds: Set<Int64>,
hasUnseenArchiveStories: Bool? archiveStoryState: StoryState?
) { ) {
self.presentationData = presentationData self.presentationData = presentationData
self.editing = editing self.editing = editing
@ -282,7 +282,7 @@ public struct ChatListNodeState: Equatable {
self.hiddenItemShouldBeTemporaryRevealed = hiddenItemShouldBeTemporaryRevealed self.hiddenItemShouldBeTemporaryRevealed = hiddenItemShouldBeTemporaryRevealed
self.hiddenPsaPeerId = hiddenPsaPeerId self.hiddenPsaPeerId = hiddenPsaPeerId
self.selectedThreadIds = selectedThreadIds self.selectedThreadIds = selectedThreadIds
self.hasUnseenArchiveStories = hasUnseenArchiveStories self.archiveStoryState = archiveStoryState
} }
public static func ==(lhs: ChatListNodeState, rhs: ChatListNodeState) -> Bool { public static func ==(lhs: ChatListNodeState, rhs: ChatListNodeState) -> Bool {
@ -325,7 +325,7 @@ public struct ChatListNodeState: Equatable {
if lhs.selectedThreadIds != rhs.selectedThreadIds { if lhs.selectedThreadIds != rhs.selectedThreadIds {
return false return false
} }
if lhs.hasUnseenArchiveStories != rhs.hasUnseenArchiveStories { if lhs.archiveStoryState != rhs.archiveStoryState {
return false return false
} }
return true return true
@ -1251,7 +1251,7 @@ public final class ChatListNode: ListView {
isSelecting = true isSelecting = true
} }
self.currentState = ChatListNodeState(presentationData: ChatListPresentationData(theme: theme, fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, disableAnimations: disableAnimations), editing: isSelecting, peerIdWithRevealedOptions: nil, selectedPeerIds: Set(), foundPeers: [], selectedPeerMap: [:], selectedAdditionalCategoryIds: Set(), peerInputActivities: nil, pendingRemovalItemIds: Set(), pendingClearHistoryPeerIds: Set(), hiddenItemShouldBeTemporaryRevealed: false, hiddenPsaPeerId: nil, selectedThreadIds: Set(), hasUnseenArchiveStories: nil) self.currentState = ChatListNodeState(presentationData: ChatListPresentationData(theme: theme, fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, disableAnimations: disableAnimations), editing: isSelecting, peerIdWithRevealedOptions: nil, selectedPeerIds: Set(), foundPeers: [], selectedPeerMap: [:], selectedAdditionalCategoryIds: Set(), peerInputActivities: nil, pendingRemovalItemIds: Set(), pendingClearHistoryPeerIds: Set(), hiddenItemShouldBeTemporaryRevealed: false, hiddenPsaPeerId: nil, selectedThreadIds: Set(), archiveStoryState: nil)
self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true) self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true)
self.theme = theme self.theme = theme

View File

@ -834,13 +834,8 @@ func chatListNodeEntriesForView(view: EngineChatList, state: ChatListNodeState,
for groupReference in view.groupItems { for groupReference in view.groupItems {
let messageIndex = EngineMessage.Index(id: EngineMessage.Id(peerId: EnginePeer.Id(0), namespace: 0, id: 0), timestamp: 1) let messageIndex = EngineMessage.Index(id: EngineMessage.Id(peerId: EnginePeer.Id(0), namespace: 0, id: 0), timestamp: 1)
var mappedStoryState: ChatListNodeState.StoryState? var mappedStoryState: ChatListNodeState.StoryState?
if let hasUnseenArchiveStories = state.hasUnseenArchiveStories { if let archiveStoryState = state.archiveStoryState {
mappedStoryState = ChatListNodeState.StoryState( mappedStoryState = archiveStoryState
stats: EngineChatList.StoryStats(
totalCount: 1, unseenCount: hasUnseenArchiveStories ? 1 : 0
),
hasUnseenCloseFriends: false
)
} }
result.append(.GroupReferenceEntry(ChatListNodeEntry.GroupReferenceEntryData( result.append(.GroupReferenceEntry(ChatListNodeEntry.GroupReferenceEntryData(
index: .chatList(EngineChatList.Item.Index.ChatList(pinningIndex: pinningIndex, messageIndex: messageIndex)), index: .chatList(EngineChatList.Item.Index.ChatList(pinningIndex: pinningIndex, messageIndex: messageIndex)),

View File

@ -414,6 +414,18 @@ public final class ChatListNavigationBar: Component {
self.addSubview(headerContentView) self.addSubview(headerContentView)
} }
transition.setFrameWithAdditivePosition(view: headerContentView, frame: headerContentFrame) transition.setFrameWithAdditivePosition(view: headerContentView, frame: headerContentFrame)
if component.isSearchActive != (headerContentView.alpha == 0.0) {
headerContentView.alpha = component.isSearchActive ? 0.0 : 1.0
if !transition.animation.isImmediate {
if component.isSearchActive {
headerContentView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.14)
} else {
headerContentView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
}
}
}
} }
if component.tabsNode !== self.tabsNode { if component.tabsNode !== self.tabsNode {

View File

@ -889,7 +889,7 @@ public final class StoryPeerListComponent: Component {
rightItemFrame = calculateItem(i + 1).itemFrame rightItemFrame = calculateItem(i + 1).itemFrame
} }
itemAlpha = collapsedState.sideAlphaFraction * 1.0 + (1.0 - collapsedState.sideAlphaFraction) * (1.0 - collapsedState.activityFraction) itemAlpha = (collapsedState.sideAlphaFraction * 1.0 + (1.0 - collapsedState.sideAlphaFraction) * (1.0 - collapsedState.activityFraction)) * collapsedState.sideAlphaFraction
} else { } else {
if itemLayout.itemCount == 1 { if itemLayout.itemCount == 1 {
itemAlpha = min(1.0, (collapsedState.minFraction + collapsedState.maxFraction) * 4.0) itemAlpha = min(1.0, (collapsedState.minFraction + collapsedState.maxFraction) * 4.0)

View File

@ -62,6 +62,20 @@ private func calculateMergingCircleShape(center: CGPoint, leftCenter: CGPoint?,
let path = CGMutablePath() let path = CGMutablePath()
let segmentCount = max(totalCount, 1)
if isSeen {
if unseenCount < totalCount {
} else {
return path
}
} else {
if unseenCount != 0 {
} else {
return path
}
}
if let leftAngles, let rightAngles { if let leftAngles, let rightAngles {
path.addArc(center: center, radius: radius, startAngle: leftAngles.point1Angle, endAngle: rightAngles.point2Angle, clockwise: true) path.addArc(center: center, radius: radius, startAngle: leftAngles.point1Angle, endAngle: rightAngles.point2Angle, clockwise: true)
@ -70,14 +84,13 @@ private func calculateMergingCircleShape(center: CGPoint, leftCenter: CGPoint?,
} else if let angles = leftAngles ?? rightAngles { } else if let angles = leftAngles ?? rightAngles {
path.addArc(center: center, radius: radius, startAngle: angles.point1Angle, endAngle: angles.point2Angle, clockwise: true) path.addArc(center: center, radius: radius, startAngle: angles.point1Angle, endAngle: angles.point2Angle, clockwise: true)
} else { } else {
let segmentCount = max(totalCount, 1)
if segmentCount == 1 { if segmentCount == 1 {
if unseenCount != 0 { if isSeen {
if !isSeen { if unseenCount == 0 {
path.addEllipse(in: CGRect(origin: CGPoint(x: center.x - radius, y: center.y - radius), size: CGSize(width: radius * 2.0, height: radius * 2.0))) path.addEllipse(in: CGRect(origin: CGPoint(x: center.x - radius, y: center.y - radius), size: CGSize(width: radius * 2.0, height: radius * 2.0)))
} }
} else { } else {
if isSeen { if unseenCount != 0 {
path.addEllipse(in: CGRect(origin: CGPoint(x: center.x - radius, y: center.y - radius), size: CGSize(width: radius * 2.0, height: radius * 2.0))) path.addEllipse(in: CGRect(origin: CGPoint(x: center.x - radius, y: center.y - radius), size: CGSize(width: radius * 2.0, height: radius * 2.0)))
} }
} }
@ -610,12 +623,12 @@ public final class StoryPeerListItemComponent: Component {
transition.setFrame(view: avatarNode.view, frame: CGRect(origin: CGPoint(), size: avatarFrame.size)) transition.setFrame(view: avatarNode.view, frame: CGRect(origin: CGPoint(), size: avatarFrame.size))
transition.setFrame(view: self.avatarBackgroundView, frame: CGRect(origin: CGPoint(), size: avatarFrame.size).insetBy(dx: -3.0 - UIScreenPixel * 2.0, dy: -3.0 - UIScreenPixel * 2.0)) transition.setFrame(view: self.avatarBackgroundView, frame: CGRect(origin: CGPoint(), size: avatarFrame.size).insetBy(dx: -3.0 - UIScreenPixel * 2.0, dy: -3.0 - UIScreenPixel * 2.0))
let indicatorFrame = avatarFrame.insetBy(dx: -6.0, dy: -6.0) let indicatorFrame = avatarFrame.insetBy(dx: -8.0, dy: -8.0)
let baseLineUnseenWidth: CGFloat = 2.0 let baseLineUnseenWidth: CGFloat = 2.0
let baseLineSeenWidth: CGFloat = 1.0 + UIScreenPixel let baseLineSeenWidth: CGFloat = 1.0 + UIScreenPixel
let minimizedLineWidth: CGFloat = 3.0 let minimizedLineWidth: CGFloat = 4.3
let indicatorLineSeenWidth: CGFloat = baseLineSeenWidth * component.scale + minimizedLineWidth * (1.0 - component.scale) let indicatorLineSeenWidth: CGFloat = baseLineSeenWidth * component.scale + minimizedLineWidth * (1.0 - component.scale)
let indicatorLineUnseenWidth: CGFloat = baseLineUnseenWidth * component.scale + minimizedLineWidth * (1.0 - component.scale) let indicatorLineUnseenWidth: CGFloat = baseLineUnseenWidth * component.scale + minimizedLineWidth * (1.0 - component.scale)
@ -691,7 +704,7 @@ public final class StoryPeerListItemComponent: Component {
self.avatarBackgroundView.isHidden = component.ringAnimation != nil || self.indicatorColorSeenLayer.isHidden self.avatarBackgroundView.isHidden = component.ringAnimation != nil || self.indicatorColorSeenLayer.isHidden
let baseRadius: CGFloat = 30.0 let baseRadius: CGFloat = 30.0
let collapsedRadius: CGFloat = 32.0 let collapsedRadius: CGFloat = 35.0
let indicatorRadius: CGFloat = baseRadius * component.scale + collapsedRadius * (1.0 - component.scale) let indicatorRadius: CGFloat = baseRadius * component.scale + collapsedRadius * (1.0 - component.scale)
self.indicatorShapeSeenLayer.lineWidth = indicatorLineSeenWidth self.indicatorShapeSeenLayer.lineWidth = indicatorLineSeenWidth
@ -748,7 +761,7 @@ public final class StoryPeerListItemComponent: Component {
let cutoutSize: CGFloat = 18.0 + UIScreenPixel * 2.0 let cutoutSize: CGFloat = 18.0 + UIScreenPixel * 2.0
avatarPath.addEllipse(in: CGRect(origin: CGPoint(x: avatarSize.width - cutoutSize + UIScreenPixel, y: avatarSize.height - 1.0 - cutoutSize + UIScreenPixel), size: CGSize(width: cutoutSize, height: cutoutSize))) avatarPath.addEllipse(in: CGRect(origin: CGPoint(x: avatarSize.width - cutoutSize + UIScreenPixel, y: avatarSize.height - 1.0 - cutoutSize + UIScreenPixel), size: CGSize(width: cutoutSize, height: cutoutSize)))
} else if let mappedLeftCenter { } else if let mappedLeftCenter {
avatarPath.addEllipse(in: CGRect(origin: CGPoint(), size: avatarSize).insetBy(dx: -indicatorLineSeenWidth, dy: -indicatorLineSeenWidth).offsetBy(dx: -abs(indicatorCenter.x - mappedLeftCenter.x), dy: -abs(indicatorCenter.y - mappedLeftCenter.y))) avatarPath.addEllipse(in: CGRect(origin: CGPoint(), size: avatarSize).insetBy(dx: -indicatorLineSeenWidth * 1.4, dy: -indicatorLineSeenWidth * 1.4).offsetBy(dx: -abs(indicatorCenter.x - mappedLeftCenter.x), dy: -abs(indicatorCenter.y - mappedLeftCenter.y)))
} }
Transition.immediate.setShapeLayerPath(layer: self.avatarShapeLayer, path: avatarPath) Transition.immediate.setShapeLayerPath(layer: self.avatarShapeLayer, path: avatarPath)