2024-01-14 09:51:54 +00:00
|
|
|
import ButtonKit
|
2023-02-27 05:39:07 +00:00
|
|
|
import Combine
|
2022-12-23 15:21:31 +00:00
|
|
|
import Foundation
|
|
|
|
import Models
|
|
|
|
import Network
|
2023-09-18 05:01:23 +00:00
|
|
|
import Observation
|
2024-02-02 17:26:24 +00:00
|
|
|
import OSLog
|
2024-02-14 11:48:14 +00:00
|
|
|
import SwiftUI
|
2022-12-23 15:21:31 +00:00
|
|
|
|
|
|
|
@MainActor
|
2023-09-18 05:01:23 +00:00
|
|
|
@Observable public class FollowButtonViewModel {
|
2022-12-23 15:21:31 +00:00
|
|
|
var client: Client?
|
2023-01-17 10:36:01 +00:00
|
|
|
|
2022-12-23 15:21:31 +00:00
|
|
|
public let accountId: String
|
2023-01-12 07:30:47 +00:00
|
|
|
public let shouldDisplayNotify: Bool
|
2023-01-22 05:38:30 +00:00
|
|
|
public let relationshipUpdated: (Relationship) -> Void
|
2023-09-18 05:01:23 +00:00
|
|
|
public private(set) var relationship: Relationship
|
2023-01-17 10:36:01 +00:00
|
|
|
|
2023-01-20 17:53:07 +00:00
|
|
|
public init(accountId: String,
|
|
|
|
relationship: Relationship,
|
|
|
|
shouldDisplayNotify: Bool,
|
2023-01-22 05:38:30 +00:00
|
|
|
relationshipUpdated: @escaping ((Relationship) -> Void))
|
|
|
|
{
|
2022-12-23 15:21:31 +00:00
|
|
|
self.accountId = accountId
|
|
|
|
self.relationship = relationship
|
2023-01-12 07:30:47 +00:00
|
|
|
self.shouldDisplayNotify = shouldDisplayNotify
|
2023-01-20 17:53:07 +00:00
|
|
|
self.relationshipUpdated = relationshipUpdated
|
2022-12-23 15:21:31 +00:00
|
|
|
}
|
2023-01-17 10:36:01 +00:00
|
|
|
|
2024-01-14 09:51:54 +00:00
|
|
|
func follow() async throws {
|
2022-12-23 15:21:31 +00:00
|
|
|
guard let client else { return }
|
|
|
|
do {
|
2023-01-23 17:50:59 +00:00
|
|
|
relationship = try await client.post(endpoint: Accounts.follow(id: accountId, notify: false, reblogs: true))
|
2023-01-20 17:53:07 +00:00
|
|
|
relationshipUpdated(relationship)
|
2022-12-23 15:21:31 +00:00
|
|
|
} catch {
|
2024-01-14 09:51:54 +00:00
|
|
|
throw error
|
2022-12-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
}
|
2023-01-17 10:36:01 +00:00
|
|
|
|
2024-01-14 09:51:54 +00:00
|
|
|
func unfollow() async throws {
|
2022-12-23 15:21:31 +00:00
|
|
|
guard let client else { return }
|
|
|
|
do {
|
|
|
|
relationship = try await client.post(endpoint: Accounts.unfollow(id: accountId))
|
2023-01-20 17:53:07 +00:00
|
|
|
relationshipUpdated(relationship)
|
2022-12-23 15:21:31 +00:00
|
|
|
} catch {
|
2024-01-14 09:51:54 +00:00
|
|
|
throw error
|
2022-12-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
}
|
2023-01-17 10:36:01 +00:00
|
|
|
|
2024-01-14 09:51:54 +00:00
|
|
|
func toggleNotify() async throws {
|
2023-01-12 06:36:19 +00:00
|
|
|
guard let client else { return }
|
|
|
|
do {
|
2023-01-23 17:50:59 +00:00
|
|
|
relationship = try await client.post(endpoint: Accounts.follow(id: accountId,
|
|
|
|
notify: !relationship.notifying,
|
|
|
|
reblogs: relationship.showingReblogs))
|
2023-01-20 17:53:07 +00:00
|
|
|
relationshipUpdated(relationship)
|
2023-01-12 06:36:19 +00:00
|
|
|
} catch {
|
2024-01-14 09:51:54 +00:00
|
|
|
throw error
|
2023-01-12 06:36:19 +00:00
|
|
|
}
|
|
|
|
}
|
2023-01-23 17:50:59 +00:00
|
|
|
|
2024-01-14 09:51:54 +00:00
|
|
|
func toggleReboosts() async throws {
|
2023-01-23 17:50:59 +00:00
|
|
|
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 {
|
2024-01-14 09:51:54 +00:00
|
|
|
throw error
|
2023-01-23 17:50:59 +00:00
|
|
|
}
|
|
|
|
}
|
2022-12-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public struct FollowButton: View {
|
2023-09-18 05:01:23 +00:00
|
|
|
@Environment(Client.self) private var client
|
|
|
|
@State private var viewModel: FollowButtonViewModel
|
2023-01-17 10:36:01 +00:00
|
|
|
|
2022-12-23 15:21:31 +00:00
|
|
|
public init(viewModel: FollowButtonViewModel) {
|
2023-09-18 05:01:23 +00:00
|
|
|
_viewModel = .init(initialValue: viewModel)
|
2022-12-23 15:21:31 +00:00
|
|
|
}
|
2023-01-17 10:36:01 +00:00
|
|
|
|
2022-12-23 15:21:31 +00:00
|
|
|
public var body: some View {
|
2023-01-25 20:15:32 +00:00
|
|
|
VStack(alignment: .trailing) {
|
2024-01-14 09:51:54 +00:00
|
|
|
AsyncButton {
|
|
|
|
if viewModel.relationship.following {
|
|
|
|
try await viewModel.unfollow()
|
|
|
|
} else {
|
|
|
|
try await viewModel.follow()
|
2023-01-12 06:36:19 +00:00
|
|
|
}
|
|
|
|
} label: {
|
|
|
|
if viewModel.relationship.requested == true {
|
2023-01-19 17:14:08 +00:00
|
|
|
Text("account.follow.requested")
|
2022-12-23 15:21:31 +00:00
|
|
|
} else {
|
2023-01-19 17:14:08 +00:00
|
|
|
Text(viewModel.relationship.following ? "account.follow.following" : "account.follow.follow")
|
2023-04-03 09:14:44 +00:00
|
|
|
.accessibilityLabel("account.follow.following")
|
|
|
|
.accessibilityValue(viewModel.relationship.following ? "accessibility.general.toggle.on" : "accessibility.general.toggle.off")
|
2022-12-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
}
|
2023-01-25 20:15:32 +00:00
|
|
|
if viewModel.relationship.following,
|
|
|
|
viewModel.shouldDisplayNotify
|
|
|
|
{
|
2023-01-23 17:50:59 +00:00
|
|
|
HStack {
|
2024-01-14 09:51:54 +00:00
|
|
|
AsyncButton {
|
|
|
|
try await viewModel.toggleNotify()
|
2023-01-23 17:50:59 +00:00
|
|
|
} label: {
|
|
|
|
Image(systemName: viewModel.relationship.notifying ? "bell.fill" : "bell")
|
|
|
|
}
|
2023-04-03 09:14:44 +00:00
|
|
|
.accessibilityLabel("accessibility.tabs.profile.user-notifications.label")
|
|
|
|
.accessibilityValue(viewModel.relationship.notifying ? "accessibility.general.toggle.on" : "accessibility.general.toggle.off")
|
2024-01-14 09:51:54 +00:00
|
|
|
AsyncButton {
|
|
|
|
try await viewModel.toggleReboosts()
|
2023-01-23 17:50:59 +00:00
|
|
|
} label: {
|
2023-02-28 13:53:31 +00:00
|
|
|
Image(viewModel.relationship.showingReblogs ? "Rocket.Fill" : "Rocket")
|
2023-01-12 06:36:19 +00:00
|
|
|
}
|
2023-04-03 09:14:44 +00:00
|
|
|
.accessibilityLabel("accessibility.tabs.profile.user-reblogs.label")
|
|
|
|
.accessibilityValue(viewModel.relationship.showingReblogs ? "accessibility.general.toggle.on" : "accessibility.general.toggle.off")
|
2023-01-12 06:36:19 +00:00
|
|
|
}
|
2024-01-14 09:51:54 +00:00
|
|
|
.asyncButtonStyle(.none)
|
|
|
|
.disabledWhenLoading()
|
2022-12-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
}
|
2023-01-25 20:15:32 +00:00
|
|
|
.buttonStyle(.bordered)
|
2022-12-23 15:21:31 +00:00
|
|
|
.onAppear {
|
|
|
|
viewModel.client = client
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|