mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-22 00:01:00 +00:00
Reply long press account menu
This commit is contained in:
parent
f3040eaad5
commit
12d0cf5ca0
8 changed files with 82 additions and 20 deletions
|
@ -146,11 +146,24 @@ public extension StatusService {
|
|||
.flatMap { contentDatabase.update(id: status.displayStatus.id, poll: $0) }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func asIdentity(id: Identity.Id) -> AnyPublisher<Self, Error> {
|
||||
fetchAs(identityId: id).tryMap {
|
||||
Self(environment: environment,
|
||||
status: $0,
|
||||
mastodonAPIClient: try MastodonAPIClient.forIdentity(id: id, environment: environment),
|
||||
contentDatabase: try ContentDatabase(
|
||||
id: id,
|
||||
useHomeTimelineLastReadId: true,
|
||||
inMemory: environment.inMemoryContent,
|
||||
appGroup: AppEnvironment.appGroup,
|
||||
keychain: environment.keychain)) }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
||||
private extension StatusService {
|
||||
func request(identityId: Identity.Id,
|
||||
endpointClosure: @escaping (Status.Id) -> StatusEndpoint) -> AnyPublisher<Never, Error> {
|
||||
func fetchAs(identityId: Identity.Id) -> AnyPublisher<Status, Error> {
|
||||
let client: MastodonAPIClient
|
||||
|
||||
do {
|
||||
|
@ -162,11 +175,25 @@ private extension StatusService {
|
|||
return client
|
||||
.request(ResultsEndpoint.search(.init(query: status.displayStatus.uri, resolve: true, limit: 1)))
|
||||
.tryMap {
|
||||
guard let id = $0.statuses.first?.id else { throw APIError.unableToFetchRemoteStatus }
|
||||
guard let status = $0.statuses.first else { throw APIError.unableToFetchRemoteStatus }
|
||||
|
||||
return id
|
||||
return status
|
||||
}
|
||||
.flatMap { client.request(endpointClosure($0)) }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func request(identityId: Identity.Id,
|
||||
endpointClosure: @escaping (Status.Id) -> StatusEndpoint) -> AnyPublisher<Never, Error> {
|
||||
let client: MastodonAPIClient
|
||||
|
||||
do {
|
||||
client = try MastodonAPIClient.forIdentity(id: identityId, environment: environment)
|
||||
} catch {
|
||||
return Fail(error: error).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
return fetchAs(identityId: identityId)
|
||||
.flatMap { client.request(endpointClosure($0.id)) }
|
||||
.flatMap { _ in mastodonAPIClient.request(StatusEndpoint.status(id: status.displayStatus.id)) }
|
||||
.flatMap(contentDatabase.insert(status:))
|
||||
.eraseToAnyPublisher()
|
||||
|
|
|
@ -533,8 +533,11 @@ private extension TableViewController {
|
|||
handle(navigation: navigation)
|
||||
case let .attachment(attachmentViewModel, statusViewModel):
|
||||
present(attachmentViewModel: attachmentViewModel, statusViewModel: statusViewModel)
|
||||
case let .compose(inReplyToViewModel, redraft, directMessageTo):
|
||||
compose(inReplyToViewModel: inReplyToViewModel, redraft: redraft, directMessageTo: directMessageTo)
|
||||
case let .compose(identity, inReplyToViewModel, redraft, directMessageTo):
|
||||
compose(identity: identity,
|
||||
inReplyToViewModel: inReplyToViewModel,
|
||||
redraft: redraft,
|
||||
directMessageTo: directMessageTo)
|
||||
case let .confirmDelete(statusViewModel, redraft):
|
||||
confirmDelete(statusViewModel: statusViewModel, redraft: redraft)
|
||||
case let .confirmUnfollow(accountViewModel):
|
||||
|
@ -613,9 +616,13 @@ private extension TableViewController {
|
|||
}
|
||||
}
|
||||
|
||||
func compose(inReplyToViewModel: StatusViewModel?, redraft: Status?, directMessageTo: AccountViewModel?) {
|
||||
func compose(identity: Identity?,
|
||||
inReplyToViewModel: StatusViewModel?,
|
||||
redraft: Status?,
|
||||
directMessageTo: AccountViewModel?) {
|
||||
rootViewModel?.navigationViewModel?.presentedNewStatusViewModel = rootViewModel?.newStatusViewModel(
|
||||
identityContext: viewModel.identityContext,
|
||||
identity: identity,
|
||||
inReplyTo: inReplyToViewModel,
|
||||
redraft: redraft,
|
||||
directMessageTo: directMessageTo)
|
||||
|
|
|
@ -9,7 +9,10 @@ public enum CollectionItemEvent {
|
|||
case refresh
|
||||
case navigation(Navigation)
|
||||
case attachment(AttachmentViewModel, StatusViewModel)
|
||||
case compose(inReplyTo: StatusViewModel? = nil, redraft: Status? = nil, directMessageTo: AccountViewModel? = nil)
|
||||
case compose(identity: Identity? = nil,
|
||||
inReplyTo: StatusViewModel? = nil,
|
||||
redraft: Status? = nil,
|
||||
directMessageTo: AccountViewModel? = nil)
|
||||
case confirmDelete(StatusViewModel, redraft: Bool)
|
||||
case confirmUnfollow(AccountViewModel)
|
||||
case confirmHideReblogs(AccountViewModel)
|
||||
|
|
|
@ -26,6 +26,7 @@ public final class NewStatusViewModel: ObservableObject {
|
|||
public init(allIdentitiesService: AllIdentitiesService,
|
||||
identityContext: IdentityContext,
|
||||
environment: AppEnvironment,
|
||||
identity: Identity?,
|
||||
inReplyTo: StatusViewModel?,
|
||||
redraft: Status?,
|
||||
directMessageTo: AccountViewModel?,
|
||||
|
@ -37,7 +38,7 @@ public final class NewStatusViewModel: ObservableObject {
|
|||
events = eventsSubject.eraseToAnyPublisher()
|
||||
visibility = redraft?.visibility
|
||||
?? inReplyTo?.visibility
|
||||
?? identityContext.identity.preferences.postingDefaultVisibility
|
||||
?? (identity ?? identityContext.identity).preferences.postingDefaultVisibility
|
||||
|
||||
if let inReplyTo = inReplyTo {
|
||||
switch inReplyTo.visibility {
|
||||
|
@ -74,7 +75,7 @@ public final class NewStatusViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
mentions.formUnion(inReplyTo.mentions.map(\.acct)
|
||||
.filter { $0 != identityContext.identity.account?.username }
|
||||
.filter { $0 != (identity ?? identityContext.identity).account?.username }
|
||||
.map("@".appending))
|
||||
|
||||
compositionViewModel.text = mentions.joined(separator: " ").appending(" ")
|
||||
|
@ -95,6 +96,10 @@ public final class NewStatusViewModel: ObservableObject {
|
|||
compositionEventsSubject
|
||||
.sink { [weak self] in self?.handle(event: $0) }
|
||||
.store(in: &cancellables)
|
||||
|
||||
if let identity = identity {
|
||||
setIdentity(identity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ public extension RootViewModel {
|
|||
|
||||
func newStatusViewModel(
|
||||
identityContext: IdentityContext,
|
||||
identity: Identity? = nil,
|
||||
inReplyTo: StatusViewModel? = nil,
|
||||
redraft: Status? = nil,
|
||||
directMessageTo: AccountViewModel? = nil) -> NewStatusViewModel {
|
||||
|
@ -72,6 +73,7 @@ public extension RootViewModel {
|
|||
allIdentitiesService: allIdentitiesService,
|
||||
identityContext: identityContext,
|
||||
environment: environment,
|
||||
identity: identity,
|
||||
inReplyTo: inReplyTo,
|
||||
redraft: redraft,
|
||||
directMessageTo: directMessageTo,
|
||||
|
|
|
@ -37,6 +37,7 @@ public extension ShareExtensionNavigationViewModel {
|
|||
allIdentitiesService: allIdentitiesService,
|
||||
identityContext: identityContext,
|
||||
environment: environment,
|
||||
identity: nil,
|
||||
inReplyTo: nil,
|
||||
redraft: nil,
|
||||
directMessageTo: nil,
|
||||
|
|
|
@ -242,17 +242,33 @@ public extension StatusViewModel {
|
|||
.eraseToAnyPublisher())
|
||||
}
|
||||
|
||||
func reply() {
|
||||
let replyViewModel = Self(statusService: statusService,
|
||||
identityContext: identityContext,
|
||||
eventsSubject: .init())
|
||||
func reply(identity: Identity? = nil) {
|
||||
if let identity = identity {
|
||||
let identityContext = self.identityContext
|
||||
let configuration = self.configuration.reply()
|
||||
|
||||
replyViewModel.configuration = configuration.reply()
|
||||
eventsSubject.send(statusService.asIdentity(id: identity.id).map {
|
||||
let replyViewModel = Self(statusService: $0,
|
||||
identityContext: identityContext,
|
||||
eventsSubject: .init())
|
||||
|
||||
eventsSubject.send(
|
||||
Just(.compose(inReplyTo: replyViewModel))
|
||||
.setFailureType(to: Error.self)
|
||||
.eraseToAnyPublisher())
|
||||
replyViewModel.configuration = configuration
|
||||
|
||||
return CollectionItemEvent.compose(identity: identity, inReplyTo: replyViewModel)
|
||||
}
|
||||
.eraseToAnyPublisher())
|
||||
} else {
|
||||
let replyViewModel = Self(statusService: statusService,
|
||||
identityContext: identityContext,
|
||||
eventsSubject: .init())
|
||||
|
||||
replyViewModel.configuration = configuration.reply()
|
||||
|
||||
eventsSubject.send(
|
||||
Just(.compose(inReplyTo: replyViewModel))
|
||||
.setFailureType(to: Error.self)
|
||||
.eraseToAnyPublisher())
|
||||
}
|
||||
}
|
||||
|
||||
func toggleReblogged(identityId: Identity.Id? = nil) {
|
||||
|
|
|
@ -605,6 +605,7 @@ private extension StatusView {
|
|||
|
||||
replyButton.setCountTitle(count: viewModel.repliesCount, isContextParent: isContextParent)
|
||||
replyButton.isEnabled = isAuthenticated
|
||||
replyButton.menu = authenticatedIdentitiesMenu { viewModel.reply(identity: $0) }
|
||||
|
||||
if viewModel.identityContext.appPreferences.showReblogAndFavoriteCounts || isContextParent {
|
||||
reblogButton.setCountTitle(count: viewModel.reblogsCount, isContextParent: isContextParent)
|
||||
|
|
Loading…
Reference in a new issue