mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-01 04:08:07 +00:00
Avatar improvements
This commit is contained in:
parent
a6009be37c
commit
bbf21bfe17
@ -93,7 +93,7 @@ extension TelegramUser {
|
|||||||
|
|
||||||
static func merge(_ lhs: TelegramUser?, rhs: Api.User) -> TelegramUser? {
|
static func merge(_ lhs: TelegramUser?, rhs: Api.User) -> TelegramUser? {
|
||||||
switch rhs {
|
switch rhs {
|
||||||
case let .user(flags, _, _, rhsAccessHash, _, _, username, _, photo, _, _, restrictionReason, botInlinePlaceholder, _, emojiStatus, usernames):
|
case let .user(flags, _, _, rhsAccessHash, _, _, _, _, photo, _, _, restrictionReason, botInlinePlaceholder, _, emojiStatus, usernames):
|
||||||
let isMin = (flags & (1 << 20)) != 0
|
let isMin = (flags & (1 << 20)) != 0
|
||||||
if !isMin {
|
if !isMin {
|
||||||
return TelegramUser(user: rhs)
|
return TelegramUser(user: rhs)
|
||||||
@ -162,7 +162,7 @@ extension TelegramUser {
|
|||||||
accessHash = lhs.accessHash ?? rhsAccessHashValue
|
accessHash = lhs.accessHash ?? rhsAccessHashValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return TelegramUser(id: lhs.id, accessHash: accessHash, firstName: lhs.firstName, lastName: lhs.lastName, username: username, phone: lhs.phone, photo: telegramPhoto, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [])
|
return TelegramUser(id: lhs.id, accessHash: accessHash, firstName: lhs.firstName, lastName: lhs.lastName, username: lhs.username, phone: lhs.phone, photo: telegramPhoto, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [])
|
||||||
} else {
|
} else {
|
||||||
return TelegramUser(user: rhs)
|
return TelegramUser(user: rhs)
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ extension TelegramUser {
|
|||||||
photo = rhs.photo
|
photo = rhs.photo
|
||||||
}
|
}
|
||||||
|
|
||||||
return TelegramUser(id: lhs.id, accessHash: accessHash, firstName: lhs.firstName, lastName: lhs.lastName, username: rhs.username, phone: lhs.phone, photo: photo, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus, usernames: rhs.usernames)
|
return TelegramUser(id: lhs.id, accessHash: accessHash, firstName: lhs.firstName, lastName: lhs.lastName, username: lhs.username, phone: lhs.phone, photo: photo, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus, usernames: rhs.usernames)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,13 +68,13 @@ enum AvatarBackground: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private let defaultBackgrounds: [AvatarBackground] = [
|
private let defaultBackgrounds: [AvatarBackground] = [
|
||||||
.gradient([0xff72d5fd, 0xff2a9ef1]),
|
.gradient([0xFF5A7FFF, 0xFF2CA0F2, 0xFF4DFF89, 0xFF6BFCEB]),
|
||||||
.gradient([0xffff885e, 0xffff516a]),
|
.gradient([0xFFFF011D, 0xFFFF530D, 0xFFFE64DC, 0xFFFFDC61]),
|
||||||
.gradient([0xffffcd6a, 0xffffa85c]),
|
.gradient([0xFFFE64DC, 0xFFFF6847, 0xFFFFDD02, 0xFFFFAE10]),
|
||||||
.gradient([0xffa0de7e, 0xff54cb68]),
|
.gradient([0xFF84EC00, 0xFF00B7C2, 0xFF00C217, 0xFFFFE600]),
|
||||||
.gradient([0xff00fcfd, 0xff4acccd]),
|
.gradient([0xFF86B0FF, 0xFF35FFCF, 0xFF69FFFF, 0xFF76DEFF]),
|
||||||
.gradient([0xffe0a2f3, 0xffd669ed]),
|
.gradient([0xFFFAE100, 0xFFFF54EE, 0xFFFC2B78, 0xFFFF52D9]),
|
||||||
.gradient([0xff82b1ff, 0xff665fff]),
|
.gradient([0xFF73A4FF, 0xFF5F55FF, 0xFFFF49F8, 0xFFEC76FF]),
|
||||||
]
|
]
|
||||||
|
|
||||||
public struct AvatarKeyboardInputData: Equatable {
|
public struct AvatarKeyboardInputData: Equatable {
|
||||||
|
|||||||
@ -180,11 +180,12 @@ final class AvatarPreviewComponent: Component {
|
|||||||
|
|
||||||
self.imageView.frame = CGRect(origin: .zero, size: availableSize)
|
self.imageView.frame = CGRect(origin: .zero, size: availableSize)
|
||||||
if previousBackground != component.background {
|
if previousBackground != component.background {
|
||||||
if let _ = previousBackground, !transition.animation.isImmediate, let snapshotView = self.imageView.snapshotContentTree() {
|
if let _ = previousBackground, !transition.animation.isImmediate {
|
||||||
self.insertSubview(snapshotView, aboveSubview: self.imageView)
|
UIView.transition(with: self.imageView, duration: 0.2, options: .transitionCrossDissolve, animations: {
|
||||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
self.imageView.image = component.background.generateImage(size: availableSize)
|
||||||
snapshotView?.removeFromSuperview()
|
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
self.imageView.image = component.background.generateImage(size: availableSize)
|
||||||
}
|
}
|
||||||
self.imageView.image = component.background.generateImage(size: availableSize)
|
self.imageView.image = component.background.generateImage(size: availableSize)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6729,8 +6729,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
threadData = .single(nil)
|
threadData = .single(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if peerId.namespace != Namespaces.Peer.SecretChat && peerId != context.account.peerId && self.subject != .scheduledMessages {
|
if case .standard(previewing: true) = self.presentationInterfaceState.mode {
|
||||||
|
|
||||||
|
} else if peerId.namespace != Namespaces.Peer.SecretChat && peerId != context.account.peerId && self.subject != .scheduledMessages {
|
||||||
var baseLanguageCode = self.presentationData.strings.baseLanguageCode
|
var baseLanguageCode = self.presentationData.strings.baseLanguageCode
|
||||||
if baseLanguageCode.contains("-") {
|
if baseLanguageCode.contains("-") {
|
||||||
baseLanguageCode = baseLanguageCode.components(separatedBy: "-").first ?? baseLanguageCode
|
baseLanguageCode = baseLanguageCode.components(separatedBy: "-").first ?? baseLanguageCode
|
||||||
|
|||||||
@ -18,12 +18,17 @@ enum PeerInfoUpdatingAvatar {
|
|||||||
case image(TelegramMediaImageRepresentation)
|
case image(TelegramMediaImageRepresentation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum AvatarUploadProgress {
|
||||||
|
case value(CGFloat)
|
||||||
|
case indefinite
|
||||||
|
}
|
||||||
|
|
||||||
final class PeerInfoState {
|
final class PeerInfoState {
|
||||||
let isEditing: Bool
|
let isEditing: Bool
|
||||||
let selectedMessageIds: Set<MessageId>?
|
let selectedMessageIds: Set<MessageId>?
|
||||||
let updatingAvatar: PeerInfoUpdatingAvatar?
|
let updatingAvatar: PeerInfoUpdatingAvatar?
|
||||||
let updatingBio: String?
|
let updatingBio: String?
|
||||||
let avatarUploadProgress: CGFloat?
|
let avatarUploadProgress: AvatarUploadProgress?
|
||||||
let highlightedButton: PeerInfoHeaderButtonKey?
|
let highlightedButton: PeerInfoHeaderButtonKey?
|
||||||
|
|
||||||
init(
|
init(
|
||||||
@ -31,7 +36,7 @@ final class PeerInfoState {
|
|||||||
selectedMessageIds: Set<MessageId>?,
|
selectedMessageIds: Set<MessageId>?,
|
||||||
updatingAvatar: PeerInfoUpdatingAvatar?,
|
updatingAvatar: PeerInfoUpdatingAvatar?,
|
||||||
updatingBio: String?,
|
updatingBio: String?,
|
||||||
avatarUploadProgress: CGFloat?,
|
avatarUploadProgress: AvatarUploadProgress?,
|
||||||
highlightedButton: PeerInfoHeaderButtonKey?
|
highlightedButton: PeerInfoHeaderButtonKey?
|
||||||
) {
|
) {
|
||||||
self.isEditing = isEditing
|
self.isEditing = isEditing
|
||||||
@ -86,7 +91,7 @@ final class PeerInfoState {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withAvatarUploadProgress(_ avatarUploadProgress: CGFloat?) -> PeerInfoState {
|
func withAvatarUploadProgress(_ avatarUploadProgress: AvatarUploadProgress?) -> PeerInfoState {
|
||||||
return PeerInfoState(
|
return PeerInfoState(
|
||||||
isEditing: self.isEditing,
|
isEditing: self.isEditing,
|
||||||
selectedMessageIds: self.selectedMessageIds,
|
selectedMessageIds: self.selectedMessageIds,
|
||||||
|
|||||||
@ -712,7 +712,7 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
|||||||
transition.updateAlpha(node: self, alpha: 1.0 - fraction)
|
transition.updateAlpha(node: self, alpha: 1.0 - fraction)
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(peer: Peer?, threadData: MessageHistoryThreadData?, chatLocation: ChatLocation, item: PeerInfoAvatarListItem?, updatingAvatar: PeerInfoUpdatingAvatar?, uploadProgress: CGFloat?, theme: PresentationTheme, avatarSize: CGFloat, isEditing: Bool) {
|
func update(peer: Peer?, threadData: MessageHistoryThreadData?, chatLocation: ChatLocation, item: PeerInfoAvatarListItem?, updatingAvatar: PeerInfoUpdatingAvatar?, uploadProgress: AvatarUploadProgress?, theme: PresentationTheme, avatarSize: CGFloat, isEditing: Bool) {
|
||||||
guard let peer = peer else {
|
guard let peer = peer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -741,7 +741,20 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
|||||||
if let updatingAvatar = updatingAvatar {
|
if let updatingAvatar = updatingAvatar {
|
||||||
overlayHidden = false
|
overlayHidden = false
|
||||||
|
|
||||||
self.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: max(0.027, uploadProgress ?? 0.0), cancelEnabled: true, animateRotation: true))
|
var cancelEnabled = true
|
||||||
|
let progressValue: CGFloat?
|
||||||
|
if let uploadProgress {
|
||||||
|
switch uploadProgress {
|
||||||
|
case let .value(value):
|
||||||
|
progressValue = max(0.027, value)
|
||||||
|
case .indefinite:
|
||||||
|
progressValue = nil
|
||||||
|
cancelEnabled = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
progressValue = 0.027
|
||||||
|
}
|
||||||
|
self.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: progressValue, cancelEnabled: cancelEnabled, animateRotation: true))
|
||||||
|
|
||||||
if case let .image(representation) = updatingAvatar {
|
if case let .image(representation) = updatingAvatar {
|
||||||
if representation != self.currentRepresentation {
|
if representation != self.currentRepresentation {
|
||||||
@ -831,7 +844,7 @@ final class PeerInfoEditingAvatarNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var removedPhotoResourceIds = Set<String>()
|
var removedPhotoResourceIds = Set<String>()
|
||||||
func update(peer: Peer?, threadData: MessageHistoryThreadData?, chatLocation: ChatLocation, item: PeerInfoAvatarListItem?, updatingAvatar: PeerInfoUpdatingAvatar?, uploadProgress: CGFloat?, theme: PresentationTheme, avatarSize: CGFloat, isEditing: Bool) {
|
func update(peer: Peer?, threadData: MessageHistoryThreadData?, chatLocation: ChatLocation, item: PeerInfoAvatarListItem?, updatingAvatar: PeerInfoUpdatingAvatar?, uploadProgress: AvatarUploadProgress?, theme: PresentationTheme, avatarSize: CGFloat, isEditing: Bool) {
|
||||||
guard let peer = peer else {
|
guard let peer = peer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6959,7 +6959,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
case .complete:
|
case .complete:
|
||||||
strongSelf.state = strongSelf.state.withUpdatingAvatar(nil).withAvatarUploadProgress(nil)
|
strongSelf.state = strongSelf.state.withUpdatingAvatar(nil).withAvatarUploadProgress(nil)
|
||||||
case let .progress(value):
|
case let .progress(value):
|
||||||
strongSelf.state = strongSelf.state.withAvatarUploadProgress(CGFloat(value))
|
strongSelf.state = strongSelf.state.withAvatarUploadProgress(.value(CGFloat(value)))
|
||||||
}
|
}
|
||||||
if let (layout, navigationHeight) = strongSelf.validLayout {
|
if let (layout, navigationHeight) = strongSelf.validLayout {
|
||||||
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||||
@ -7015,21 +7015,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
self.context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
self.context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
||||||
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: mode == .custom ? true : false)
|
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: mode == .custom ? true : false)
|
||||||
|
|
||||||
if [.suggest, .fallback].contains(mode) {
|
|
||||||
} else {
|
|
||||||
self.state = self.state.withUpdatingAvatar(.image(representation))
|
|
||||||
}
|
|
||||||
|
|
||||||
if let (layout, navigationHeight) = self.validLayout {
|
|
||||||
self.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: mode == .custom ? .animated(duration: 0.2, curve: .easeInOut) : .immediate, additive: false)
|
|
||||||
}
|
|
||||||
self.headerNode.ignoreCollapse = false
|
|
||||||
|
|
||||||
var videoStartTimestamp: Double? = nil
|
|
||||||
if let adjustments = adjustments, adjustments.videoStartValue > 0.0 {
|
|
||||||
videoStartTimestamp = adjustments.videoStartValue - adjustments.trimStartValue
|
|
||||||
}
|
|
||||||
|
|
||||||
var markup: UploadPeerPhotoMarkup? = nil
|
var markup: UploadPeerPhotoMarkup? = nil
|
||||||
if let fileId = adjustments?.documentId, let backgroundColors = adjustments?.colors as? [Int32], fileId != 0 {
|
if let fileId = adjustments?.documentId, let backgroundColors = adjustments?.colors as? [Int32], fileId != 0 {
|
||||||
if let packId = adjustments?.stickerPackId, let accessHash = adjustments?.stickerPackAccessHash, packId != 0 {
|
if let packId = adjustments?.stickerPackId, let accessHash = adjustments?.stickerPackAccessHash, packId != 0 {
|
||||||
@ -7048,6 +7033,24 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if [.suggest, .fallback].contains(mode) {
|
||||||
|
} else {
|
||||||
|
self.state = self.state.withUpdatingAvatar(.image(representation))
|
||||||
|
if !uploadVideo {
|
||||||
|
self.state = self.state.withAvatarUploadProgress(.indefinite)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let (layout, navigationHeight) = self.validLayout {
|
||||||
|
self.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: mode == .custom ? .animated(duration: 0.2, curve: .easeInOut) : .immediate, additive: false)
|
||||||
|
}
|
||||||
|
self.headerNode.ignoreCollapse = false
|
||||||
|
|
||||||
|
var videoStartTimestamp: Double? = nil
|
||||||
|
if let adjustments = adjustments, adjustments.videoStartValue > 0.0 {
|
||||||
|
videoStartTimestamp = adjustments.videoStartValue - adjustments.trimStartValue
|
||||||
|
}
|
||||||
|
|
||||||
let account = self.context.account
|
let account = self.context.account
|
||||||
let context = self.context
|
let context = self.context
|
||||||
|
|
||||||
@ -7114,7 +7117,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
} else if let strongSelf = self, let progress = next as? NSNumber {
|
} else if let strongSelf = self, let progress = next as? NSNumber {
|
||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
strongSelf.state = strongSelf.state.withAvatarUploadProgress(CGFloat(progress.floatValue * 0.45))
|
strongSelf.state = strongSelf.state.withAvatarUploadProgress(.value(CGFloat(progress.floatValue * 0.45)))
|
||||||
if let (layout, navigationHeight) = strongSelf.validLayout {
|
if let (layout, navigationHeight) = strongSelf.validLayout {
|
||||||
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||||
}
|
}
|
||||||
@ -7189,7 +7192,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
case .complete:
|
case .complete:
|
||||||
strongSelf.state = strongSelf.state.withUpdatingAvatar(nil).withAvatarUploadProgress(nil)
|
strongSelf.state = strongSelf.state.withUpdatingAvatar(nil).withAvatarUploadProgress(nil)
|
||||||
case let .progress(value):
|
case let .progress(value):
|
||||||
strongSelf.state = strongSelf.state.withAvatarUploadProgress(CGFloat(0.45 + value * 0.55))
|
strongSelf.state = strongSelf.state.withAvatarUploadProgress(.value(CGFloat(0.45 + value * 0.55)))
|
||||||
}
|
}
|
||||||
if let (layout, navigationHeight) = strongSelf.validLayout {
|
if let (layout, navigationHeight) = strongSelf.validLayout {
|
||||||
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user