mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-12-25 00:20:45 +00:00
137 lines
4 KiB
Swift
137 lines
4 KiB
Swift
import Foundation
|
|
import Models
|
|
import Network
|
|
import Observation
|
|
import SwiftUI
|
|
|
|
@MainActor
|
|
public protocol StatusDataControlling {
|
|
var isReblogged: Bool { get set }
|
|
var isBookmarked: Bool { get set }
|
|
var isFavorited: Bool { get set }
|
|
|
|
var favoritesCount: Int { get set }
|
|
var reblogsCount: Int { get set }
|
|
var repliesCount: Int { get set }
|
|
|
|
func toggleBookmark(remoteStatus: String?) async
|
|
func toggleReblog(remoteStatus: String?) async
|
|
func toggleFavorite(remoteStatus: String?) async
|
|
}
|
|
|
|
@MainActor
|
|
public final class StatusDataControllerProvider {
|
|
public static let shared = StatusDataControllerProvider()
|
|
|
|
private var cache: NSMutableDictionary = [:]
|
|
|
|
private struct CacheKey: Hashable {
|
|
let statusId: String
|
|
let client: Client
|
|
}
|
|
|
|
public func dataController(for status: any AnyStatus, client: Client) -> StatusDataController {
|
|
let key = CacheKey(statusId: status.id, client: client)
|
|
if let controller = cache[key] as? StatusDataController {
|
|
return controller
|
|
}
|
|
let controller = StatusDataController(status: status, client: client)
|
|
cache[key] = controller
|
|
return controller
|
|
}
|
|
|
|
public func updateDataControllers(for statuses: [Status], client: Client) {
|
|
for status in statuses {
|
|
let realStatus: AnyStatus = status.reblog ?? status
|
|
let controller = dataController(for: realStatus, client: client)
|
|
controller.updateFrom(status: realStatus)
|
|
}
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
@Observable public final class StatusDataController: StatusDataControlling {
|
|
private let status: AnyStatus
|
|
private let client: Client
|
|
|
|
public var isReblogged: Bool
|
|
public var isBookmarked: Bool
|
|
public var isFavorited: Bool
|
|
public var content: HTMLString
|
|
|
|
public var favoritesCount: Int
|
|
public var reblogsCount: Int
|
|
public var repliesCount: Int
|
|
|
|
init(status: AnyStatus, client: Client) {
|
|
self.status = status
|
|
self.client = client
|
|
|
|
isReblogged = status.reblogged == true
|
|
isBookmarked = status.bookmarked == true
|
|
isFavorited = status.favourited == true
|
|
|
|
reblogsCount = status.reblogsCount
|
|
repliesCount = status.repliesCount
|
|
favoritesCount = status.favouritesCount
|
|
content = status.content
|
|
}
|
|
|
|
public func updateFrom(status: AnyStatus) {
|
|
isReblogged = status.reblogged == true
|
|
isBookmarked = status.bookmarked == true
|
|
isFavorited = status.favourited == true
|
|
|
|
reblogsCount = status.reblogsCount
|
|
repliesCount = status.repliesCount
|
|
favoritesCount = status.favouritesCount
|
|
content = status.content
|
|
}
|
|
|
|
public func toggleFavorite(remoteStatus: String?) async {
|
|
guard client.isAuth else { return }
|
|
isFavorited.toggle()
|
|
let id = remoteStatus ?? status.id
|
|
let endpoint = isFavorited ? Statuses.favorite(id: id) : Statuses.unfavorite(id: id)
|
|
withAnimation(.default) {
|
|
favoritesCount += isFavorited ? 1 : -1
|
|
}
|
|
do {
|
|
let status: Status = try await client.post(endpoint: endpoint)
|
|
updateFrom(status: status)
|
|
} catch {
|
|
isFavorited.toggle()
|
|
favoritesCount += isFavorited ? -1 : 1
|
|
}
|
|
}
|
|
|
|
public func toggleReblog(remoteStatus: String?) async {
|
|
guard client.isAuth else { return }
|
|
isReblogged.toggle()
|
|
let id = remoteStatus ?? status.id
|
|
let endpoint = isReblogged ? Statuses.reblog(id: id) : Statuses.unreblog(id: id)
|
|
withAnimation(.default) {
|
|
reblogsCount += isReblogged ? 1 : -1
|
|
}
|
|
do {
|
|
let status: Status = try await client.post(endpoint: endpoint)
|
|
updateFrom(status: status.reblog ?? status)
|
|
} catch {
|
|
isReblogged.toggle()
|
|
reblogsCount += isReblogged ? -1 : 1
|
|
}
|
|
}
|
|
|
|
public func toggleBookmark(remoteStatus: String?) async {
|
|
guard client.isAuth else { return }
|
|
isBookmarked.toggle()
|
|
let id = remoteStatus ?? status.id
|
|
let endpoint = isBookmarked ? Statuses.bookmark(id: id) : Statuses.unbookmark(id: id)
|
|
do {
|
|
let status: Status = try await client.post(endpoint: endpoint)
|
|
updateFrom(status: status)
|
|
} catch {
|
|
isBookmarked.toggle()
|
|
}
|
|
}
|
|
}
|