TM-SGNL-iOS/Signal/Emoji/EmojiReactionPickerConfigViewController.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

140 lines
5 KiB
Swift

//
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import SignalServiceKit
public import SignalUI
public class EmojiReactionPickerConfigViewController: UIViewController {
private lazy var reactionPicker: MessageReactionPicker = {
return MessageReactionPicker(
selectedEmoji: nil,
delegate: nil,
style: .configure,
forceDarkTheme: self.forceDarkTheme
)
}()
private lazy var instructionLabel: UILabel = {
let label = UILabel()
label.text = OWSLocalizedString("TAP_REPLACE_EMOJI", comment: "Tap to Replace Emoji string for reaction configuration")
label.font = UIFont.dynamicTypeBody2
label.textColor = self.forceDarkTheme ? Theme.darkThemeSecondaryTextAndIconColor : Theme.secondaryTextAndIconColor
return label
}()
private let forceDarkTheme: Bool
private let reactionPickerConfigurationListener: ReactionPickerConfigurationListener?
init(
forceDarkTheme: Bool = false,
reactionPickerConfigurationListener: ReactionPickerConfigurationListener? = nil
) {
self.forceDarkTheme = forceDarkTheme
self.reactionPickerConfigurationListener = reactionPickerConfigurationListener
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func viewDidLoad() {
super.viewDidLoad()
title = OWSLocalizedString("CONFIGURE_REACTIONS", comment: "Configure reactions title text")
if self.forceDarkTheme || Theme.isDarkThemeEnabled {
view.backgroundColor = .ows_gray75
} else {
view.backgroundColor = UIColor.color(rgbHex: 0xF0F0F0)
}
navigationItem.rightBarButtonItem = .doneButton { [weak self] in
self?.doneButtonTapped()
}
navigationItem.leftBarButtonItem = .button(
title: OWSLocalizedString(
"RESET",
comment: "Configure reactions reset button text"
),
style: .plain,
action: { [weak self] in
self?.resetButtonTapped()
}
)
if self.forceDarkTheme {
navigationController?.navigationBar.tintColor = .white
let textAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
navigationController?.navigationBar.titleTextAttributes = textAttributes
}
// Reaction picker
reactionPicker.delegate = self
view.addSubview(reactionPicker)
reactionPicker.autoHCenterInSuperview()
reactionPicker.autoPinEdge(toSuperviewMargin: .top, withInset: 95)
view.addSubview(instructionLabel)
instructionLabel.autoHCenterInSuperview()
instructionLabel.autoPinEdge(.top, to: .bottom, of: reactionPicker, withOffset: 30)
}
private func resetButtonTapped() {
let emojiSet: [EmojiWithSkinTones] = ReactionManager.defaultEmojiSet.map { EmojiWithSkinTones(rawValue: $0)! }
for (index, emoji) in reactionPicker.currentEmojiSet().enumerated() {
if let newEmoji = emojiSet[safe: index]?.rawValue {
reactionPicker.replaceEmojiReaction(emoji, newEmoji: newEmoji, inPosition: index)
}
}
}
private func doneButtonTapped() {
let currentEmojiSet = reactionPicker.currentEmojiSet()
SSKEnvironment.shared.databaseStorageRef.write { transaction in
ReactionManager.setCustomEmojiSet(currentEmojiSet, transaction: transaction)
}
self.reactionPickerConfigurationListener?.didCompleteReactionPickerConfiguration()
SSKEnvironment.shared.storageServiceManagerRef.recordPendingLocalAccountUpdates()
dismiss(animated: true, completion: nil)
}
}
extension EmojiReactionPickerConfigViewController: MessageReactionPickerDelegate {
func didSelectReaction(reaction: String, isRemoving: Bool, inPosition position: Int) {
if presentedViewController != nil {
self.reactionPicker.endReplaceAnimation()
presentedViewController?.dismiss(animated: true, completion: nil)
return
}
let picker = EmojiPickerSheet(message: nil, allowReactionConfiguration: false) { [weak self] emoji in
guard let self = self else { return }
guard let emojiString = emoji?.rawValue else {
self.reactionPicker.endReplaceAnimation()
return
}
self.reactionPicker.replaceEmojiReaction(reaction, newEmoji: emojiString, inPosition: position)
self.reactionPicker.endReplaceAnimation()
}
picker.backdropColor = .clear
reactionPicker.startReplaceAnimation(focusedEmoji: reaction, inPosition: position)
present(picker, animated: true)
}
func didSelectAnyEmoji() {
// No-op for configuration
}
}
protocol ReactionPickerConfigurationListener {
func didCompleteReactionPickerConfiguration()
}