Make show/hide reblogs finally work (#365)

oh, and also indent to 4 spaces.

I needed some time to wrap my head around the data model and especially the various view-models, but hey, in the end it works. I still feel like this "I have no idea what I'm doing"-dog :D
This commit is contained in:
Nathan Mattes 2022-11-06 09:25:26 +01:00
parent 18720a9a51
commit ee523c098e
2 changed files with 64 additions and 51 deletions

View File

@ -127,46 +127,50 @@ extension APIService {
authenticationBox: MastodonAuthenticationBox
) async throws -> Mastodon.Response.Content<Mastodon.Entity.Relationship> {
let managedObjectContext = backgroundManagedObjectContext
guard let user = user.object(in: managedObjectContext) else { throw APIError.implicit(.badRequest) }
let managedObjectContext = backgroundManagedObjectContext
guard let user = user.object(in: managedObjectContext),
let authentication = authenticationBox.authenticationRecord.object(in: managedObjectContext)
else { throw APIError.implicit(.badRequest) }
let result: Result<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error>
let showReblogs = false //FIXME: Use showReblogs-value from data
let oldShowReblogs = true
let me = authentication.user
let result: Result<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error>
do {
let response = try await Mastodon.API.Account.follow(
session: session,
domain: authenticationBox.domain,
accountID: user.id,
followQueryType: .follow(query: .init(reblogs: showReblogs)),
authorization: authenticationBox.userAuthorization
).singleOutput()
let oldShowReblogs = me.showingReblogsBy.contains(user)
let newShowReblogs = (oldShowReblogs == false)
result = .success(response)
} catch {
result = .failure(error)
}
do {
let response = try await Mastodon.API.Account.follow(
session: session,
domain: authenticationBox.domain,
accountID: user.id,
followQueryType: .follow(query: .init(reblogs: showReblogs)),
authorization: authenticationBox.userAuthorization
).singleOutput()
try await managedObjectContext.performChanges {
guard let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user else { return }
switch result {
case .success(let response):
Persistence.MastodonUser.update(
mastodonUser: user,
context: Persistence.MastodonUser.RelationshipContext(
entity: response.value,
me: me,
networkDate: response.networkDate
)
)
case .failure:
// rollback
user.update(isShowingReblogs: oldShowReblogs, by: me)
result = .success(response)
} catch {
result = .failure(error)
}
}
return try result.get()
try await managedObjectContext.performChanges {
guard let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user else { return }
switch result {
case .success(let response):
Persistence.MastodonUser.update(
mastodonUser: user,
context: Persistence.MastodonUser.RelationshipContext(
entity: response.value,
me: me,
networkDate: response.networkDate
)
)
case .failure:
// rollback
user.update(isShowingReblogs: oldShowReblogs, by: me)
}
}
return try result.get()
}
}

View File

@ -27,6 +27,7 @@ public enum RelationshipAction: Int, CaseIterable {
case edit
case editing
case updating
case showReblogs
public var option: RelationshipActionOptionSet {
return RelationshipActionOptionSet(rawValue: 1 << rawValue)
@ -57,6 +58,7 @@ public struct RelationshipActionOptionSet: OptionSet {
public static let edit = RelationshipAction.edit.option
public static let editing = RelationshipAction.editing.option
public static let updating = RelationshipAction.updating.option
public static let showReblogs = RelationshipAction.showReblogs.option
public static let editOptions: RelationshipActionOptionSet = [.edit, .editing, .updating]
@ -75,24 +77,24 @@ public struct RelationshipActionOptionSet: OptionSet {
return " "
}
switch highPriorityAction {
case .isMyself: return ""
case .followingBy: return " "
case .blockingBy: return " "
case .none: return " "
case .follow: return L10n.Common.Controls.Friendship.follow
case .request: return L10n.Common.Controls.Friendship.request
case .pending: return L10n.Common.Controls.Friendship.pending
case .following: return L10n.Common.Controls.Friendship.following
case .muting: return L10n.Common.Controls.Friendship.muted
case .blocked: return L10n.Common.Controls.Friendship.follow // blocked by user (deprecated)
case .blocking: return L10n.Common.Controls.Friendship.blocked
case .suspended: return L10n.Common.Controls.Friendship.follow
case .edit: return L10n.Common.Controls.Friendship.editInfo
case .editing: return L10n.Common.Controls.Actions.done
case .updating: return " "
case .isMyself: return ""
case .followingBy: return " "
case .blockingBy: return " "
case .none: return " "
case .follow: return L10n.Common.Controls.Friendship.follow
case .request: return L10n.Common.Controls.Friendship.request
case .pending: return L10n.Common.Controls.Friendship.pending
case .following: return L10n.Common.Controls.Friendship.following
case .muting: return L10n.Common.Controls.Friendship.muted
case .blocked: return L10n.Common.Controls.Friendship.follow // blocked by user (deprecated)
case .blocking: return L10n.Common.Controls.Friendship.blocked
case .suspended: return L10n.Common.Controls.Friendship.follow
case .edit: return L10n.Common.Controls.Friendship.editInfo
case .editing: return L10n.Common.Controls.Actions.done
case .updating: return " "
case .showReblogs: return ""
}
}
}
public final class RelationshipViewModel {
@ -185,6 +187,7 @@ extension RelationshipViewModel {
self.isBlockingBy = optionSet.contains(.blockingBy)
self.isBlocking = optionSet.contains(.blocking)
self.isSuspended = optionSet.contains(.suspended)
self.showReblogs = optionSet.contains(.showReblogs)
self.optionSet = optionSet
}
@ -197,6 +200,7 @@ extension RelationshipViewModel {
isBlockingBy = false
isBlocking = false
optionSet = nil
showReblogs = false
}
}
@ -215,6 +219,7 @@ extension RelationshipViewModel {
let isMuting = user.mutingBy.contains(me)
let isBlockingBy = me.blockingBy.contains(user)
let isBlocking = user.blockingBy.contains(me)
let isShowingReblogs = me.showingReblogsBy.contains(user)// user.showingReblogsBy.contains(me)
var optionSet: RelationshipActionOptionSet = [.follow]
@ -253,6 +258,10 @@ extension RelationshipViewModel {
if user.suspended {
optionSet.insert(.suspended)
}
if isShowingReblogs {
optionSet.insert(.showReblogs)
}
return optionSet
}