Improve user profile/details
This commit is contained in:
parent
07bc128464
commit
d6a63036fb
|
@ -24,6 +24,7 @@
|
|||
F8210DE52966E160001D9973 /* Color+SystemColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8210DE42966E160001D9973 /* Color+SystemColors.swift */; };
|
||||
F8210DE72966E1D1001D9973 /* Color+Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8210DE62966E1D1001D9973 /* Color+Assets.swift */; };
|
||||
F8210DEA2966E4F9001D9973 /* AnimatePlaceholderModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8210DE92966E4F9001D9973 /* AnimatePlaceholderModifier.swift */; };
|
||||
F8210DEC2966F30C001D9973 /* UserFeedbackService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8210DEB2966F30C001D9973 /* UserFeedbackService.swift */; };
|
||||
F8341F90295C636C009C8EE6 /* UIImage+Exif.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8341F8F295C636C009C8EE6 /* UIImage+Exif.swift */; };
|
||||
F8341F92295C63BB009C8EE6 /* ImageStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8341F91295C63BB009C8EE6 /* ImageStatus.swift */; };
|
||||
F83901A6295D8EC000456AE2 /* LabelIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F83901A5295D8EC000456AE2 /* LabelIcon.swift */; };
|
||||
|
@ -83,6 +84,7 @@
|
|||
F8210DE42966E160001D9973 /* Color+SystemColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+SystemColors.swift"; sourceTree = "<group>"; };
|
||||
F8210DE62966E1D1001D9973 /* Color+Assets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Assets.swift"; sourceTree = "<group>"; };
|
||||
F8210DE92966E4F9001D9973 /* AnimatePlaceholderModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatePlaceholderModifier.swift; sourceTree = "<group>"; };
|
||||
F8210DEB2966F30C001D9973 /* UserFeedbackService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserFeedbackService.swift; sourceTree = "<group>"; };
|
||||
F8341F8F295C636C009C8EE6 /* UIImage+Exif.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Exif.swift"; sourceTree = "<group>"; };
|
||||
F8341F91295C63BB009C8EE6 /* ImageStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageStatus.swift; sourceTree = "<group>"; };
|
||||
F83901A5295D8EC000456AE2 /* LabelIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelIcon.swift; sourceTree = "<group>"; };
|
||||
|
@ -290,6 +292,7 @@
|
|||
F85D4974296407F100751DF7 /* TimelineService.swift */,
|
||||
F8A93D7F2965FED4001D8331 /* AccountService.swift */,
|
||||
F8210DE02966D0C4001D9973 /* StatusService.swift */,
|
||||
F8210DEB2966F30C001D9973 /* UserFeedbackService.swift */,
|
||||
);
|
||||
path = Services;
|
||||
sourceTree = "<group>";
|
||||
|
@ -427,6 +430,7 @@
|
|||
F8A93D802965FED4001D8331 /* AccountService.swift in Sources */,
|
||||
F866F6AA29605AFA002E8F88 /* SceneDelegate.swift in Sources */,
|
||||
F85D4973296406E700751DF7 /* BottomRight.swift in Sources */,
|
||||
F8210DEC2966F30C001D9973 /* UserFeedbackService.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -41,4 +41,15 @@ extension MastodonClientAuthenticated {
|
|||
let (data, _) = try await urlSession.data(for: request)
|
||||
return try JSONDecoder().decode([Status].self, from: data)
|
||||
}
|
||||
|
||||
func follow(for accountId: String) async throws -> Relationship {
|
||||
let request = try Self.request(
|
||||
for: baseURL,
|
||||
target: Mastodon.Account.follow(accountId),
|
||||
withBearerToken: token
|
||||
)
|
||||
|
||||
let (data, _) = try await urlSession.data(for: request)
|
||||
return try JSONDecoder().decode(Relationship.self, from: data)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,4 +37,13 @@ public class AccountService {
|
|||
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
|
||||
return try await client.getStatuses(for: accountId)
|
||||
}
|
||||
|
||||
public func follow(forAccountId accountId: String, andContext accountData: AccountData?) async throws -> Relationship? {
|
||||
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
|
||||
return try await client.follow(for: accountId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,57 @@ public class StatusService {
|
|||
public static let shared = StatusService()
|
||||
private init() { }
|
||||
|
||||
func copy(from status: Status, to statusData: StatusData) {
|
||||
func favourite(statusId: String, accountData: AccountData?) async throws -> Status? {
|
||||
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
|
||||
return try await client.favourite(statusId: statusId)
|
||||
}
|
||||
|
||||
func unfavourite(statusId: String, accountData: AccountData?) async throws -> Status? {
|
||||
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
|
||||
return try await client.unfavourite(statusId: statusId)
|
||||
}
|
||||
|
||||
func boost(statusId: String, accountData: AccountData?) async throws -> Status? {
|
||||
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
|
||||
return try await client.boost(statusId: statusId)
|
||||
}
|
||||
|
||||
func unboost(statusId: String, accountData: AccountData?) async throws -> Status? {
|
||||
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
|
||||
return try await client.unboost(statusId: statusId)
|
||||
}
|
||||
|
||||
func bookmark(statusId: String, accountData: AccountData?) async throws -> Status? {
|
||||
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
|
||||
return try await client.bookmark(statusId: statusId)
|
||||
}
|
||||
|
||||
func unbookmark(statusId: String, accountData: AccountData?) async throws -> Status? {
|
||||
guard let accessToken = accountData?.accessToken, let serverUrl = accountData?.serverUrl else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let client = MastodonClient(baseURL: serverUrl).getAuthenticated(token: accessToken)
|
||||
return try await client.unbookmark(statusId: statusId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// https://mczachurski.dev
|
||||
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AVFoundation
|
||||
|
||||
public class UserFeedbackService {
|
||||
public static let shared = UserFeedbackService()
|
||||
private init() { }
|
||||
|
||||
func send() {
|
||||
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
|
||||
// AudioServicesPlaySystemSound(1016)
|
||||
}
|
||||
}
|
|
@ -79,7 +79,19 @@ struct UserProfileView: View {
|
|||
Spacer()
|
||||
|
||||
Button {
|
||||
// TODO: Folllow/Unfollow.
|
||||
Task {
|
||||
do {
|
||||
if let relationship = try await AccountService.shared.follow(
|
||||
forAccountId: self.accountId,
|
||||
andContext: self.applicationState.accountData
|
||||
) {
|
||||
UserFeedbackService.shared.send()
|
||||
self.relationship = relationship
|
||||
}
|
||||
} catch {
|
||||
print("Error \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
HStack {
|
||||
Image(systemName: relationship?.following == true ? "person.badge.minus" : "person.badge.plus")
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
import SwiftUI
|
||||
|
||||
struct InteractionRow: View {
|
||||
@EnvironmentObject var applicationState: ApplicationState
|
||||
@ObservedObject public var statusData: StatusData
|
||||
|
||||
var body: some View {
|
||||
HStack (alignment: .top) {
|
||||
Button {
|
||||
// TODO: Reply.
|
||||
UserFeedbackService.shared.send()
|
||||
} label: {
|
||||
HStack(alignment: .center) {
|
||||
Image(systemName: "message")
|
||||
|
@ -24,7 +26,24 @@ struct InteractionRow: View {
|
|||
Spacer()
|
||||
|
||||
Button {
|
||||
// TODO: Reboost.
|
||||
Task {
|
||||
do {
|
||||
let status = self.statusData.reblogged
|
||||
? try await StatusService.shared.unboost(statusId: self.statusData.id, accountData: self.applicationState.accountData)
|
||||
: try await StatusService.shared.boost(statusId: self.statusData.id, accountData: self.applicationState.accountData)
|
||||
|
||||
if let status {
|
||||
self.statusData.reblogsCount = status.reblogsCount == self.statusData.reblogsCount
|
||||
? Int32(status.reblogsCount + 1)
|
||||
: Int32(status.reblogsCount)
|
||||
|
||||
self.statusData.reblogged = status.reblogged
|
||||
UserFeedbackService.shared.send()
|
||||
}
|
||||
} catch {
|
||||
print("Error \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
HStack(alignment: .center) {
|
||||
Image(systemName: statusData.reblogged ? "paperplane.fill" : "paperplane")
|
||||
|
@ -36,7 +55,24 @@ struct InteractionRow: View {
|
|||
Spacer()
|
||||
|
||||
Button {
|
||||
// TODO: Favorite.
|
||||
Task {
|
||||
do {
|
||||
let status = self.statusData.favourited
|
||||
? try await StatusService.shared.unfavourite(statusId: self.statusData.id, accountData: self.applicationState.accountData)
|
||||
: try await StatusService.shared.favourite(statusId: self.statusData.id, accountData: self.applicationState.accountData)
|
||||
|
||||
if let status {
|
||||
self.statusData.favouritesCount = status.favouritesCount == self.statusData.favouritesCount
|
||||
? Int32(status.favouritesCount + 1)
|
||||
: Int32(status.favouritesCount)
|
||||
|
||||
self.statusData.favourited = status.favourited
|
||||
UserFeedbackService.shared.send()
|
||||
}
|
||||
} catch {
|
||||
print("Error \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
HStack(alignment: .center) {
|
||||
Image(systemName: statusData.favourited ? "hand.thumbsup.fill" : "hand.thumbsup")
|
||||
|
@ -48,7 +84,18 @@ struct InteractionRow: View {
|
|||
Spacer()
|
||||
|
||||
Button {
|
||||
// TODO: Bookmark.
|
||||
Task {
|
||||
do {
|
||||
let status = self.statusData.bookmarked
|
||||
? try await StatusService.shared.unbookmark(statusId: self.statusData.id, accountData: self.applicationState.accountData)
|
||||
: try await StatusService.shared.bookmark(statusId: self.statusData.id, accountData: self.applicationState.accountData)
|
||||
|
||||
self.statusData.bookmarked.toggle()
|
||||
UserFeedbackService.shared.send()
|
||||
} catch {
|
||||
print("Error \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: statusData.bookmarked ? "bookmark.fill" : "bookmark")
|
||||
}
|
||||
|
@ -57,6 +104,7 @@ struct InteractionRow: View {
|
|||
|
||||
Button {
|
||||
// TODO: Share.
|
||||
UserFeedbackService.shared.send()
|
||||
} label: {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue