Optimization interactor
This commit is contained in:
parent
51db0c2442
commit
fc039504f7
@ -33,6 +33,7 @@
|
||||
B9B63B232B447B8000BBC82D /* PostCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9B63B222B447B8000BBC82D /* PostCardView.swift */; };
|
||||
B9B63B252B44997400BBC82D /* QuotePostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9B63B242B44997400BBC82D /* QuotePostView.swift */; };
|
||||
B9B63B272B449CDC00BBC82D /* SearchResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9B63B262B449CDC00BBC82D /* SearchResults.swift */; };
|
||||
B9BED5162B5D5E6500C9B715 /* PostInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9BED5152B5D5E6500C9B715 /* PostInteractor.swift */; };
|
||||
B9CC45B82B40A2D6001E4FA5 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9CC45B72B40A2D6001E4FA5 /* AboutView.swift */; };
|
||||
B9CFC43B2B4F08C9004CFCB7 /* LaunchStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9CFC43A2B4F08C9004CFCB7 /* LaunchStoryboard.storyboard */; };
|
||||
B9EBE8562B47256900FB594D /* PostAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9EBE8552B47256900FB594D /* PostAttachment.swift */; };
|
||||
@ -115,6 +116,7 @@
|
||||
B9B63B222B447B8000BBC82D /* PostCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostCardView.swift; sourceTree = "<group>"; };
|
||||
B9B63B242B44997400BBC82D /* QuotePostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuotePostView.swift; sourceTree = "<group>"; };
|
||||
B9B63B262B449CDC00BBC82D /* SearchResults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResults.swift; sourceTree = "<group>"; };
|
||||
B9BED5152B5D5E6500C9B715 /* PostInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostInteractor.swift; sourceTree = "<group>"; };
|
||||
B9CC45B72B40A2D6001E4FA5 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
|
||||
B9CC45B92B40AA1E001E4FA5 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
B9CFC43A2B4F08C9004CFCB7 /* LaunchStoryboard.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchStoryboard.storyboard; sourceTree = "<group>"; };
|
||||
@ -179,6 +181,18 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
B9BED5142B5D5CCD00C9B715 /* Status */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B9842C0D2B2F21B700D9F3C1 /* CompactPostView.swift */,
|
||||
B9B63B222B447B8000BBC82D /* PostCardView.swift */,
|
||||
B9EBE8552B47256900FB594D /* PostAttachment.swift */,
|
||||
B9B63B242B44997400BBC82D /* QuotePostView.swift */,
|
||||
B9BED5152B5D5E6500C9B715 /* PostInteractor.swift */,
|
||||
);
|
||||
path = Status;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B9FB944E2B2DEECE00D81C07 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -268,17 +282,14 @@
|
||||
B9FB946E2B2DF3BB00D81C07 /* Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B9BED5142B5D5CCD00C9B715 /* Status */,
|
||||
B9FB94752B2E023D00D81C07 /* TabsView.swift */,
|
||||
B9FB94732B2DF6A100D81C07 /* ButtonStyles.swift */,
|
||||
B93B67792B42EC51000892E9 /* MetaPicker.swift */,
|
||||
B9FB948B2B2E232300D81C07 /* OnlineImage.swift */,
|
||||
B9842C0D2B2F21B700D9F3C1 /* CompactPostView.swift */,
|
||||
B93B67772B42E8F0000892E9 /* TextEmoji.swift */,
|
||||
B9B63B202B442D1500BBC82D /* DynamicTextEditor.swift */,
|
||||
B9B63B222B447B8000BBC82D /* PostCardView.swift */,
|
||||
B9B63B242B44997400BBC82D /* QuotePostView.swift */,
|
||||
B98BC74A2B46CF0400595441 /* ListStyle.swift */,
|
||||
B9EBE8552B47256900FB594D /* PostAttachment.swift */,
|
||||
);
|
||||
path = Components;
|
||||
sourceTree = "<group>";
|
||||
@ -465,6 +476,7 @@
|
||||
B9FB945B2B2DEECE00D81C07 /* ThreadedApp.swift in Sources */,
|
||||
B9FB94862B2E211200D81C07 /* Account+Elms.swift in Sources */,
|
||||
B9FB94BC2B2F035500D81C07 /* Tag.swift in Sources */,
|
||||
B9BED5162B5D5E6500C9B715 /* PostInteractor.swift in Sources */,
|
||||
B98BC74B2B46CF0400595441 /* ListStyle.swift in Sources */,
|
||||
B9FB94812B2E1FEF00D81C07 /* HTMLString.swift in Sources */,
|
||||
B9FB947F2B2E1D5F00D81C07 /* Account.swift in Sources */,
|
||||
|
@ -13,14 +13,17 @@ struct CompactPostView: View {
|
||||
|
||||
@State private var preferences: UserPreferences = .defaultPreferences
|
||||
@State private var initialLike: Bool = false
|
||||
|
||||
@State private var isLiked: Bool = false
|
||||
@State private var isReposted: Bool = false
|
||||
@State private var isBookmarked: Bool = false
|
||||
|
||||
@State private var hasQuote: Bool = false
|
||||
@State private var quoteStatus: Status? = nil
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
statusPost(status)
|
||||
statusPost(status.reblog ?? status)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
navigator.navigate(to: .post(status: status))
|
||||
@ -40,9 +43,7 @@ struct CompactPostView: View {
|
||||
print(error)
|
||||
}
|
||||
|
||||
isLiked = status.reblog != nil ? status.reblog!.favourited ?? false : status.favourited ?? false
|
||||
initialLike = isLiked
|
||||
isReposted = status.reblog != nil ? status.reblog!.reblogged ?? false : status.reblogged ?? false
|
||||
}
|
||||
.task {
|
||||
await loadEmbeddedStatus(status: status)
|
||||
@ -55,34 +56,6 @@ struct CompactPostView: View {
|
||||
}
|
||||
}
|
||||
|
||||
func likePost() async throws {
|
||||
if let client = accountManager.getClient() {
|
||||
guard client.isAuth else { fatalError("Client is not authenticated") }
|
||||
let statusId: String = status.reblog != nil ? status.reblog!.id : status.id
|
||||
let endpoint = !isLiked ? Statuses.favorite(id: statusId) : Statuses.unfavorite(id: statusId)
|
||||
|
||||
isLiked = !isLiked
|
||||
let newStatus: Status = try await client.post(endpoint: endpoint)
|
||||
if isLiked != newStatus.favourited {
|
||||
isLiked = newStatus.favourited ?? !isLiked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func repostPost() async throws {
|
||||
if let client = accountManager.getClient() {
|
||||
guard client.isAuth else { fatalError("Client is not authenticated") }
|
||||
let statusId: String = status.reblog != nil ? status.reblog!.id : status.id
|
||||
let endpoint = !isReposted ? Statuses.reblog(id: statusId) : Statuses.unreblog(id: statusId)
|
||||
|
||||
isReposted = !isReposted
|
||||
let newStatus: Status = try await client.post(endpoint: endpoint)
|
||||
if isReposted != newStatus.reblogged {
|
||||
isReposted = newStatus.reblogged ?? !isReposted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func statusPost(_ status: AnyStatus) -> some View {
|
||||
HStack(alignment: .top, spacing: 0) {
|
||||
@ -181,35 +154,7 @@ struct CompactPostView: View {
|
||||
|
||||
//MARK: Action buttons
|
||||
if !quoted {
|
||||
HStack(spacing: 13) {
|
||||
asyncActionButton(isLiked ? "heart.fill" : "heart") {
|
||||
do {
|
||||
HapticManager.playHaptics(haptics: Haptic.tap)
|
||||
try await likePost()
|
||||
} catch {
|
||||
HapticManager.playHaptics(haptics: Haptic.error)
|
||||
print("Error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
actionButton("bubble.right") {
|
||||
navigator.presentedSheet = .post(content: "@\(status.account.acct)", replyId: status.id)
|
||||
}
|
||||
asyncActionButton(isReposted ? "bolt.horizontal.fill" : "bolt.horizontal") {
|
||||
do {
|
||||
HapticManager.playHaptics(haptics: Haptic.tap)
|
||||
try await repostPost()
|
||||
} catch {
|
||||
HapticManager.playHaptics(haptics: Haptic.error)
|
||||
print("Error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
ShareLink(item: URL(string: status.url ?? "https://joinmastodon.org/")!) {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
.font(.title2)
|
||||
}
|
||||
.tint(Color(uiColor: UIColor.label))
|
||||
}
|
||||
.padding(.top)
|
||||
|
||||
}
|
||||
|
||||
// MARK: Status stats
|
||||
@ -350,28 +295,4 @@ struct CompactPostView: View {
|
||||
quoteStatus = nil
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func actionButton(_ image: String, action: @escaping () -> Void) -> some View {
|
||||
Button {
|
||||
action()
|
||||
} label: {
|
||||
Image(systemName: image)
|
||||
.font(.title2)
|
||||
}
|
||||
.tint(Color(uiColor: UIColor.label))
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func asyncActionButton(_ image: String, action: @escaping () async -> Void) -> some View {
|
||||
Button {
|
||||
Task {
|
||||
await action()
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: image)
|
||||
.font(.title2)
|
||||
}
|
||||
.tint(Color(uiColor: UIColor.label))
|
||||
}
|
||||
}
|
||||
|
130
Threaded/Components/Status/PostInteractor.swift
Normal file
130
Threaded/Components/Status/PostInteractor.swift
Normal file
@ -0,0 +1,130 @@
|
||||
//Made by Lumaa
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct PostInteractor: View {
|
||||
@Environment(AccountManager.self) private var accountManager
|
||||
@Environment(Navigator.self) private var navigator
|
||||
|
||||
var status: Status
|
||||
|
||||
@Binding var isLiked: Bool
|
||||
@Binding var isReposted: Bool
|
||||
@Binding var isBookmarked: Bool
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 13) {
|
||||
asyncActionButton(isLiked ? "heart.fill" : "heart") {
|
||||
do {
|
||||
HapticManager.playHaptics(haptics: Haptic.tap)
|
||||
try await likePost()
|
||||
} catch {
|
||||
HapticManager.playHaptics(haptics: Haptic.error)
|
||||
print("Error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
actionButton("bubble.right") {
|
||||
navigator.presentedSheet = .post(content: "@\(status.account.acct)", replyId: status.id)
|
||||
}
|
||||
asyncActionButton(isReposted ? "bolt.horizontal.fill" : "bolt.horizontal") {
|
||||
do {
|
||||
HapticManager.playHaptics(haptics: Haptic.tap)
|
||||
try await repostPost()
|
||||
} catch {
|
||||
HapticManager.playHaptics(haptics: Haptic.error)
|
||||
print("Error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
asyncActionButton(isBookmarked ? "bookmark.fill" : "bookmark") {
|
||||
do {
|
||||
HapticManager.playHaptics(haptics: Haptic.tap)
|
||||
try await bookmarkPost()
|
||||
} catch {
|
||||
HapticManager.playHaptics(haptics: Haptic.error)
|
||||
print("Error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
ShareLink(item: URL(string: status.url ?? "https://joinmastodon.org/")!) {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
.font(.title2)
|
||||
.padding(.horizontal)
|
||||
}
|
||||
.tint(Color(uiColor: UIColor.label))
|
||||
}
|
||||
.padding(.top)
|
||||
.onAppear {
|
||||
isLiked = status.reblog != nil ? status.reblog!.favourited ?? false : status.favourited ?? false
|
||||
isReposted = status.reblog != nil ? status.reblog!.reblogged ?? false : status.reblogged ?? false
|
||||
isBookmarked = status.reblog != nil ? status.reblog!.bookmarked ?? false : status.bookmarked ?? false
|
||||
}
|
||||
}
|
||||
|
||||
func likePost() async throws {
|
||||
if let client = accountManager.getClient() {
|
||||
guard client.isAuth else { fatalError("Client is not authenticated") }
|
||||
let statusId: String = status.reblog != nil ? status.reblog!.id : status.id
|
||||
let endpoint = !isLiked ? Statuses.favorite(id: statusId) : Statuses.unfavorite(id: statusId)
|
||||
|
||||
isLiked = !isLiked
|
||||
let newStatus: Status = try await client.post(endpoint: endpoint)
|
||||
if isLiked != newStatus.favourited {
|
||||
isLiked = newStatus.favourited ?? !isLiked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func repostPost() async throws {
|
||||
if let client = accountManager.getClient() {
|
||||
guard client.isAuth else { fatalError("Client is not authenticated") }
|
||||
let statusId: String = status.reblog != nil ? status.reblog!.id : status.id
|
||||
let endpoint = !isReposted ? Statuses.reblog(id: statusId) : Statuses.unreblog(id: statusId)
|
||||
|
||||
isReposted = !isReposted
|
||||
let newStatus: Status = try await client.post(endpoint: endpoint)
|
||||
if isReposted != newStatus.reblogged {
|
||||
isReposted = newStatus.reblogged ?? !isReposted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func bookmarkPost() async throws {
|
||||
if let client = accountManager.getClient() {
|
||||
guard client.isAuth else { fatalError("Client is not authenticated") }
|
||||
let statusId: String = status.reblog != nil ? status.reblog!.id : status.id
|
||||
let endpoint = !isBookmarked ? Statuses.bookmark(id: statusId) : Statuses.unbookmark(id: statusId)
|
||||
|
||||
isBookmarked = !isBookmarked
|
||||
let newStatus: Status = try await client.post(endpoint: endpoint)
|
||||
if isBookmarked != newStatus.bookmarked {
|
||||
isBookmarked = newStatus.bookmarked ?? !isBookmarked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func actionButton(_ image: String, action: @escaping () -> Void) -> some View {
|
||||
Button {
|
||||
action()
|
||||
} label: {
|
||||
Image(systemName: image)
|
||||
.font(.title2)
|
||||
}
|
||||
.tint(Color(uiColor: UIColor.label))
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func asyncActionButton(_ image: String, action: @escaping () async -> Void) -> some View {
|
||||
Button {
|
||||
Task {
|
||||
await action()
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: image)
|
||||
.font(.title2)
|
||||
}
|
||||
.tint(Color(uiColor: UIColor.label))
|
||||
}
|
||||
}
|
@ -11,8 +11,11 @@ struct PostDetailsView: View {
|
||||
@State private var statuses: [Status] = []
|
||||
@State private var scrollId: String? = nil
|
||||
@State private var initialLike: Bool = false
|
||||
|
||||
@State private var isLiked: Bool = false
|
||||
@State private var isReposted: Bool = false
|
||||
@State private var isBookmarked: Bool = false
|
||||
|
||||
@State private var hasQuote: Bool = false
|
||||
@State private var quoteStatus: Status? = nil
|
||||
|
||||
@ -27,7 +30,7 @@ struct PostDetailsView: View {
|
||||
if statuses.isEmpty {
|
||||
statusPost(detailedStatus)
|
||||
|
||||
Spacer()
|
||||
// Spacer()
|
||||
} else {
|
||||
ForEach(statuses) { status in
|
||||
if status.id == detailedStatus.id {
|
||||
@ -104,36 +107,7 @@ struct PostDetailsView: View {
|
||||
}
|
||||
|
||||
//MARK: Action buttons
|
||||
HStack(spacing: 13) {
|
||||
asyncActionButton(isLiked ? "heart.fill" : "heart") {
|
||||
do {
|
||||
HapticManager.playHaptics(haptics: Haptic.tap)
|
||||
try await likePost()
|
||||
} catch {
|
||||
HapticManager.playHaptics(haptics: Haptic.error)
|
||||
print("Error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
actionButton("bubble.right") {
|
||||
print("reply")
|
||||
navigator.presentedSheet = .post()
|
||||
}
|
||||
asyncActionButton(isReposted ? "bolt.horizontal.fill" : "bolt.horizontal") {
|
||||
do {
|
||||
HapticManager.playHaptics(haptics: Haptic.tap)
|
||||
try await repostPost()
|
||||
} catch {
|
||||
HapticManager.playHaptics(haptics: Haptic.error)
|
||||
print("Error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
ShareLink(item: URL(string: status.url ?? "https://joinmastodon.org/")!) {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
.font(.title2)
|
||||
}
|
||||
.tint(Color(uiColor: UIColor.label))
|
||||
}
|
||||
.padding(.top)
|
||||
PostInteractor(status: status as! Status, isLiked: $isLiked, isReposted: $isReposted, isBookmarked: $isBookmarked)
|
||||
|
||||
// MARK: Status stats
|
||||
stats.padding(.top, 5)
|
||||
@ -169,34 +143,6 @@ struct PostDetailsView: View {
|
||||
let context: StatusContext
|
||||
}
|
||||
|
||||
func likePost() async throws {
|
||||
if let client = accountManager.getClient() {
|
||||
guard client.isAuth else { fatalError("Client is not authenticated") }
|
||||
let statusId: String = detailedStatus.reblog != nil ? detailedStatus.reblog!.id : detailedStatus.id
|
||||
let endpoint = !isLiked ? Statuses.favorite(id: statusId) : Statuses.unfavorite(id: statusId)
|
||||
|
||||
isLiked = !isLiked
|
||||
let newStatus: Status = try await client.post(endpoint: endpoint)
|
||||
if isLiked != newStatus.favourited {
|
||||
isLiked = newStatus.favourited ?? !isLiked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func repostPost() async throws {
|
||||
if let client = accountManager.getClient() {
|
||||
guard client.isAuth else { fatalError("Client is not authenticated") }
|
||||
let statusId: String = detailedStatus.reblog != nil ? detailedStatus.reblog!.id : detailedStatus.id
|
||||
let endpoint = !isReposted ? Statuses.reblog(id: statusId) : Statuses.unreblog(id: statusId)
|
||||
|
||||
isReposted = !isReposted
|
||||
let newStatus: Status = try await client.post(endpoint: endpoint)
|
||||
if isReposted != newStatus.reblogged {
|
||||
isReposted = newStatus.reblogged ?? !isReposted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var profilePicture: some View {
|
||||
if detailedStatus.reblog != nil {
|
||||
OnlineImage(url: detailedStatus.reblog!.account.avatar, size: 50, useNuke: true)
|
||||
@ -292,28 +238,4 @@ struct PostDetailsView: View {
|
||||
quoteStatus = nil
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func actionButton(_ image: String, action: @escaping () -> Void) -> some View {
|
||||
Button {
|
||||
action()
|
||||
} label: {
|
||||
Image(systemName: image)
|
||||
.font(.title2)
|
||||
}
|
||||
.tint(Color(uiColor: UIColor.label))
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func asyncActionButton(_ image: String, action: @escaping () async -> Void) -> some View {
|
||||
Button {
|
||||
Task {
|
||||
await action()
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: image)
|
||||
.font(.title2)
|
||||
}
|
||||
.tint(Color(uiColor: UIColor.label))
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user