Changes in UI.
This commit is contained in:
parent
949234a7a1
commit
92c0bf75ce
|
@ -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),
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue