mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branches 'master' and 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
dd4e80c50a
@ -2493,6 +2493,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
destinationView: transitionView,
|
destinationView: transitionView,
|
||||||
destinationRect: transitionView.bounds,
|
destinationRect: transitionView.bounds,
|
||||||
destinationCornerRadius: transitionView.bounds.height * 0.5,
|
destinationCornerRadius: transitionView.bounds.height * 0.5,
|
||||||
|
destinationIsAvatar: true,
|
||||||
completed: {}
|
completed: {}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -329,7 +329,7 @@ func _internal_getStoryById(accountPeerId: PeerId, postbox: Postbox, network: Ne
|
|||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<StoryListContext.Item?, NoError> in
|
|> mapToSignal { result -> Signal<StoryListContext.Item?, NoError> in
|
||||||
guard let result else {
|
guard let result = result else {
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
return postbox.transaction { transaction -> StoryListContext.Item? in
|
return postbox.transaction { transaction -> StoryListContext.Item? in
|
||||||
@ -382,7 +382,7 @@ func _internal_getStoryViewList(account: Account, id: Int32, offsetTimestamp: In
|
|||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<StoryViewList?, NoError> in
|
|> mapToSignal { result -> Signal<StoryViewList?, NoError> in
|
||||||
guard let result else {
|
guard let result = result else {
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
return account.postbox.transaction { transaction -> StoryViewList? in
|
return account.postbox.transaction { transaction -> StoryViewList? in
|
||||||
@ -425,7 +425,7 @@ func _internal_getStoryViews(account: Account, ids: [Int32]) -> Signal<[Int32: S
|
|||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<[Int32: StoryListContext.Views], NoError> in
|
|> mapToSignal { result -> Signal<[Int32: StoryListContext.Views], NoError> in
|
||||||
guard let result else {
|
guard let result = result else {
|
||||||
return .single([:])
|
return .single([:])
|
||||||
}
|
}
|
||||||
return account.postbox.transaction { transaction -> [Int32: StoryListContext.Views] in
|
return account.postbox.transaction { transaction -> [Int32: StoryListContext.Views] in
|
||||||
|
@ -177,7 +177,7 @@ public final class StoryListContext {
|
|||||||
return transaction.getPeer(account.peerId)
|
return transaction.getPeer(account.peerId)
|
||||||
}
|
}
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||||
guard let self, let peer else {
|
guard let `self` = self, let peer = peer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.stateValue = State(itemSets: [
|
self.stateValue = State(itemSets: [
|
||||||
@ -213,7 +213,7 @@ public final class StoryListContext {
|
|||||||
}
|
}
|
||||||
return peers
|
return peers
|
||||||
}).start(next: { peers in
|
}).start(next: { peers in
|
||||||
guard let self else {
|
guard let `self` = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if self.isLoadingMore {
|
if self.isLoadingMore {
|
||||||
@ -257,7 +257,7 @@ public final class StoryListContext {
|
|||||||
if lhsItem.timestamp != rhsItem.timestamp {
|
if lhsItem.timestamp != rhsItem.timestamp {
|
||||||
switch scope {
|
switch scope {
|
||||||
case .all:
|
case .all:
|
||||||
return lhsItem.timestamp > rhsItem.timestamp
|
return lhsItem.timestamp < rhsItem.timestamp
|
||||||
case .peer:
|
case .peer:
|
||||||
return lhsItem.timestamp < rhsItem.timestamp
|
return lhsItem.timestamp < rhsItem.timestamp
|
||||||
}
|
}
|
||||||
@ -309,7 +309,7 @@ public final class StoryListContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
itemSets.sort(by: { lhs, rhs in
|
itemSets.sort(by: { lhs, rhs in
|
||||||
guard let lhsItem = lhs.items.first, let rhsItem = rhs.items.first else {
|
guard let lhsItem = lhs.items.last, let rhsItem = rhs.items.last else {
|
||||||
if lhs.items.first != nil {
|
if lhs.items.first != nil {
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
@ -417,6 +417,8 @@ public final class StoryListContext {
|
|||||||
var itemSets = self.stateValue.itemSets
|
var itemSets = self.stateValue.itemSets
|
||||||
if let index = itemSets.firstIndex(where: { $0.peerId == id }) {
|
if let index = itemSets.firstIndex(where: { $0.peerId == id }) {
|
||||||
itemSets[index] = itemSet
|
itemSets[index] = itemSet
|
||||||
|
} else {
|
||||||
|
itemSets.append(itemSet)
|
||||||
}
|
}
|
||||||
self.stateValue.itemSets = itemSets
|
self.stateValue.itemSets = itemSets
|
||||||
}))
|
}))
|
||||||
@ -468,7 +470,7 @@ public final class StoryListContext {
|
|||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<([PeerItemSet], LoadMoreToken?), NoError> in
|
|> mapToSignal { result -> Signal<([PeerItemSet], LoadMoreToken?), NoError> in
|
||||||
guard let result else {
|
guard let result = result else {
|
||||||
return .single(([], nil))
|
return .single(([], nil))
|
||||||
}
|
}
|
||||||
return account.postbox.transaction { transaction -> ([PeerItemSet], LoadMoreToken?) in
|
return account.postbox.transaction { transaction -> ([PeerItemSet], LoadMoreToken?) in
|
||||||
@ -553,7 +555,7 @@ public final class StoryListContext {
|
|||||||
if lhsItem.timestamp != rhsItem.timestamp {
|
if lhsItem.timestamp != rhsItem.timestamp {
|
||||||
switch scope {
|
switch scope {
|
||||||
case .all:
|
case .all:
|
||||||
return lhsItem.timestamp > rhsItem.timestamp
|
return lhsItem.timestamp < rhsItem.timestamp
|
||||||
case .peer:
|
case .peer:
|
||||||
return lhsItem.timestamp < rhsItem.timestamp
|
return lhsItem.timestamp < rhsItem.timestamp
|
||||||
}
|
}
|
||||||
@ -573,7 +575,7 @@ public final class StoryListContext {
|
|||||||
if lhsItem.timestamp != rhsItem.timestamp {
|
if lhsItem.timestamp != rhsItem.timestamp {
|
||||||
switch scope {
|
switch scope {
|
||||||
case .all:
|
case .all:
|
||||||
return lhsItem.timestamp > rhsItem.timestamp
|
return lhsItem.timestamp < rhsItem.timestamp
|
||||||
case .peer:
|
case .peer:
|
||||||
return lhsItem.timestamp < rhsItem.timestamp
|
return lhsItem.timestamp < rhsItem.timestamp
|
||||||
}
|
}
|
||||||
@ -585,8 +587,8 @@ public final class StoryListContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
itemSets.sort(by: { lhs, rhs in
|
itemSets.sort(by: { lhs, rhs in
|
||||||
guard let lhsItem = lhs.items.first, let rhsItem = rhs.items.first else {
|
guard let lhsItem = lhs.items.last, let rhsItem = rhs.items.last else {
|
||||||
if lhs.items.first != nil {
|
if lhs.items.last != nil {
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
@ -724,4 +726,10 @@ public final class StoryListContext {
|
|||||||
impl.upload(media: media, text: text, entities: entities, privacy: privacy)
|
impl.upload(media: media, text: text, entities: entities, privacy: privacy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func loadPeer(id: EnginePeer.Id) {
|
||||||
|
self.impl.with { impl in
|
||||||
|
impl.loadPeer(id: id)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -775,8 +775,7 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
self.mediaRecordingVibrancyContainer.addSubview(mediaRecordingPanelView.vibrancyContainer)
|
self.mediaRecordingVibrancyContainer.addSubview(mediaRecordingPanelView.vibrancyContainer)
|
||||||
}
|
}
|
||||||
mediaRecordingPanelTransition.setFrame(view: mediaRecordingPanelView, frame: CGRect(origin: CGPoint(), size: size))
|
mediaRecordingPanelTransition.setFrame(view: mediaRecordingPanelView, frame: CGRect(origin: CGPoint(), size: size))
|
||||||
|
mediaRecordingPanelTransition.setFrame(view: self.mediaRecordingVibrancyContainer, frame: CGRect(origin: CGPoint(x: -fieldBackgroundFrame.minX, y: -fieldBackgroundFrame.minY), size: size))
|
||||||
transition.setFrame(view: self.mediaRecordingVibrancyContainer, frame: CGRect(origin: CGPoint(x: -fieldBackgroundFrame.minX, y: -fieldBackgroundFrame.minY), size: size))
|
|
||||||
|
|
||||||
if animateIn && !transition.animation.isImmediate {
|
if animateIn && !transition.animation.isImmediate {
|
||||||
mediaRecordingPanelView.animateIn()
|
mediaRecordingPanelView.animateIn()
|
||||||
@ -855,8 +854,7 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
self.mediaRecordingVibrancyContainer.addSubview(mediaPreviewPanelView.vibrancyContainer)
|
self.mediaRecordingVibrancyContainer.addSubview(mediaPreviewPanelView.vibrancyContainer)
|
||||||
}
|
}
|
||||||
mediaPreviewPanelTransition.setFrame(view: mediaPreviewPanelView, frame: CGRect(origin: CGPoint(), size: size))
|
mediaPreviewPanelTransition.setFrame(view: mediaPreviewPanelView, frame: CGRect(origin: CGPoint(), size: size))
|
||||||
|
mediaPreviewPanelTransition.setFrame(view: self.mediaRecordingVibrancyContainer, frame: CGRect(origin: CGPoint(x: -fieldBackgroundFrame.minX, y: -fieldBackgroundFrame.minY), size: size))
|
||||||
transition.setFrame(view: self.mediaRecordingVibrancyContainer, frame: CGRect(origin: CGPoint(x: -fieldBackgroundFrame.minX, y: -fieldBackgroundFrame.minY), size: size))
|
|
||||||
|
|
||||||
if animateIn && !transition.animation.isImmediate {
|
if animateIn && !transition.animation.isImmediate {
|
||||||
mediaPreviewPanelView.animateIn()
|
mediaPreviewPanelView.animateIn()
|
||||||
|
@ -947,6 +947,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||||||
destinationView: self.view,
|
destinationView: self.view,
|
||||||
destinationRect: self.itemGrid.view.convert(itemRect, to: self.view),
|
destinationRect: self.itemGrid.view.convert(itemRect, to: self.view),
|
||||||
destinationCornerRadius: 0.0,
|
destinationCornerRadius: 0.0,
|
||||||
|
destinationIsAvatar: false,
|
||||||
completed: {}
|
completed: {}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -756,17 +756,20 @@ public class StoryContainerScreen: ViewControllerComponentContainer {
|
|||||||
public weak var destinationView: UIView?
|
public weak var destinationView: UIView?
|
||||||
public let destinationRect: CGRect
|
public let destinationRect: CGRect
|
||||||
public let destinationCornerRadius: CGFloat
|
public let destinationCornerRadius: CGFloat
|
||||||
|
public let destinationIsAvatar: Bool
|
||||||
public let completed: () -> Void
|
public let completed: () -> Void
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
destinationView: UIView,
|
destinationView: UIView,
|
||||||
destinationRect: CGRect,
|
destinationRect: CGRect,
|
||||||
destinationCornerRadius: CGFloat,
|
destinationCornerRadius: CGFloat,
|
||||||
|
destinationIsAvatar: Bool,
|
||||||
completed: @escaping () -> Void
|
completed: @escaping () -> Void
|
||||||
) {
|
) {
|
||||||
self.destinationView = destinationView
|
self.destinationView = destinationView
|
||||||
self.destinationRect = destinationRect
|
self.destinationRect = destinationRect
|
||||||
self.destinationCornerRadius = destinationCornerRadius
|
self.destinationCornerRadius = destinationCornerRadius
|
||||||
|
self.destinationIsAvatar = destinationIsAvatar
|
||||||
self.completed = completed
|
self.completed = completed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,10 +568,12 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
let innerSourceLocalFrame = CGRect(origin: CGPoint(x: sourceLocalFrame.minX - self.contentContainerView.frame.minX, y: sourceLocalFrame.minY - self.contentContainerView.frame.minY), size: sourceLocalFrame.size)
|
let innerSourceLocalFrame = CGRect(origin: CGPoint(x: sourceLocalFrame.minX - self.contentContainerView.frame.minX, y: sourceLocalFrame.minY - self.contentContainerView.frame.minY), size: sourceLocalFrame.size)
|
||||||
|
|
||||||
if let rightInfoView = self.rightInfoItem?.view.view {
|
if let rightInfoView = self.rightInfoItem?.view.view {
|
||||||
let positionKeyframes: [CGPoint] = generateParabollicMotionKeyframes(from: CGPoint(x: innerSourceLocalFrame.center.x - rightInfoView.layer.position.x, y: innerSourceLocalFrame.center.y - rightInfoView.layer.position.y), to: CGPoint(), elevation: 0.0, duration: 0.3, curve: .spring, reverse: false)
|
if transitionIn.sourceCornerRadius != 0.0 {
|
||||||
rightInfoView.layer.animateKeyframes(values: positionKeyframes.map { NSValue(cgPoint: $0) }, duration: 0.3, keyPath: "position", additive: true)
|
let positionKeyframes: [CGPoint] = generateParabollicMotionKeyframes(from: CGPoint(x: innerSourceLocalFrame.center.x - rightInfoView.layer.position.x, y: innerSourceLocalFrame.center.y - rightInfoView.layer.position.y), to: CGPoint(), elevation: 0.0, duration: 0.3, curve: .spring, reverse: false)
|
||||||
|
rightInfoView.layer.animateKeyframes(values: positionKeyframes.map { NSValue(cgPoint: $0) }, duration: 0.3, keyPath: "position", additive: true)
|
||||||
rightInfoView.layer.animateScale(from: innerSourceLocalFrame.width / rightInfoView.bounds.width, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
|
||||||
|
rightInfoView.layer.animateScale(from: innerSourceLocalFrame.width / rightInfoView.bounds.width, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.contentContainerView.layer.animatePosition(from: sourceLocalFrame.center, to: self.contentContainerView.center, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
self.contentContainerView.layer.animatePosition(from: sourceLocalFrame.center, to: self.contentContainerView.center, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
@ -635,11 +637,13 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
let innerSourceLocalFrame = CGRect(origin: CGPoint(x: sourceLocalFrame.minX - self.contentContainerView.frame.minX, y: sourceLocalFrame.minY - self.contentContainerView.frame.minY), size: sourceLocalFrame.size)
|
let innerSourceLocalFrame = CGRect(origin: CGPoint(x: sourceLocalFrame.minX - self.contentContainerView.frame.minX, y: sourceLocalFrame.minY - self.contentContainerView.frame.minY), size: sourceLocalFrame.size)
|
||||||
|
|
||||||
if let rightInfoView = self.rightInfoItem?.view.view {
|
if let rightInfoView = self.rightInfoItem?.view.view {
|
||||||
let positionKeyframes: [CGPoint] = generateParabollicMotionKeyframes(from: innerSourceLocalFrame.center, to: rightInfoView.layer.position, elevation: 0.0, duration: 0.3, curve: .spring, reverse: true)
|
if transitionOut.destinationIsAvatar {
|
||||||
rightInfoView.layer.position = positionKeyframes[positionKeyframes.count - 1]
|
let positionKeyframes: [CGPoint] = generateParabollicMotionKeyframes(from: innerSourceLocalFrame.center, to: rightInfoView.layer.position, elevation: 0.0, duration: 0.3, curve: .spring, reverse: true)
|
||||||
rightInfoView.layer.animateKeyframes(values: positionKeyframes.map { NSValue(cgPoint: $0) }, duration: 0.3, keyPath: "position", removeOnCompletion: false, additive: false)
|
rightInfoView.layer.position = positionKeyframes[positionKeyframes.count - 1]
|
||||||
|
rightInfoView.layer.animateKeyframes(values: positionKeyframes.map { NSValue(cgPoint: $0) }, duration: 0.3, keyPath: "position", removeOnCompletion: false, additive: false)
|
||||||
rightInfoView.layer.animateScale(from: 1.0, to: innerSourceLocalFrame.width / rightInfoView.bounds.width, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
|
||||||
|
rightInfoView.layer.animateScale(from: 1.0, to: innerSourceLocalFrame.width / rightInfoView.bounds.width, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.contentContainerView.layer.animatePosition(from: self.contentContainerView.center, to: sourceLocalFrame.center, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
self.contentContainerView.layer.animatePosition(from: self.contentContainerView.center, to: sourceLocalFrame.center, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
||||||
|
@ -368,8 +368,8 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
|
|||||||
if let chatListController = self.chatListController as? ChatListControllerImpl, let storyListContext = chatListController.storyListContext {
|
if let chatListController = self.chatListController as? ChatListControllerImpl, let storyListContext = chatListController.storyListContext {
|
||||||
switch mediaResult {
|
switch mediaResult {
|
||||||
case let .image(image, dimensions, caption):
|
case let .image(image, dimensions, caption):
|
||||||
if let scaledImageData = compressImageToJPEG(image, quality: 0.6) {
|
if let imageData = compressImageToJPEG(image, quality: 0.6) {
|
||||||
storyListContext.upload(media: .image(dimensions: dimensions, data: scaledImageData), text: caption?.string ?? "", entities: [], privacy: privacy)
|
storyListContext.upload(media: .image(dimensions: dimensions, data: imageData), text: caption?.string ?? "", entities: [], privacy: privacy)
|
||||||
Queue.mainQueue().after(0.2, { [weak chatListController] in
|
Queue.mainQueue().after(0.2, { [weak chatListController] in
|
||||||
chatListController?.animateStoryUploadRipple()
|
chatListController?.animateStoryUploadRipple()
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user