mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-22 08:20:59 +00:00
Refactor follow to shared FollowButton
This commit is contained in:
parent
7068ad90bb
commit
2f7653d05c
6 changed files with 89 additions and 62 deletions
|
@ -86,6 +86,9 @@ struct SettingsTabs: View {
|
|||
.cornerRadius(4)
|
||||
}
|
||||
}
|
||||
Link(destination: URL(string: "https://github.com/Dimillian/IceCubesApp")!) {
|
||||
Text("https://github.com/Dimillian/IceCubesApp")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ struct AccountDetailHeaderView: View {
|
|||
|
||||
let isCurrentUser: Bool
|
||||
let account: Account
|
||||
@Binding var relationship: Relationshionship?
|
||||
@Binding var following: Bool
|
||||
let relationship: Relationshionship?
|
||||
|
||||
@Binding var scrollOffset: CGFloat
|
||||
|
||||
private var bannerHeight: CGFloat {
|
||||
|
@ -97,16 +97,9 @@ struct AccountDetailHeaderView: View {
|
|||
.foregroundColor(.gray)
|
||||
}
|
||||
Spacer()
|
||||
if relationship != nil && !isCurrentUser {
|
||||
Button {
|
||||
following.toggle()
|
||||
} label: {
|
||||
if relationship?.requested == true {
|
||||
Text("Requested")
|
||||
} else {
|
||||
Text(following ? "Following" : "Follow")
|
||||
}
|
||||
}.buttonStyle(.bordered)
|
||||
if let relationship = relationship, !isCurrentUser {
|
||||
FollowButton(viewModel: .init(accountId: account.id,
|
||||
relationship: relationship))
|
||||
}
|
||||
}
|
||||
Text(account.note.asSafeAttributedString)
|
||||
|
@ -135,8 +128,7 @@ struct AccountDetailHeaderView_Previews: PreviewProvider {
|
|||
static var previews: some View {
|
||||
AccountDetailHeaderView(isCurrentUser: false,
|
||||
account: .placeholder(),
|
||||
relationship: .constant(.placeholder()),
|
||||
following: .constant(true),
|
||||
relationship: .placeholder(),
|
||||
scrollOffset: .constant(0))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,26 +86,13 @@ public struct AccountDetailView: View {
|
|||
case .loading:
|
||||
AccountDetailHeaderView(isCurrentUser: isCurrentUser,
|
||||
account: .placeholder(),
|
||||
relationship: .constant(.placeholder()),
|
||||
following: .constant(false),
|
||||
relationship: .placeholder(),
|
||||
scrollOffset: $scrollOffset)
|
||||
.redacted(reason: .placeholder)
|
||||
case let .data(account):
|
||||
AccountDetailHeaderView(isCurrentUser: isCurrentUser,
|
||||
account: account,
|
||||
relationship: $viewModel.relationship,
|
||||
following:
|
||||
.init(get: {
|
||||
viewModel.relationship?.following ?? false
|
||||
}, set: { following in
|
||||
Task {
|
||||
if following {
|
||||
await viewModel.follow()
|
||||
} else {
|
||||
await viewModel.unfollow()
|
||||
}
|
||||
}
|
||||
}),
|
||||
relationship: viewModel.relationship,
|
||||
scrollOffset: $scrollOffset)
|
||||
case let .error(error):
|
||||
Text("Error: \(error.localizedDescription)")
|
||||
|
@ -156,7 +143,7 @@ public struct AccountDetailView: View {
|
|||
@ViewBuilder
|
||||
private var familliarFollowers: some View {
|
||||
if !viewModel.familliarFollowers.isEmpty {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text("Also followed by")
|
||||
.font(.headline)
|
||||
.padding(.leading, DS.Constants.layoutPadding)
|
||||
|
|
72
Packages/Account/Sources/Account/Follow/FollowButton.swift
Normal file
72
Packages/Account/Sources/Account/Follow/FollowButton.swift
Normal file
|
@ -0,0 +1,72 @@
|
|||
import Foundation
|
||||
import SwiftUI
|
||||
import Models
|
||||
import Network
|
||||
|
||||
@MainActor
|
||||
public class FollowButtonViewModel: ObservableObject {
|
||||
var client: Client?
|
||||
|
||||
public let accountId: String
|
||||
@Published private(set) public var relationship: Relationshionship
|
||||
@Published private(set) public var isUpdating: Bool = false
|
||||
|
||||
public init(accountId: String, relationship: Relationshionship) {
|
||||
self.accountId = accountId
|
||||
self.relationship = relationship
|
||||
}
|
||||
|
||||
func follow() async {
|
||||
guard let client else { return }
|
||||
isUpdating = true
|
||||
do {
|
||||
relationship = try await client.post(endpoint: Accounts.follow(id: accountId))
|
||||
} catch {
|
||||
print("Error while following: \(error.localizedDescription)")
|
||||
}
|
||||
isUpdating = false
|
||||
}
|
||||
|
||||
func unfollow() async {
|
||||
guard let client else { return }
|
||||
isUpdating = true
|
||||
do {
|
||||
relationship = try await client.post(endpoint: Accounts.unfollow(id: accountId))
|
||||
} catch {
|
||||
print("Error while unfollowing: \(error.localizedDescription)")
|
||||
}
|
||||
isUpdating = false
|
||||
}
|
||||
}
|
||||
|
||||
public struct FollowButton: View {
|
||||
@EnvironmentObject private var client: Client
|
||||
@StateObject private var viewModel: FollowButtonViewModel
|
||||
|
||||
public init(viewModel: FollowButtonViewModel) {
|
||||
_viewModel = StateObject(wrappedValue: viewModel)
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
Button {
|
||||
Task {
|
||||
if viewModel.relationship.following {
|
||||
await viewModel.unfollow()
|
||||
} else {
|
||||
await viewModel.follow()
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
if viewModel.relationship.requested == true {
|
||||
Text("Requested")
|
||||
} else {
|
||||
Text(viewModel.relationship.following ? "Following" : "Follow")
|
||||
}
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.disabled(viewModel.isUpdating)
|
||||
.onAppear {
|
||||
viewModel.client = client
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ let package = Package(
|
|||
targets: ["Explore"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(name: "Account", path: "../Account"),
|
||||
.package(name: "Network", path: "../Network"),
|
||||
.package(name: "Models", path: "../Models"),
|
||||
.package(name: "Env", path: "../Env"),
|
||||
|
@ -24,6 +25,7 @@ let package = Package(
|
|||
.target(
|
||||
name: "Explore",
|
||||
dependencies: [
|
||||
.product(name: "Account", package: "Account"),
|
||||
.product(name: "Network", package: "Network"),
|
||||
.product(name: "Models", package: "Models"),
|
||||
.product(name: "Env", package: "Env"),
|
||||
|
|
|
@ -3,6 +3,7 @@ import Models
|
|||
import Network
|
||||
import DesignSystem
|
||||
import Env
|
||||
import Account
|
||||
|
||||
@MainActor
|
||||
class SuggestedAccountViewModel: ObservableObject {
|
||||
|
@ -15,20 +16,6 @@ class SuggestedAccountViewModel: ObservableObject {
|
|||
self.account = account
|
||||
self.relationShip = relationShip
|
||||
}
|
||||
|
||||
func follow() async {
|
||||
guard let client else { return }
|
||||
do {
|
||||
self.relationShip = try await client.post(endpoint: Accounts.follow(id: account.id))
|
||||
} catch {}
|
||||
}
|
||||
|
||||
func unfollow() async {
|
||||
guard let client else { return }
|
||||
do {
|
||||
self.relationShip = try await client.post(endpoint: Accounts.unfollow(id: account.id))
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
struct SuggestedAccountRow: View {
|
||||
|
@ -54,24 +41,8 @@ struct SuggestedAccountRow: View {
|
|||
})
|
||||
}
|
||||
Spacer()
|
||||
Button {
|
||||
Task {
|
||||
if viewModel.relationShip.following {
|
||||
await viewModel.unfollow()
|
||||
} else {
|
||||
await viewModel.follow()
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
if viewModel.relationShip.requested {
|
||||
Text("Requested")
|
||||
.font(.callout)
|
||||
} else {
|
||||
Text(viewModel.relationShip.following ? "Unfollow" : "Follow")
|
||||
.font(.callout)
|
||||
}
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
FollowButton(viewModel: .init(accountId: viewModel.account.id,
|
||||
relationship: viewModel.relationShip))
|
||||
}
|
||||
.onAppear {
|
||||
viewModel.client = client
|
||||
|
|
Loading…
Reference in a new issue