Refactor account context menu and add it to account list row
This commit is contained in:
parent
242998799a
commit
0ec33b802d
|
@ -0,0 +1,174 @@
|
|||
import SwiftUI
|
||||
import Env
|
||||
import Network
|
||||
|
||||
public struct AccountDetailContextMenu: View {
|
||||
@EnvironmentObject private var client: Client
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@EnvironmentObject private var currentInstance: CurrentInstance
|
||||
@EnvironmentObject private var preferences: UserPreferences
|
||||
|
||||
@ObservedObject var viewModel: AccountDetailViewModel
|
||||
|
||||
public var body: some View {
|
||||
if let account = viewModel.account {
|
||||
Section(account.acct) {
|
||||
if !viewModel.isCurrentUser {
|
||||
Button {
|
||||
routerPath.presentedSheet = .mentionStatusEditor(account: account,
|
||||
visibility: preferences.postVisibility)
|
||||
} label: {
|
||||
Label("account.action.mention", systemImage: "at")
|
||||
}
|
||||
Button {
|
||||
routerPath.presentedSheet = .mentionStatusEditor(account: account, visibility: .direct)
|
||||
} label: {
|
||||
Label("account.action.message", systemImage: "tray.full")
|
||||
}
|
||||
|
||||
Divider()
|
||||
|
||||
if viewModel.relationship?.blocking == true {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.unblock(id: account.id))
|
||||
} catch {
|
||||
print("Error while unblocking: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.unblock", systemImage: "person.crop.circle.badge.exclamationmark")
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.block(id: account.id))
|
||||
} catch {
|
||||
print("Error while blocking: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.block", systemImage: "person.crop.circle.badge.xmark")
|
||||
}
|
||||
}
|
||||
|
||||
if viewModel.relationship?.muting == true {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.unmute(id: account.id))
|
||||
} catch {
|
||||
print("Error while unmuting: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.unmute", systemImage: "speaker")
|
||||
}
|
||||
} else {
|
||||
Menu {
|
||||
ForEach(MutingDuration.allCases, id: \.rawValue) { duration in
|
||||
Button(duration.description) {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.mute(id: account.id, json: MuteData(duration: duration.rawValue)))
|
||||
} catch {
|
||||
print("Error while muting: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.mute", systemImage: "speaker.slash")
|
||||
}
|
||||
}
|
||||
|
||||
if let relationship = viewModel.relationship,
|
||||
relationship.following
|
||||
{
|
||||
if relationship.notifying {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id,
|
||||
notify: false,
|
||||
reblogs: relationship.showingReblogs))
|
||||
} catch {
|
||||
print("Error while disabling notifications: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.notify-disable", systemImage: "bell.fill")
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id,
|
||||
notify: true,
|
||||
reblogs: relationship.showingReblogs))
|
||||
} catch {
|
||||
print("Error while enabling notifications: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.notify-enable", systemImage: "bell")
|
||||
}
|
||||
}
|
||||
if relationship.showingReblogs {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id,
|
||||
notify: relationship.notifying,
|
||||
reblogs: false))
|
||||
} catch {
|
||||
print("Error while disabling reboosts: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.reboosts-hide", systemImage: "arrow.left.arrow.right.circle.fill")
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id,
|
||||
notify: relationship.notifying,
|
||||
reblogs: true))
|
||||
} catch {
|
||||
print("Error while enabling reboosts: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.reboosts-show", systemImage: "arrow.left.arrow.right.circle")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Divider()
|
||||
}
|
||||
|
||||
if viewModel.relationship?.following == true {
|
||||
Button {
|
||||
routerPath.presentedSheet = .listAddAccount(account: account)
|
||||
} label: {
|
||||
Label("account.action.add-remove-list", systemImage: "list.bullet")
|
||||
}
|
||||
}
|
||||
|
||||
if let url = account.url {
|
||||
ShareLink(item: url, subject: Text(account.safeDisplayName)) {
|
||||
Label("account.action.share", systemImage: "square.and.arrow.up")
|
||||
}
|
||||
Button { UIApplication.shared.open(url) } label: {
|
||||
Label("status.action.view-in-browser", systemImage: "safari")
|
||||
}
|
||||
}
|
||||
|
||||
Divider()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -289,191 +289,35 @@ public struct AccountDetailView: View {
|
|||
private var toolbarContent: some ToolbarContent {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Menu {
|
||||
if let account = viewModel.account {
|
||||
Section(account.acct) {
|
||||
if !viewModel.isCurrentUser {
|
||||
Button {
|
||||
routerPath.presentedSheet = .mentionStatusEditor(account: account,
|
||||
visibility: preferences.postVisibility)
|
||||
} label: {
|
||||
Label("account.action.mention", systemImage: "at")
|
||||
}
|
||||
Button {
|
||||
routerPath.presentedSheet = .mentionStatusEditor(account: account, visibility: .direct)
|
||||
} label: {
|
||||
Label("account.action.message", systemImage: "tray.full")
|
||||
}
|
||||
AccountDetailContextMenu(viewModel: viewModel)
|
||||
|
||||
if viewModel.relationship?.following == true, !viewModel.isCurrentUser {
|
||||
Button {
|
||||
isEditingRelationshipNote = true
|
||||
} label: {
|
||||
Label("account.relation.note.edit", systemImage: "pencil")
|
||||
}
|
||||
}
|
||||
|
||||
if isCurrentUser {
|
||||
Button {
|
||||
isEditingAccount = true
|
||||
} label: {
|
||||
Label("account.action.edit-info", systemImage: "pencil")
|
||||
}
|
||||
|
||||
Divider()
|
||||
|
||||
if viewModel.relationship?.blocking == true {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.unblock(id: account.id))
|
||||
} catch {
|
||||
print("Error while unblocking: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.unblock", systemImage: "person.crop.circle.badge.exclamationmark")
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.block(id: account.id))
|
||||
} catch {
|
||||
print("Error while blocking: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.block", systemImage: "person.crop.circle.badge.xmark")
|
||||
}
|
||||
}
|
||||
|
||||
if viewModel.relationship?.muting == true {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.unmute(id: account.id))
|
||||
} catch {
|
||||
print("Error while unmuting: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.unmute", systemImage: "speaker")
|
||||
}
|
||||
} else {
|
||||
Menu {
|
||||
ForEach(MutingDuration.allCases, id: \.rawValue) { duration in
|
||||
Button(duration.description) {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.mute(id: account.id, json: MuteData(duration: duration.rawValue)))
|
||||
} catch {
|
||||
print("Error while muting: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.mute", systemImage: "speaker.slash")
|
||||
}
|
||||
}
|
||||
|
||||
if let relationship = viewModel.relationship,
|
||||
relationship.following
|
||||
{
|
||||
if relationship.notifying {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id,
|
||||
notify: false,
|
||||
reblogs: relationship.showingReblogs))
|
||||
} catch {
|
||||
print("Error while disabling notifications: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.notify-disable", systemImage: "bell.fill")
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id,
|
||||
notify: true,
|
||||
reblogs: relationship.showingReblogs))
|
||||
} catch {
|
||||
print("Error while enabling notifications: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.notify-enable", systemImage: "bell")
|
||||
}
|
||||
}
|
||||
if relationship.showingReblogs {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id,
|
||||
notify: relationship.notifying,
|
||||
reblogs: false))
|
||||
} catch {
|
||||
print("Error while disabling reboosts: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.reboosts-hide", systemImage: "arrow.left.arrow.right.circle.fill")
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
Task {
|
||||
do {
|
||||
viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id,
|
||||
notify: relationship.notifying,
|
||||
reblogs: true))
|
||||
} catch {
|
||||
print("Error while enabling reboosts: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("account.action.reboosts-show", systemImage: "arrow.left.arrow.right.circle")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Divider()
|
||||
|
||||
Button {
|
||||
isEditingRelationshipNote = true
|
||||
} label: {
|
||||
Label("account.relation.note.edit", systemImage: "pencil")
|
||||
}
|
||||
if curretnInstance.isFiltersSupported {
|
||||
Button {
|
||||
isEditingFilters = true
|
||||
} label: {
|
||||
Label("account.action.edit-filters", systemImage: "line.3.horizontal.decrease.circle")
|
||||
}
|
||||
}
|
||||
|
||||
if viewModel.relationship?.following == true {
|
||||
Button {
|
||||
routerPath.presentedSheet = .listAddAccount(account: account)
|
||||
} label: {
|
||||
Label("account.action.add-remove-list", systemImage: "list.bullet")
|
||||
}
|
||||
}
|
||||
|
||||
if let url = account.url {
|
||||
ShareLink(item: url, subject: Text(account.safeDisplayName)) {
|
||||
Label("account.action.share", systemImage: "square.and.arrow.up")
|
||||
}
|
||||
Button { UIApplication.shared.open(url) } label: {
|
||||
Label("status.action.view-in-browser", systemImage: "safari")
|
||||
}
|
||||
}
|
||||
|
||||
Divider()
|
||||
|
||||
if isCurrentUser {
|
||||
Button {
|
||||
isEditingAccount = true
|
||||
} label: {
|
||||
Label("account.action.edit-info", systemImage: "pencil")
|
||||
}
|
||||
|
||||
if curretnInstance.isFiltersSupported {
|
||||
Button {
|
||||
isEditingFilters = true
|
||||
} label: {
|
||||
Label("account.action.edit-filters", systemImage: "line.3.horizontal.decrease.circle")
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
routerPath.presentedSheet = .accountPushNotficationsSettings
|
||||
} label: {
|
||||
Label("settings.push.navigation-title", systemImage: "bell")
|
||||
}
|
||||
}
|
||||
Button {
|
||||
routerPath.presentedSheet = .accountPushNotficationsSettings
|
||||
} label: {
|
||||
Label("settings.push.navigation-title", systemImage: "bell")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
|
@ -483,7 +327,7 @@ public struct AccountDetailView: View {
|
|||
}
|
||||
}
|
||||
|
||||
private extension View {
|
||||
extension View {
|
||||
func applyAccountDetailsRowStyle(theme: Theme) -> some View {
|
||||
listRowInsets(.init())
|
||||
.listRowSeparator(.hidden)
|
||||
|
|
|
@ -19,11 +19,15 @@ public class AccountsListRowViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
public struct AccountsListRow: View {
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@EnvironmentObject private var client: Client
|
||||
|
||||
@StateObject var viewModel: AccountsListRowViewModel
|
||||
|
||||
@State private var isEditingRelationshipNote: Bool = false
|
||||
|
||||
let isFollowRequest: Bool
|
||||
let requestUpdated: (() -> Void)?
|
||||
|
||||
|
@ -75,5 +79,22 @@ public struct AccountsListRow: View {
|
|||
.onTapGesture {
|
||||
routerPath.navigate(to: .accountDetailWithAccount(account: viewModel.account))
|
||||
}
|
||||
.contextMenu {
|
||||
AccountDetailContextMenu(viewModel: .init(account: viewModel.account))
|
||||
} preview: {
|
||||
List {
|
||||
AccountDetailHeaderView(viewModel: .init(account: viewModel.account),
|
||||
account: viewModel.account,
|
||||
scrollViewProxy: nil)
|
||||
.applyAccountDetailsRowStyle(theme: theme)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.primaryBackgroundColor)
|
||||
.environmentObject(theme)
|
||||
.environmentObject(currentAccount)
|
||||
.environmentObject(client)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue