fix: make interface style preference as global setting
This commit is contained in:
parent
6b1d3f8738
commit
b5052cca5e
|
@ -191,7 +191,6 @@
|
||||||
<relationship name="status" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Status" inverseName="searchHistories" inverseEntity="Status"/>
|
<relationship name="status" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Status" inverseName="searchHistories" inverseEntity="Status"/>
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="Setting" representedClassName=".Setting" syncable="YES">
|
<entity name="Setting" representedClassName=".Setting" syncable="YES">
|
||||||
<attribute name="appearanceRaw" attributeType="String"/>
|
|
||||||
<attribute name="createdAt" attributeType="Date" usesScalarValueType="NO"/>
|
<attribute name="createdAt" attributeType="Date" usesScalarValueType="NO"/>
|
||||||
<attribute name="domain" attributeType="String"/>
|
<attribute name="domain" attributeType="String"/>
|
||||||
<attribute name="preferredStaticAvatar" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
<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="PollOption" positionX="0" positionY="0" width="128" height="134"/>
|
||||||
<element name="PrivateNote" positionX="0" positionY="0" width="128" height="89"/>
|
<element name="PrivateNote" positionX="0" positionY="0" width="128" height="89"/>
|
||||||
<element name="SearchHistory" positionX="0" positionY="0" width="128" height="149"/>
|
<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="Status" positionX="0" positionY="0" width="128" height="599"/>
|
||||||
<element name="Subscription" positionX="81" positionY="171" width="128" height="179"/>
|
<element name="Subscription" positionX="81" positionY="171" width="128" height="179"/>
|
||||||
<element name="SubscriptionAlerts" positionX="72" positionY="162" width="128" height="14"/>
|
<element name="SubscriptionAlerts" positionX="72" positionY="162" width="128" height="14"/>
|
||||||
|
|
|
@ -13,7 +13,7 @@ public final class Setting: NSManagedObject {
|
||||||
@NSManaged public var domain: String
|
@NSManaged public var domain: String
|
||||||
@NSManaged public var userID: String
|
@NSManaged public var userID: String
|
||||||
|
|
||||||
@NSManaged public var appearanceRaw: String
|
// @NSManaged public var appearanceRaw: String
|
||||||
@NSManaged public var preferredTrueBlackDarkMode: Bool
|
@NSManaged public var preferredTrueBlackDarkMode: Bool
|
||||||
@NSManaged public var preferredStaticAvatar: Bool
|
@NSManaged public var preferredStaticAvatar: Bool
|
||||||
@NSManaged public var preferredStaticEmoji: Bool
|
@NSManaged public var preferredStaticEmoji: Bool
|
||||||
|
@ -41,17 +41,17 @@ extension Setting {
|
||||||
property: Property
|
property: Property
|
||||||
) -> Setting {
|
) -> Setting {
|
||||||
let setting: Setting = context.insertObject()
|
let setting: Setting = context.insertObject()
|
||||||
setting.appearanceRaw = property.appearanceRaw
|
// setting.appearanceRaw = property.appearanceRaw
|
||||||
setting.domain = property.domain
|
setting.domain = property.domain
|
||||||
setting.userID = property.userID
|
setting.userID = property.userID
|
||||||
return setting
|
return setting
|
||||||
}
|
}
|
||||||
|
|
||||||
public func update(appearanceRaw: String) {
|
// public func update(appearanceRaw: String) {
|
||||||
guard appearanceRaw != self.appearanceRaw else { return }
|
// guard appearanceRaw != self.appearanceRaw else { return }
|
||||||
self.appearanceRaw = appearanceRaw
|
// self.appearanceRaw = appearanceRaw
|
||||||
didUpdate(at: Date())
|
// didUpdate(at: Date())
|
||||||
}
|
// }
|
||||||
|
|
||||||
public func update(preferredTrueBlackDarkMode: Bool) {
|
public func update(preferredTrueBlackDarkMode: Bool) {
|
||||||
guard preferredTrueBlackDarkMode != self.preferredTrueBlackDarkMode else { return }
|
guard preferredTrueBlackDarkMode != self.preferredTrueBlackDarkMode else { return }
|
||||||
|
@ -87,12 +87,16 @@ extension Setting {
|
||||||
public struct Property {
|
public struct Property {
|
||||||
public let domain: String
|
public let domain: String
|
||||||
public let userID: 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.domain = domain
|
||||||
self.userID = userID
|
self.userID = userID
|
||||||
self.appearanceRaw = appearanceRaw
|
// self.appearanceRaw = appearanceRaw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,21 +41,17 @@ extension SettingsSection {
|
||||||
switch item {
|
switch item {
|
||||||
case .appearance(let objectID):
|
case .appearance(let objectID):
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SettingsAppearanceTableViewCell.self), for: indexPath) as! SettingsAppearanceTableViewCell
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SettingsAppearanceTableViewCell.self), for: indexPath) as! SettingsAppearanceTableViewCell
|
||||||
managedObjectContext.performAndWait {
|
UserDefaults.shared.observe(\.customUserInterfaceStyle, options: [.initial, .new]) { [weak cell] defaults, _ in
|
||||||
let setting = managedObjectContext.object(with: objectID) as! Setting
|
guard let cell = cell else { return }
|
||||||
cell.update(with: setting.appearance)
|
switch defaults.customUserInterfaceStyle {
|
||||||
ManagedObjectObserver.observe(object: setting)
|
case .unspecified: cell.update(with: .automatic)
|
||||||
.receive(on: DispatchQueue.main)
|
case .dark: cell.update(with: .dark)
|
||||||
.sink(receiveCompletion: { _ in
|
case .light: cell.update(with: .light)
|
||||||
// do nothing
|
@unknown default:
|
||||||
}, receiveValue: { [weak cell] change in
|
assertionFailure()
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
.store(in: &cell.observations)
|
||||||
cell.delegate = settingsAppearanceTableViewCellDelegate
|
cell.delegate = settingsAppearanceTableViewCellDelegate
|
||||||
return cell
|
return cell
|
||||||
case .notification(let objectID, let switchMode):
|
case .notification(let objectID, let switchMode):
|
||||||
|
|
|
@ -11,9 +11,9 @@ import MastodonSDK
|
||||||
|
|
||||||
extension Setting {
|
extension Setting {
|
||||||
|
|
||||||
var appearance: SettingsItem.AppearanceMode {
|
// var appearance: SettingsItem.AppearanceMode {
|
||||||
return SettingsItem.AppearanceMode(rawValue: appearanceRaw) ?? .automatic
|
// return SettingsItem.AppearanceMode(rawValue: appearanceRaw) ?? .automatic
|
||||||
}
|
// }
|
||||||
|
|
||||||
var activeSubscription: Subscription? {
|
var activeSubscription: Subscription? {
|
||||||
return (subscriptions ?? Set())
|
return (subscriptions ?? Set())
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
|
<true/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
|
|
@ -439,7 +439,7 @@ extension SettingsViewController {
|
||||||
.sink { _ in
|
.sink { _ in
|
||||||
// do nothing
|
// do nothing
|
||||||
} receiveValue: { _ in
|
} receiveValue: { _ in
|
||||||
// do nohting
|
// do nothing
|
||||||
}
|
}
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
}
|
}
|
||||||
|
@ -451,16 +451,19 @@ extension SettingsViewController: SettingsAppearanceTableViewCellDelegate {
|
||||||
guard let dataSource = viewModel.dataSource else { return }
|
guard let dataSource = viewModel.dataSource else { return }
|
||||||
guard let indexPath = tableView.indexPath(for: cell) else { return }
|
guard let indexPath = tableView.indexPath(for: cell) else { return }
|
||||||
let item = dataSource.itemIdentifier(for: indexPath)
|
let item = dataSource.itemIdentifier(for: indexPath)
|
||||||
guard case let .appearance(settingObjectID) = item else { return }
|
guard case .appearance = item else { return }
|
||||||
|
|
||||||
context.managedObjectContext.performChanges {
|
switch appearanceMode {
|
||||||
let setting = self.context.managedObjectContext.object(with: settingObjectID) as! Setting
|
case .automatic:
|
||||||
setting.update(appearanceRaw: appearanceMode.rawValue)
|
UserDefaults.shared.customUserInterfaceStyle = .unspecified
|
||||||
|
case .light:
|
||||||
|
UserDefaults.shared.customUserInterfaceStyle = .light
|
||||||
|
case .dark:
|
||||||
|
UserDefaults.shared.customUserInterfaceStyle = .dark
|
||||||
}
|
}
|
||||||
.sink { _ in
|
|
||||||
let feedbackGenerator = UIImpactFeedbackGenerator(style: .light)
|
let feedbackGenerator = UIImpactFeedbackGenerator(style: .light)
|
||||||
feedbackGenerator.impactOccurred()
|
feedbackGenerator.impactOccurred()
|
||||||
}.store(in: &disposeBag)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ protocol SettingsAppearanceTableViewCellDelegate: AnyObject {
|
||||||
class SettingsAppearanceTableViewCell: UITableViewCell {
|
class SettingsAppearanceTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
var disposeBag = Set<AnyCancellable>()
|
var disposeBag = Set<AnyCancellable>()
|
||||||
|
var observations = Set<NSKeyValueObservation>()
|
||||||
|
|
||||||
static let spacing: CGFloat = 18
|
static let spacing: CGFloat = 18
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ class SettingsAppearanceTableViewCell: UITableViewCell {
|
||||||
super.prepareForReuse()
|
super.prepareForReuse()
|
||||||
|
|
||||||
disposeBag.removeAll()
|
disposeBag.removeAll()
|
||||||
|
observations.removeAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
|
|
|
@ -54,8 +54,7 @@ final class SettingService {
|
||||||
into: managedObjectContext,
|
into: managedObjectContext,
|
||||||
property: Setting.Property(
|
property: Setting.Property(
|
||||||
domain: domain,
|
domain: domain,
|
||||||
userID: userID,
|
userID: userID
|
||||||
appearanceRaw: SettingsItem.AppearanceMode.automatic.rawValue
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} // end for
|
} // end for
|
||||||
|
@ -190,16 +189,16 @@ extension SettingService {
|
||||||
|
|
||||||
static func updatePreference(setting: Setting) {
|
static func updatePreference(setting: Setting) {
|
||||||
// set appearance
|
// set appearance
|
||||||
let userInterfaceStyle: UIUserInterfaceStyle = {
|
// let userInterfaceStyle: UIUserInterfaceStyle = {
|
||||||
switch setting.appearance {
|
// switch setting.appearance {
|
||||||
case .automatic: return .unspecified
|
// case .automatic: return .unspecified
|
||||||
case .light: return .light
|
// case .light: return .light
|
||||||
case .dark: return .dark
|
// case .dark: return .dark
|
||||||
}
|
// }
|
||||||
}()
|
// }()
|
||||||
if UserDefaults.shared.customUserInterfaceStyle != userInterfaceStyle {
|
// if UserDefaults.shared.customUserInterfaceStyle != userInterfaceStyle {
|
||||||
UserDefaults.shared.customUserInterfaceStyle = userInterfaceStyle
|
// UserDefaults.shared.customUserInterfaceStyle = userInterfaceStyle
|
||||||
}
|
// }
|
||||||
|
|
||||||
// set theme
|
// set theme
|
||||||
let themeName: ThemeName = setting.preferredTrueBlackDarkMode ? .system : .mastodon
|
let themeName: ThemeName = setting.preferredTrueBlackDarkMode ? .system : .mastodon
|
||||||
|
|
Loading…
Reference in New Issue