Tusker/Tusker/Preferences/Preferences.swift

254 lines
12 KiB
Swift
Raw Normal View History

2018-08-28 23:16:17 +00:00
//
// Preferences.swift
// Tusker
//
// Created by Shadowfacts on 8/28/18.
// Copyright © 2018 Shadowfacts. All rights reserved.
//
import UIKit
2018-09-11 14:52:21 +00:00
import Pachyderm
2019-06-14 00:53:17 +00:00
import Combine
2018-08-28 23:16:17 +00:00
2019-08-06 03:08:00 +00:00
class Preferences: Codable, ObservableObject {
2019-07-18 22:44:35 +00:00
2019-06-14 00:53:17 +00:00
static var shared: Preferences = load()
2018-08-28 23:16:17 +00:00
private static var documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
private static var archiveURL = Preferences.documentsDirectory.appendingPathComponent("preferences").appendingPathExtension("plist")
static func save() {
let encoder = PropertyListEncoder()
let data = try? encoder.encode(shared)
2018-10-23 02:09:11 +00:00
try? data?.write(to: archiveURL, options: .noFileProtection)
2018-08-28 23:16:17 +00:00
}
static func load() -> Preferences {
let decoder = PropertyListDecoder()
2018-10-23 02:09:11 +00:00
if let data = try? Data(contentsOf: archiveURL),
2018-08-28 23:16:17 +00:00
let preferences = try? decoder.decode(Preferences.self, from: data) {
return preferences
}
return Preferences()
}
private init() {}
2018-08-28 23:16:17 +00:00
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.theme = try container.decode(UIUserInterfaceStyle.self, forKey: .theme)
self.avatarStyle = try container.decode(AvatarStyle.self, forKey: .avatarStyle)
self.hideCustomEmojiInUsernames = try container.decode(Bool.self, forKey: .hideCustomEmojiInUsernames)
2020-06-17 21:45:34 +00:00
self.showIsStatusReplyIcon = try container.decode(Bool.self, forKey: .showIsStatusReplyIcon)
self.alwaysShowStatusVisibilityIcon = try container.decode(Bool.self, forKey: .alwaysShowStatusVisibilityIcon)
self.hideActionsInTimeline = try container.decodeIfPresent(Bool.self, forKey: .hideActionsInTimeline) ?? false
self.defaultPostVisibility = try container.decode(Status.Visibility.self, forKey: .defaultPostVisibility)
self.defaultReplyVisibility = try container.decodeIfPresent(ReplyVisibility.self, forKey: .defaultReplyVisibility) ?? .sameAsPost
self.automaticallySaveDrafts = try container.decode(Bool.self, forKey: .automaticallySaveDrafts)
self.requireAttachmentDescriptions = try container.decode(Bool.self, forKey: .requireAttachmentDescriptions)
self.contentWarningCopyMode = try container.decode(ContentWarningCopyMode.self, forKey: .contentWarningCopyMode)
self.mentionReblogger = try container.decode(Bool.self, forKey: .mentionReblogger)
self.useTwitterKeyboard = try container.decodeIfPresent(Bool.self, forKey: .useTwitterKeyboard) ?? false
2020-06-17 21:38:00 +00:00
2019-11-17 17:52:42 +00:00
self.blurAllMedia = try container.decode(Bool.self, forKey: .blurAllMedia)
self.blurMediaBehindContentWarning = try container.decodeIfPresent(Bool.self, forKey: .blurMediaBehindContentWarning) ?? true
self.automaticallyPlayGifs = try container.decode(Bool.self, forKey: .automaticallyPlayGifs)
2020-06-17 21:38:00 +00:00
self.openLinksInApps = try container.decode(Bool.self, forKey: .openLinksInApps)
self.useInAppSafari = try container.decode(Bool.self, forKey: .useInAppSafari)
self.inAppSafariAutomaticReaderMode = try container.decode(Bool.self, forKey: .inAppSafariAutomaticReaderMode)
self.expandAllContentWarnings = try container.decodeIfPresent(Bool.self, forKey: .expandAllContentWarnings) ?? false
self.collapseLongPosts = try container.decodeIfPresent(Bool.self, forKey: .collapseLongPosts) ?? true
self.oppositeCollapseKeywords = try container.decodeIfPresent([String].self, forKey: .oppositeCollapseKeywords) ?? []
self.confirmBeforeReblog = try container.decodeIfPresent(Bool.self, forKey: .confirmBeforeReblog) ?? false
self.showFavoriteAndReblogCounts = try container.decode(Bool.self, forKey: .showFavoriteAndReblogCounts)
self.defaultNotificationsMode = try container.decode(NotificationsMode.self, forKey: .defaultNotificationsType)
self.grayscaleImages = try container.decodeIfPresent(Bool.self, forKey: .grayscaleImages) ?? false
self.disableInfiniteScrolling = try container.decodeIfPresent(Bool.self, forKey: .disableInfiniteScrolling) ?? false
2022-04-01 23:23:49 +00:00
self.hideDiscover = try container.decodeIfPresent(Bool.self, forKey: .hideDiscover) ?? false
self.statusContentType = try container.decode(StatusContentType.self, forKey: .statusContentType)
2021-08-07 18:39:01 +00:00
self.hasShownLocalTimelineDescription = try container.decodeIfPresent(Bool.self, forKey: .hasShownLocalTimelineDescription) ?? false
self.hasShownFederatedTimelineDescription = try container.decodeIfPresent(Bool.self, forKey: .hasShownFederatedTimelineDescription) ?? false
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(theme, forKey: .theme)
try container.encode(avatarStyle, forKey: .avatarStyle)
try container.encode(hideCustomEmojiInUsernames, forKey: .hideCustomEmojiInUsernames)
2020-06-17 21:45:34 +00:00
try container.encode(showIsStatusReplyIcon, forKey: .showIsStatusReplyIcon)
try container.encode(alwaysShowStatusVisibilityIcon, forKey: .alwaysShowStatusVisibilityIcon)
try container.encode(hideActionsInTimeline, forKey: .hideActionsInTimeline)
try container.encode(defaultPostVisibility, forKey: .defaultPostVisibility)
try container.encode(defaultReplyVisibility, forKey: .defaultReplyVisibility)
try container.encode(automaticallySaveDrafts, forKey: .automaticallySaveDrafts)
try container.encode(requireAttachmentDescriptions, forKey: .requireAttachmentDescriptions)
try container.encode(contentWarningCopyMode, forKey: .contentWarningCopyMode)
try container.encode(mentionReblogger, forKey: .mentionReblogger)
try container.encode(useTwitterKeyboard, forKey: .useTwitterKeyboard)
2020-06-17 21:38:00 +00:00
2019-11-17 17:52:42 +00:00
try container.encode(blurAllMedia, forKey: .blurAllMedia)
try container.encode(blurMediaBehindContentWarning, forKey: .blurMediaBehindContentWarning)
try container.encode(automaticallyPlayGifs, forKey: .automaticallyPlayGifs)
2020-06-17 21:38:00 +00:00
try container.encode(openLinksInApps, forKey: .openLinksInApps)
try container.encode(useInAppSafari, forKey: .useInAppSafari)
try container.encode(inAppSafariAutomaticReaderMode, forKey: .inAppSafariAutomaticReaderMode)
try container.encode(expandAllContentWarnings, forKey: .expandAllContentWarnings)
try container.encode(collapseLongPosts, forKey: .collapseLongPosts)
try container.encode(oppositeCollapseKeywords, forKey: .oppositeCollapseKeywords)
try container.encode(confirmBeforeReblog, forKey: .confirmBeforeReblog)
try container.encode(showFavoriteAndReblogCounts, forKey: .showFavoriteAndReblogCounts)
try container.encode(defaultNotificationsMode, forKey: .defaultNotificationsType)
2020-11-01 18:59:58 +00:00
try container.encode(grayscaleImages, forKey: .grayscaleImages)
try container.encode(disableInfiniteScrolling, forKey: .disableInfiniteScrolling)
2022-04-01 23:23:49 +00:00
try container.encode(hideDiscover, forKey: .hideDiscover)
try container.encode(statusContentType, forKey: .statusContentType)
2021-08-07 18:39:01 +00:00
try container.encode(hasShownLocalTimelineDescription, forKey: .hasShownLocalTimelineDescription)
try container.encode(hasShownFederatedTimelineDescription, forKey: .hasShownFederatedTimelineDescription)
}
2020-06-17 21:38:00 +00:00
// MARK: Appearance
@Published var theme = UIUserInterfaceStyle.unspecified
@Published var avatarStyle = AvatarStyle.roundRect
@Published var hideCustomEmojiInUsernames = false
2020-06-17 21:45:34 +00:00
@Published var showIsStatusReplyIcon = false
@Published var alwaysShowStatusVisibilityIcon = false
@Published var hideActionsInTimeline = false
@Published var leadingStatusSwipeActions: [StatusSwipeAction] = [.favorite, .reblog]
@Published var trailingStatusSwipeActions: [StatusSwipeAction] = [.reply, .share]
2020-06-17 21:38:00 +00:00
// MARK: Composing
@Published var defaultPostVisibility = Status.Visibility.public
@Published var defaultReplyVisibility = ReplyVisibility.sameAsPost
@Published var automaticallySaveDrafts = true
@Published var requireAttachmentDescriptions = false
@Published var contentWarningCopyMode = ContentWarningCopyMode.asIs
@Published var mentionReblogger = false
@Published var useTwitterKeyboard = false
2020-06-17 21:38:00 +00:00
// MARK: Media
@Published var blurAllMedia = false {
didSet {
if blurAllMedia {
blurMediaBehindContentWarning = true
}
}
}
@Published var blurMediaBehindContentWarning = true
@Published var automaticallyPlayGifs = true
2020-06-17 21:38:00 +00:00
// MARK: Behavior
@Published var openLinksInApps = true
@Published var useInAppSafari = true
@Published var inAppSafariAutomaticReaderMode = false
@Published var expandAllContentWarnings = false
@Published var collapseLongPosts = true
@Published var oppositeCollapseKeywords: [String] = []
@Published var confirmBeforeReblog = false
2018-10-23 02:09:11 +00:00
2020-06-17 21:38:00 +00:00
// MARK: Digital Wellness
@Published var showFavoriteAndReblogCounts = true
@Published var defaultNotificationsMode = NotificationsMode.allNotifications
2020-11-01 18:59:58 +00:00
@Published var grayscaleImages = false
@Published var disableInfiniteScrolling = false
2022-04-01 23:23:49 +00:00
@Published var hideDiscover = false
2020-06-17 21:38:00 +00:00
// MARK: Advanced
@Published var statusContentType: StatusContentType = .plain
@Published var reportErrorsAutomatically = true
2021-08-07 18:39:01 +00:00
// MARK:
@Published var hasShownLocalTimelineDescription = false
@Published var hasShownFederatedTimelineDescription = false
2020-11-01 18:59:58 +00:00
private enum CodingKeys: String, CodingKey {
case theme
case avatarStyle
case hideCustomEmojiInUsernames
2020-06-17 21:45:34 +00:00
case showIsStatusReplyIcon
case alwaysShowStatusVisibilityIcon
case hideActionsInTimeline
2019-06-14 00:53:17 +00:00
case defaultPostVisibility
case defaultReplyVisibility
case automaticallySaveDrafts
case requireAttachmentDescriptions
case contentWarningCopyMode
case mentionReblogger
case useTwitterKeyboard
2020-06-17 21:38:00 +00:00
2019-11-17 17:52:42 +00:00
case blurAllMedia
case blurMediaBehindContentWarning
case automaticallyPlayGifs
2020-06-17 21:38:00 +00:00
case openLinksInApps
case useInAppSafari
case inAppSafariAutomaticReaderMode
case expandAllContentWarnings
case collapseLongPosts
case oppositeCollapseKeywords
case confirmBeforeReblog
case showFavoriteAndReblogCounts
case defaultNotificationsType
2020-11-01 18:59:58 +00:00
case grayscaleImages
case disableInfiniteScrolling
2022-04-01 23:23:49 +00:00
case hideDiscover
case statusContentType
2021-08-07 18:39:01 +00:00
case hasShownLocalTimelineDescription
case hasShownFederatedTimelineDescription
2019-06-14 00:53:17 +00:00
}
}
extension Preferences {
enum ReplyVisibility: Codable, Hashable, CaseIterable {
case sameAsPost
case visibility(Status.Visibility)
static var allCases: [Preferences.ReplyVisibility] = [.sameAsPost] + Status.Visibility.allCases.map { .visibility($0) }
var resolved: Status.Visibility {
switch self {
case .sameAsPost:
return Preferences.shared.defaultPostVisibility
case .visibility(let vis):
return vis
}
}
var displayName: String {
switch self {
case .sameAsPost:
return "Same as Default"
case .visibility(let vis):
return vis.displayName
}
}
var imageName: String? {
switch self {
case .sameAsPost:
return nil
case .visibility(let vis):
return vis.imageName
}
}
}
}
extension UIUserInterfaceStyle: Codable {}