2022-10-08 16:15:12 +00:00
//
// R e b l o g S e r v i c e . s w i f t
// T u s k e r
//
// C r e a t e d b y S h a d o w f a c t s o n 1 0 / 8 / 2 2 .
// C o p y r i g h t © 2 0 2 2 S h a d o w f a c t s . A l l r i g h t s r e s e r v e d .
//
import UIKit
import Pachyderm
@ MainActor
class ReblogService {
private let mastodonController : MastodonController
private let presenter : any TuskerNavigationDelegate
private let status : StatusMO
var hapticFeedback = true
2023-03-07 15:14:35 +00:00
var visibility : Visibility ? = nil
2022-10-08 16:15:12 +00:00
var requireConfirmation = Preferences . shared . confirmBeforeReblog
init ( status : StatusMO , mastodonController : MastodonController , presenter : any TuskerNavigationDelegate ) {
self . status = status
self . mastodonController = mastodonController
self . presenter = presenter
}
func toggleReblog ( ) async {
if ! status . reblogged ,
requireConfirmation {
presentConfirmationAlert ( )
} else {
await doToggleReblog ( )
}
}
private func presentConfirmationAlert ( ) {
let image : UIImage ?
let reblogVisibilityActions : [ CustomAlertController . MenuAction ] ?
if mastodonController . instanceFeatures . reblogVisibility {
2023-03-07 15:14:35 +00:00
image = UIImage ( systemName : Visibility . public . unfilledImageName )
reblogVisibilityActions = [ Visibility . unlisted , . private ] . map { visibility in
2022-10-08 16:15:12 +00:00
CustomAlertController . MenuAction ( title : " Reblog as \( visibility . displayName ) " , subtitle : visibility . subtitle , image : UIImage ( systemName : visibility . unfilledImageName ) ) {
// d e l i b e r a t e l y r e t a i n a s t r o n g r e f e r e n c e t o s e l f
Task {
await self . doToggleReblog ( )
}
}
}
} else {
image = nil
2022-11-13 22:07:57 +00:00
reblogVisibilityActions = nil
2022-10-08 16:15:12 +00:00
}
let preview = ConfirmReblogStatusPreviewView ( status : status )
var config = CustomAlertController . Configuration ( title : " Are you sure you want to reblog this post? " , content : preview , actions : [
CustomAlertController . Action ( title : " Cancel " , style : . cancel , handler : nil ) ,
CustomAlertController . Action ( title : " Reblog " , image : image , style : . default , handler : {
// d e l i b e r a t e l y r e t a i n a s t r o n g r e f e r e n c e t o s e l f
Task {
await self . doToggleReblog ( )
}
} )
] )
if let reblogVisibilityActions {
var menuAction = CustomAlertController . Action ( title : nil , image : UIImage ( systemName : " chevron.down " ) , style : . menu ( reblogVisibilityActions ) , handler : nil )
menuAction . isSecondaryMenu = true
config . actions . append ( menuAction )
}
let alert = CustomAlertController ( config : config )
presenter . present ( alert , animated : true )
}
private func doToggleReblog ( ) async {
let oldValue = status . reblogged
status . reblogged . toggle ( )
mastodonController . persistentContainer . statusSubject . send ( status . id )
if hapticFeedback {
UIImpactFeedbackGenerator ( style : . light ) . impactOccurred ( )
}
let request : Request < Status >
if status . reblogged {
request = Status . reblog ( status . id , visibility : visibility )
} else {
request = Status . unreblog ( status . id )
}
do {
let ( newStatus , _ ) = try await mastodonController . run ( request )
mastodonController . persistentContainer . addOrUpdate ( status : newStatus )
} catch {
status . favourited = oldValue
mastodonController . persistentContainer . statusSubject . send ( status . id )
2023-03-02 02:09:56 +00:00
let title = oldValue ? " Error Unreblogging " : " Error Reblogging "
2022-10-08 16:15:12 +00:00
let config = ToastConfiguration ( from : error , with : title , in : presenter ) { toast in
toast . dismissToast ( animated : true )
await self . toggleReblog ( )
}
presenter . showToast ( configuration : config , animated : true )
if hapticFeedback {
UINotificationFeedbackGenerator ( ) . notificationOccurred ( . error )
}
}
}
}