chore: restore the appearance settings
This commit is contained in:
parent
ce80409ead
commit
d561683c35
|
@ -13,6 +13,7 @@ import MastodonLocalization
|
|||
|
||||
enum SettingsItem {
|
||||
case appearance(record: ManagedObjectRecord<Setting>)
|
||||
case appearancePreference(record: ManagedObjectRecord<Setting>, appearanceType: AppearanceType)
|
||||
case preference(settingRecord: ManagedObjectRecord<Setting>, preferenceType: PreferenceType)
|
||||
case notification(settingRecord: ManagedObjectRecord<Setting>, switchMode: NotificationSwitchMode)
|
||||
case boringZone(item: Link)
|
||||
|
@ -23,11 +24,18 @@ extension SettingsItem {
|
|||
|
||||
enum AppearanceMode: String {
|
||||
case system
|
||||
case reallyDark
|
||||
case sortaDark
|
||||
case dark
|
||||
case light
|
||||
}
|
||||
|
||||
enum AppearanceType: Hashable {
|
||||
case preferredTrueDarkMode
|
||||
|
||||
var title: String {
|
||||
return L10n.Scene.Settings.Section.Preference.trueBlackDarkMode
|
||||
}
|
||||
}
|
||||
|
||||
enum NotificationSwitchMode: CaseIterable, Hashable {
|
||||
case favorite
|
||||
case follow
|
||||
|
@ -94,9 +102,13 @@ extension SettingsItem {
|
|||
extension SettingsItem: Hashable {
|
||||
func hash(into hasher: inout Hasher) {
|
||||
switch self {
|
||||
case .appearance(let settingObjectID):
|
||||
case .appearance(let record):
|
||||
hasher.combine(String(describing: SettingsItem.AppearanceMode.self))
|
||||
hasher.combine(settingObjectID)
|
||||
hasher.combine(record)
|
||||
case .appearancePreference(let record, let appearanceType):
|
||||
hasher.combine(String(describing: SettingsItem.AppearanceType.self))
|
||||
hasher.combine(record)
|
||||
hasher.combine(appearanceType)
|
||||
case .notification(let settingObjectID, let switchMode):
|
||||
hasher.combine(String(describing: SettingsItem.notification.self))
|
||||
hasher.combine(settingObjectID)
|
||||
|
|
|
@ -13,6 +13,7 @@ import MastodonLocalization
|
|||
|
||||
enum SettingsSection: Hashable {
|
||||
case appearance
|
||||
case appearancePreference
|
||||
case preference
|
||||
case notifications
|
||||
case boringZone
|
||||
|
@ -20,8 +21,9 @@ enum SettingsSection: Hashable {
|
|||
|
||||
var title: String {
|
||||
switch self {
|
||||
case .appearance: return "Look and Feel" // TODO: i18n
|
||||
case .preference: return ""
|
||||
case .appearance: return L10n.Scene.Settings.Section.Appearance.title
|
||||
case .appearancePreference: return ""
|
||||
case .preference: return L10n.Scene.Settings.Section.Preference.title
|
||||
case .notifications: return L10n.Scene.Settings.Section.Notifications.title
|
||||
case .boringZone: return L10n.Scene.Settings.Section.BoringZone.title
|
||||
case .spicyZone: return L10n.Scene.Settings.Section.SpicyZone.title
|
||||
|
@ -49,6 +51,26 @@ extension SettingsSection {
|
|||
}
|
||||
cell.delegate = settingsAppearanceTableViewCellDelegate
|
||||
return cell
|
||||
case .appearancePreference(let record, let appearanceType):
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SettingsToggleTableViewCell.self), for: indexPath) as! SettingsToggleTableViewCell
|
||||
cell.delegate = settingsToggleCellDelegate
|
||||
managedObjectContext.performAndWait {
|
||||
guard let setting = record.object(in: managedObjectContext) else { return }
|
||||
SettingsSection.configureSettingToggle(cell: cell, item: item, setting: setting)
|
||||
|
||||
ManagedObjectObserver.observe(object: setting)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveCompletion: { _ in
|
||||
// do nothing
|
||||
}, receiveValue: { [weak cell] change in
|
||||
guard let cell = cell else { return }
|
||||
guard case .update(let object) = change.changeType,
|
||||
let setting = object as? Setting else { return }
|
||||
SettingsSection.configureSettingToggle(cell: cell, item: item, setting: setting)
|
||||
})
|
||||
.store(in: &cell.disposeBag)
|
||||
}
|
||||
return cell
|
||||
case .preference(let record, _):
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SettingsToggleTableViewCell.self), for: indexPath) as! SettingsToggleTableViewCell
|
||||
cell.delegate = settingsToggleCellDelegate
|
||||
|
@ -107,17 +129,29 @@ extension SettingsSection {
|
|||
item: SettingsItem,
|
||||
setting: Setting
|
||||
) {
|
||||
guard case let .preference(_, preferenceType) = item else { return }
|
||||
|
||||
cell.textLabel?.text = preferenceType.title
|
||||
|
||||
switch preferenceType {
|
||||
case .disableAvatarAnimation:
|
||||
cell.switchButton.isOn = setting.preferredStaticAvatar
|
||||
case .disableEmojiAnimation:
|
||||
cell.switchButton.isOn = setting.preferredStaticEmoji
|
||||
case .useDefaultBrowser:
|
||||
cell.switchButton.isOn = setting.preferredUsingDefaultBrowser
|
||||
switch item {
|
||||
case .appearancePreference(_, let appearanceType):
|
||||
cell.textLabel?.text = appearanceType.title
|
||||
|
||||
switch appearanceType {
|
||||
case .preferredTrueDarkMode:
|
||||
cell.switchButton.isOn = setting.preferredTrueBlackDarkMode
|
||||
}
|
||||
|
||||
case .preference(_, let preferenceType):
|
||||
cell.textLabel?.text = preferenceType.title
|
||||
|
||||
switch preferenceType {
|
||||
case .disableAvatarAnimation:
|
||||
cell.switchButton.isOn = setting.preferredStaticAvatar
|
||||
case .disableEmojiAnimation:
|
||||
cell.switchButton.isOn = setting.preferredStaticEmoji
|
||||
case .useDefaultBrowser:
|
||||
cell.switchButton.isOn = setting.preferredUsingDefaultBrowser
|
||||
}
|
||||
|
||||
default:
|
||||
assertionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,11 +51,7 @@ extension SettingsAppearanceTableViewCell.ViewModel {
|
|||
case .unspecified:
|
||||
cell.systemAppearanceView.selected = true
|
||||
case .dark:
|
||||
if preferredTrueBlackDarkMode {
|
||||
cell.reallyDarkAppearanceView.selected = true
|
||||
} else {
|
||||
cell.sortaDarkAppearanceView.selected = true
|
||||
}
|
||||
cell.darkAppearanceView.selected = true
|
||||
case .light:
|
||||
cell.lightAppearanceView.selected = true
|
||||
@unknown default:
|
||||
|
|
|
@ -39,26 +39,21 @@ class SettingsAppearanceTableViewCell: UITableViewCell {
|
|||
|
||||
let systemAppearanceView = AppearanceView(
|
||||
image: Asset.Settings.darkAuto.image,
|
||||
title: "Use System" // TODO: i18n
|
||||
title: L10n.Scene.Settings.Section.Appearance.automatic
|
||||
)
|
||||
let reallyDarkAppearanceView = AppearanceView(
|
||||
let darkAppearanceView = AppearanceView(
|
||||
image: Asset.Settings.dark.image,
|
||||
title: "Really Dark"
|
||||
)
|
||||
let sortaDarkAppearanceView = AppearanceView(
|
||||
image: Asset.Settings.dark.image,
|
||||
title: "Sorta Dark"
|
||||
title: L10n.Scene.Settings.Section.Appearance.dark
|
||||
)
|
||||
let lightAppearanceView = AppearanceView(
|
||||
image: Asset.Settings.light.image,
|
||||
title: "Light"
|
||||
title: L10n.Scene.Settings.Section.Appearance.light
|
||||
)
|
||||
|
||||
var appearanceViews: [AppearanceView] {
|
||||
return [
|
||||
systemAppearanceView,
|
||||
reallyDarkAppearanceView,
|
||||
sortaDarkAppearanceView,
|
||||
darkAppearanceView,
|
||||
lightAppearanceView,
|
||||
]
|
||||
}
|
||||
|
@ -111,8 +106,7 @@ extension SettingsAppearanceTableViewCell {
|
|||
])
|
||||
|
||||
stackView.addArrangedSubview(systemAppearanceView)
|
||||
stackView.addArrangedSubview(reallyDarkAppearanceView)
|
||||
stackView.addArrangedSubview(sortaDarkAppearanceView)
|
||||
stackView.addArrangedSubview(darkAppearanceView)
|
||||
stackView.addArrangedSubview(lightAppearanceView)
|
||||
|
||||
appearanceViews.forEach { view in
|
||||
|
@ -132,10 +126,8 @@ extension SettingsAppearanceTableViewCell {
|
|||
switch sender.view {
|
||||
case systemAppearanceView:
|
||||
mode = .system
|
||||
case reallyDarkAppearanceView:
|
||||
mode = .reallyDark
|
||||
case sortaDarkAppearanceView:
|
||||
mode = .sortaDark
|
||||
case darkAppearanceView:
|
||||
mode = .dark
|
||||
case lightAppearanceView:
|
||||
mode = .light
|
||||
default:
|
||||
|
|
|
@ -328,6 +328,8 @@ extension SettingsViewController: UITableViewDelegate {
|
|||
|
||||
let header: SettingsSectionHeader
|
||||
switch sectionIdentifier {
|
||||
case .appearancePreference:
|
||||
return UIView()
|
||||
case .notifications:
|
||||
header = SettingsSectionHeader(
|
||||
frame: CGRect(x: 0, y: 0, width: 375, height: 66),
|
||||
|
@ -360,6 +362,9 @@ extension SettingsViewController: UITableViewDelegate {
|
|||
case .appearance:
|
||||
// do nothing
|
||||
break
|
||||
case .appearancePreference:
|
||||
// do nothing
|
||||
break
|
||||
case .notification:
|
||||
// do nothing
|
||||
break
|
||||
|
@ -450,28 +455,16 @@ extension SettingsViewController: SettingsAppearanceTableViewCellDelegate {
|
|||
let item = dataSource.itemIdentifier(for: indexPath)
|
||||
guard case let .appearance(record) = item else { return }
|
||||
|
||||
Task { @MainActor in
|
||||
var preferredTrueBlackDarkMode = false
|
||||
|
||||
Task { @MainActor in
|
||||
switch appearanceMode {
|
||||
case .system:
|
||||
UserDefaults.shared.customUserInterfaceStyle = .unspecified
|
||||
case .reallyDark:
|
||||
UserDefaults.shared.customUserInterfaceStyle = .dark
|
||||
preferredTrueBlackDarkMode = true
|
||||
case .sortaDark:
|
||||
case .dark:
|
||||
UserDefaults.shared.customUserInterfaceStyle = .dark
|
||||
case .light:
|
||||
UserDefaults.shared.customUserInterfaceStyle = .light
|
||||
}
|
||||
|
||||
let managedObjectContext = context.managedObjectContext
|
||||
try await managedObjectContext.performChanges {
|
||||
guard let setting = record.object(in: managedObjectContext) else { return }
|
||||
setting.update(preferredTrueBlackDarkMode: preferredTrueBlackDarkMode)
|
||||
}
|
||||
ThemeService.shared.set(themeName: preferredTrueBlackDarkMode ? .system : .mastodon)
|
||||
|
||||
let feedbackGenerator = UIImpactFeedbackGenerator(style: .light)
|
||||
feedbackGenerator.impactOccurred()
|
||||
} // end Task
|
||||
|
@ -507,6 +500,18 @@ extension SettingsViewController: SettingsToggleCellDelegate {
|
|||
// do nothing
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
case .appearancePreference(let record, let appearanceType):
|
||||
switch appearanceType {
|
||||
case .preferredTrueDarkMode:
|
||||
Task {
|
||||
let managedObjectContext = context.managedObjectContext
|
||||
try await managedObjectContext.performChanges {
|
||||
guard let setting = record.object(in: managedObjectContext) else { return }
|
||||
setting.update(preferredTrueBlackDarkMode: isOn)
|
||||
}
|
||||
ThemeService.shared.set(themeName: isOn ? .system : .mastodon)
|
||||
} // end Task
|
||||
}
|
||||
case .preference(let record, let preferenceType):
|
||||
let managedObjectContext = context.backgroundManagedObjectContext
|
||||
managedObjectContext.performChanges {
|
||||
|
|
|
@ -108,10 +108,16 @@ extension SettingsViewModel {
|
|||
var snapshot = NSDiffableDataSourceSnapshot<SettingsSection, SettingsItem>()
|
||||
|
||||
// appearance
|
||||
let appearanceItems = [SettingsItem.appearance(record: .init(objectID: setting.objectID))]
|
||||
let appearanceItems = [
|
||||
SettingsItem.appearance(record: .init(objectID: setting.objectID))
|
||||
]
|
||||
snapshot.appendSections([.appearance])
|
||||
snapshot.appendItems(appearanceItems, toSection: .appearance)
|
||||
|
||||
// appearancePreference
|
||||
snapshot.appendSections([.appearancePreference])
|
||||
snapshot.appendItems([SettingsItem.appearancePreference(record: .init(objectID: setting.objectID), appearanceType: .preferredTrueDarkMode)], toSection: .appearancePreference)
|
||||
|
||||
// preference
|
||||
snapshot.appendSections([.preference])
|
||||
let preferenceItems: [SettingsItem] = SettingsItem.PreferenceType.allCases.map { preferenceType in
|
||||
|
|
Loading…
Reference in New Issue