Changes in UI.

This commit is contained in:
Marcin Czachursk 2023-01-22 21:44:07 +01:00
parent 949234a7a1
commit 92c0bf75ce
17 changed files with 188 additions and 139 deletions

View File

@ -17,7 +17,7 @@ public extension MastodonClientAuthenticated {
return try await downloadJson(Account.self, request: request) return try await downloadJson(Account.self, request: request)
} }
func getAccount(for accountId: String) async throws -> Account { func account(for accountId: String) async throws -> Account {
let request = try Self.request( let request = try Self.request(
for: baseURL, for: baseURL,
target: Mastodon.Account.account(accountId), target: Mastodon.Account.account(accountId),
@ -27,7 +27,7 @@ public extension MastodonClientAuthenticated {
return try await downloadJson(Account.self, request: request) return try await downloadJson(Account.self, request: request)
} }
func getRelationship(for accountId: String) async throws -> Relationship? { func relationships(for accountId: String) async throws -> Relationship? {
let request = try Self.request( let request = try Self.request(
for: baseURL, for: baseURL,
target: Mastodon.Account.relationships([accountId]), target: Mastodon.Account.relationships([accountId]),
@ -38,7 +38,7 @@ public extension MastodonClientAuthenticated {
return relationships.first return relationships.first
} }
func getStatuses(for accountId: String, func statuses(for accountId: String,
onlyMedia: Bool = true, onlyMedia: Bool = true,
excludeReplies: Bool = true, excludeReplies: Bool = true,
maxId: String? = nil, maxId: String? = nil,
@ -114,7 +114,7 @@ public extension MastodonClientAuthenticated {
return try await downloadJson(Relationship.self, request: request) return try await downloadJson(Relationship.self, request: request)
} }
func getFollowers(for accountId: String, page: Int = 1) async throws -> [Account] { func followers(for accountId: String, page: Int = 1) async throws -> [Account] {
let request = try Self.request( let request = try Self.request(
for: baseURL, for: baseURL,
target: Mastodon.Account.followers(accountId, nil, nil, nil, nil, page), target: Mastodon.Account.followers(accountId, nil, nil, nil, nil, page),
@ -124,7 +124,7 @@ public extension MastodonClientAuthenticated {
return try await downloadJson([Account].self, request: request) return try await downloadJson([Account].self, request: request)
} }
func getFollowing(for accountId: String, page: Int = 1) async throws -> [Account] { func following(for accountId: String, page: Int = 1) async throws -> [Account] {
let request = try Self.request( let request = try Self.request(
for: baseURL, for: baseURL,
target: Mastodon.Account.following(accountId, nil, nil, nil, nil, page), target: Mastodon.Account.following(accountId, nil, nil, nil, nil, page),

View File

@ -7,7 +7,7 @@
import Foundation import Foundation
public extension MastodonClientAuthenticated { public extension MastodonClientAuthenticated {
func getNotifications(maxId: MaxId? = nil, func notifications(maxId: MaxId? = nil,
sinceId: SinceId? = nil, sinceId: SinceId? = nil,
minId: MinId? = nil, minId: MinId? = nil,
limit: Int? = nil limit: Int? = nil
@ -15,6 +15,7 @@ public extension MastodonClientAuthenticated {
let request = try Self.request(for: baseURL, let request = try Self.request(for: baseURL,
target: Mastodon.Notifications.notifications(maxId, sinceId, minId, limit), target: Mastodon.Notifications.notifications(maxId, sinceId, minId, limit),
withBearerToken: token) withBearerToken: token)
return try await downloadJsonWithLink([Notification].self, request: request) return try await downloadJsonWithLink([Notification].self, request: request)
} }
} }

View File

@ -7,7 +7,7 @@
import Foundation import Foundation
public extension MastodonClientAuthenticated { public extension MastodonClientAuthenticated {
func read(statusId: EntityId) async throws -> Status { func status(statusId: EntityId) async throws -> Status {
let request = try Self.request( let request = try Self.request(
for: baseURL, for: baseURL,
target: Mastodon.Statuses.status(statusId), target: Mastodon.Statuses.status(statusId),

View File

@ -58,7 +58,7 @@ public extension MastodonClientAuthenticated {
return try await downloadJson([Status].self, request: request) return try await downloadJson([Status].self, request: request)
} }
func saveMarkers(_ markers: [Mastodon.Markers.Timeline: EntityId]) async throws -> Markers { func setMarkers(_ markers: [Mastodon.Markers.Timeline: EntityId]) async throws -> Markers {
let request = try Self.request( let request = try Self.request(
for: baseURL, for: baseURL,
target: Mastodon.Markers.set(markers), target: Mastodon.Markers.set(markers),

View File

@ -11,38 +11,38 @@ public class AccountService {
public static let shared = AccountService() public static let shared = AccountService()
private init() { } private init() { }
public func getAccount(withId accountId: String, and accountData: AccountData?) async throws -> Account? { public func account(withId accountId: String, and accountData: AccountData?) async throws -> Account? {
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else { guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
return nil return nil
} }
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken) let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
return try await client.getAccount(for: accountId) return try await client.account(for: accountId)
} }
public func getRelationship(withId accountId: String, forUser accountData: AccountData?) async throws -> Relationship? { public func relationships(withId accountId: String, forUser accountData: AccountData?) async throws -> Relationship? {
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else { guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
return nil return nil
} }
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken) let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
return try await client.getRelationship(for: accountId) return try await client.relationships(for: accountId)
} }
public func getStatuses(forAccountId accountId: String, public func statuses(forAccountId accountId: String,
andContext accountData: AccountData?, andContext accountData: AccountData?,
onlyMedia: Bool = true, onlyMedia: Bool = true,
excludeReplies: Bool = true, excludeReplies: Bool = true,
maxId: String? = nil, maxId: String? = nil,
sinceId: String? = nil, sinceId: String? = nil,
minId: String? = nil, minId: String? = nil,
limit: Int = 40) async throws -> [Status] { limit: Int = 40) async throws -> [Status] {
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else { guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
return [] return []
} }
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken) let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
return try await client.getStatuses(for: accountId, return try await client.statuses(for: accountId,
onlyMedia: onlyMedia, onlyMedia: onlyMedia,
excludeReplies: excludeReplies, excludeReplies: excludeReplies,
maxId: maxId, maxId: maxId,
@ -105,21 +105,21 @@ public class AccountService {
return try await client.unblock(for: accountId) return try await client.unblock(for: accountId)
} }
public func getFollowers(forAccountId accountId: String, andContext accountData: AccountData?, page: Int) async throws -> [Account] { public func followers(forAccountId accountId: String, andContext accountData: AccountData?, page: Int) async throws -> [Account] {
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else { guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
return [] return []
} }
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken) let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
return try await client.getFollowers(for: accountId, page: page) return try await client.followers(for: accountId, page: page)
} }
public func getFollowing(forAccountId accountId: String, andContext accountData: AccountData?, page: Int) async throws -> [Account] { public func following(forAccountId accountId: String, andContext accountData: AccountData?, page: Int) async throws -> [Account] {
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else { guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
return [] return []
} }
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken) let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
return try await client.getFollowing(for: accountId, page: page) return try await client.following(for: accountId, page: page)
} }
} }

View File

@ -11,7 +11,7 @@ public class NotificationService {
public static let shared = NotificationService() public static let shared = NotificationService()
private init() { } private init() { }
public func getNotifications(forAccountId accountId: String, public func notifications(forAccountId accountId: String,
andContext accountData: AccountData?, andContext accountData: AccountData?,
maxId: MaxId? = nil, maxId: MaxId? = nil,
sinceId: SinceId? = nil, sinceId: SinceId? = nil,
@ -23,6 +23,6 @@ public class NotificationService {
} }
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken) let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
return try await client.getNotifications(maxId: maxId, sinceId: sinceId, minId: minId, limit: limit) return try await client.notifications(maxId: maxId, sinceId: sinceId, minId: minId, limit: limit)
} }
} }

View File

@ -11,13 +11,13 @@ public class StatusService {
public static let shared = StatusService() public static let shared = StatusService()
private init() { } private init() { }
public func getStatus(withId statusId: String, and accountData: AccountData?) async throws -> Status? { public func status(withId statusId: String, and accountData: AccountData?) async throws -> Status? {
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else { guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
return nil return nil
} }
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken) let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
return try await client.read(statusId: statusId) return try await client.status(statusId: statusId)
} }
func favourite(statusId: String, accountData: AccountData?) async throws -> Status? { func favourite(statusId: String, accountData: AccountData?) async throws -> Status? {
@ -83,7 +83,7 @@ public class StatusService {
return try await client.new(statusComponents: status) return try await client.new(statusComponents: status)
} }
func getComments(for statusId: String, and accountData: AccountData) async throws -> [CommentViewModel] { func comments(for statusId: String, and accountData: AccountData) async throws -> [CommentViewModel] {
var commentViewModels: [CommentViewModel] = [] var commentViewModels: [CommentViewModel] = []
let client = MastodonClient(baseURL: accountData.serverUrl).getAuthenticated(token: accountData.accessToken ?? String.empty()) let client = MastodonClient(baseURL: accountData.serverUrl).getAuthenticated(token: accountData.accessToken ?? String.empty())

View File

@ -110,12 +110,12 @@ struct AccountsView: View {
private func loadFromApi() async throws -> [Account] { private func loadFromApi() async throws -> [Account] {
switch self.listType { switch self.listType {
case .followers: case .followers:
return try await AccountService.shared.getFollowers( return try await AccountService.shared.followers(
forAccountId: self.entityId, forAccountId: self.entityId,
andContext: self.applicationState.accountData, andContext: self.applicationState.accountData,
page: page) page: page)
case .following: case .following:
return try await AccountService.shared.getFollowing( return try await AccountService.shared.following(
forAccountId: self.entityId, forAccountId: self.entityId,
andContext: self.applicationState.accountData, andContext: self.applicationState.accountData,
page: page) page: page)

View File

@ -196,7 +196,7 @@ struct MainView: View {
Button { Button {
self.sheet = .compose self.sheet = .compose
} label: { } label: {
Image(systemName: "photo.stack") Image(systemName: "square.and.pencil")
.tint(.mainTextColor) .tint(.mainTextColor)
} }

View File

@ -94,7 +94,7 @@ struct NotificationsView: View {
func loadNotifications() async { func loadNotifications() async {
do { do {
let linkable = try await NotificationService.shared.getNotifications( let linkable = try await NotificationService.shared.notifications(
forAccountId: self.accountId, forAccountId: self.accountId,
andContext: self.applicationState.accountData, andContext: self.applicationState.accountData,
maxId: maxId, maxId: maxId,
@ -119,7 +119,7 @@ struct NotificationsView: View {
private func loadMoreNotifications() async { private func loadMoreNotifications() async {
do { do {
let linkable = try await NotificationService.shared.getNotifications( let linkable = try await NotificationService.shared.notifications(
forAccountId: self.accountId, forAccountId: self.accountId,
andContext: self.applicationState.accountData, andContext: self.applicationState.accountData,
maxId: self.maxId, maxId: self.maxId,
@ -140,7 +140,7 @@ struct NotificationsView: View {
private func loadNewNotifications() async { private func loadNewNotifications() async {
do { do {
let linkable = try await NotificationService.shared.getNotifications( let linkable = try await NotificationService.shared.notifications(
forAccountId: self.accountId, forAccountId: self.accountId,
andContext: self.applicationState.accountData, andContext: self.applicationState.accountData,
minId: self.minId, minId: self.minId,
@ -154,9 +154,7 @@ struct NotificationsView: View {
await self.downloadAllImages(notifications: linkable.data) await self.downloadAllImages(notifications: linkable.data)
self.minId = linkable.link?.minId self.minId = linkable.link?.minId
var downloaded = linkable.data self.notifications.insert(contentsOf: linkable.data, at: 0)
self.notifications.insert(contentsOf: downloaded, at: 0)
} catch { } catch {
ErrorService.shared.handle(error, message: "Error during download notifications from server.", showToastr: !Task.isCancelled) ErrorService.shared.handle(error, message: "Error during download notifications from server.", showToastr: !Task.isCancelled)
} }

View File

@ -41,9 +41,9 @@ struct StatusView: View {
exifCreatedDate: $exifCreatedDate, exifCreatedDate: $exifCreatedDate,
exifLens: $exifLens) exifLens: $exifLens)
.onTapGesture { .onTapGesture {
// withoutAnimation { withoutAnimation {
self.showImageViewer.toggle() self.showImageViewer.toggle()
// } }
} }
VStack(alignment: .leading) { VStack(alignment: .leading) {
@ -119,7 +119,7 @@ struct StatusView: View {
} }
// Get status from API. // Get status from API.
if let status = try await StatusService.shared.getStatus(withId: self.statusId, and: self.applicationState.accountData) { if let status = try await StatusService.shared.status(withId: self.statusId, and: self.applicationState.accountData) {
let statusViewModel = StatusViewModel(status: status) let statusViewModel = StatusViewModel(status: status)
// Download images and recalculate exif data. // Download images and recalculate exif data.

View File

@ -45,8 +45,8 @@ struct UserProfileView: View {
return return
} }
async let relationshipTask = AccountService.shared.getRelationship(withId: self.accountId, forUser: self.applicationState.accountData) async let relationshipTask = AccountService.shared.relationships(withId: self.accountId, forUser: self.applicationState.accountData)
async let accountTask = AccountService.shared.getAccount(withId: self.accountId, and: self.applicationState.accountData) async let accountTask = AccountService.shared.account(withId: self.accountId, and: self.applicationState.accountData)
// Wait for download account and relationships. // Wait for download account and relationships.
self.firstLoadFinished = true self.firstLoadFinished = true

View File

@ -13,7 +13,7 @@ struct ImagesViewer: View {
// Opacity usied during close dialog animation. // Opacity usied during close dialog animation.
@State private var opacity = 1.0 @State private var opacity = 1.0
private let closeDragDistance = 140.0 private let closeDragDistance = 100.0
// Zoom. // Zoom.
@State private var zoomScale = 1.0 @State private var zoomScale = 1.0
@ -37,7 +37,7 @@ struct ImagesViewer: View {
.tag(attachment.id) .tag(attachment.id)
.offset(currentOffset) .offset(currentOffset)
.scaleEffect(finalAmount + currentAmount) .scaleEffect(finalAmount + currentAmount)
.opacity(self.opacity) // .opacity(self.opacity)
//.gesture((finalAmount + currentAmount) > 1.0 ? dragGesture : nil) //.gesture((finalAmount + currentAmount) > 1.0 ? dragGesture : nil)
.gesture(dragGesture) .gesture(dragGesture)
.gesture(magnificationGesture) .gesture(magnificationGesture)
@ -51,7 +51,9 @@ struct ImagesViewer: View {
} }
private func close() { private func close() {
dismiss() withoutAnimation {
dismiss()
}
} }
var magnificationGesture: some Gesture { var magnificationGesture: some Gesture {
@ -86,17 +88,22 @@ struct ImagesViewer: View {
let pictureOpacity = (self.closeDragDistance - self.currentOffset.height) / self.closeDragDistance let pictureOpacity = (self.closeDragDistance - self.currentOffset.height) / self.closeDragDistance
self.opacity = pictureOpacity >= 0 ? pictureOpacity : 0 self.opacity = pictureOpacity >= 0 ? pictureOpacity : 0
} .onEnded { amount in } .onEnded { amount in
self.currentOffset = CGSize(width: amount.translation.width + self.accumulatedOffset.width, let offset = CGSize(width: amount.translation.width + self.accumulatedOffset.width,
height: amount.translation.height + self.accumulatedOffset.height) height: amount.translation.height + self.accumulatedOffset.height)
self.accumulatedOffset = self.currentOffset
if self.accumulatedOffset.height < self.closeDragDistance { if offset.height < closeDragDistance {
withAnimation(.default) { withAnimation(.easeInOut) {
self.currentOffset = CGSize.zero self.currentOffset = CGSize.zero
self.accumulatedOffset = CGSize.zero self.accumulatedOffset = CGSize.zero
self.opacity = 1.0 self.opacity = 1.0
} }
} else { } else {
withAnimation(.easeInOut) {
self.currentOffset = amount.predictedEndTranslation
self.accumulatedOffset = CGSize.zero
self.opacity = 1.0
}
self.close() self.close()
} }
} }
@ -137,10 +144,3 @@ struct ImagesViewer: View {
} }
} }
} }
struct ImagesViewer_Previews: PreviewProvider {
static var previews: some View {
Text("Cos")
// ImagesViewer(statusViewModel: StatusViewModel())
}
}

View File

@ -36,19 +36,7 @@ struct InteractionRow: View {
Spacer() Spacer()
ActionMenu { ActionButton {
NavigationLink(destination: AccountsView(entityId: statusViewModel.id, listType: .reblogged)
.environmentObject(applicationState)
) {
Label("Reboosted by", systemImage: "person.3.sequence")
}
} label: {
HStack(alignment: .center) {
Image(systemName: self.reblogged ? "paperplane.fill" : "paperplane")
Text("\(self.reblogsCount)")
.font(.caption)
}
} primaryAction: {
do { do {
let status = self.reblogged let status = self.reblogged
? try await StatusService.shared.unboost(statusId: self.statusViewModel.id, accountData: self.applicationState.accountData) ? try await StatusService.shared.unboost(statusId: self.statusViewModel.id, accountData: self.applicationState.accountData)
@ -66,23 +54,17 @@ struct InteractionRow: View {
} catch { } catch {
ErrorService.shared.handle(error, message: "Reboost action failed.", showToastr: true) ErrorService.shared.handle(error, message: "Reboost action failed.", showToastr: true)
} }
} label: {
HStack(alignment: .center) {
Image(systemName: self.reblogged ? "paperplane.fill" : "paperplane")
Text("\(self.reblogsCount)")
.font(.caption)
}
} }
Spacer() Spacer()
ActionMenu { ActionButton {
NavigationLink(destination: AccountsView(entityId: statusViewModel.id, listType: .favourited)
.environmentObject(applicationState)
) {
Label("Favourited by", systemImage: "person.3.sequence")
}
} label: {
HStack(alignment: .center) {
Image(systemName: self.favourited ? "hand.thumbsup.fill" : "hand.thumbsup")
Text("\(self.favouritesCount)")
.font(.caption)
}
} primaryAction: {
do { do {
let status = self.favourited let status = self.favourited
? try await StatusService.shared.unfavourite(statusId: self.statusViewModel.id, accountData: self.applicationState.accountData) ? try await StatusService.shared.unfavourite(statusId: self.statusViewModel.id, accountData: self.applicationState.accountData)
@ -100,6 +82,12 @@ struct InteractionRow: View {
} catch { } catch {
ErrorService.shared.handle(error, message: "Favourite action failed.", showToastr: true) ErrorService.shared.handle(error, message: "Favourite action failed.", showToastr: true)
} }
} label: {
HStack(alignment: .center) {
Image(systemName: self.favourited ? "hand.thumbsup.fill" : "hand.thumbsup")
Text("\(self.favouritesCount)")
.font(.caption)
}
} }
Spacer() Spacer()
@ -120,11 +108,34 @@ struct InteractionRow: View {
Image(systemName: self.bookmarked ? "bookmark.fill" : "bookmark") Image(systemName: self.bookmarked ? "bookmark.fill" : "bookmark")
} }
if let url = statusViewModel.url { Spacer()
Spacer()
ShareLink(item: url) { Menu {
Image(systemName: "square.and.arrow.up") NavigationLink(destination: AccountsView(entityId: statusViewModel.id, listType: .reblogged)
.environmentObject(applicationState)
) {
Label("Reboosted by", systemImage: "paperplane")
} }
NavigationLink(destination: AccountsView(entityId: statusViewModel.id, listType: .favourited)
.environmentObject(applicationState)
) {
Label("Favourited by", systemImage: "hand.thumbsup")
}
if let url = statusViewModel.url {
Divider()
Link(destination: url) {
Label("Open in browser", systemImage: "safari")
}
ShareLink(item: url) {
Label("Share post", systemImage: "square.and.arrow.up")
}
}
} label: {
Image(systemName: "gear")
} }
} }
.font(.title3) .font(.title3)

View File

@ -56,7 +56,7 @@ struct CommentsSection: View {
.task { .task {
do { do {
if let accountData = applicationState.accountData { if let accountData = applicationState.accountData {
self.commentViewModels = try await StatusService.shared.getComments(for: statusId, and: accountData) self.commentViewModels = try await StatusService.shared.comments(for: statusId, and: accountData)
} }
} catch { } catch {
ErrorService.shared.handle(error, message: "Comments cannot be downloaded.", showToastr: !Task.isCancelled) ErrorService.shared.handle(error, message: "Comments cannot be downloaded.", showToastr: !Task.isCancelled)

View File

@ -69,7 +69,11 @@ struct UserProfileHeader: View {
Spacer() Spacer()
self.actionButtons() if self.applicationState.accountData?.id != self.account.id {
self.otherAccountActionButtons()
} else {
self.profileAccountActionButtons()
}
} }
if let note = account.note, !note.isEmpty { if let note = account.note, !note.isEmpty {
@ -87,62 +91,97 @@ struct UserProfileHeader: View {
} }
@ViewBuilder @ViewBuilder
private func actionButtons() -> some View { private func otherAccountActionButtons() -> some View {
if self.applicationState.accountData?.id != self.account.id { ActionButton {
ActionButton { await onRelationshipButtonTap()
await onRelationshipButtonTap() } label: {
HStack {
Image(systemName: relationship?.following == true ? "person.badge.minus" : "person.badge.plus")
Text(relationship?.following == true ? "Unfollow" : (relationship?.followedBy == true ? "Follow back" : "Follow"))
}
}
.buttonStyle(.borderedProminent)
.tint(relationship?.following == true ? .dangerColor : .accentColor)
Menu (content: {
if let accountUrl = account.url {
Link(destination: accountUrl) {
Label("Open in browser", systemImage: "safari")
}
ShareLink(item: accountUrl) {
Label("Share", systemImage: "square.and.arrow.up")
}
Divider()
}
Button {
Task {
await onMuteAccount()
}
} label: { } label: {
HStack { if self.relationship?.muting == true {
Image(systemName: relationship?.following == true ? "person.badge.minus" : "person.badge.plus") Label("Unute", systemImage: "message.and.waveform.fill")
Text(relationship?.following == true ? "Unfollow" : (relationship?.followedBy == true ? "Follow back" : "Follow")) } else {
Label("Mute", systemImage: "message.and.waveform")
} }
} }
.buttonStyle(.borderedProminent)
.tint(relationship?.following == true ? .dangerColor : .accentColor)
Menu (content: { Button {
if let accountUrl = account.url { Task {
Link(destination: accountUrl) { await onBlockAccount()
Label("Open link to profile", systemImage: "safari") }
} } label: {
if self.relationship?.blocking == true {
ShareLink(item: accountUrl) { Label("Unblock", systemImage: "hand.raised.fill")
Label("Share", systemImage: "square.and.arrow.up") } else {
} Label("Block", systemImage: "hand.raised")
}
Divider() }
}, label: {
Image(systemName: "gear")
})
.buttonStyle(.borderedProminent)
.tint(.accentColor)
}
@ViewBuilder
private func profileAccountActionButtons() -> some View {
Menu (content: {
if let accountUrl = account.url {
Link(destination: accountUrl) {
Label("Open in browser", systemImage: "safari")
} }
Button { ShareLink(item: accountUrl) {
Task { Label("Share", systemImage: "square.and.arrow.up")
await onMuteAccount()
}
} label: {
if self.relationship?.muting == true {
Label("Unute", systemImage: "message.and.waveform.fill")
} else {
Label("Mute", systemImage: "message.and.waveform")
}
} }
Button { Divider()
Task { }
await onBlockAccount()
} Button {
} label: { Task {
if self.relationship?.blocking == true { // await onMuteAccount()
Label("Unblock", systemImage: "hand.raised.fill")
} else {
Label("Block", systemImage: "hand.raised")
}
} }
} label: {
}, label: { Label("Favourites", systemImage: "hand.thumbsup")
Image(systemName: "person.crop.square.fill") }
})
.buttonStyle(.borderedProminent) Button {
.tint(Color.secondaryLabel) Task {
} // await onMuteAccount()
}
} label: {
Label("Bookmarks", systemImage: "bookmark")
}
}, label: {
Image(systemName: "gear")
})
.buttonStyle(.borderedProminent)
.tint(.accentColor)
} }
private func onRelationshipButtonTap() async { private func onRelationshipButtonTap() async {

View File

@ -66,7 +66,7 @@ struct UserProfileStatuses: View {
return return
} }
let statuses = try await AccountService.shared.getStatuses( let statuses = try await AccountService.shared.statuses(
forAccountId: self.accountId, forAccountId: self.accountId,
andContext: self.applicationState.accountData, andContext: self.applicationState.accountData,
limit: self.defaultLimit) limit: self.defaultLimit)
@ -86,7 +86,7 @@ struct UserProfileStatuses: View {
private func loadMoreStatuses() async throws { private func loadMoreStatuses() async throws {
if let lastStatusId = self.statusViewModels.last?.id { if let lastStatusId = self.statusViewModels.last?.id {
let previousStatuses = try await AccountService.shared.getStatuses( let previousStatuses = try await AccountService.shared.statuses(
forAccountId: self.accountId, forAccountId: self.accountId,
andContext: self.applicationState.accountData, andContext: self.applicationState.accountData,
maxId: lastStatusId, maxId: lastStatusId,