Chat wallpaper removal

This commit is contained in:
Ilya Laktyushin 2023-04-06 17:53:37 +04:00
parent f2225fad71
commit 34062b0a06
6 changed files with 119 additions and 45 deletions

View File

@ -387,7 +387,13 @@ public struct AttachmentMainButtonState {
case center
}
public enum Font: Equatable {
case regular
case bold
}
public let text: String?
public let font: Font
public let background: Background
public let textColor: UIColor
public let isVisible: Bool
@ -396,6 +402,7 @@ public struct AttachmentMainButtonState {
public init(
text: String?,
font: Font,
background: Background,
textColor: UIColor,
isVisible: Bool,
@ -403,6 +410,7 @@ public struct AttachmentMainButtonState {
isEnabled: Bool
) {
self.text = text
self.font = font
self.background = background
self.textColor = textColor
self.isVisible = isVisible
@ -411,7 +419,7 @@ public struct AttachmentMainButtonState {
}
static var initial: AttachmentMainButtonState {
return AttachmentMainButtonState(text: nil, background: .color(.clear), textColor: .clear, isVisible: false, progress: .none, isEnabled: false)
return AttachmentMainButtonState(text: nil, font: .bold, background: .color(.clear), textColor: .clear, isVisible: false, progress: .none, isEnabled: false)
}
}
@ -643,7 +651,14 @@ private final class MainButtonNode: HighlightTrackingButtonNode {
self.setupShimmering()
if let text = state.text {
self.textNode.attributedText = NSAttributedString(string: text, font: Font.semibold(17.0), textColor: state.textColor)
let font: UIFont
switch state.font {
case .regular:
font = Font.regular(17.0)
case .bold:
font = Font.semibold(17.0)
}
self.textNode.attributedText = NSAttributedString(string: text, font: font, textColor: state.textColor)
let textSize = self.textNode.updateLayout(size)
self.textNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: floorToScreenPixels((size.height - textSize.height) / 2.0)), size: textSize)
@ -1267,7 +1282,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
func updateMainButtonState(_ mainButtonState: AttachmentMainButtonState?) {
var currentButtonState = self.mainButtonState
if mainButtonState == nil {
currentButtonState = AttachmentMainButtonState(text: currentButtonState.text, background: currentButtonState.background, textColor: currentButtonState.textColor, isVisible: false, progress: .none, isEnabled: currentButtonState.isEnabled)
currentButtonState = AttachmentMainButtonState(text: currentButtonState.text, font: currentButtonState.font, background: currentButtonState.background, textColor: currentButtonState.textColor, isVisible: false, progress: .none, isEnabled: currentButtonState.isEnabled)
}
self.mainButtonState = mainButtonState ?? currentButtonState
}
@ -1417,6 +1432,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
self.scrollNode.isUserInteractionEnabled = !isSelecting
let isButtonVisible = self.mainButtonState.isVisible
let isNarrowButton = isButtonVisible && self.mainButtonState.font == .regular
var insets = layout.insets(options: [])
if let inputHeight = layout.inputHeight, inputHeight > 0.0 && (isSelecting || isButtonVisible) {
@ -1457,7 +1473,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
if isButtonVisible {
var height: CGFloat
if layout.intrinsicInsets.bottom > 0.0 && (layout.inputHeight ?? 0.0).isZero {
height = bounds.height + 9.0
height = bounds.height
if case .regular = layout.metrics.widthClass {
if self.isStandalone {
height -= 3.0
@ -1466,7 +1482,10 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
}
}
} else {
height = bounds.height + 9.0 + 8.0
height = bounds.height + 8.0
}
if !isNarrowButton {
height += 9.0
}
containerFrame = CGRect(origin: CGPoint(), size: CGSize(width: bounds.width, height: height))
} else if isSelecting {
@ -1532,11 +1551,13 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
let sideInset: CGFloat = 16.0
let buttonSize = CGSize(width: layout.size.width - (sideInset + layout.safeInsets.left) * 2.0, height: 50.0)
let buttonTopInset: CGFloat = isNarrowButton ? 2.0 : 8.0
if !self.dismissed {
self.mainButtonNode.updateLayout(size: buttonSize, state: self.mainButtonState, transition: transition)
}
if !self.animatingTransition {
transition.updateFrame(node: self.mainButtonNode, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left + sideInset, y: isButtonVisible || self.fromMenu ? 8.0 : containerFrame.height), size: buttonSize))
transition.updateFrame(node: self.mainButtonNode, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left + sideInset, y: isButtonVisible || self.fromMenu ? buttonTopInset : containerFrame.height), size: buttonSize))
}
return containerFrame.height

View File

@ -1238,7 +1238,24 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
private var isDismissing = false
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer?, threadTitle: String?, chatLocation: ChatLocation?, bannedSendPhotos: (Int32, Bool)?, bannedSendVideos: (Int32, Bool)?, subject: Subject, editingContext: TGMediaEditingContext? = nil, selectionContext: TGMediaSelectionContext? = nil, saveEditedPhotos: Bool = false) {
fileprivate let mainButtonState: AttachmentMainButtonState?
private let mainButtonAction: (() -> Void)?
public init(
context: AccountContext,
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil,
peer: EnginePeer?,
threadTitle: String?,
chatLocation: ChatLocation?,
bannedSendPhotos: (Int32, Bool)?,
bannedSendVideos: (Int32, Bool)?,
subject: Subject,
editingContext: TGMediaEditingContext? = nil,
selectionContext: TGMediaSelectionContext? = nil,
saveEditedPhotos: Bool = false,
mainButtonState: AttachmentMainButtonState? = nil,
mainButtonAction: (() -> Void)? = nil
) {
self.context = context
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
@ -1251,6 +1268,8 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
self.bannedSendVideos = bannedSendVideos
self.subject = subject
self.saveEditedPhotos = saveEditedPhotos
self.mainButtonState = mainButtonState
self.mainButtonAction = mainButtonAction
let selectionContext = selectionContext ?? TGMediaSelectionContext()
@ -1627,6 +1646,10 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
}
}
func mainButtonPressed() {
self.mainButtonAction?()
}
func dismissAllTooltips() {
self.undoOverlayController?.dismissWithCommitAction()
}
@ -1811,21 +1834,17 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
}
public var mediaPickerContext: AttachmentMediaPickerContext? {
if let interaction = self.interaction {
return MediaPickerContext(interaction: interaction)
} else {
return nil
}
return MediaPickerContext(controller: self)
}
}
final class MediaPickerContext: AttachmentMediaPickerContext {
private weak var interaction: MediaPickerInteraction?
private weak var controller: MediaPickerScreen?
var selectionCount: Signal<Int, NoError> {
return Signal { [weak self] subscriber in
let disposable = self?.interaction?.selectionState?.selectionChangedSignal().start(next: { [weak self] value in
subscriber.putNext(Int(self?.interaction?.selectionState?.count() ?? 0))
let disposable = self?.controller?.interaction?.selectionState?.selectionChangedSignal().start(next: { [weak self] value in
subscriber.putNext(Int(self?.controller?.interaction?.selectionState?.count() ?? 0))
}, error: { _ in }, completed: { })
return ActionDisposable {
disposable?.dispose()
@ -1835,7 +1854,7 @@ final class MediaPickerContext: AttachmentMediaPickerContext {
var caption: Signal<NSAttributedString?, NoError> {
return Signal { [weak self] subscriber in
let disposable = self?.interaction?.editingState.forcedCaption().start(next: { caption in
let disposable = self?.controller?.interaction?.editingState.forcedCaption().start(next: { caption in
if let caption = caption as? NSAttributedString {
subscriber.putNext(caption)
} else {
@ -1853,27 +1872,27 @@ final class MediaPickerContext: AttachmentMediaPickerContext {
}
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
return .single(nil)
return .single(self.controller?.mainButtonState)
}
init(interaction: MediaPickerInteraction) {
self.interaction = interaction
init(controller: MediaPickerScreen) {
self.controller = controller
}
func setCaption(_ caption: NSAttributedString) {
self.interaction?.editingState.setForcedCaption(caption, skipUpdate: true)
self.controller?.interaction?.editingState.setForcedCaption(caption, skipUpdate: true)
}
func send(mode: AttachmentMediaPickerSendMode, attachmentMode: AttachmentMediaPickerAttachmentMode) {
self.interaction?.sendSelected(nil, mode == .silently, mode == .whenOnline ? scheduleWhenOnlineTimestamp : nil, true, {})
self.controller?.interaction?.sendSelected(nil, mode == .silently, mode == .whenOnline ? scheduleWhenOnlineTimestamp : nil, true, {})
}
func schedule() {
self.interaction?.schedule()
self.controller?.interaction?.schedule()
}
func mainButtonAction() {
self.controller?.mainButtonPressed()
}
}
@ -1987,12 +2006,22 @@ public class MediaPickerGridSelectionGesture<T> : UIPanGestureRecognizer {
}
}
public func standaloneMediaPickerController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, subject: MediaPickerScreen.Subject, completion: @escaping (PHAsset) -> Void = { _ in }) -> ViewController {
public func wallpaperMediaPickerController(
context: AccountContext,
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil,
peer: EnginePeer,
canDelete: Bool,
completion: @escaping (PHAsset) -> Void = { _ in }
) -> ViewController {
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: nil, buttons: [.standalone], initialButton: .standalone, fromMenu: false, hasTextInput: false, makeEntityInputView: {
return nil
})
controller.requestController = { _, present in
let mediaPickerController = MediaPickerScreen(context: context, peer: nil, threadTitle: nil, chatLocation: nil, bannedSendPhotos: nil, bannedSendVideos: nil, subject: subject)
controller.requestController = { [weak controller] _, present in
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let mediaPickerController = MediaPickerScreen(context: context, peer: nil, threadTitle: nil, chatLocation: nil, bannedSendPhotos: nil, bannedSendVideos: nil, subject: .assets(nil, .wallpaper), mainButtonState: canDelete ? AttachmentMainButtonState(text: presentationData.strings.Conversation_Theme_ResetWallpaper, font: .regular, background: .color(.clear), textColor: presentationData.theme.actionSheet.destructiveActionTextColor, isVisible: true, progress: .none, isEnabled: true) : nil, mainButtonAction: canDelete ? {
let _ = context.engine.themes.setChatWallpaper(peerId: peer.id, wallpaper: nil).start()
controller?.dismiss(animated: true)
} : nil)
mediaPickerController.customSelection = completion
present(mediaPickerController, mediaPickerController.mediaPickerContext)
}

View File

@ -645,7 +645,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
price = nil
}
let buttonText = presentationData.strings.Premium_Gift_GiftSubscription(price ?? "").string
self.buttonStatePromise.set(.single(AttachmentMainButtonState(text: buttonText, background: .premium, textColor: .white, isVisible: true, progress: self.inProgress ? .center : .none, isEnabled: true)))
self.buttonStatePromise.set(.single(AttachmentMainButtonState(text: buttonText, font: .bold, background: .premium, textColor: .white, isVisible: true, progress: self.inProgress ? .center : .none, isEnabled: true)))
}
func buy() {

View File

@ -150,7 +150,7 @@ public final class ThemeColorsGridController: ViewController, AttachmentContaina
var pushController: (ViewController) -> Void = { _ in }
public init(context: AccountContext, mode: Mode = .default) {
public init(context: AccountContext, mode: Mode = .default, canDelete: Bool = false) {
self.context = context
self.mode = mode
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
@ -190,6 +190,10 @@ public final class ThemeColorsGridController: ViewController, AttachmentContaina
self.pushController = { [weak self] controller in
self?.push(controller)
}
if canDelete {
self.mainButtonStatePromise.set(.single(AttachmentMainButtonState(text: self.presentationData.strings.Conversation_Theme_ResetWallpaper, font: .regular, background: .color(.clear), textColor: self.presentationData.theme.actionSheet.destructiveActionTextColor, isVisible: true, progress: .none, isEnabled: true)))
}
}
required public init(coder aDecoder: NSCoder) {
@ -317,7 +321,12 @@ public final class ThemeColorsGridController: ViewController, AttachmentContaina
}
@objc fileprivate func mainButtonPressed() {
guard case let .peer(peer) = self.mode else {
return
}
let _ = self.context.engine.themes.setChatWallpaper(peerId: peer.id, wallpaper: nil).start()
self.dismiss(animated: true)
}
public var requestAttachmentMenuExpansion: () -> Void = {}
@ -370,12 +379,12 @@ private final class ThemeColorsGridContext: AttachmentMediaPickerContext {
}
public func standaloneColorPickerController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer, push: @escaping (ViewController) -> Void) -> ViewController {
public func standaloneColorPickerController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer, canDelete: Bool, push: @escaping (ViewController) -> Void) -> ViewController {
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: nil, buttons: [.standalone], initialButton: .standalone, fromMenu: false, hasTextInput: false, makeEntityInputView: {
return nil
})
controller.requestController = { _, present in
let colorPickerController = ThemeColorsGridController(context: context, mode: .peer(peer))
let colorPickerController = ThemeColorsGridController(context: context, mode: .peer(peer), canDelete: canDelete)
colorPickerController.pushController = { controller in
push(controller)
}

View File

@ -18520,21 +18520,31 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
let controller = standaloneMediaPickerController(context: strongSelf.context, subject: .assets(nil, .wallpaper), completion: { asset in
guard let strongSelf = self else {
return
}
let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset), mode: .peer(EnginePeer(peer), false))
controller.navigationPresentation = .modal
controller.apply = { [weak self] wallpaper, options, cropRect in
if let strongSelf = self {
uploadCustomPeerWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, cropRect: cropRect, peerId: peerId, completion: {
dismissControllers()
})
var canDelete = false
if let cachedUserData = strongSelf.peerView?.cachedData as? CachedUserData {
canDelete = cachedUserData.wallpaper != nil
}
let controller = wallpaperMediaPickerController(
context: strongSelf.context,
updatedPresentationData: strongSelf.updatedPresentationData,
peer: EnginePeer(peer),
canDelete: canDelete,
completion: { asset in
guard let strongSelf = self else {
return
}
let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset), mode: .peer(EnginePeer(peer), false))
controller.navigationPresentation = .modal
controller.apply = { [weak self] wallpaper, options, cropRect in
if let strongSelf = self {
uploadCustomPeerWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, cropRect: cropRect, peerId: peerId, completion: {
dismissControllers()
})
}
}
strongSelf.push(controller)
}
strongSelf.push(controller)
})
)
controller.navigationPresentation = .flatModal
strongSelf.push(controller)
},
@ -18546,7 +18556,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
strongSelf.themeScreen = nil
themeController.dimTapped()
}
let controller = standaloneColorPickerController(context: strongSelf.context, peer: EnginePeer(peer), push: { [weak self] controller in
var canDelete = false
if let cachedUserData = strongSelf.peerView?.cachedData as? CachedUserData {
canDelete = cachedUserData.wallpaper != nil
}
let controller = standaloneColorPickerController(context: strongSelf.context, peer: EnginePeer(peer), canDelete: canDelete, push: { [weak self] controller in
if let strongSelf = self {
strongSelf.push(controller)
}

View File

@ -675,7 +675,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
let isLoading = json["is_progress_visible"] as? Bool
let isEnabled = json["is_active"] as? Bool
let state = AttachmentMainButtonState(text: text, background: .color(backgroundColor), textColor: textColor, isVisible: isVisible, progress: (isLoading ?? false) ? .side : .none, isEnabled: isEnabled ?? true)
let state = AttachmentMainButtonState(text: text, font: .bold, background: .color(backgroundColor), textColor: textColor, isVisible: isVisible, progress: (isLoading ?? false) ? .side : .none, isEnabled: isEnabled ?? true)
self.mainButtonState = state
}
}