2021-03-09 08:18:43 +01:00
//
// A P I S e r v i c e + R e b l o g . s w i f t
// M a s t o d o n
//
// C r e a t e d b y M a i n a s u K C i r n o o n 2 0 2 1 - 3 - 9 .
//
import Foundation
import Combine
import MastodonSDK
import CoreData
import CoreDataStack
import CommonOSLog
extension APIService {
// m a k e l o c a l s t a t e c h a n g e o n l y
func boost (
tootObjectID : NSManagedObjectID ,
mastodonUserObjectID : NSManagedObjectID ,
2021-03-09 12:39:44 +01:00
boostKind : Mastodon . API . Reblog . BoostKind
2021-03-09 08:18:43 +01:00
) -> AnyPublisher < Toot . ID , Error > {
var _targetTootID : Toot . ID ?
let managedObjectContext = backgroundManagedObjectContext
return managedObjectContext . performChanges {
let toot = managedObjectContext . object ( with : tootObjectID ) as ! Toot
let mastodonUser = managedObjectContext . object ( with : mastodonUserObjectID ) as ! MastodonUser
let targetToot = toot . reblog ? ? toot
let targetTootID = targetToot . id
_targetTootID = targetTootID
targetToot . update ( reblogged : boostKind = = . boost , mastodonUser : mastodonUser )
}
. tryMap { result in
switch result {
case . success :
guard let targetTootID = _targetTootID else {
throw APIError . implicit ( . badRequest )
}
return targetTootID
case . failure ( let error ) :
assertionFailure ( error . localizedDescription )
throw error
}
}
. eraseToAnyPublisher ( )
}
// s e n d b o o s t r e q u e s t t o r e m o t e
func boost (
statusID : Mastodon . Entity . Status . ID ,
2021-03-09 12:39:44 +01:00
boostKind : Mastodon . API . Reblog . BoostKind ,
2021-03-09 08:18:43 +01:00
mastodonAuthenticationBox : AuthenticationService . MastodonAuthenticationBox
) -> AnyPublisher < Mastodon . Response . Content < Mastodon . Entity . Status > , Error > {
let domain = mastodonAuthenticationBox . domain
let authorization = mastodonAuthenticationBox . userAuthorization
let requestMastodonUserID = mastodonAuthenticationBox . userID
2021-03-09 12:39:44 +01:00
return Mastodon . API . Reblog . boost (
2021-03-09 08:18:43 +01:00
session : session ,
domain : domain ,
statusID : statusID ,
boostKind : boostKind ,
authorization : authorization
)
. map { response -> AnyPublisher < Mastodon . Response . Content < Mastodon . Entity . Status > , Error > in
let log = OSLog . api
let entity = response . value
let managedObjectContext = self . backgroundManagedObjectContext
return managedObjectContext . performChanges {
2021-03-11 07:08:00 +01:00
guard let requestMastodonUser : MastodonUser = {
2021-03-09 08:18:43 +01:00
let request = MastodonUser . sortedFetchRequest
request . predicate = MastodonUser . predicate ( domain : mastodonAuthenticationBox . domain , id : requestMastodonUserID )
request . fetchLimit = 1
request . returnsObjectsAsFaults = false
do {
return try managedObjectContext . fetch ( request ) . first
} catch {
assertionFailure ( error . localizedDescription )
return nil
}
2021-03-11 07:08:00 +01:00
} ( ) else {
return
}
guard let oldToot : Toot = {
2021-03-09 08:18:43 +01:00
let request = Toot . sortedFetchRequest
request . predicate = Toot . predicate ( domain : domain , id : statusID )
2021-03-11 04:43:49 +01:00
request . fetchLimit = 1
2021-03-09 08:18:43 +01:00
request . returnsObjectsAsFaults = false
request . relationshipKeyPathsForPrefetching = [ # keyPath ( Toot . reblog ) ]
do {
return try managedObjectContext . fetch ( request ) . first
} catch {
assertionFailure ( error . localizedDescription )
return nil
}
2021-03-11 07:08:00 +01:00
} ( ) else {
2021-03-09 08:18:43 +01:00
return
}
2021-03-11 07:08:00 +01:00
2021-03-09 08:18:43 +01:00
APIService . CoreData . merge ( toot : oldToot , entity : entity . reblog ? ? entity , requestMastodonUser : requestMastodonUser , domain : mastodonAuthenticationBox . domain , networkDate : response . networkDate )
2021-03-09 12:41:18 +01:00
if boostKind = = . undoBoost {
oldToot . update ( reblogsCount : NSNumber ( value : max ( 0 , oldToot . reblogsCount . intValue - 1 ) ) )
}
2021-03-09 08:18:43 +01:00
os_log ( . info , log : log , " %{public}s[%{public}ld], %{public}s: did update toot %{public}s reblog status to: %{public}s. now %ld boosts " , ( ( #file as NSString ) . lastPathComponent ) , #line , #function , entity . id , entity . reblogged . flatMap { $0 ? " boost " : " unboost " } ? ? " <nil> " , entity . reblogsCount )
}
. setFailureType ( to : Error . self )
. tryMap { result -> Mastodon . Response . Content < Mastodon . Entity . Status > in
switch result {
case . success :
return response
case . failure ( let error ) :
throw error
}
}
. eraseToAnyPublisher ( )
}
. switchToLatest ( )
. handleEvents ( receiveCompletion : { completion in
switch completion {
case . failure ( let error ) :
os_log ( . info , log : . debug , " %{public}s[%{public}ld], %{public}s: error: " , ( ( #file as NSString ) . lastPathComponent ) , #line , #function )
debugPrint ( error )
case . finished :
break
}
} )
. eraseToAnyPublisher ( )
}
}