Experimental layout

This commit is contained in:
Ali 2023-06-26 19:09:19 +03:00
parent 4a3292df29
commit 7223edc9cd
7 changed files with 58 additions and 35 deletions

View File

@ -2807,7 +2807,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
component: AnyComponent(AvatarStoryIndicatorComponent( component: AnyComponent(AvatarStoryIndicatorComponent(
hasUnseen: storyState.hasUnseen, hasUnseen: storyState.hasUnseen,
hasUnseenCloseFriendsItems: storyState.hasUnseenCloseFriends, hasUnseenCloseFriendsItems: storyState.hasUnseenCloseFriends,
isDarkTheme: item.presentationData.theme.overallDarkAppearance, theme: item.presentationData.theme,
activeLineWidth: 2.0, activeLineWidth: 2.0,
inactiveLineWidth: 1.0 + UIScreenPixel, inactiveLineWidth: 1.0 + UIScreenPixel,
counters: nil counters: nil

View File

@ -1115,7 +1115,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
component: AnyComponent(AvatarStoryIndicatorComponent( component: AnyComponent(AvatarStoryIndicatorComponent(
hasUnseen: storyStats.unseen != 0, hasUnseen: storyStats.unseen != 0,
hasUnseenCloseFriendsItems: storyStats.hasUnseenCloseFriends, hasUnseenCloseFriendsItems: storyStats.hasUnseenCloseFriends,
isDarkTheme: item.presentationData.theme.overallDarkAppearance, theme: item.presentationData.theme,
activeLineWidth: 1.0 + UIScreenPixel, activeLineWidth: 1.0 + UIScreenPixel,
inactiveLineWidth: 1.0 + UIScreenPixel, inactiveLineWidth: 1.0 + UIScreenPixel,
counters: AvatarStoryIndicatorComponent.Counters(totalCount: storyStats.total, unseenCount: storyStats.unseen) counters: AvatarStoryIndicatorComponent.Counters(totalCount: storyStats.total, unseenCount: storyStats.unseen)

View File

@ -214,7 +214,7 @@ public final class ChatAvatarNavigationNode: ASDisplayNode {
component: AnyComponent(AvatarStoryIndicatorComponent( component: AnyComponent(AvatarStoryIndicatorComponent(
hasUnseen: storyData.hasUnseen, hasUnseen: storyData.hasUnseen,
hasUnseenCloseFriendsItems: storyData.hasUnseenCloseFriends, hasUnseenCloseFriendsItems: storyData.hasUnseenCloseFriends,
isDarkTheme: theme.overallDarkAppearance, theme: theme,
activeLineWidth: 1.0, activeLineWidth: 1.0,
inactiveLineWidth: 1.0, inactiveLineWidth: 1.0,
counters: nil counters: nil

View File

@ -17,7 +17,7 @@ public final class AvatarStoryIndicatorComponent: Component {
public let hasUnseen: Bool public let hasUnseen: Bool
public let hasUnseenCloseFriendsItems: Bool public let hasUnseenCloseFriendsItems: Bool
public let isDarkTheme: Bool public let theme: PresentationTheme
public let activeLineWidth: CGFloat public let activeLineWidth: CGFloat
public let inactiveLineWidth: CGFloat public let inactiveLineWidth: CGFloat
public let counters: Counters? public let counters: Counters?
@ -25,14 +25,14 @@ public final class AvatarStoryIndicatorComponent: Component {
public init( public init(
hasUnseen: Bool, hasUnseen: Bool,
hasUnseenCloseFriendsItems: Bool, hasUnseenCloseFriendsItems: Bool,
isDarkTheme: Bool, theme: PresentationTheme,
activeLineWidth: CGFloat, activeLineWidth: CGFloat,
inactiveLineWidth: CGFloat, inactiveLineWidth: CGFloat,
counters: Counters? counters: Counters?
) { ) {
self.hasUnseen = hasUnseen self.hasUnseen = hasUnseen
self.hasUnseenCloseFriendsItems = hasUnseenCloseFriendsItems self.hasUnseenCloseFriendsItems = hasUnseenCloseFriendsItems
self.isDarkTheme = isDarkTheme self.theme = theme
self.activeLineWidth = activeLineWidth self.activeLineWidth = activeLineWidth
self.inactiveLineWidth = inactiveLineWidth self.inactiveLineWidth = inactiveLineWidth
self.counters = counters self.counters = counters
@ -45,7 +45,7 @@ public final class AvatarStoryIndicatorComponent: Component {
if lhs.hasUnseenCloseFriendsItems != rhs.hasUnseenCloseFriendsItems { if lhs.hasUnseenCloseFriendsItems != rhs.hasUnseenCloseFriendsItems {
return false return false
} }
if lhs.isDarkTheme != rhs.isDarkTheme { if lhs.theme !== rhs.theme {
return false return false
} }
if lhs.activeLineWidth != rhs.activeLineWidth { if lhs.activeLineWidth != rhs.activeLineWidth {
@ -112,8 +112,8 @@ public final class AvatarStoryIndicatorComponent: Component {
] ]
} }
if component.isDarkTheme { if component.theme.overallDarkAppearance {
inactiveColors = [UIColor(rgb: 0x48484A).cgColor, UIColor(rgb: 0x48484A).cgColor] inactiveColors = [component.theme.rootController.tabBar.textColor.cgColor, component.theme.rootController.tabBar.textColor.cgColor]
} else { } else {
inactiveColors = [UIColor(rgb: 0xD8D8E1).cgColor, UIColor(rgb: 0xD8D8E1).cgColor] inactiveColors = [UIColor(rgb: 0xD8D8E1).cgColor, UIColor(rgb: 0xD8D8E1).cgColor]
} }

View File

@ -195,7 +195,18 @@ public final class StoryPeerListComponent: Component {
} }
func frame(at index: Int) -> CGRect { func frame(at index: Int) -> CGRect {
return CGRect(origin: CGPoint(x: self.containerInsets.left + (self.itemSize.width + self.itemSpacing) * CGFloat(index), y: self.containerInsets.top), size: self.itemSize) if self.itemCount <= 1 {
return CGRect(origin: CGPoint(x: floor((self.containerSize.width - self.itemSize.width) * 0.5), y: self.containerInsets.top), size: self.itemSize)
} else if self.contentSize.width < self.containerSize.width {
let usableWidth = self.containerSize.width - self.containerInsets.left - self.containerInsets.right
let usableSpacingWidth = usableWidth - self.itemSize.width * CGFloat(self.itemCount)
var spacing = floor(usableSpacingWidth / CGFloat(self.itemCount + 1))
spacing = min(120.0, spacing)
return CGRect(origin: CGPoint(x: self.containerInsets.left + spacing + (self.itemSize.width + spacing) * CGFloat(index), y: self.containerInsets.top), size: self.itemSize)
} else {
return CGRect(origin: CGPoint(x: self.containerInsets.left + (self.itemSize.width + self.itemSpacing) * CGFloat(index), y: self.containerInsets.top), size: self.itemSize)
}
} }
} }
@ -432,11 +443,6 @@ public final class StoryPeerListComponent: Component {
var sideAlphaFraction: CGFloat var sideAlphaFraction: CGFloat
} }
/*let calculateCollapedFraction: (CGFloat) -> CGFloat = { t in
let offset = scrollingRubberBandingOffset(offset: (1.0 - t) * 94.0, bandingStart: 0.0, range: 400.0, coefficient: 0.4)
return 1.0 - max(0.0, min(1.0, offset / 94.0))
}*/
let targetExpandedFraction = component.collapseFraction let targetExpandedFraction = component.collapseFraction
let targetFraction: CGFloat = component.collapseFraction let targetFraction: CGFloat = component.collapseFraction
@ -504,7 +510,7 @@ public final class StoryPeerListComponent: Component {
var rawProgress = CGFloat((timestamp - animationState.startTime) / animationState.duration) var rawProgress = CGFloat((timestamp - animationState.startTime) / animationState.duration)
rawProgress = max(0.0, min(1.0, rawProgress)) rawProgress = max(0.0, min(1.0, rawProgress))
if !animationState.fromIsUnlocked && animationState.bounce { if !animationState.fromIsUnlocked && animationState.bounce && itemLayout.itemCount > 3 {
expandBoundsFraction = animationState.interpolatedFraction(at: timestamp, effectiveFromFraction: 1.0, toFraction: 0.0) expandBoundsFraction = animationState.interpolatedFraction(at: timestamp, effectiveFromFraction: 1.0, toFraction: 0.0)
} else { } else {
expandBoundsFraction = 0.0 expandBoundsFraction = 0.0
@ -520,15 +526,6 @@ public final class StoryPeerListComponent: Component {
expandBoundsFraction = 0.0 expandBoundsFraction = 0.0
} }
let defaultCollapsedTitleOffset = floor((itemLayout.containerSize.width - component.titleContentWidth) * 0.5)
let targetCollapsedTitleOffset: CGFloat = collapsedContentOrigin + collapsedContentWidth + titleContentSpacing
let collapsedTitleOffset = targetCollapsedTitleOffset - defaultCollapsedTitleOffset
let titleMinContentOffset: CGFloat = collapsedTitleOffset.interpolate(to: collapsedTitleOffset + 12.0, amount: collapsedState.minFraction)
let titleContentOffset: CGFloat = titleMinContentOffset.interpolate(to: 0.0 as CGFloat, amount: collapsedState.maxFraction)
component.updateTitleContentOffset(titleContentOffset, transition)
self.currentFraction = collapsedState.globalFraction self.currentFraction = collapsedState.globalFraction
component.externalState.collapsedWidth = collapsedContentWidth component.externalState.collapsedWidth = collapsedContentWidth
@ -556,12 +553,14 @@ public final class StoryPeerListComponent: Component {
var collapsedMaxItemFrame = collapsedItemFrame var collapsedMaxItemFrame = collapsedItemFrame
var collapseDistance: CGFloat = CGFloat(i - collapseStartIndex) / CGFloat(collapseEndIndex - collapseStartIndex) if itemLayout.itemCount > 1 {
collapseDistance = max(0.0, min(1.0, collapseDistance)) var collapseDistance: CGFloat = CGFloat(i - collapseStartIndex) / CGFloat(collapseEndIndex - collapseStartIndex)
collapsedMaxItemFrame.origin.x -= collapsedState.minFraction * 4.0 collapseDistance = max(0.0, min(1.0, collapseDistance))
collapsedMaxItemFrame.origin.x += collapseDistance * 20.0 collapsedMaxItemFrame.origin.x -= collapsedState.minFraction * 4.0
collapsedMaxItemFrame.origin.y += collapseDistance * 20.0 collapsedMaxItemFrame.origin.x += collapseDistance * 20.0
collapsedMaxItemFrame.origin.y += collapsedState.minFraction * 10.0 collapsedMaxItemFrame.origin.y += collapseDistance * 20.0
collapsedMaxItemFrame.origin.y += collapsedState.minFraction * 10.0
}
let minimizedItemScale: CGFloat = 24.0 / 52.0 let minimizedItemScale: CGFloat = 24.0 / 52.0
let minimizedMaxItemScale: CGFloat = (24.0 + 4.0) / 52.0 let minimizedMaxItemScale: CGFloat = (24.0 + 4.0) / 52.0
@ -654,6 +653,11 @@ public final class StoryPeerListComponent: Component {
var itemAlpha: CGFloat = 1.0 var itemAlpha: CGFloat = 1.0
var isCollapsable: Bool = false var isCollapsable: Bool = false
var itemScale = measuredItem.itemScale
if itemLayout.itemCount == 1 {
let singleScaleFactor = min(1.0, collapsedState.minFraction + collapsedState.maxFraction)
itemScale = 0.001 * (1.0 - singleScaleFactor) + itemScale * singleScaleFactor
}
if i >= collapseStartIndex && i <= collapseEndIndex { if i >= collapseStartIndex && i <= collapseEndIndex {
isCollapsable = true isCollapsable = true
@ -665,7 +669,11 @@ public final class StoryPeerListComponent: Component {
rightItemFrame = calculateItem(i + 1).itemFrame rightItemFrame = calculateItem(i + 1).itemFrame
} }
} else { } else {
itemAlpha = collapsedState.sideAlphaFraction if itemLayout.itemCount == 1 {
itemAlpha = min(1.0, (collapsedState.minFraction + collapsedState.maxFraction) * 4.0)
} else {
itemAlpha = collapsedState.sideAlphaFraction
}
} }
var leftNeighborDistance: CGPoint? var leftNeighborDistance: CGPoint?
@ -690,7 +698,7 @@ public final class StoryPeerListComponent: Component {
hasItems: hasItems, hasItems: hasItems,
ringAnimation: itemRingAnimation, ringAnimation: itemRingAnimation,
collapseFraction: isReallyVisible ? (1.0 - collapsedState.maxFraction) : 0.0, collapseFraction: isReallyVisible ? (1.0 - collapsedState.maxFraction) : 0.0,
scale: measuredItem.itemScale, scale: itemScale,
collapsedWidth: collapsedItemWidth, collapsedWidth: collapsedItemWidth,
expandedAlphaFraction: collapsedState.sideAlphaFraction, expandedAlphaFraction: collapsedState.sideAlphaFraction,
leftNeighborDistance: leftNeighborDistance, leftNeighborDistance: leftNeighborDistance,
@ -751,6 +759,21 @@ public final class StoryPeerListComponent: Component {
} }
transition.setFrame(view: self.collapsedButton, frame: CGRect(origin: CGPoint(x: collapsedContentOrigin - 4.0, y: 6.0 - 59.0), size: CGSize(width: collapsedContentWidth + 4.0, height: 44.0))) transition.setFrame(view: self.collapsedButton, frame: CGRect(origin: CGPoint(x: collapsedContentOrigin - 4.0, y: 6.0 - 59.0), size: CGSize(width: collapsedContentWidth + 4.0, height: 44.0)))
let defaultCollapsedTitleOffset = floor((itemLayout.containerSize.width - component.titleContentWidth) * 0.5)
var targetCollapsedTitleOffset: CGFloat = collapsedContentOrigin + collapsedContentWidth + titleContentSpacing
if itemLayout.itemCount == 1 && collapsedContentWidth <= 0.1 {
let singleScaleFactor = min(1.0, collapsedState.minFraction)
targetCollapsedTitleOffset += singleScaleFactor * calculateItem(0).itemScale * (itemLayout.itemSize.width + 4.0)
}
let collapsedTitleOffset = targetCollapsedTitleOffset - defaultCollapsedTitleOffset
let titleMinContentOffset: CGFloat = collapsedTitleOffset.interpolate(to: collapsedTitleOffset + 12.0, amount: collapsedState.minFraction)
let titleContentOffset: CGFloat = titleMinContentOffset.interpolate(to: 0.0 as CGFloat, amount: collapsedState.maxFraction)
component.updateTitleContentOffset(titleContentOffset, transition)
} }
override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

View File

@ -665,7 +665,7 @@ public final class StoryPeerListItemComponent: Component {
} }
} else { } else {
if component.theme.overallDarkAppearance { if component.theme.overallDarkAppearance {
colors = [UIColor(rgb: 0x48484A).cgColor, UIColor(rgb: 0x48484A).cgColor] colors = [component.theme.rootController.tabBar.textColor.cgColor, component.theme.rootController.tabBar.textColor.cgColor]
} else { } else {
colors = [UIColor(rgb: 0xD8D8E1).cgColor, UIColor(rgb: 0xD8D8E1).cgColor] colors = [UIColor(rgb: 0xD8D8E1).cgColor, UIColor(rgb: 0xD8D8E1).cgColor]
} }

View File

@ -469,7 +469,7 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
component: AnyComponent(AvatarStoryIndicatorComponent( component: AnyComponent(AvatarStoryIndicatorComponent(
hasUnseen: storyData.hasUnseen, hasUnseen: storyData.hasUnseen,
hasUnseenCloseFriendsItems: storyData.hasUnseenCloseFriends, hasUnseenCloseFriendsItems: storyData.hasUnseenCloseFriends,
isDarkTheme: theme.overallDarkAppearance, theme: theme,
activeLineWidth: 3.0, activeLineWidth: 3.0,
inactiveLineWidth: 2.0, inactiveLineWidth: 2.0,
counters: nil counters: nil