From 788fab930ba29f2b90f90f8358eaad4be9c598bf Mon Sep 17 00:00:00 2001 From: Thomas Durand Date: Sun, 14 Jan 2024 10:51:54 +0100 Subject: [PATCH] Using AsyncButton from button kit to improve following and related buttons (#1888) --- .../xcshareddata/swiftpm/Package.resolved | 9 ++++ Packages/Account/Package.swift | 2 + .../Sources/Account/Follow/FollowButton.swift | 45 +++++++++---------- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index b9f39cc1..10b96ea5 100644 --- a/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -9,6 +9,15 @@ "version" : "2.1.0" } }, + { + "identity" : "buttonkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Dean151/ButtonKit", + "state" : { + "revision" : "377f5bab4ed047704316d531e0826d4de5ebf6a4", + "version" : "0.1.1" + } + }, { "identity" : "emojitext", "kind" : "remoteSourceControl", diff --git a/Packages/Account/Package.swift b/Packages/Account/Package.swift index ce9c0468..653cb030 100644 --- a/Packages/Account/Package.swift +++ b/Packages/Account/Package.swift @@ -21,6 +21,7 @@ let package = Package( .package(name: "Models", path: "../Models"), .package(name: "StatusKit", path: "../StatusKit"), .package(name: "Env", path: "../Env"), + .package(url: "https://github.com/Dean151/ButtonKit", from: "0.1.1"), ], targets: [ .target( @@ -30,6 +31,7 @@ let package = Package( .product(name: "Models", package: "Models"), .product(name: "StatusKit", package: "StatusKit"), .product(name: "Env", package: "Env"), + .product(name: "ButtonKit", package: "ButtonKit") ], swiftSettings: [ .enableExperimentalFeature("StrictConcurrency"), diff --git a/Packages/Account/Sources/Account/Follow/FollowButton.swift b/Packages/Account/Sources/Account/Follow/FollowButton.swift index 8695d067..05043779 100644 --- a/Packages/Account/Sources/Account/Follow/FollowButton.swift +++ b/Packages/Account/Sources/Account/Follow/FollowButton.swift @@ -1,3 +1,4 @@ +import ButtonKit import Combine import Foundation import Models @@ -13,7 +14,6 @@ import SwiftUI public let shouldDisplayNotify: Bool public let relationshipUpdated: (Relationship) -> Void public private(set) var relationship: Relationship - public private(set) var isUpdating: Bool = false public init(accountId: String, relationship: Relationship, @@ -26,31 +26,29 @@ import SwiftUI self.relationshipUpdated = relationshipUpdated } - func follow() async { + func follow() async throws { guard let client else { return } - isUpdating = true do { relationship = try await client.post(endpoint: Accounts.follow(id: accountId, notify: false, reblogs: true)) relationshipUpdated(relationship) } catch { print("Error while following: \(error.localizedDescription)") + throw error } - isUpdating = false } - func unfollow() async { + func unfollow() async throws { guard let client else { return } - isUpdating = true do { relationship = try await client.post(endpoint: Accounts.unfollow(id: accountId)) relationshipUpdated(relationship) } catch { print("Error while unfollowing: \(error.localizedDescription)") + throw error } - isUpdating = false } - func toggleNotify() async { + func toggleNotify() async throws { guard let client else { return } do { relationship = try await client.post(endpoint: Accounts.follow(id: accountId, @@ -59,10 +57,11 @@ import SwiftUI relationshipUpdated(relationship) } catch { print("Error while following: \(error.localizedDescription)") + throw error } } - func toggleReboosts() async { + func toggleReboosts() async throws { guard let client else { return } do { relationship = try await client.post(endpoint: Accounts.follow(id: accountId, @@ -71,6 +70,7 @@ import SwiftUI relationshipUpdated(relationship) } catch { print("Error while switching reboosts: \(error.localizedDescription)") + throw error } } } @@ -85,13 +85,11 @@ public struct FollowButton: View { public var body: some View { VStack(alignment: .trailing) { - Button { - Task { - if viewModel.relationship.following { - await viewModel.unfollow() - } else { - await viewModel.follow() - } + AsyncButton { + if viewModel.relationship.following { + try await viewModel.unfollow() + } else { + try await viewModel.follow() } } label: { if viewModel.relationship.requested == true { @@ -106,29 +104,26 @@ public struct FollowButton: View { viewModel.shouldDisplayNotify { HStack { - Button { - Task { - await viewModel.toggleNotify() - } + AsyncButton { + try await viewModel.toggleNotify() } label: { Image(systemName: viewModel.relationship.notifying ? "bell.fill" : "bell") } .accessibilityLabel("accessibility.tabs.profile.user-notifications.label") .accessibilityValue(viewModel.relationship.notifying ? "accessibility.general.toggle.on" : "accessibility.general.toggle.off") - Button { - Task { - await viewModel.toggleReboosts() - } + AsyncButton { + try await viewModel.toggleReboosts() } label: { Image(viewModel.relationship.showingReblogs ? "Rocket.Fill" : "Rocket") } .accessibilityLabel("accessibility.tabs.profile.user-reblogs.label") .accessibilityValue(viewModel.relationship.showingReblogs ? "accessibility.general.toggle.on" : "accessibility.general.toggle.off") } + .asyncButtonStyle(.none) + .disabledWhenLoading() } } .buttonStyle(.bordered) - .disabled(viewModel.isUpdating) .onAppear { viewModel.client = client }