mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Channel story upload UI
This commit is contained in:
parent
f4ed424c7e
commit
520ba51f15
@ -867,15 +867,18 @@ public final class AvatarNode: ASDisplayNode {
|
||||
public var totalCount: Int
|
||||
public var unseenCount: Int
|
||||
public var hasUnseenCloseFriendsItems: Bool
|
||||
public var progress: Float?
|
||||
|
||||
public init(
|
||||
totalCount: Int,
|
||||
unseenCount: Int,
|
||||
hasUnseenCloseFriendsItems: Bool
|
||||
hasUnseenCloseFriendsItems: Bool,
|
||||
progress: Float? = nil
|
||||
) {
|
||||
self.totalCount = totalCount
|
||||
self.unseenCount = unseenCount
|
||||
self.hasUnseenCloseFriendsItems = hasUnseenCloseFriendsItems
|
||||
self.progress = progress
|
||||
}
|
||||
}
|
||||
|
||||
@ -1135,6 +1138,12 @@ public final class AvatarNode: ASDisplayNode {
|
||||
storyIndicator = ComponentView()
|
||||
self.storyIndicator = storyIndicator
|
||||
}
|
||||
var mappedProgress: AvatarStoryIndicatorComponent.Progress?
|
||||
if let value = storyStats.progress {
|
||||
mappedProgress = .definite(value)
|
||||
} else if !self.loadingStatuses.isEmpty {
|
||||
mappedProgress = .indefinite
|
||||
}
|
||||
let _ = storyIndicator.update(
|
||||
transition: indicatorTransition,
|
||||
component: AnyComponent(AvatarStoryIndicatorComponent(
|
||||
@ -1151,7 +1160,7 @@ public final class AvatarNode: ASDisplayNode {
|
||||
totalCount: storyStats.totalCount,
|
||||
unseenCount: storyStats.unseenCount
|
||||
),
|
||||
displayProgress: !self.loadingStatuses.isEmpty
|
||||
progress: mappedProgress
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: indicatorSize
|
||||
|
@ -2724,6 +2724,34 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
}
|
||||
destinationView.isHidden = true
|
||||
|
||||
if let destinationTransitionView {
|
||||
destinationTransitionView.layer.anchorPoint = CGPoint(x: 0.0, y: 0.5)
|
||||
let snapshotScale = self.previewContainerView.bounds.width / destinationTransitionView.frame.width
|
||||
destinationTransitionView.center = CGPoint(x: 0.0, y: self.previewContainerView.bounds.height / 2.0)
|
||||
destinationTransitionView.layer.transform = CATransform3DMakeScale(snapshotScale, snapshotScale, 1.0)
|
||||
|
||||
destinationTransitionView.alpha = 0.0
|
||||
Queue.mainQueue().after(0.15) {
|
||||
destinationTransitionView.alpha = 1.0
|
||||
destinationTransitionView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
||||
}
|
||||
|
||||
self.previewContainerView.addSubview(destinationTransitionView)
|
||||
destinationSnapshotView = destinationTransitionView
|
||||
}
|
||||
} else if let destinationNode = destinationView.asyncdisplaykit_node as? AvatarNode.ContentNode {
|
||||
let destinationTransitionView: UIView?
|
||||
if let image = destinationNode.unroundedImage {
|
||||
destinationTransitionView = UIImageView(image: image)
|
||||
destinationTransitionView?.bounds = destinationNode.bounds
|
||||
destinationTransitionView?.layer.cornerRadius = destinationNode.bounds.width / 2.0
|
||||
} else if let snapshotView = destinationView.snapshotView(afterScreenUpdates: false) {
|
||||
destinationTransitionView = snapshotView
|
||||
} else {
|
||||
destinationTransitionView = nil
|
||||
}
|
||||
destinationView.isHidden = true
|
||||
|
||||
if let destinationTransitionView {
|
||||
destinationTransitionView.layer.anchorPoint = CGPoint(x: 0.0, y: 0.5)
|
||||
let snapshotScale = self.previewContainerView.bounds.width / destinationTransitionView.frame.width
|
||||
|
@ -38,13 +38,18 @@ public final class AvatarStoryIndicatorComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
public enum Progress: Equatable {
|
||||
case indefinite
|
||||
case definite(Float)
|
||||
}
|
||||
|
||||
public let hasUnseen: Bool
|
||||
public let hasUnseenCloseFriendsItems: Bool
|
||||
public let colors: Colors
|
||||
public let activeLineWidth: CGFloat
|
||||
public let inactiveLineWidth: CGFloat
|
||||
public let counters: Counters?
|
||||
public let displayProgress: Bool
|
||||
public let progress: Progress?
|
||||
|
||||
public init(
|
||||
hasUnseen: Bool,
|
||||
@ -53,7 +58,7 @@ public final class AvatarStoryIndicatorComponent: Component {
|
||||
activeLineWidth: CGFloat,
|
||||
inactiveLineWidth: CGFloat,
|
||||
counters: Counters?,
|
||||
displayProgress: Bool = false
|
||||
progress: Progress? = nil
|
||||
) {
|
||||
self.hasUnseen = hasUnseen
|
||||
self.hasUnseenCloseFriendsItems = hasUnseenCloseFriendsItems
|
||||
@ -61,7 +66,7 @@ public final class AvatarStoryIndicatorComponent: Component {
|
||||
self.activeLineWidth = activeLineWidth
|
||||
self.inactiveLineWidth = inactiveLineWidth
|
||||
self.counters = counters
|
||||
self.displayProgress = displayProgress
|
||||
self.progress = progress
|
||||
}
|
||||
|
||||
public static func ==(lhs: AvatarStoryIndicatorComponent, rhs: AvatarStoryIndicatorComponent) -> Bool {
|
||||
@ -83,7 +88,7 @@ public final class AvatarStoryIndicatorComponent: Component {
|
||||
if lhs.counters != rhs.counters {
|
||||
return false
|
||||
}
|
||||
if lhs.displayProgress != rhs.displayProgress {
|
||||
if lhs.progress != rhs.progress {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -364,7 +369,7 @@ public final class AvatarStoryIndicatorComponent: Component {
|
||||
transition.setFrame(view: self.indicatorView, frame: indicatorFrame)
|
||||
|
||||
let progressTransition = Transition(animation: .curve(duration: 0.3, curve: .easeInOut))
|
||||
if component.displayProgress {
|
||||
if let progress = component.progress {
|
||||
let colorLayer: SimpleGradientLayer
|
||||
if let current = self.colorLayer {
|
||||
colorLayer = current
|
||||
@ -379,13 +384,12 @@ public final class AvatarStoryIndicatorComponent: Component {
|
||||
progressTransition.setAlpha(layer: colorLayer, alpha: 1.0)
|
||||
|
||||
let colors: [CGColor] = activeColors
|
||||
/*if component.hasUnseen {
|
||||
colors = activeColors
|
||||
let lineWidth: CGFloat
|
||||
if case .definite = progress {
|
||||
lineWidth = component.activeLineWidth
|
||||
} else {
|
||||
colors = inactiveColors
|
||||
}*/
|
||||
|
||||
let lineWidth: CGFloat = component.hasUnseen ? component.activeLineWidth : component.inactiveLineWidth
|
||||
lineWidth = component.hasUnseen ? component.activeLineWidth : component.inactiveLineWidth
|
||||
}
|
||||
|
||||
colorLayer.colors = colors
|
||||
colorLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
|
||||
@ -402,7 +406,16 @@ public final class AvatarStoryIndicatorComponent: Component {
|
||||
|
||||
colorLayer.frame = indicatorFrame
|
||||
progressLayer.frame = CGRect(origin: CGPoint(), size: indicatorFrame.size)
|
||||
progressLayer.update(size: indicatorFrame.size, radius: radius, lineWidth: lineWidth, value: .indefinite, transition: .immediate)
|
||||
|
||||
let mappedProgress: ProgressLayer.Value
|
||||
switch progress {
|
||||
case .indefinite:
|
||||
mappedProgress = .indefinite
|
||||
case let .definite(value):
|
||||
mappedProgress = .progress(value)
|
||||
}
|
||||
|
||||
progressLayer.update(size: indicatorFrame.size, radius: radius, lineWidth: lineWidth, value: mappedProgress, transition: .immediate)
|
||||
} else {
|
||||
progressTransition.setAlpha(view: self.indicatorView, alpha: 1.0)
|
||||
|
||||
|
@ -424,6 +424,7 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
private let playbackStartDisposable = MetaDisposable()
|
||||
|
||||
var storyData: (totalCount: Int, unseenCount: Int, hasUnseenCloseFriends: Bool)?
|
||||
var storyProgress: Float?
|
||||
|
||||
init(context: AccountContext) {
|
||||
self.context = context
|
||||
@ -462,13 +463,23 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
theme.list.controlSecondaryColor,
|
||||
theme.list.controlSecondaryColor
|
||||
]
|
||||
self.avatarNode.setStoryStats(storyStats: self.storyData.flatMap { storyData in
|
||||
return AvatarNode.StoryStats(
|
||||
var storyStats: AvatarNode.StoryStats?
|
||||
if let storyData = self.storyData {
|
||||
storyStats = AvatarNode.StoryStats(
|
||||
totalCount: storyData.totalCount,
|
||||
unseenCount: storyData.unseenCount,
|
||||
hasUnseenCloseFriendsItems: storyData.hasUnseenCloseFriends
|
||||
hasUnseenCloseFriendsItems: storyData.hasUnseenCloseFriends,
|
||||
progress: self.storyProgress
|
||||
)
|
||||
}, presentationParams: AvatarNode.StoryPresentationParams(
|
||||
} else if let storyProgress = self.storyProgress {
|
||||
storyStats = AvatarNode.StoryStats(
|
||||
totalCount: 1,
|
||||
unseenCount: 1,
|
||||
hasUnseenCloseFriendsItems: false,
|
||||
progress: storyProgress
|
||||
)
|
||||
}
|
||||
self.avatarNode.setStoryStats(storyStats: storyStats, presentationParams: AvatarNode.StoryPresentationParams(
|
||||
colors: colors,
|
||||
lineWidth: 3.0,
|
||||
inactiveLineWidth: 1.5
|
||||
|
@ -2169,6 +2169,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
private var expiringStoryList: PeerExpiringStoryListContext?
|
||||
private var expiringStoryListState: PeerExpiringStoryListContext.State?
|
||||
private var expiringStoryListDisposable: Disposable?
|
||||
private var storyUploadProgressDisposable: Disposable?
|
||||
private var postingAvailabilityDisposable: Disposable?
|
||||
|
||||
private let storiesReady = ValuePromise<Bool>(true, ignoreRepeated: true)
|
||||
@ -3936,6 +3937,24 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
self.storiesReady.set(false)
|
||||
let expiringStoryList = PeerExpiringStoryListContext(account: context.account, peerId: peerId)
|
||||
self.expiringStoryList = expiringStoryList
|
||||
self.storyUploadProgressDisposable = (context.engine.messages.allStoriesUploadProgress()
|
||||
|> map { value -> Float? in
|
||||
return value[peerId]
|
||||
}
|
||||
|> distinctUntilChanged).start(next: { [weak self] value in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
var mappedValue = value
|
||||
if let value {
|
||||
mappedValue = max(0.027, value)
|
||||
}
|
||||
|
||||
if self.headerNode.avatarListNode.avatarContainerNode.storyProgress != mappedValue {
|
||||
self.headerNode.avatarListNode.avatarContainerNode.storyProgress = mappedValue
|
||||
self.headerNode.avatarListNode.avatarContainerNode.updateStoryView(transition: .immediate, theme: self.presentationData.theme)
|
||||
}
|
||||
})
|
||||
self.expiringStoryListDisposable = (combineLatest(queue: .mainQueue(),
|
||||
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)),
|
||||
expiringStoryList.state
|
||||
@ -8269,7 +8288,14 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
private func openPostStory() {
|
||||
self.postingAvailabilityDisposable?.dispose()
|
||||
|
||||
self.postingAvailabilityDisposable = (self.context.engine.messages.checkStoriesUploadAvailability(target: .peer(self.peerId))
|
||||
let canPostStatus: Signal<StoriesUploadAvailability, NoError>
|
||||
#if DEBUG
|
||||
canPostStatus = .single(.available)
|
||||
#else
|
||||
canPostStatus = self.context.engine.messages.checkStoriesUploadAvailability(target: .peer(self.peerId))
|
||||
#endif
|
||||
|
||||
self.postingAvailabilityDisposable = (canPostStatus
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
guard let self else {
|
||||
return
|
||||
@ -8338,15 +8364,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
guard let self else {
|
||||
return nil
|
||||
}
|
||||
let _ = self
|
||||
|
||||
/*if let transitionView = self.headerNode.navigationButtonContainer.rightButtonNodes[.postStory]?.view {
|
||||
if !self.headerNode.isAvatarExpanded {
|
||||
let transitionView = self.headerNode.avatarListNode.avatarContainerNode.avatarNode.contentNode.view
|
||||
return StoryCameraTransitionOut(
|
||||
destinationView: transitionView,
|
||||
destinationRect: transitionView.bounds,
|
||||
destinationCornerRadius: transitionView.bounds.height * 0.5
|
||||
)
|
||||
}*/
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user