Hook up the emoji picker to the custom status row. (#5902)

* Refactor EmojiPickerScreen to take a continuation instead of a timeline/itemID.

* Hook up the emoji picker to the custom status row.
This commit is contained in:
Doug
2026-07-22 13:35:37 +01:00
committed by GitHub
parent a6466e80e0
commit 32a54c5b71
19 changed files with 223 additions and 92 deletions
@@ -22,6 +22,7 @@ enum SettingsScreenCoordinatorAction {
case logout
case secureBackup
case userDetails
case userStatusEmojiPicker(EmojiPickerScreenContinuation)
case analytics
case appLock
case bugReport
@@ -64,6 +65,8 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
actionsSubject.send(.dismiss)
case .userDetails:
actionsSubject.send(.userDetails)
case let .userStatusEmojiPicker(continuation):
actionsSubject.send(.userStatusEmojiPicker(continuation))
case .linkNewDevice:
actionsSubject.send(.linkNewDevice)
case let .manageAccount(url):
@@ -8,9 +8,10 @@
import SwiftUI
enum SettingsScreenViewModelAction: Equatable {
enum SettingsScreenViewModelAction {
case close
case userDetails
case userStatusEmojiPicker(EmojiPickerScreenContinuation)
case linkNewDevice
case manageAccount(url: URL)
case analytics
@@ -55,7 +56,7 @@ struct SettingsScreenViewState: BindableState {
var userStatusRowMode: SettingsScreenUserStatusRow.Mode {
if bindings.isShowingCustomStatusField {
.custom
.custom(emoji: bindings.customStatusEmoji)
} else if let rawStatus = userProfile.status.raw {
.show(rawStatus)
} else {
@@ -66,7 +67,15 @@ struct SettingsScreenViewState: BindableState {
struct SettingsScreenViewStateBindings {
var isPresentingStatusPicker = false
var isShowingCustomStatusField = false
var customStatusEmoji: Character = "😄"
var isShowingCustomStatusField = false {
didSet {
if !isShowingCustomStatusField {
customStatusEmoji = "😄" // Reset the emoji.
}
}
}
var isPresentingAccountDeactivationConfirmation = false
}
@@ -103,7 +103,7 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
state.bindings.isPresentingStatusPicker = false
state.bindings.isShowingCustomStatusField = true
case .userStatus(.pickCustomEmoji):
break // Hook-up the emoji picker here.
pickCustomEmoji()
case .userStatus(.set(let status)):
Task { await setUserStatus(status) }
case .userStatus(.cancel):
@@ -144,6 +144,19 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
// MARK: - Private
private var pickCustomEmojiCancellable: AnyCancellable?
private func pickCustomEmoji() {
let (stream, continuation) = AsyncStream<String>.makeStream()
actionsSubject.send(.userStatusEmojiPicker(continuation))
pickCustomEmojiCancellable = Task { [weak self] in
for await emoji in stream {
self?.state.bindings.customStatusEmoji = Character(emoji)
}
}
.asCancellable()
}
func setUserStatus(_ status: UserStatus.Raw?) async {
// Loading state tbc
state.bindings.isPresentingStatusPicker = false
@@ -9,11 +9,10 @@ import Compound
import SwiftUI
struct SettingsScreenUserStatusRow: View {
enum Mode: Equatable { case pick, custom, show(UserStatus.Raw) }
enum Mode: Equatable { case pick, custom(emoji: Character), show(UserStatus.Raw) }
let mode: Mode
let action: (SettingsScreenViewAction.UserStatusAction) -> Void
@State private var customEmoji = "😄"
@State private var customText = ""
var body: some View {
@@ -21,15 +20,15 @@ struct SettingsScreenUserStatusRow: View {
case .pick:
ListRow(label: .default(title: L10n.screenSettingsUserStatusPlaceholder, icon: \.reaction),
kind: .button { action(.pickStatus) })
case .custom:
case .custom(let emoji):
ListRow(kind: .custom {
HStack(spacing: ListRowPadding.labelIconSpacing) {
Button { action(.pickCustomEmoji) } label: {
Text(customEmoji)
Text(String(emoji))
.font(.compound.headingSM)
.foregroundStyle(.compound.textPrimary)
.accessibilityLabel(L10n.a11yCustomEmoji)
.accessibilityValue(customEmoji)
.accessibilityValue(String(emoji))
}
.buttonStyle(EditEmojiButtonStyle())
@@ -81,7 +80,7 @@ struct SettingsScreenUserStatusRow: View {
}
private func saveCustomStatus() {
guard let emoji = customEmoji.first else { return }
guard case let .custom(emoji) = mode else { return }
action(.set(.init(text: customText, emoji: emoji)))
}
@@ -109,7 +108,7 @@ struct SettingsScreenUserStatusRow_Previews: PreviewProvider, TestablePreview {
}
Section {
SettingsScreenUserStatusRow(mode: .custom) { _ in }
SettingsScreenUserStatusRow(mode: .custom(emoji: "😄")) { _ in }
}
Section {