diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index dedf768b3b..a711cfeef9 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -16,6 +16,10 @@ D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; }; D663625D2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D663625C2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib */; }; D663625F2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663625E2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift */; }; + D663626221360B1900C9CBA2 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626121360B1900C9CBA2 /* Preferences.swift */; }; + D663626421360D2300C9CBA2 /* AvatarStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626321360D2300C9CBA2 /* AvatarStyle.swift */; }; + D663626621360DD700C9CBA2 /* Preferences.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D663626521360DD700C9CBA2 /* Preferences.storyboard */; }; + D663626821360E2C00C9CBA2 /* PreferencesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */; }; D667E5E12134937B0057A976 /* StatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E02134937B0057A976 /* StatusTableViewCell.xib */; }; D667E5E3213499F70057A976 /* Profile.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E2213499F70057A976 /* Profile.storyboard */; }; D667E5E721349D4C0057A976 /* ProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */; }; @@ -84,6 +88,10 @@ D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = ""; }; D663625C2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConversationMainStatusTableViewCell.xib; sourceTree = ""; }; D663625E2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationMainStatusTableViewCell.swift; sourceTree = ""; }; + D663626121360B1900C9CBA2 /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = ""; }; + D663626321360D2300C9CBA2 /* AvatarStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarStyle.swift; sourceTree = ""; }; + D663626521360DD700C9CBA2 /* Preferences.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Preferences.storyboard; sourceTree = ""; }; + D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesTableViewController.swift; sourceTree = ""; }; D667E5E02134937B0057A976 /* StatusTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StatusTableViewCell.xib; sourceTree = ""; }; D667E5E2213499F70057A976 /* Profile.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Profile.storyboard; sourceTree = ""; }; D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTableViewController.swift; sourceTree = ""; }; @@ -141,6 +149,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + D663626021360A9600C9CBA2 /* Preferences */ = { + isa = PBXGroup; + children = ( + D663626121360B1900C9CBA2 /* Preferences.swift */, + D663626321360D2300C9CBA2 /* AvatarStyle.swift */, + ); + path = Preferences; + sourceTree = ""; + }; D667E5F62135C2ED0057A976 /* Extensions */ = { isa = PBXGroup; children = ( @@ -194,6 +211,7 @@ 04DACE89212CA6B7009840C4 /* Timeline.swift */, D64D0AAC2128D88B005A6F37 /* LocalData.swift */, 04DACE8D212CC7CC009840C4 /* AvatarCache.swift */, + D663626021360A9600C9CBA2 /* Preferences */, D667E5F62135C2ED0057A976 /* Extensions */, D6F953F121251A2F00CF0F2B /* Controllers */, D6F953E9212519B800CF0F2B /* View Controllers */, @@ -232,6 +250,7 @@ 04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */, D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */, D667E5F42135BCD50057A976 /* ConversationViewController.swift */, + D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */, ); path = "View Controllers"; sourceTree = ""; @@ -244,6 +263,7 @@ D64D0AAE2128D954005A6F37 /* Onboarding.storyboard */, D667E5E2213499F70057A976 /* Profile.storyboard */, D667E5F22135BC260057A976 /* Conversation.storyboard */, + D663626521360DD700C9CBA2 /* Preferences.storyboard */, ); path = Storyboards; sourceTree = ""; @@ -370,6 +390,7 @@ D6F953EE21251A0700CF0F2B /* Timeline.storyboard in Resources */, D6D4DDD5212518A000E1C4BB /* Main.storyboard in Resources */, D667E5E3213499F70057A976 /* Profile.storyboard in Resources */, + D663626621360DD700C9CBA2 /* Preferences.storyboard in Resources */, D667E5E12134937B0057A976 /* StatusTableViewCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -401,10 +422,13 @@ D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */, D667E5F82135C3040057A976 /* Mastodon+Equatable.swift in Sources */, 04DACE8E212CC7CC009840C4 /* AvatarCache.swift in Sources */, + D663626421360D2300C9CBA2 /* AvatarStyle.swift in Sources */, D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */, D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */, + D663626221360B1900C9CBA2 /* Preferences.swift in Sources */, D667E5EF2134C39F0057A976 /* StatusContentLabel.swift in Sources */, D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */, + D663626821360E2C00C9CBA2 /* PreferencesTableViewController.swift in Sources */, D6F953EC212519E700CF0F2B /* TimelineTableViewController.swift in Sources */, D667E5EB21349EF80057A976 /* ProfileHeaderTableViewCell.swift in Sources */, D64A0CD32132153900640E3B /* HTMLContentLabel.swift in Sources */, diff --git a/Tusker/AppDelegate.swift b/Tusker/AppDelegate.swift index 69befaf5f9..54e534c18d 100644 --- a/Tusker/AppDelegate.swift +++ b/Tusker/AppDelegate.swift @@ -33,6 +33,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + Preferences.save() } func applicationWillEnterForeground(_ application: UIApplication) { diff --git a/Tusker/Preferences/AvatarStyle.swift b/Tusker/Preferences/AvatarStyle.swift new file mode 100644 index 0000000000..ab840fc4df --- /dev/null +++ b/Tusker/Preferences/AvatarStyle.swift @@ -0,0 +1,13 @@ +// +// AvatarStyle.swift +// Tusker +// +// Created by Shadowfacts on 8/28/18. +// Copyright © 2018 Shadowfacts. All rights reserved. +// + +import Foundation + +enum AvatarStyle: String, Codable { + case roundRect, circle +} diff --git a/Tusker/Preferences/Preferences.swift b/Tusker/Preferences/Preferences.swift new file mode 100644 index 0000000000..5af83cf8aa --- /dev/null +++ b/Tusker/Preferences/Preferences.swift @@ -0,0 +1,35 @@ +// +// Preferences.swift +// Tusker +// +// Created by Shadowfacts on 8/28/18. +// Copyright © 2018 Shadowfacts. All rights reserved. +// + +import Foundation + +class Preferences: Codable { + + private(set) static var shared: Preferences = load() + + 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) + try? data?.write(to: Preferences.archiveURL, options: .noFileProtection) + } + + static func load() -> Preferences { + let decoder = PropertyListDecoder() + if let data = try? Data(contentsOf: Preferences.archiveURL), + let preferences = try? decoder.decode(Preferences.self, from: data) { + return preferences + } + return Preferences() + } + + var showRepliesInProfiles = false + +} diff --git a/Tusker/Storyboards/Preferences.storyboard b/Tusker/Storyboards/Preferences.storyboard new file mode 100644 index 0000000000..726fdc0bae --- /dev/null +++ b/Tusker/Storyboards/Preferences.storyboard @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tusker/View Controllers/MainTabBarViewController.swift b/Tusker/View Controllers/MainTabBarViewController.swift index 10d68452ee..04c5900bed 100644 --- a/Tusker/View Controllers/MainTabBarViewController.swift +++ b/Tusker/View Controllers/MainTabBarViewController.swift @@ -16,7 +16,8 @@ class MainTabBarViewController: UITabBarController { viewControllers = [ TimelineTableViewController.create(for: .home), TimelineTableViewController.create(for: .federated), - TimelineTableViewController.create(for: .local) + TimelineTableViewController.create(for: .local), + PreferencesTableViewController.create() ] } diff --git a/Tusker/View Controllers/PreferencesTableViewController.swift b/Tusker/View Controllers/PreferencesTableViewController.swift new file mode 100644 index 0000000000..400a27f0f1 --- /dev/null +++ b/Tusker/View Controllers/PreferencesTableViewController.swift @@ -0,0 +1,40 @@ +// +// PreferencesTableViewController.swift +// Tusker +// +// Created by Shadowfacts on 8/28/18. +// Copyright © 2018 Shadowfacts. All rights reserved. +// + +import UIKit + +class PreferencesTableViewController: UITableViewController { + + static func create() -> UIViewController { + guard let navigationController = UIStoryboard(name: "Preferences", bundle: nil).instantiateInitialViewController() as? UINavigationController else { fatalError() } + return navigationController + } + + @IBOutlet weak var showRepliesInProfilesSwitch: UISwitch! + + override func viewDidLoad() { + super.viewDidLoad() + + showRepliesInProfilesSwitch.setOn(Preferences.shared.showRepliesInProfiles, animated: false) + } + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + + @IBAction func showRepliesInProfilesChanged(_ sender: Any) { + Preferences.shared.showRepliesInProfiles = showRepliesInProfilesSwitch.isOn + } + +} diff --git a/Tusker/View Controllers/ProfileTableViewController.swift b/Tusker/View Controllers/ProfileTableViewController.swift index 86f3085e75..9b5abceca3 100644 --- a/Tusker/View Controllers/ProfileTableViewController.swift +++ b/Tusker/View Controllers/ProfileTableViewController.swift @@ -33,7 +33,7 @@ class ProfileTableViewController: UITableViewController { func request(for range: RequestRange? = .default) -> Request<[Status]> { let range = range ?? .default - return Accounts.statuses(id: account.id, mediaOnly: false, pinnedOnly: false, excludeReplies: true, range: range) + return Accounts.statuses(id: account.id, mediaOnly: false, pinnedOnly: false, excludeReplies: !Preferences.shared.showRepliesInProfiles, range: range) } override func viewDidLoad() {