chore: restore the appearance settings

This commit is contained in:
CMK 2022-02-14 19:57:15 +08:00
parent ce80409ead
commit d561683c35
6 changed files with 98 additions and 53 deletions

View File

@ -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)

View File

@ -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()
}
}

View File

@ -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:

View File

@ -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:

View File

@ -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 {

View File

@ -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