mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-07-12 02:36:32 +02:00
chore: migrate to new version + fixed several critical bugs
- Migrated project to latest Telegram iOS base (v12.3.2+) - Fixed circular dependency between GhostModeManager and MiscSettingsManager - Fixed multiple Bazel build configuration errors (select() default conditions) - Fixed duplicate type definitions in PeerInfoScreen - Fixed swiftmodule directory resolution in build scripts - Added Ghostgram Settings tab in main Settings menu with all 5 features - Cleared sensitive credentials from config.json (template-only now) - Excluded bazel-cache from version control
This commit is contained in:
@@ -33,6 +33,7 @@ import ComponentFlow
|
||||
import BundleIconComponent
|
||||
import LottieComponent
|
||||
import GlassBarButtonComponent
|
||||
import AlertComponent
|
||||
|
||||
final class MediaPickerInteraction {
|
||||
let downloadManager: AssetDownloadManager
|
||||
@@ -1436,7 +1437,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
}
|
||||
|
||||
if asFile && hasHeic {
|
||||
controller.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.MediaPicker_JpegConversionText, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.MediaPicker_KeepHeic, action: {
|
||||
controller.present(textAlertController(context: controller.context, updatedPresentationData: self.controller?.updatedPresentationData, title: nil, text: self.presentationData.strings.MediaPicker_JpegConversionText, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.MediaPicker_KeepHeic, action: {
|
||||
proceed(false)
|
||||
}), TextAlertAction(type: .genericAction, title: self.presentationData.strings.MediaPicker_ConvertToJpeg, action: {
|
||||
proceed(true)
|
||||
@@ -2042,26 +2043,26 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
|
||||
if let _ = item as? TGMediaPickerGalleryPhotoItem {
|
||||
if self.bannedSendPhotos != nil {
|
||||
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
self.present(textAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
|
||||
return false
|
||||
}
|
||||
} else if let _ = item as? TGMediaPickerGalleryVideoItem {
|
||||
if self.bannedSendVideos != nil {
|
||||
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
self.present(textAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
|
||||
return false
|
||||
}
|
||||
} else if let asset = item as? TGMediaAsset {
|
||||
if asset.isVideo {
|
||||
if self.bannedSendVideos != nil {
|
||||
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
self.present(textAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if self.bannedSendPhotos != nil {
|
||||
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
self.present(textAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -2112,6 +2113,10 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
}
|
||||
}
|
||||
|
||||
self.selectedButtonNode.action = { [weak self] in
|
||||
self?.selectedPressed()
|
||||
}
|
||||
|
||||
self.navigationItem.titleView = self.titleView
|
||||
|
||||
if case let .assets(collection, mode) = self.subject, mode != .default {
|
||||
@@ -2184,8 +2189,6 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
// }
|
||||
// }
|
||||
|
||||
self.selectedButtonNode.addTarget(self, action: #selector(self.selectedPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
self.scrollToTop = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
if let webSearchController = strongSelf.webSearchController {
|
||||
@@ -2220,26 +2223,26 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
if let self = self, let selectionState = self.interaction?.selectionState {
|
||||
if let _ = item as? TGMediaPickerGalleryPhotoItem {
|
||||
if self.bannedSendPhotos != nil {
|
||||
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
self.present(textAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
|
||||
return false
|
||||
}
|
||||
} else if let _ = item as? TGMediaPickerGalleryVideoItem {
|
||||
if self.bannedSendVideos != nil {
|
||||
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
self.present(textAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
|
||||
return false
|
||||
}
|
||||
} else if let asset = item as? TGMediaAsset {
|
||||
if asset.isVideo {
|
||||
if self.bannedSendVideos != nil {
|
||||
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
self.present(textAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if self.bannedSendPhotos != nil {
|
||||
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
self.present(textAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -2548,7 +2551,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
let useGlassButtons = (isBack || !self.controllerNode.scrolledToTop) && !self.controllerNode.isSwitchingAssetGroup
|
||||
|
||||
let barButtonSideInset: CGFloat = 16.0
|
||||
let barButtonSize = CGSize(width: 40.0, height: 40.0)
|
||||
let barButtonSize = CGSize(width: 44.0, height: 44.0)
|
||||
|
||||
var buttonTransition = ComponentTransition.easeInOut(duration: 0.25)
|
||||
if case let .animated(duration, _) = transition, duration > 0.25 {
|
||||
@@ -2580,13 +2583,13 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
transition: buttonTransition,
|
||||
component: AnyComponent(GlassBarButtonComponent(
|
||||
size: barButtonSize,
|
||||
backgroundColor: self.presentationData.theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
backgroundColor: nil,
|
||||
isDark: self.presentationData.theme.overallDarkAppearance,
|
||||
state: useGlassButtons ? .glass : .generic,
|
||||
state: .glass,
|
||||
component: AnyComponentWithIdentity(id: isBack ? "back" : "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: isBack ? "Navigation/Back" : "Navigation/Close",
|
||||
tintColor: self.presentationData.theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
tintColor: self.presentationData.theme.chat.inputPanel.panelControlColor
|
||||
)
|
||||
)),
|
||||
action: { [weak self] _ in
|
||||
@@ -2611,15 +2614,15 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
transition: buttonTransition,
|
||||
component: AnyComponent(GlassBarButtonComponent(
|
||||
size: barButtonSize,
|
||||
backgroundColor: self.presentationData.theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
backgroundColor: nil,
|
||||
isDark: self.presentationData.theme.overallDarkAppearance,
|
||||
state: useGlassButtons ? .glass : .generic,
|
||||
state: .glass,
|
||||
component: AnyComponentWithIdentity(id: "more", component: AnyComponent(
|
||||
LottieComponent(
|
||||
content: LottieComponent.AppBundleContent(
|
||||
name: "anim_morewide"
|
||||
),
|
||||
color: self.presentationData.theme.rootController.navigationBar.glassBarButtonForegroundColor,
|
||||
color: self.presentationData.theme.chat.inputPanel.panelControlColor,
|
||||
size: CGSize(width: 34.0, height: 34.0),
|
||||
playOnce: self.moreButtonPlayOnce
|
||||
)
|
||||
@@ -2673,7 +2676,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
} else {
|
||||
navigationBarPresentationData = NavigationBarPresentationData(presentationData: self.presentationData)
|
||||
}
|
||||
self.navigationBar?.updatePresentationData(navigationBarPresentationData)
|
||||
self.navigationBar?.updatePresentationData(navigationBarPresentationData, transition: .immediate)
|
||||
self.titleView.theme = self.presentationData.theme
|
||||
self.cancelButtonNode.theme = self.presentationData.theme
|
||||
self.moreButtonNode.theme = self.presentationData.theme
|
||||
@@ -2717,16 +2720,22 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
} else {
|
||||
text = self.presentationData.strings.Attachment_CancelSelectionAlertText
|
||||
}
|
||||
|
||||
let controller = textAlertController(context: self.context, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: self.presentationData.strings.Attachment_CancelSelectionAlertNo, action: {
|
||||
}), TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Attachment_CancelSelectionAlertYes, action: { [weak self] in
|
||||
self?.dismissAllTooltips()
|
||||
completion()
|
||||
})])
|
||||
controller.dismissed = { [weak self] _ in
|
||||
let alertController = AlertScreen(
|
||||
context: self.context,
|
||||
title: nil,
|
||||
text: text,
|
||||
actions: [
|
||||
.init(title: self.presentationData.strings.Attachment_CancelSelectionAlertNo),
|
||||
.init(title: self.presentationData.strings.Attachment_CancelSelectionAlertYes, type: .default, action: { [weak self] in
|
||||
self?.dismissAllTooltips()
|
||||
completion()
|
||||
}),
|
||||
]
|
||||
)
|
||||
alertController.dismissed = { [weak self] _ in
|
||||
self?.isDismissing = false
|
||||
}
|
||||
self.present(controller, in: .window(.root))
|
||||
self.present(alertController, in: .window(.root))
|
||||
} else {
|
||||
completion()
|
||||
}
|
||||
@@ -3777,126 +3786,188 @@ public func avatarMediaPickerController(
|
||||
performDelete: @escaping () -> Void,
|
||||
completion: @escaping (Any?, UIView?, CGRect, UIImage?, Bool, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void,
|
||||
dismissed: @escaping () -> Void
|
||||
) -> ViewController {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with({ $0 })
|
||||
let updatedPresentationData: (PresentationData, Signal<PresentationData, NoError>) = (presentationData, .single(presentationData))
|
||||
let controller = AttachmentController(
|
||||
context: context,
|
||||
updatedPresentationData: updatedPresentationData,
|
||||
style: .glass,
|
||||
chatLocation: nil,
|
||||
buttons: [.standalone],
|
||||
initialButton: .standalone,
|
||||
fromMenu: false,
|
||||
hasTextInput: false,
|
||||
makeEntityInputView: {
|
||||
return nil
|
||||
})
|
||||
controller.forceSourceRect = true
|
||||
controller.getSourceRect = getSourceRect
|
||||
controller.requestController = { [weak controller] _, present in
|
||||
var mainButtonState: AttachmentMainButtonState?
|
||||
|
||||
if canDelete {
|
||||
mainButtonState = AttachmentMainButtonState(text: presentationData.strings.MediaPicker_RemovePhoto, font: .regular, background: .color(.clear), textColor: presentationData.theme.actionSheet.destructiveActionTextColor, isVisible: true, progress: .none, isEnabled: true, hasShimmer: false)
|
||||
) -> (controller: ViewController?, holder: Any?) {
|
||||
if #available(iOS 14.0, *), PHPhotoLibrary.authorizationStatus(for: .readWrite) != .authorized {
|
||||
final class PickerDelegate: NSObject, PHPickerViewControllerDelegate {
|
||||
var completion: ((Any?, UIView?, CGRect, UIImage?, Bool, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void)?
|
||||
|
||||
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
|
||||
picker.dismiss(animated: true)
|
||||
|
||||
for item in results {
|
||||
if item.itemProvider.canLoadObject(ofClass: UIImage.self) {
|
||||
item.itemProvider.loadObject(ofClass: UIImage.self) { image, error in
|
||||
if let uiImage = image as? UIImage {
|
||||
Queue.mainQueue().async {
|
||||
self.completion?(uiImage, nil, CGRect(), nil, false, { _ in return nil }, {})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mediaPickerController = MediaPickerScreenImpl(
|
||||
let holder = PickerDelegate()
|
||||
holder.completion = completion
|
||||
|
||||
let openMediaPicker = {
|
||||
var configuration = PHPickerConfiguration(photoLibrary: .shared())
|
||||
configuration.filter = .images
|
||||
configuration.selectionLimit = 1
|
||||
|
||||
let picker = PHPickerViewController(configuration: configuration)
|
||||
picker.delegate = holder
|
||||
(context.sharedContext.mainWindow?.viewController as? NavigationController)?.topViewController?.present(picker, animated: true, completion: nil)
|
||||
}
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let controller = ActionSheetController(presentationData: presentationData)
|
||||
let dismissAction: () -> Void = { [weak controller] in
|
||||
controller?.dismissAnimated()
|
||||
}
|
||||
|
||||
var items: [ActionSheetButtonItem] = [
|
||||
ActionSheetButtonItem(title: presentationData.strings.Settings_SetNewProfilePhotoOrVideo, color: .accent, action: {
|
||||
dismissAction()
|
||||
openMediaPicker()
|
||||
}),
|
||||
ActionSheetButtonItem(title: presentationData.strings.ProfilePhoto_SetEmoji, color: .accent, action: {
|
||||
dismissAction()
|
||||
completion(nil, nil, CGRect(), nil, false, { _ in return nil }, {})
|
||||
})
|
||||
]
|
||||
if canDelete {
|
||||
items.append(ActionSheetButtonItem(title: presentationData.strings.MediaPicker_RemovePhoto, color: .destructive, action: {
|
||||
dismissAction()
|
||||
performDelete()
|
||||
}))
|
||||
}
|
||||
controller.setItemGroups([
|
||||
ActionSheetItemGroup(items: items),
|
||||
ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })])
|
||||
])
|
||||
return (controller, holder)
|
||||
} else {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with({ $0 })
|
||||
let updatedPresentationData: (PresentationData, Signal<PresentationData, NoError>) = (presentationData, .single(presentationData))
|
||||
let controller = AttachmentController(
|
||||
context: context,
|
||||
updatedPresentationData: updatedPresentationData,
|
||||
style: .glass,
|
||||
peer: nil,
|
||||
threadTitle: nil,
|
||||
chatLocation: nil,
|
||||
bannedSendPhotos: nil,
|
||||
bannedSendVideos: nil,
|
||||
subject: .assets(nil, .createAvatar),
|
||||
mainButtonState: mainButtonState,
|
||||
mainButtonAction: { [weak controller] in
|
||||
controller?.dismiss(animated: true)
|
||||
performDelete()
|
||||
}
|
||||
)
|
||||
mediaPickerController.customSelection = { controller, result in
|
||||
if let result = result as? PHAsset {
|
||||
controller.updateHiddenMediaId(result.localIdentifier)
|
||||
if let transitionView = controller.transitionView(for: result.localIdentifier, snapshot: false) {
|
||||
let transitionOut: (Bool?) -> (UIView, CGRect)? = { isNew in
|
||||
if let isNew {
|
||||
if isNew {
|
||||
controller.updateHiddenMediaId(nil)
|
||||
if let transitionView = controller.defaultTransitionView() {
|
||||
return (transitionView, transitionView.bounds)
|
||||
}
|
||||
} else if let transitionView = controller.transitionView(for: result.localIdentifier, snapshot: false) {
|
||||
return (transitionView, transitionView.bounds)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
completion(result, transitionView, transitionView.bounds, controller.transitionImage(for: result.localIdentifier), false, transitionOut, { [weak controller] in
|
||||
controller?.updateHiddenMediaId(nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
mediaPickerController.openAvatarEditor = { [weak controller] in
|
||||
completion(nil, nil, .zero, nil, false, { _ in return nil }, {
|
||||
buttons: [.standalone],
|
||||
initialButton: .standalone,
|
||||
fromMenu: false,
|
||||
hasTextInput: false,
|
||||
makeEntityInputView: {
|
||||
return nil
|
||||
})
|
||||
controller?.dismiss(animated: true)
|
||||
}
|
||||
mediaPickerController.openCamera = { [weak controller] cameraHolder in
|
||||
let _ = controller
|
||||
guard let cameraHolder = cameraHolder as? CameraHolder else {
|
||||
return
|
||||
controller.forceSourceRect = true
|
||||
controller.getSourceRect = getSourceRect
|
||||
controller.requestController = { [weak controller] _, present in
|
||||
var mainButtonState: AttachmentMainButtonState?
|
||||
|
||||
if canDelete {
|
||||
mainButtonState = AttachmentMainButtonState(text: presentationData.strings.MediaPicker_RemovePhoto, font: .regular, background: .color(.clear), textColor: presentationData.theme.actionSheet.destructiveActionTextColor, isVisible: true, progress: .none, isEnabled: true, hasShimmer: false)
|
||||
}
|
||||
|
||||
var returnToCameraImpl: (() -> Void)?
|
||||
|
||||
let cameraScreen = context.sharedContext.makeCameraScreen(
|
||||
let mediaPickerController = MediaPickerScreenImpl(
|
||||
context: context,
|
||||
mode: .avatar,
|
||||
cameraHolder: cameraHolder,
|
||||
transitionIn: CameraScreenTransitionIn(
|
||||
sourceView: cameraHolder.parentView,
|
||||
sourceRect: cameraHolder.parentView.bounds,
|
||||
sourceCornerRadius: 0.0,
|
||||
useFillAnimation: false
|
||||
),
|
||||
transitionOut: { _ in
|
||||
return CameraScreenTransitionOut(
|
||||
destinationView: cameraHolder.parentView,
|
||||
destinationRect: cameraHolder.parentView.bounds,
|
||||
destinationCornerRadius: 0.0
|
||||
)
|
||||
},
|
||||
completion: { result, commit in
|
||||
completion(result, nil, .zero, nil, true, { _ in return nil }, {
|
||||
returnToCameraImpl?()
|
||||
})
|
||||
},
|
||||
transitionedOut: { [weak cameraHolder] in
|
||||
if let cameraHolder {
|
||||
cameraHolder.restore()
|
||||
}
|
||||
updatedPresentationData: updatedPresentationData,
|
||||
style: .glass,
|
||||
peer: nil,
|
||||
threadTitle: nil,
|
||||
chatLocation: nil,
|
||||
bannedSendPhotos: nil,
|
||||
bannedSendVideos: nil,
|
||||
subject: .assets(nil, .createAvatar),
|
||||
mainButtonState: mainButtonState,
|
||||
mainButtonAction: { [weak controller] in
|
||||
controller?.dismiss(animated: true)
|
||||
performDelete()
|
||||
}
|
||||
)
|
||||
controller?.push(cameraScreen)
|
||||
|
||||
returnToCameraImpl = { [weak cameraScreen] in
|
||||
if let cameraScreen = cameraScreen as? CameraScreen {
|
||||
cameraScreen.returnFromEditor()
|
||||
mediaPickerController.customSelection = { controller, result in
|
||||
if let result = result as? PHAsset {
|
||||
controller.updateHiddenMediaId(result.localIdentifier)
|
||||
if let transitionView = controller.transitionView(for: result.localIdentifier, snapshot: false) {
|
||||
let transitionOut: (Bool?) -> (UIView, CGRect)? = { isNew in
|
||||
if let isNew {
|
||||
if isNew {
|
||||
controller.updateHiddenMediaId(nil)
|
||||
if let transitionView = controller.defaultTransitionView() {
|
||||
return (transitionView, transitionView.bounds)
|
||||
}
|
||||
} else if let transitionView = controller.transitionView(for: result.localIdentifier, snapshot: false) {
|
||||
return (transitionView, transitionView.bounds)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
completion(result, transitionView, transitionView.bounds, controller.transitionImage(for: result.localIdentifier), false, transitionOut, { [weak controller] in
|
||||
controller?.updateHiddenMediaId(nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
mediaPickerController.openAvatarEditor = { [weak controller] in
|
||||
completion(nil, nil, .zero, nil, false, { _ in return nil }, {
|
||||
})
|
||||
controller?.dismiss(animated: true)
|
||||
}
|
||||
mediaPickerController.openCamera = { [weak controller] cameraHolder in
|
||||
let _ = controller
|
||||
guard let cameraHolder = cameraHolder as? CameraHolder else {
|
||||
return
|
||||
}
|
||||
|
||||
var returnToCameraImpl: (() -> Void)?
|
||||
|
||||
let cameraScreen = context.sharedContext.makeCameraScreen(
|
||||
context: context,
|
||||
mode: .avatar,
|
||||
cameraHolder: cameraHolder,
|
||||
transitionIn: CameraScreenTransitionIn(
|
||||
sourceView: cameraHolder.parentView,
|
||||
sourceRect: cameraHolder.parentView.bounds,
|
||||
sourceCornerRadius: 0.0,
|
||||
useFillAnimation: false
|
||||
),
|
||||
transitionOut: { _ in
|
||||
return CameraScreenTransitionOut(
|
||||
destinationView: cameraHolder.parentView,
|
||||
destinationRect: cameraHolder.parentView.bounds,
|
||||
destinationCornerRadius: 0.0
|
||||
)
|
||||
},
|
||||
completion: { result, commit in
|
||||
completion(result, nil, .zero, nil, true, { _ in return nil }, {
|
||||
returnToCameraImpl?()
|
||||
})
|
||||
},
|
||||
transitionedOut: { [weak cameraHolder] in
|
||||
if let cameraHolder {
|
||||
cameraHolder.restore()
|
||||
}
|
||||
}
|
||||
)
|
||||
controller?.push(cameraScreen)
|
||||
|
||||
returnToCameraImpl = { [weak cameraScreen] in
|
||||
if let cameraScreen = cameraScreen as? CameraScreen {
|
||||
cameraScreen.returnFromEditor()
|
||||
}
|
||||
}
|
||||
}
|
||||
present(mediaPickerController, mediaPickerController.mediaPickerContext)
|
||||
}
|
||||
present(mediaPickerController, mediaPickerController.mediaPickerContext)
|
||||
controller.willDismiss = {
|
||||
dismissed()
|
||||
}
|
||||
controller.navigationPresentation = .flatModal
|
||||
controller.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||
return (controller, nil)
|
||||
}
|
||||
controller.willDismiss = {
|
||||
dismissed()
|
||||
}
|
||||
controller.navigationPresentation = .flatModal
|
||||
controller.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||
return controller
|
||||
}
|
||||
|
||||
|
||||
@@ -3961,12 +4032,13 @@ public func coverMediaPickerController(
|
||||
return controller
|
||||
}
|
||||
|
||||
private class SelectedButtonNode: HighlightTrackingButtonNode {
|
||||
private class SelectedButtonNode: ASDisplayNode {
|
||||
private let containerView: UIView
|
||||
private let backgroundView: GlassBackgroundView?
|
||||
private let background: ASImageNode?
|
||||
private let icon = ASImageNode()
|
||||
private let label = ImmediateAnimatedCountLabelNode()
|
||||
private let button = HighlightTrackingButton()
|
||||
|
||||
private let glass: Bool
|
||||
|
||||
@@ -3982,6 +4054,8 @@ private class SelectedButtonNode: HighlightTrackingButtonNode {
|
||||
|
||||
private var count: Int32 = 0
|
||||
|
||||
var action: () -> Void = {}
|
||||
|
||||
init(theme: PresentationTheme, glass: Bool) {
|
||||
self.theme = theme
|
||||
self.glass = glass
|
||||
@@ -4007,6 +4081,9 @@ private class SelectedButtonNode: HighlightTrackingButtonNode {
|
||||
|
||||
self.view.addSubview(self.containerView)
|
||||
if let backgroundView = self.backgroundView {
|
||||
backgroundView.contentView.addSubnode(self.icon)
|
||||
backgroundView.contentView.addSubnode(self.label)
|
||||
backgroundView.contentView.addSubview(self.button)
|
||||
self.containerView.addSubview(backgroundView)
|
||||
}
|
||||
if let background = self.background {
|
||||
@@ -4014,35 +4091,19 @@ private class SelectedButtonNode: HighlightTrackingButtonNode {
|
||||
self.containerView.addSubnode(background)
|
||||
}
|
||||
|
||||
self.containerView.addSubnode(self.icon)
|
||||
self.containerView.addSubnode(self.label)
|
||||
|
||||
|
||||
self.highligthedChanged = { [weak self] highlighted in
|
||||
if let self {
|
||||
if glass {
|
||||
let transition = ComponentTransition(animation: .curve(duration: highlighted ? 0.25 : 0.35, curve: .spring))
|
||||
if highlighted {
|
||||
transition.setScale(view: self.containerView, scale: 1.2)
|
||||
} else {
|
||||
transition.setScale(view: self.containerView, scale: 1.0)
|
||||
}
|
||||
} else {
|
||||
if highlighted {
|
||||
self.containerView.layer.removeAnimation(forKey: "opacity")
|
||||
self.containerView.alpha = 0.4
|
||||
} else {
|
||||
self.containerView.alpha = 1.0
|
||||
self.containerView.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.button.addTarget(self, action: #selector(self.tapped), for: .touchUpInside)
|
||||
}
|
||||
|
||||
@objc private func tapped() {
|
||||
self.action()
|
||||
}
|
||||
|
||||
func update(count: Int32) -> CGSize {
|
||||
self.count = count
|
||||
|
||||
let diameter: CGFloat = self.glass ? 40.0 : 21.0
|
||||
let diameter: CGFloat = self.glass ? 44.0 : 21.0
|
||||
let font = self.glass ? Font.with(size: 17.0, weight: .medium, traits: [.monospacedNumbers]) : Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers])
|
||||
|
||||
let stringValue = "\(max(1, count))"
|
||||
@@ -4078,11 +4139,13 @@ private class SelectedButtonNode: HighlightTrackingButtonNode {
|
||||
self.containerView.frame = backgroundFrame
|
||||
if let backgroundView = self.backgroundView {
|
||||
backgroundView.frame = backgroundFrame
|
||||
backgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.size.height * 0.5, isDark: false, tintColor: .init(kind: .custom, color: self.theme.list.itemCheckColors.fillColor), transition: .immediate)
|
||||
backgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.size.height * 0.5, isDark: false, tintColor: .init(kind: .custom, color: self.theme.list.itemCheckColors.fillColor), isInteractive: true, transition: .immediate)
|
||||
}
|
||||
if let background = self.background {
|
||||
background.frame = backgroundFrame
|
||||
}
|
||||
|
||||
self.button.frame = CGRect(origin: .zero, size: size)
|
||||
|
||||
return size
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user