From 94ab5766a1b1b6b1c89fd7a8d6447de68e6a45d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Danthinne?= Date: Mon, 23 Jan 2023 18:50:59 +0100 Subject: [PATCH] Allow hiding or showing user boosts (#305) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * allow hiding or showing user boosts * move notify and reboosts buttons below follow button * move the account joined date below the name * fix join date padding Co-authored-by: Jérôme Danthinne --- .../Account/AccountDetailHeaderView.swift | 17 ++++++- .../Sources/Account/AccountDetailView.swift | 18 -------- .../Sources/Account/Follow/FollowButton.swift | 46 +++++++++++++++---- .../Sources/Network/Endpoint/Accounts.swift | 11 +++-- 4 files changed, 59 insertions(+), 33 deletions(-) diff --git a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift index becfbd43..d24047e6 100644 --- a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift +++ b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift @@ -104,13 +104,14 @@ struct AccountDetailHeaderView: View { private var accountInfoView: some View { Group { accountAvatarView - HStack { + HStack(alignment: .firstTextBaseline) { VStack(alignment: .leading, spacing: 0) { EmojiTextApp(.init(stringValue: account.safeDisplayName), emojis: account.emojis) .font(.scaledHeadline) Text("@\(account.acct)") .font(.scaledCallout) .foregroundColor(.gray) + joinedAtView } Spacer() if let relationship = viewModel.relationship, !viewModel.isCurrentUser { @@ -145,6 +146,20 @@ struct AccountDetailHeaderView: View { .foregroundColor(.gray) } } + + @ViewBuilder + private var joinedAtView: some View { + if let joinedAt = viewModel.account?.createdAt.asDate { + HStack(spacing: 4) { + Image(systemName: "calendar") + Text("account.joined") + Text(joinedAt, style: .date) + } + .foregroundColor(.gray) + .font(.footnote) + .padding(.top, 6) + } + } } struct AccountDetailHeaderView_Previews: PreviewProvider { diff --git a/Packages/Account/Sources/Account/AccountDetailView.swift b/Packages/Account/Sources/Account/AccountDetailView.swift index 79752066..84cedb1f 100644 --- a/Packages/Account/Sources/Account/AccountDetailView.swift +++ b/Packages/Account/Sources/Account/AccountDetailView.swift @@ -43,8 +43,6 @@ public struct AccountDetailView: View { } content: { LazyVStack(alignment: .leading) { makeHeaderView(proxy: proxy) - joinedAtView - .offset(y: -36) familiarFollowers .offset(y: -36) featuredTagsView @@ -150,22 +148,6 @@ public struct AccountDetailView: View { } } - @ViewBuilder - private var joinedAtView: some View { - if let joinedAt = viewModel.account?.createdAt.asDate { - HStack(spacing: 4) { - Image(systemName: "calendar") - Text("account.joined") - Text(joinedAt, style: .date) - } - .foregroundColor(.gray) - .font(.footnote) - .padding(.horizontal, .layoutPadding) - .padding(.top, 2) - .padding(.bottom, 5) - } - } - @ViewBuilder private var featuredTagsView: some View { if !viewModel.featuredTags.isEmpty || !viewModel.fields.isEmpty { diff --git a/Packages/Account/Sources/Account/Follow/FollowButton.swift b/Packages/Account/Sources/Account/Follow/FollowButton.swift index 115cfa31..89d58afe 100644 --- a/Packages/Account/Sources/Account/Follow/FollowButton.swift +++ b/Packages/Account/Sources/Account/Follow/FollowButton.swift @@ -28,7 +28,7 @@ public class FollowButtonViewModel: ObservableObject { guard let client else { return } isUpdating = true do { - relationship = try await client.post(endpoint: Accounts.follow(id: accountId, notify: false)) + relationship = try await client.post(endpoint: Accounts.follow(id: accountId, notify: false, reblogs: true)) relationshipUpdated(relationship) } catch { print("Error while following: \(error.localizedDescription)") @@ -51,12 +51,26 @@ public class FollowButtonViewModel: ObservableObject { func toggleNotify() async { guard let client else { return } do { - relationship = try await client.post(endpoint: Accounts.follow(id: accountId, notify: !relationship.notifying)) + relationship = try await client.post(endpoint: Accounts.follow(id: accountId, + notify: !relationship.notifying, + reblogs: relationship.showingReblogs)) relationshipUpdated(relationship) } catch { print("Error while following: \(error.localizedDescription)") } } + + func toggleReboosts() async { + guard let client else { return } + do { + relationship = try await client.post(endpoint: Accounts.follow(id: accountId, + notify: relationship.notifying, + reblogs: !relationship.showingReblogs)) + relationshipUpdated(relationship) + } catch { + print("Error while switching reboosts: \(error.localizedDescription)") + } + } } public struct FollowButton: View { @@ -68,7 +82,7 @@ public struct FollowButton: View { } public var body: some View { - HStack { + VStack { Button { Task { if viewModel.relationship.following { @@ -87,15 +101,27 @@ public struct FollowButton: View { .buttonStyle(.bordered) .disabled(viewModel.isUpdating) if viewModel.relationship.following, viewModel.shouldDisplayNotify { - Button { - Task { - await viewModel.toggleNotify() + HStack { + Button { + Task { + await viewModel.toggleNotify() + } + } label: { + Image(systemName: viewModel.relationship.notifying ? "bell.fill" : "bell") } - } label: { - Image(systemName: viewModel.relationship.notifying ? "bell.fill" : "bell") + .buttonStyle(.bordered) + .disabled(viewModel.isUpdating) + + Button { + Task { + await viewModel.toggleReboosts() + } + } label: { + Image(systemName: viewModel.relationship.showingReblogs ? "arrow.left.arrow.right.circle.fill" : "arrow.left.arrow.right.circle") + } + .buttonStyle(.bordered) + .disabled(viewModel.isUpdating) } - .buttonStyle(.bordered) - .disabled(viewModel.isUpdating) } } .onAppear { diff --git a/Packages/Network/Sources/Network/Endpoint/Accounts.swift b/Packages/Network/Sources/Network/Endpoint/Accounts.swift index cf00cf32..d061e85d 100644 --- a/Packages/Network/Sources/Network/Endpoint/Accounts.swift +++ b/Packages/Network/Sources/Network/Endpoint/Accounts.swift @@ -22,7 +22,7 @@ public enum Accounts: Endpoint { excludeReplies: Bool?, pinned: Bool?) case relationships(ids: [String]) - case follow(id: String, notify: Bool) + case follow(id: String, notify: Bool, reblogs: Bool) case unfollow(id: String) case familiarFollowers(withAccount: String) case suggestions @@ -55,7 +55,7 @@ public enum Accounts: Endpoint { return "accounts/\(id)/statuses" case .relationships: return "accounts/relationships" - case let .follow(id, _): + case let .follow(id, _, _): return "accounts/\(id)/follow" case let .unfollow(id): return "accounts/\(id)/unfollow" @@ -106,8 +106,11 @@ public enum Accounts: Endpoint { return ids.map { URLQueryItem(name: "id[]", value: $0) } - case let .follow(_, notify): - return [.init(name: "notify", value: notify ? "true" : "false")] + case let .follow(_, notify, reblogs): + return [ + .init(name: "notify", value: notify ? "true" : "false"), + .init(name: "reblogs", value: reblogs ? "true" : "false") + ] case let .familiarFollowers(withAccount): return [.init(name: "id[]", value: withAccount)] case let .followers(_, maxId):