From ff65f50689c1ed5637d487da09d72b572214f3a2 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 3 Nov 2022 17:17:02 +0100 Subject: [PATCH 01/15] Add menu-entry for show/hide reblogs (#365) translations are still missing, as well as viewModel/networking-stuff. --- .../Provider/DataSourceFacade+Status.swift | 3 +++ .../Scene/Profile/ProfileViewController.swift | 1 + .../Generated/Strings.swift | 4 ++++ .../Resources/en.lproj/Localizable.strings | 2 ++ .../MastodonUI/View/Menu/MastodonMenu.swift | 21 ++++++++++++++++++- .../ViewModel/RelationshipViewModel.swift | 1 + 6 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index 9d9e73eb3..412079293 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -205,6 +205,9 @@ extension DataSourceFacade { menuContext: MenuContext ) async throws { switch action { + case .hideReblogs(_): + //TODO: Implement. Alert. Toggle on Server. + return case .muteUser(let actionContext): let alertController = UIAlertController( title: actionContext.isMuting ? L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.title : L10n.Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.title, diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 9dd06b22c..34c2775c8 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -378,6 +378,7 @@ extension ProfileViewController { let _ = ManagedObjectRecord(objectID: user.objectID) let menu = MastodonMenu.setupMenu( actions: [ + .hideReblogs(.init(showReblogs: self.viewModel.relationshipViewModel.showReblogs)), .muteUser(.init(name: name, isMuting: self.viewModel.relationshipViewModel.isMuting)), .blockUser(.init(name: name, isBlocking: self.viewModel.relationshipViewModel.isBlocking)), .reportUser(.init(name: name)), diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index c64a50fa2..1d5b9895b 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -198,6 +198,8 @@ public enum L10n { public static let follow = L10n.tr("Localizable", "Common.Controls.Friendship.Follow") /// Following public static let following = L10n.tr("Localizable", "Common.Controls.Friendship.Following") + /// Hide Reblogs + public static let hideReblogs = L10n.tr("Localizable", "Common.Controls.Friendship.HideReblogs") /// Mute public static let mute = L10n.tr("Localizable", "Common.Controls.Friendship.Mute") /// Muted @@ -210,6 +212,8 @@ public enum L10n { public static let pending = L10n.tr("Localizable", "Common.Controls.Friendship.Pending") /// Request public static let request = L10n.tr("Localizable", "Common.Controls.Friendship.Request") + /// Show Reblogs + public static let showReblogs = L10n.tr("Localizable", "Common.Controls.Friendship.ShowReblogs") /// Unblock public static let unblock = L10n.tr("Localizable", "Common.Controls.Friendship.Unblock") /// Unblock %@ diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 1c40bf855..94bee697c 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -77,6 +77,8 @@ Please check your internet connection."; "Common.Controls.Friendship.UnblockUser" = "Unblock %@"; "Common.Controls.Friendship.Unmute" = "Unmute"; "Common.Controls.Friendship.UnmuteUser" = "Unmute %@"; +"Common.Controls.Friendship.HideReblogs" = "Hide Reblogs"; +"Common.Controls.Friendship.ShowReblogs" = "Show Reblogs"; "Common.Controls.Keyboard.Common.ComposeNewPost" = "Compose New Post"; "Common.Controls.Keyboard.Common.OpenSettings" = "Open Settings"; "Common.Controls.Keyboard.Common.ShowFavorites" = "Show Favorites"; diff --git a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift index d6a5bdbac..b85e71138 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift @@ -45,11 +45,23 @@ extension MastodonMenu { case reportUser(ReportUserActionContext) case shareUser(ShareUserActionContext) case bookmarkStatus(BookmarkStatusActionContext) + case hideReblogs(HideReblogsActionContext) case shareStatus case deleteStatus func build(delegate: MastodonMenuDelegate) -> BuiltAction { switch self { + case .hideReblogs(let context): + let title = context.showReblogs ? L10n.Common.Controls.Friendship.hideReblogs : L10n.Common.Controls.Friendship.hideReblogs + let reblogAction = BuiltAction( + title: title, + image: UIImage(systemName: "arrow.2.squarepath") + ) { [weak delegate] in + guard let delegate = delegate else { return } + delegate.menuAction(self) + } + + return reblogAction case .muteUser(let context): let muteAction = BuiltAction( title: context.isMuting ? L10n.Common.Controls.Friendship.unmuteUser(context.name) : L10n.Common.Controls.Friendship.muteUser(context.name), @@ -205,5 +217,12 @@ extension MastodonMenu { self.name = name } } - + + public struct HideReblogsActionContext { + public let showReblogs: Bool + + public init(showReblogs: Bool) { + self.showReblogs = showReblogs + } + } } diff --git a/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift b/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift index a19de5138..5b032aa90 100644 --- a/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift @@ -114,6 +114,7 @@ public final class RelationshipViewModel { @Published public var isFollowing = false @Published public var isFollowingBy = false @Published public var isMuting = false + @Published public var showReblogs = false @Published public var isBlocking = false @Published public var isBlockingBy = false @Published public var isSuspended = false From 13b849449450bb38d936e5505c7caa4ba5e05c17 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 3 Nov 2022 17:17:28 +0100 Subject: [PATCH 02/15] Consider old-school intel macs for development --- Gemfile.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile.lock b/Gemfile.lock index 873f725e5..e0ed91c5b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,6 +100,7 @@ GEM PLATFORMS arm64-darwin-21 + x86_64-darwin-21 DEPENDENCIES arkana From 8f8ae7d6a25e059a43d978df7fceb0bee2568c4f Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 3 Nov 2022 17:18:03 +0100 Subject: [PATCH 03/15] Have xcode update dependencies --- .../xcshareddata/swiftpm/Package.resolved | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index 34ffd227b..f15e4a422 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/Alamofire/Alamofire.git", "state" : { - "revision" : "354dda32d89fc8cd4f5c46487f64957d355f53d8", - "version" : "5.6.1" + "revision" : "8dd85aee02e39dd280c75eef88ffdb86eed4b07b", + "version" : "5.6.2" } }, { @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/Flipboard/FLAnimatedImage.git", "state" : { - "revision" : "e7f9fd4681ae41bf6f3056db08af4f401d61da52", - "version" : "1.0.16" + "revision" : "d4f07b6f164d53c1212c3e54d6460738b1981e9f", + "version" : "1.0.17" } }, { @@ -95,8 +95,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/kean/Nuke.git", "state" : { - "revision" : "0ea7545b5c918285aacc044dc75048625c8257cc", - "version" : "10.8.0" + "revision" : "a002b7fd786f2df2ed4333fe73a9727499fd9d97", + "version" : "10.11.2" } }, { @@ -113,8 +113,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/uias/Pageboy", "state" : { - "revision" : "34ecb6e7c4e0e07494960ab2f7cc9a02293915a6", - "version" : "3.6.2" + "revision" : "af8fa81788b893205e1ff42ddd88c5b0b315d7c5", + "version" : "3.7.0" } }, { @@ -131,8 +131,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/SDWebImage/SDWebImage.git", "state" : { - "revision" : "2e63d0061da449ad0ed130768d05dceb1496de44", - "version" : "5.12.5" + "revision" : "318cca556b0489aede0cd98d8d0c7f1408ab7bd6", + "version" : "5.13.5" } }, { @@ -176,8 +176,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/scinfu/SwiftSoup.git", "state" : { - "revision" : "41e7c263fb8c277e980ebcb9b0b5f6031d3d4886", - "version" : "2.4.2" + "revision" : "6778575285177365cbad3e5b8a72f2a20583cfec", + "version" : "2.4.3" } }, { From ce0e56b84e3c140074c6bd6c7c7fbc5fd2aa7885 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 4 Nov 2022 16:25:11 +0100 Subject: [PATCH 04/15] Add showsReblog to CoreData/persistence (#365) --- .../CoreData.xcdatamodeld/.xccurrentversion | 2 +- .../CoreData 4.xcdatamodel/contents | 254 ++++++++++++++++++ .../Entity/Mastodon/MastodonUser.swift | 15 +- .../Persistence+MastodonUser.swift | 1 + 4 files changed, 270 insertions(+), 2 deletions(-) create mode 100644 MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 4.xcdatamodel/contents diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion index cdd244c9c..1d5ea989f 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - CoreData 3.xcdatamodel + CoreData 4.xcdatamodel diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 4.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 4.xcdatamodel/contents new file mode 100644 index 000000000..7604028f1 --- /dev/null +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 4.xcdatamodel/contents @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift index 85e844b09..760985d68 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift @@ -89,7 +89,8 @@ final public class MastodonUser: NSManagedObject { @NSManaged public private(set) var endorsedBy: Set @NSManaged public private(set) var domainBlocking: Set @NSManaged public private(set) var domainBlockingBy: Set - + @NSManaged public private(set) var showingReblogs: Set + @NSManaged public private(set) var showingReblogsBy: Set } extension MastodonUser { @@ -521,6 +522,7 @@ extension MastodonUser: AutoUpdatableObject { } } } + public func update(isDomainBlocking: Bool, by mastodonUser: MastodonUser) { if isDomainBlocking { if !self.domainBlockingBy.contains(mastodonUser) { @@ -533,4 +535,15 @@ extension MastodonUser: AutoUpdatableObject { } } + public func update(isShowingReblogs: Bool, by mastodonUser: MastodonUser) { + if isShowingReblogs { + if !self.showingReblogsBy.contains(mastodonUser) { + self.mutableSetValue(forKey: #keyPath(MastodonUser.showingReblogsBy)).add(mastodonUser) + } + } else { + if self.showingReblogsBy.contains(mastodonUser) { + self.mutableSetValue(forKey: #keyPath(MastodonUser.showingReblogsBy)).remove(mastodonUser) + } + } + } } diff --git a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+MastodonUser.swift b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+MastodonUser.swift index eb69c36d1..8571a11cf 100644 --- a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+MastodonUser.swift +++ b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+MastodonUser.swift @@ -157,5 +157,6 @@ extension Persistence.MastodonUser { user.update(isBlocking: relationship.blocking, by: me) relationship.domainBlocking.flatMap { user.update(isDomainBlocking: $0, by: me) } relationship.blockedBy.flatMap { me.update(isBlocking: $0, by: user) } + relationship.showingReblogs.flatMap { me.update(isShowingReblogs: $0, by: user) } } } From b719d84d3fdd0e29c28f14318177c95d2cbdf883 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 4 Nov 2022 16:28:14 +0100 Subject: [PATCH 05/15] [WIP] Toggle showReblogs-status on mastodon-server --- .../Provider/DataSourceFacade+Follow.swift | 11 ++++ .../Provider/DataSourceFacade+Status.swift | 52 +++++++++++++++---- .../Scene/Profile/ProfileViewController.swift | 6 ++- .../Service/API/APIService+Follow.swift | 52 ++++++++++++++++++- 4 files changed, 108 insertions(+), 13 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Follow.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Follow.swift index c6e40e7d9..b3812f198 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Follow.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Follow.swift @@ -132,3 +132,14 @@ extension DataSourceFacade { } } // end func } + +extension DataSourceFacade { + static func responseToShowHideReblogAction( + dependency: NeedsDependency & AuthContextProvider, + user: ManagedObjectRecord + ) async throws { + _ = try await dependency.context.apiService.toggleShowReblogs( + for: user, + authenticationBox: dependency.authContext.mastodonAuthenticationBox) + } +} diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index 412079293..ff41cc126 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -205,9 +205,42 @@ extension DataSourceFacade { menuContext: MenuContext ) async throws { switch action { - case .hideReblogs(_): - //TODO: Implement. Alert. Toggle on Server. - return + case .hideReblogs(let actionContext): + //FIXME: Add localized strings + let alertController = UIAlertController( + title: actionContext.showReblogs ? "Really hide?" : "Really show?", + message: actionContext.showReblogs ? "Really??" : "Really??", + preferredStyle: .alert + ) + + let showHideReblogsAction = UIAlertAction( + title: actionContext.showReblogs ? "Show" : "Hide", + style: .default + ) { [weak dependency] _ in + guard let dependency else { return } + + Task { + let managedObjectContext = dependency.context.managedObjectContext + let _user: ManagedObjectRecord? = try? await managedObjectContext.perform { + guard let user = menuContext.author?.object(in: managedObjectContext) else { return nil } + return ManagedObjectRecord(objectID: user.objectID) + } + + guard let user = _user else { return } + + try await DataSourceFacade.responseToShowHideReblogAction( + dependency: dependency, + user: user + ) + } + } + + alertController.addAction(showHideReblogsAction) + + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) + alertController.addAction(cancelAction) + + dependency.present(alertController, animated: true) case .muteUser(let actionContext): let alertController = UIAlertController( title: actionContext.isMuting ? L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.title : L10n.Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.title, @@ -233,9 +266,9 @@ extension DataSourceFacade { } // end Task } alertController.addAction(confirmAction) - let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil) + let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel) alertController.addAction(cancelAction) - dependency.present(alertController, animated: true, completion: nil) + dependency.present(alertController, animated: true) case .blockUser(let actionContext): let alertController = UIAlertController( title: actionContext.isBlocking ? L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.title : L10n.Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.title, @@ -261,9 +294,9 @@ extension DataSourceFacade { } // end Task } alertController.addAction(confirmAction) - let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil) + let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel) alertController.addAction(cancelAction) - dependency.present(alertController, animated: true, completion: nil) + dependency.present(alertController, animated: true) case .reportUser: Task { guard let user = menuContext.author else { return } @@ -352,9 +385,9 @@ extension DataSourceFacade { } // end Task } alertController.addAction(confirmAction) - let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil) + let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel) alertController.addAction(cancelAction) - dependency.present(alertController, animated: true, completion: nil) + dependency.present(alertController, animated: true) } } // end func @@ -374,3 +407,4 @@ extension DataSourceFacade { } } + diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 34c2775c8..dcaefccb7 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -378,8 +378,8 @@ extension ProfileViewController { let _ = ManagedObjectRecord(objectID: user.objectID) let menu = MastodonMenu.setupMenu( actions: [ - .hideReblogs(.init(showReblogs: self.viewModel.relationshipViewModel.showReblogs)), .muteUser(.init(name: name, isMuting: self.viewModel.relationshipViewModel.isMuting)), + .hideReblogs(.init(showReblogs: self.viewModel.relationshipViewModel.showReblogs)), .blockUser(.init(name: name, isBlocking: self.viewModel.relationshipViewModel.isBlocking)), .reportUser(.init(name: name)), .shareUser(.init(name: name)), @@ -398,7 +398,9 @@ extension ProfileViewController { } } receiveValue: { [weak self] menu in guard let self = self else { return } - self.moreMenuBarButtonItem.menu = menu + OperationQueue.main.addOperation { + self.moreMenuBarButtonItem.menu = menu + } } .store(in: &disposeBag) } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift index cfb5b8ee2..38c49970c 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift @@ -13,13 +13,14 @@ import CommonOSLog import MastodonSDK extension APIService { - + private struct MastodonFollowContext { let sourceUserID: MastodonUser.ID let targetUserID: MastodonUser.ID let isFollowing: Bool let isPending: Bool let needsUnfollow: Bool + let showsReblogs: Bool } /// Toggle friendship between target MastodonUser and current MastodonUser @@ -121,5 +122,52 @@ extension APIService { let response = try result.get() return response } - + + public func toggleShowReblogs( + for user: ManagedObjectRecord, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content { + + let managedObjectContext = backgroundManagedObjectContext + guard let user = user.object(in: managedObjectContext) else { throw APIError.implicit(.badRequest) } + + let result: Result, Error> + let showReblogs = false //FIXME: Use showReblogs-value from data + let oldShowReblogs = true + + do { + let response = try await Mastodon.API.Account.follow( + session: session, + domain: authenticationBox.domain, + accountID: user.id, + followQueryType: .follow(query: .init(reblogs: showReblogs)), + authorization: authenticationBox.userAuthorization + ).singleOutput() + + result = .success(response) + } catch { + result = .failure(error) + } + + try await managedObjectContext.performChanges { + guard let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user else { return } + + switch result { + case .success(let response): + Persistence.MastodonUser.update( + mastodonUser: user, + context: Persistence.MastodonUser.RelationshipContext( + entity: response.value, + me: me, + networkDate: response.networkDate + ) + ) + case .failure: + // rollback + user.update(isShowingReblogs: oldShowReblogs, by: me) + } + } + + return try result.get() + } } From 28749b5029c8c952556eeb4df50d5eeea953fc4e Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 4 Nov 2022 16:41:59 +0100 Subject: [PATCH 06/15] Fix build (#365) :see_no_evil: --- .../Sources/MastodonCore/Service/API/APIService+Follow.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift index 38c49970c..ffcfae046 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift @@ -20,7 +20,6 @@ extension APIService { let isFollowing: Bool let isPending: Bool let needsUnfollow: Bool - let showsReblogs: Bool } /// Toggle friendship between target MastodonUser and current MastodonUser From 18720a9a51acab5d7f0d889d60e77cbb6fcc85c3 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 6 Nov 2022 09:22:26 +0100 Subject: [PATCH 07/15] Add localized strings (#365) --- .../Provider/DataSourceFacade+Status.swift | 61 ++++++++++--------- .../Generated/Strings.swift | 12 ++++ .../Resources/en.lproj/Localizable.strings | 5 ++ .../MastodonUI/View/Menu/MastodonMenu.swift | 2 +- 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index ff41cc126..332ed75e4 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -205,42 +205,45 @@ extension DataSourceFacade { menuContext: MenuContext ) async throws { switch action { - case .hideReblogs(let actionContext): - //FIXME: Add localized strings - let alertController = UIAlertController( - title: actionContext.showReblogs ? "Really hide?" : "Really show?", - message: actionContext.showReblogs ? "Really??" : "Really??", - preferredStyle: .alert - ) + case .hideReblogs(let actionContext): + let title = actionContext.showReblogs ? L10n.Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.title : L10n.Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.title + let message = actionContext.showReblogs ? L10n.Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.message : L10n.Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.message - let showHideReblogsAction = UIAlertAction( - title: actionContext.showReblogs ? "Show" : "Hide", - style: .default - ) { [weak dependency] _ in - guard let dependency else { return } + let alertController = UIAlertController( + title: title, + message: message, + preferredStyle: .alert + ) - Task { - let managedObjectContext = dependency.context.managedObjectContext - let _user: ManagedObjectRecord? = try? await managedObjectContext.perform { - guard let user = menuContext.author?.object(in: managedObjectContext) else { return nil } - return ManagedObjectRecord(objectID: user.objectID) - } + let actionTitle = actionContext.showReblogs ? L10n.Common.Controls.Friendship.hideReblogs : L10n.Common.Controls.Friendship.showReblogs + let showHideReblogsAction = UIAlertAction( + title: actionTitle, + style: .destructive + ) { [weak dependency] _ in + guard let dependency else { return } - guard let user = _user else { return } + Task { + let managedObjectContext = dependency.context.managedObjectContext + let _user: ManagedObjectRecord? = try? await managedObjectContext.perform { + guard let user = menuContext.author?.object(in: managedObjectContext) else { return nil } + return ManagedObjectRecord(objectID: user.objectID) + } - try await DataSourceFacade.responseToShowHideReblogAction( - dependency: dependency, - user: user - ) - } - } + guard let user = _user else { return } - alertController.addAction(showHideReblogsAction) + try await DataSourceFacade.responseToShowHideReblogAction( + dependency: dependency, + user: user + ) + } + } - let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) - alertController.addAction(cancelAction) + alertController.addAction(showHideReblogsAction) - dependency.present(alertController, animated: true) + let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel) + alertController.addAction(cancelAction) + + dependency.present(alertController, animated: true) case .muteUser(let actionContext): let alertController = UIAlertController( title: actionContext.isMuting ? L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.title : L10n.Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.title, diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 1d5b9895b..52ed59c09 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -713,6 +713,12 @@ public enum L10n { /// Block Account public static let title = L10n.tr("Localizable", "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title") } + public enum ConfirmHideReblogs { + /// Confirm to hide reblogs + public static let message = L10n.tr("Localizable", "Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message") + /// Hide reblogs + public static let title = L10n.tr("Localizable", "Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title") + } public enum ConfirmMuteUser { /// Confirm to mute %@ public static func message(_ p1: Any) -> String { @@ -721,6 +727,12 @@ public enum L10n { /// Mute Account public static let title = L10n.tr("Localizable", "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title") } + public enum ConfirmShowReblogs { + /// Confirm to show reblogs + public static let message = L10n.tr("Localizable", "Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message") + /// Show Reblogs + public static let title = L10n.tr("Localizable", "Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title") + } public enum ConfirmUnblockUser { /// Confirm to unblock %@ public static func message(_ p1: Any) -> String { diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 94bee697c..6917eb0c7 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -79,6 +79,7 @@ Please check your internet connection."; "Common.Controls.Friendship.UnmuteUser" = "Unmute %@"; "Common.Controls.Friendship.HideReblogs" = "Hide Reblogs"; "Common.Controls.Friendship.ShowReblogs" = "Show Reblogs"; + "Common.Controls.Keyboard.Common.ComposeNewPost" = "Compose New Post"; "Common.Controls.Keyboard.Common.OpenSettings" = "Open Settings"; "Common.Controls.Keyboard.Common.ShowFavorites" = "Show Favorites"; @@ -264,6 +265,10 @@ uploaded to Mastodon."; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Unblock Account"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Confirm to unmute %@"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Title" = "Unmute Account"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Confirm to show reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Show Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Confirm to hide reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Hide reblogs"; "Scene.Profile.SegmentedControl.About" = "About"; "Scene.Profile.SegmentedControl.Media" = "Media"; "Scene.Profile.SegmentedControl.Posts" = "Posts"; diff --git a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift index b85e71138..422494328 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift @@ -52,7 +52,7 @@ extension MastodonMenu { func build(delegate: MastodonMenuDelegate) -> BuiltAction { switch self { case .hideReblogs(let context): - let title = context.showReblogs ? L10n.Common.Controls.Friendship.hideReblogs : L10n.Common.Controls.Friendship.hideReblogs + let title = context.showReblogs ? L10n.Common.Controls.Friendship.hideReblogs : L10n.Common.Controls.Friendship.showReblogs let reblogAction = BuiltAction( title: title, image: UIImage(systemName: "arrow.2.squarepath") From ee523c098efa68a9cdc963adb6d4baf3413f8c1c Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 6 Nov 2022 09:25:26 +0100 Subject: [PATCH 08/15] Make show/hide reblogs finally work (#365) oh, and also indent to 4 spaces. I needed some time to wrap my head around the data model and especially the various view-models, but hey, in the end it works. I still feel like this "I have no idea what I'm doing"-dog :D --- .../Service/API/APIService+Follow.swift | 74 ++++++++++--------- .../ViewModel/RelationshipViewModel.swift | 41 ++++++---- 2 files changed, 64 insertions(+), 51 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift index ffcfae046..05d1302b6 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift @@ -127,46 +127,50 @@ extension APIService { authenticationBox: MastodonAuthenticationBox ) async throws -> Mastodon.Response.Content { - let managedObjectContext = backgroundManagedObjectContext - guard let user = user.object(in: managedObjectContext) else { throw APIError.implicit(.badRequest) } + let managedObjectContext = backgroundManagedObjectContext + guard let user = user.object(in: managedObjectContext), + let authentication = authenticationBox.authenticationRecord.object(in: managedObjectContext) + else { throw APIError.implicit(.badRequest) } - let result: Result, Error> - let showReblogs = false //FIXME: Use showReblogs-value from data - let oldShowReblogs = true + let me = authentication.user + let result: Result, Error> - do { - let response = try await Mastodon.API.Account.follow( - session: session, - domain: authenticationBox.domain, - accountID: user.id, - followQueryType: .follow(query: .init(reblogs: showReblogs)), - authorization: authenticationBox.userAuthorization - ).singleOutput() + let oldShowReblogs = me.showingReblogsBy.contains(user) + let newShowReblogs = (oldShowReblogs == false) - result = .success(response) - } catch { - result = .failure(error) - } + do { + let response = try await Mastodon.API.Account.follow( + session: session, + domain: authenticationBox.domain, + accountID: user.id, + followQueryType: .follow(query: .init(reblogs: showReblogs)), + authorization: authenticationBox.userAuthorization + ).singleOutput() - try await managedObjectContext.performChanges { - guard let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user else { return } - - switch result { - case .success(let response): - Persistence.MastodonUser.update( - mastodonUser: user, - context: Persistence.MastodonUser.RelationshipContext( - entity: response.value, - me: me, - networkDate: response.networkDate - ) - ) - case .failure: - // rollback - user.update(isShowingReblogs: oldShowReblogs, by: me) + result = .success(response) + } catch { + result = .failure(error) } - } - return try result.get() + try await managedObjectContext.performChanges { + guard let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user else { return } + + switch result { + case .success(let response): + Persistence.MastodonUser.update( + mastodonUser: user, + context: Persistence.MastodonUser.RelationshipContext( + entity: response.value, + me: me, + networkDate: response.networkDate + ) + ) + case .failure: + // rollback + user.update(isShowingReblogs: oldShowReblogs, by: me) + } + } + + return try result.get() } } diff --git a/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift b/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift index 5b032aa90..d51737b1e 100644 --- a/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift @@ -27,6 +27,7 @@ public enum RelationshipAction: Int, CaseIterable { case edit case editing case updating + case showReblogs public var option: RelationshipActionOptionSet { return RelationshipActionOptionSet(rawValue: 1 << rawValue) @@ -57,6 +58,7 @@ public struct RelationshipActionOptionSet: OptionSet { public static let edit = RelationshipAction.edit.option public static let editing = RelationshipAction.editing.option public static let updating = RelationshipAction.updating.option + public static let showReblogs = RelationshipAction.showReblogs.option public static let editOptions: RelationshipActionOptionSet = [.edit, .editing, .updating] @@ -75,24 +77,24 @@ public struct RelationshipActionOptionSet: OptionSet { return " " } switch highPriorityAction { - case .isMyself: return "" - case .followingBy: return " " - case .blockingBy: return " " - case .none: return " " - case .follow: return L10n.Common.Controls.Friendship.follow - case .request: return L10n.Common.Controls.Friendship.request - case .pending: return L10n.Common.Controls.Friendship.pending - case .following: return L10n.Common.Controls.Friendship.following - case .muting: return L10n.Common.Controls.Friendship.muted - case .blocked: return L10n.Common.Controls.Friendship.follow // blocked by user (deprecated) - case .blocking: return L10n.Common.Controls.Friendship.blocked - case .suspended: return L10n.Common.Controls.Friendship.follow - case .edit: return L10n.Common.Controls.Friendship.editInfo - case .editing: return L10n.Common.Controls.Actions.done - case .updating: return " " + case .isMyself: return "" + case .followingBy: return " " + case .blockingBy: return " " + case .none: return " " + case .follow: return L10n.Common.Controls.Friendship.follow + case .request: return L10n.Common.Controls.Friendship.request + case .pending: return L10n.Common.Controls.Friendship.pending + case .following: return L10n.Common.Controls.Friendship.following + case .muting: return L10n.Common.Controls.Friendship.muted + case .blocked: return L10n.Common.Controls.Friendship.follow // blocked by user (deprecated) + case .blocking: return L10n.Common.Controls.Friendship.blocked + case .suspended: return L10n.Common.Controls.Friendship.follow + case .edit: return L10n.Common.Controls.Friendship.editInfo + case .editing: return L10n.Common.Controls.Actions.done + case .updating: return " " + case .showReblogs: return "" } } - } public final class RelationshipViewModel { @@ -185,6 +187,7 @@ extension RelationshipViewModel { self.isBlockingBy = optionSet.contains(.blockingBy) self.isBlocking = optionSet.contains(.blocking) self.isSuspended = optionSet.contains(.suspended) + self.showReblogs = optionSet.contains(.showReblogs) self.optionSet = optionSet } @@ -197,6 +200,7 @@ extension RelationshipViewModel { isBlockingBy = false isBlocking = false optionSet = nil + showReblogs = false } } @@ -215,6 +219,7 @@ extension RelationshipViewModel { let isMuting = user.mutingBy.contains(me) let isBlockingBy = me.blockingBy.contains(user) let isBlocking = user.blockingBy.contains(me) + let isShowingReblogs = me.showingReblogsBy.contains(user)// user.showingReblogsBy.contains(me) var optionSet: RelationshipActionOptionSet = [.follow] @@ -253,6 +258,10 @@ extension RelationshipViewModel { if user.suspended { optionSet.insert(.suspended) } + + if isShowingReblogs { + optionSet.insert(.showReblogs) + } return optionSet } From 1ac9e5c73044c632ede1daa63560c43a3008d566 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 6 Nov 2022 09:33:55 +0100 Subject: [PATCH 09/15] Fix build (again) (#365) :facepalm: --- .../Sources/MastodonCore/Service/API/APIService+Follow.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift index 05d1302b6..442d293ce 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Follow.swift @@ -143,7 +143,7 @@ extension APIService { session: session, domain: authenticationBox.domain, accountID: user.id, - followQueryType: .follow(query: .init(reblogs: showReblogs)), + followQueryType: .follow(query: .init(reblogs: newShowReblogs)), authorization: authenticationBox.userAuthorization ).singleOutput() From 746d70f3e061207b556ec91e0675b2fbee5e55a8 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 6 Nov 2022 10:16:56 +0100 Subject: [PATCH 10/15] [WIP] Show show/hide-reblog-menu-entry only for people you already follow (#365) Please consider this WIP, as the breaks the ProfileRelationshipActionButton, somethingsomething RelationshipActionOptionSet for whatever reason, I assume. Also: fixed some typos and warnings. --- .../Scene/Profile/ProfileViewController.swift | 30 +++++++++++-------- .../ViewModel/RelationshipViewModel.swift | 4 +-- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index dcaefccb7..c1c5ccea7 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -376,14 +376,20 @@ extension ProfileViewController { } let name = user.displayNameWithFallback let _ = ManagedObjectRecord(objectID: user.objectID) + + var menuActions: [MastodonMenu.Action] = [ + .muteUser(.init(name: name, isMuting: self.viewModel.relationshipViewModel.isMuting)), + .blockUser(.init(name: name, isBlocking: self.viewModel.relationshipViewModel.isBlocking)), + .reportUser(.init(name: name)), + .shareUser(.init(name: name)), + ] + + if let me = self.viewModel?.me, me.following.contains(user) { + menuActions.insert(.hideReblogs(.init(showReblogs: self.viewModel.relationshipViewModel.showReblogs)), at: 1) + } + let menu = MastodonMenu.setupMenu( - actions: [ - .muteUser(.init(name: name, isMuting: self.viewModel.relationshipViewModel.isMuting)), - .hideReblogs(.init(showReblogs: self.viewModel.relationshipViewModel.showReblogs)), - .blockUser(.init(name: name, isBlocking: self.viewModel.relationshipViewModel.isBlocking)), - .reportUser(.init(name: name)), - .shareUser(.init(name: name)), - ], + actions: menuActions, delegate: self ) return menu @@ -743,7 +749,7 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate { let alertController = UIAlertController(for: error, title: L10n.Common.Alerts.EditProfileFailure.title, preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) alertController.addAction(okAction) - self.coordinator.present( + _ = self.coordinator.present( scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil) @@ -766,11 +772,11 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate { break case .follow, .request, .pending, .following: guard let user = viewModel.user else { return } - let reocrd = ManagedObjectRecord(objectID: user.objectID) + let record = ManagedObjectRecord(objectID: user.objectID) Task { try await DataSourceFacade.responseToUserFollowAction( dependency: self, - user: reocrd + user: record ) } case .muting: @@ -819,10 +825,8 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate { let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil) alertController.addAction(cancelAction) present(alertController, animated: true, completion: nil) - case .blocked: + case .blocked, .showReblogs, .isMyself,.followingBy, .blockingBy, .suspended, .edit, .editing, .updating: break - default: - assertionFailure() } } diff --git a/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift b/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift index d51737b1e..059ef0413 100644 --- a/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift @@ -92,7 +92,7 @@ public struct RelationshipActionOptionSet: OptionSet { case .edit: return L10n.Common.Controls.Friendship.editInfo case .editing: return L10n.Common.Controls.Actions.done case .updating: return " " - case .showReblogs: return "" + case .showReblogs: return " " } } } @@ -219,7 +219,7 @@ extension RelationshipViewModel { let isMuting = user.mutingBy.contains(me) let isBlockingBy = me.blockingBy.contains(user) let isBlocking = user.blockingBy.contains(me) - let isShowingReblogs = me.showingReblogsBy.contains(user)// user.showingReblogsBy.contains(me) + let isShowingReblogs = me.showingReblogsBy.contains(user) var optionSet: RelationshipActionOptionSet = [.follow] From 143a9b32948fa4d02c03085825174a8461e75052 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 7 Nov 2022 17:51:09 +0100 Subject: [PATCH 11/15] Get rid of SwiftyJSON it's not used anymore. --- .../xcshareddata/swiftpm/Package.resolved | 9 --------- MastodonSDK/Package.swift | 2 -- 2 files changed, 11 deletions(-) diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index f15e4a422..3d914a3f1 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -189,15 +189,6 @@ "version" : "0.1.4" } }, - { - "identity" : "swiftyjson", - "kind" : "remoteSourceControl", - "location" : "https://github.com/SwiftyJSON/SwiftyJSON.git", - "state" : { - "revision" : "b3dcd7dbd0d488e1a7077cb33b00f2083e382f07", - "version" : "5.0.1" - } - }, { "identity" : "tabbarpager", "kind" : "remoteSourceControl", diff --git a/MastodonSDK/Package.swift b/MastodonSDK/Package.swift index 852817c20..ca241038b 100644 --- a/MastodonSDK/Package.swift +++ b/MastodonSDK/Package.swift @@ -40,7 +40,6 @@ let package = Package( .package(url: "https://github.com/MainasuK/CommonOSLog", from: "0.1.1"), .package(url: "https://github.com/MainasuK/FPSIndicator.git", from: "1.0.0"), .package(url: "https://github.com/slackhq/PanModal.git", from: "1.2.7"), - .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "5.0.0"), .package(url: "https://github.com/TimOliver/TOCropViewController.git", from: "2.6.1"), .package(url: "https://github.com/TwidereProject/MetaTextKit.git", exact: "2.2.5"), .package(url: "https://github.com/TwidereProject/TabBarPager.git", from: "0.1.0"), @@ -103,7 +102,6 @@ let package = Package( .target( name: "MastodonSDK", dependencies: [ - .product(name: "SwiftyJSON", package: "SwiftyJSON"), .product(name: "NIOHTTP1", package: "swift-nio"), ] ), From 00ab7ac2b0e193913e82c806c84481bf75cc5ee5 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 7 Nov 2022 18:52:02 +0100 Subject: [PATCH 12/15] Remove RelationshipActionOption for reblogs again (#365) --- Mastodon/Scene/Profile/ProfileViewController.swift | 4 +++- .../MastodonUI/ViewModel/RelationshipViewModel.swift | 11 ++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index c1c5ccea7..3ce1fd33a 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -385,7 +385,9 @@ extension ProfileViewController { ] if let me = self.viewModel?.me, me.following.contains(user) { - menuActions.insert(.hideReblogs(.init(showReblogs: self.viewModel.relationshipViewModel.showReblogs)), at: 1) + let showReblogs = me.showingReblogsBy.contains(user) + let context = MastodonMenu.HideReblogsActionContext(showReblogs: showReblogs) + menuActions.insert(.hideReblogs(context), at: 1) } let menu = MastodonMenu.setupMenu( diff --git a/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift b/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift index 059ef0413..3815568ab 100644 --- a/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift @@ -58,8 +58,6 @@ public struct RelationshipActionOptionSet: OptionSet { public static let edit = RelationshipAction.edit.option public static let editing = RelationshipAction.editing.option public static let updating = RelationshipAction.updating.option - public static let showReblogs = RelationshipAction.showReblogs.option - public static let editOptions: RelationshipActionOptionSet = [.edit, .editing, .updating] public func highPriorityAction(except: RelationshipActionOptionSet) -> RelationshipAction? { @@ -187,7 +185,7 @@ extension RelationshipViewModel { self.isBlockingBy = optionSet.contains(.blockingBy) self.isBlocking = optionSet.contains(.blocking) self.isSuspended = optionSet.contains(.suspended) - self.showReblogs = optionSet.contains(.showReblogs) + self.showReblogs = me.showingReblogsBy.contains(user) self.optionSet = optionSet } @@ -219,8 +217,7 @@ extension RelationshipViewModel { let isMuting = user.mutingBy.contains(me) let isBlockingBy = me.blockingBy.contains(user) let isBlocking = user.blockingBy.contains(me) - let isShowingReblogs = me.showingReblogsBy.contains(user) - + var optionSet: RelationshipActionOptionSet = [.follow] if isMyself { @@ -259,10 +256,6 @@ extension RelationshipViewModel { optionSet.insert(.suspended) } - if isShowingReblogs { - optionSet.insert(.showReblogs) - } - return optionSet } } From 822ea5d843db1b8784852e22cc1a1a4fa7095fc5 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 7 Nov 2022 22:23:00 +0100 Subject: [PATCH 13/15] Add localization keys to app.json (#365) --- Localization/app.json | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index a965b23ae..1f04cf65f 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -180,7 +180,9 @@ "unmute": "Unmute", "unmute_user": "Unmute %s", "muted": "Muted", - "edit_info": "Edit Info" + "edit_info": "Edit Info", + "show_reblogs": "Show Reblogs", + "hide_reblogs": "Hide Reblogs", }, "timeline": { "filtered": "Filtered", @@ -455,7 +457,15 @@ "confirm_unblock_user": { "title": "Unblock Account", "message": "Confirm to unblock %s" - } + }, + "confirm_show_reblogs": { + "title": "Show Reblogs", + "message": "Confirm to show reblogs + }, + "confirm_hide_reblogs": { + "title": "Hide Reblogs", + "message": "Confirm to hide reblogs + }, }, "accessibility": { "show_avatar_image": "Show avatar image", @@ -686,4 +696,4 @@ "accessibility_hint": "Double tap to dismiss this wizard" } } -} \ No newline at end of file +} From 3751cd172c1252b23fa0453581b8b1b024376578 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 8 Nov 2022 08:08:30 +0100 Subject: [PATCH 14/15] Make json valid again (#365) :see_no_evil: --- Localization/app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 1f04cf65f..c44029040 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -460,11 +460,11 @@ }, "confirm_show_reblogs": { "title": "Show Reblogs", - "message": "Confirm to show reblogs + "message": "Confirm to show reblogs" }, "confirm_hide_reblogs": { "title": "Hide Reblogs", - "message": "Confirm to hide reblogs + "message": "Confirm to hide reblogs" }, }, "accessibility": { From 21800a4c81ed26e4d6a67f5d30cf13344ecb35f9 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 8 Nov 2022 15:26:32 +0100 Subject: [PATCH 15/15] Add optionSet for reblog again (#365) --- .../MastodonUI/ViewModel/RelationshipViewModel.swift | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift b/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift index 3815568ab..99cff19be 100644 --- a/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/ViewModel/RelationshipViewModel.swift @@ -12,6 +12,7 @@ import MastodonLocalization import CoreDataStack public enum RelationshipAction: Int, CaseIterable { + case showReblogs case isMyself case followingBy case blockingBy @@ -27,8 +28,7 @@ public enum RelationshipAction: Int, CaseIterable { case edit case editing case updating - case showReblogs - + public var option: RelationshipActionOptionSet { return RelationshipActionOptionSet(rawValue: 1 << rawValue) } @@ -58,6 +58,7 @@ public struct RelationshipActionOptionSet: OptionSet { public static let edit = RelationshipAction.edit.option public static let editing = RelationshipAction.editing.option public static let updating = RelationshipAction.updating.option + public static let showReblogs = RelationshipAction.showReblogs.option public static let editOptions: RelationshipActionOptionSet = [.edit, .editing, .updating] public func highPriorityAction(except: RelationshipActionOptionSet) -> RelationshipAction? { @@ -185,7 +186,7 @@ extension RelationshipViewModel { self.isBlockingBy = optionSet.contains(.blockingBy) self.isBlocking = optionSet.contains(.blocking) self.isSuspended = optionSet.contains(.suspended) - self.showReblogs = me.showingReblogsBy.contains(user) + self.showReblogs = optionSet.contains(.showReblogs) self.optionSet = optionSet } @@ -217,6 +218,7 @@ extension RelationshipViewModel { let isMuting = user.mutingBy.contains(me) let isBlockingBy = me.blockingBy.contains(user) let isBlocking = user.blockingBy.contains(me) + let isShowingReblogs = me.showingReblogsBy.contains(user) var optionSet: RelationshipActionOptionSet = [.follow] @@ -256,6 +258,10 @@ extension RelationshipViewModel { optionSet.insert(.suspended) } + if isShowingReblogs { + optionSet.insert(.showReblogs) + } + return optionSet } }