fix: make interface style preference as global setting

This commit is contained in:
CMK 2021-10-08 18:47:46 +08:00
parent 6b1d3f8738
commit b5052cca5e
8 changed files with 55 additions and 50 deletions

View File

@ -191,7 +191,6 @@
<relationship name="status" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Status" inverseName="searchHistories" inverseEntity="Status"/>
</entity>
<entity name="Setting" representedClassName=".Setting" syncable="YES">
<attribute name="appearanceRaw" attributeType="String"/>
<attribute name="createdAt" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="domain" attributeType="String"/>
<attribute name="preferredStaticAvatar" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
@ -289,7 +288,7 @@
<element name="PollOption" positionX="0" positionY="0" width="128" height="134"/>
<element name="PrivateNote" positionX="0" positionY="0" width="128" height="89"/>
<element name="SearchHistory" positionX="0" positionY="0" width="128" height="149"/>
<element name="Setting" positionX="72" positionY="162" width="128" height="179"/>
<element name="Setting" positionX="72" positionY="162" width="128" height="164"/>
<element name="Status" positionX="0" positionY="0" width="128" height="599"/>
<element name="Subscription" positionX="81" positionY="171" width="128" height="179"/>
<element name="SubscriptionAlerts" positionX="72" positionY="162" width="128" height="14"/>

View File

@ -13,7 +13,7 @@ public final class Setting: NSManagedObject {
@NSManaged public var domain: String
@NSManaged public var userID: String
@NSManaged public var appearanceRaw: String
// @NSManaged public var appearanceRaw: String
@NSManaged public var preferredTrueBlackDarkMode: Bool
@NSManaged public var preferredStaticAvatar: Bool
@NSManaged public var preferredStaticEmoji: Bool
@ -41,17 +41,17 @@ extension Setting {
property: Property
) -> Setting {
let setting: Setting = context.insertObject()
setting.appearanceRaw = property.appearanceRaw
// setting.appearanceRaw = property.appearanceRaw
setting.domain = property.domain
setting.userID = property.userID
return setting
}
public func update(appearanceRaw: String) {
guard appearanceRaw != self.appearanceRaw else { return }
self.appearanceRaw = appearanceRaw
didUpdate(at: Date())
}
// public func update(appearanceRaw: String) {
// guard appearanceRaw != self.appearanceRaw else { return }
// self.appearanceRaw = appearanceRaw
// didUpdate(at: Date())
// }
public func update(preferredTrueBlackDarkMode: Bool) {
guard preferredTrueBlackDarkMode != self.preferredTrueBlackDarkMode else { return }
@ -87,12 +87,16 @@ extension Setting {
public struct Property {
public let domain: String
public let userID: String
public let appearanceRaw: String
// public let appearanceRaw: String
public init(domain: String, userID: String, appearanceRaw: String) {
public init(
domain: String,
userID: String
// appearanceRaw: String
) {
self.domain = domain
self.userID = userID
self.appearanceRaw = appearanceRaw
// self.appearanceRaw = appearanceRaw
}
}
}

View File

@ -41,21 +41,17 @@ extension SettingsSection {
switch item {
case .appearance(let objectID):
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SettingsAppearanceTableViewCell.self), for: indexPath) as! SettingsAppearanceTableViewCell
managedObjectContext.performAndWait {
let setting = managedObjectContext.object(with: objectID) as! Setting
cell.update(with: setting.appearance)
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 }
cell.update(with: setting.appearance)
})
.store(in: &cell.disposeBag)
UserDefaults.shared.observe(\.customUserInterfaceStyle, options: [.initial, .new]) { [weak cell] defaults, _ in
guard let cell = cell else { return }
switch defaults.customUserInterfaceStyle {
case .unspecified: cell.update(with: .automatic)
case .dark: cell.update(with: .dark)
case .light: cell.update(with: .light)
@unknown default:
assertionFailure()
}
}
.store(in: &cell.observations)
cell.delegate = settingsAppearanceTableViewCellDelegate
return cell
case .notification(let objectID, let switchMode):

View File

@ -11,9 +11,9 @@ import MastodonSDK
extension Setting {
var appearance: SettingsItem.AppearanceMode {
return SettingsItem.AppearanceMode(rawValue: appearanceRaw) ?? .automatic
}
// var appearance: SettingsItem.AppearanceMode {
// return SettingsItem.AppearanceMode(rawValue: appearanceRaw) ?? .automatic
// }
var activeSubscription: Subscription? {
return (subscriptions ?? Set())

View File

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>

View File

@ -439,7 +439,7 @@ extension SettingsViewController {
.sink { _ in
// do nothing
} receiveValue: { _ in
// do nohting
// do nothing
}
.store(in: &disposeBag)
}
@ -451,16 +451,19 @@ extension SettingsViewController: SettingsAppearanceTableViewCellDelegate {
guard let dataSource = viewModel.dataSource else { return }
guard let indexPath = tableView.indexPath(for: cell) else { return }
let item = dataSource.itemIdentifier(for: indexPath)
guard case let .appearance(settingObjectID) = item else { return }
guard case .appearance = item else { return }
context.managedObjectContext.performChanges {
let setting = self.context.managedObjectContext.object(with: settingObjectID) as! Setting
setting.update(appearanceRaw: appearanceMode.rawValue)
switch appearanceMode {
case .automatic:
UserDefaults.shared.customUserInterfaceStyle = .unspecified
case .light:
UserDefaults.shared.customUserInterfaceStyle = .light
case .dark:
UserDefaults.shared.customUserInterfaceStyle = .dark
}
.sink { _ in
let feedbackGenerator = UIImpactFeedbackGenerator(style: .light)
feedbackGenerator.impactOccurred()
}.store(in: &disposeBag)
let feedbackGenerator = UIImpactFeedbackGenerator(style: .light)
feedbackGenerator.impactOccurred()
}
}

View File

@ -15,6 +15,7 @@ protocol SettingsAppearanceTableViewCellDelegate: AnyObject {
class SettingsAppearanceTableViewCell: UITableViewCell {
var disposeBag = Set<AnyCancellable>()
var observations = Set<NSKeyValueObservation>()
static let spacing: CGFloat = 18
@ -59,6 +60,7 @@ class SettingsAppearanceTableViewCell: UITableViewCell {
super.prepareForReuse()
disposeBag.removeAll()
observations.removeAll()
}
// MARK: - Methods

View File

@ -54,8 +54,7 @@ final class SettingService {
into: managedObjectContext,
property: Setting.Property(
domain: domain,
userID: userID,
appearanceRaw: SettingsItem.AppearanceMode.automatic.rawValue
userID: userID
)
)
} // end for
@ -190,16 +189,16 @@ extension SettingService {
static func updatePreference(setting: Setting) {
// set appearance
let userInterfaceStyle: UIUserInterfaceStyle = {
switch setting.appearance {
case .automatic: return .unspecified
case .light: return .light
case .dark: return .dark
}
}()
if UserDefaults.shared.customUserInterfaceStyle != userInterfaceStyle {
UserDefaults.shared.customUserInterfaceStyle = userInterfaceStyle
}
// let userInterfaceStyle: UIUserInterfaceStyle = {
// switch setting.appearance {
// case .automatic: return .unspecified
// case .light: return .light
// case .dark: return .dark
// }
// }()
// if UserDefaults.shared.customUserInterfaceStyle != userInterfaceStyle {
// UserDefaults.shared.customUserInterfaceStyle = userInterfaceStyle
// }
// set theme
let themeName: ThemeName = setting.preferredTrueBlackDarkMode ? .system : .mastodon