feat: add reply entry for profile scene

This commit is contained in:
CMK 2021-04-02 18:50:08 +08:00
parent 5d3b6d1943
commit 3b576badeb
6 changed files with 23 additions and 8 deletions

View File

@ -22,6 +22,7 @@ enum ComposeStatusSection: Equatable, Hashable {
extension ComposeStatusSection { extension ComposeStatusSection {
enum ComposeKind { enum ComposeKind {
case post case post
case mention(mastodonUserObjectID: NSManagedObjectID)
case reply(repliedToStatusObjectID: NSManagedObjectID) case reply(repliedToStatusObjectID: NSManagedObjectID)
} }
} }

View File

@ -11,7 +11,7 @@ import ActiveLabel
enum MastodonField { enum MastodonField {
static func parse(field string: String) -> ParseResult { static func parse(field string: String) -> ParseResult {
let mentionMatches = string.matches(pattern: "(?:@([a-zA-Z0-9_]+))") let mentionMatches = string.matches(pattern: "(?:@([a-zA-Z0-9_]+)(@[a-zA-Z0-9_.]+)?)")
let hashtagMatches = string.matches(pattern: "(?:#([^\\s.]+))") let hashtagMatches = string.matches(pattern: "(?:#([^\\s.]+))")
let urlMatches = string.matches(pattern: "(?i)https?://\\S+(?:/|\\b)") let urlMatches = string.matches(pattern: "(?i)https?://\\S+(?:/|\\b)")

View File

@ -538,7 +538,7 @@ extension ComposeViewController: TextEditorViewTextAttributesDelegate {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: update: %s", ((#file as NSString).lastPathComponent), #line, #function, string) os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: update: %s", ((#file as NSString).lastPathComponent), #line, #function, string)
let stringRange = NSRange(location: 0, length: string.length) let stringRange = NSRange(location: 0, length: string.length)
let highlightMatches = string.matches(pattern: "(?:@([a-zA-Z0-9_]+)|#([^\\s.]+))") let highlightMatches = string.matches(pattern: "(?:@([a-zA-Z0-9_]+)(@[a-zA-Z0-9_.]+)?|#([^\\s.]+))")
// accept ^\B: or \s: but not accept \B: to force user input a space to make emoji take effect // accept ^\B: or \s: but not accept \B: to force user input a space to make emoji take effect
// precondition :\B with following space // precondition :\B with following space
let emojiMatches = string.matches(pattern: "(?:(^\\B:|\\s:)([a-zA-Z0-9_]+)(:\\B(?=\\s)))") let emojiMatches = string.matches(pattern: "(?:(^\\B:|\\s:)([a-zA-Z0-9_]+)(:\\B(?=\\s)))")

View File

@ -62,7 +62,7 @@ extension ComposeViewModel {
case .reply(let statusObjectID): case .reply(let statusObjectID):
snapshot.appendItems([.replyTo(statusObjectID: statusObjectID)], toSection: .repliedTo) snapshot.appendItems([.replyTo(statusObjectID: statusObjectID)], toSection: .repliedTo)
snapshot.appendItems([.input(replyToStatusObjectID: statusObjectID, attribute: composeStatusAttribute)], toSection: .repliedTo) snapshot.appendItems([.input(replyToStatusObjectID: statusObjectID, attribute: composeStatusAttribute)], toSection: .repliedTo)
case .post: case .mention, .post:
snapshot.appendItems([.input(replyToStatusObjectID: nil, attribute: composeStatusAttribute)], toSection: .status) snapshot.appendItems([.input(replyToStatusObjectID: nil, attribute: composeStatusAttribute)], toSection: .status)
} }
diffableDataSource.apply(snapshot, animatingDifferences: false) diffableDataSource.apply(snapshot, animatingDifferences: false)

View File

@ -71,18 +71,27 @@ final class ComposeViewModel {
init( init(
context: AppContext, context: AppContext,
composeKind: ComposeStatusSection.ComposeKind composeKind: ComposeStatusSection.ComposeKind,
initialComposeContent: String? = nil
) { ) {
self.context = context self.context = context
self.composeKind = composeKind self.composeKind = composeKind
switch composeKind { switch composeKind {
case .post: self.title = CurrentValueSubject(L10n.Scene.Compose.Title.newPost) case .post, .mention: self.title = CurrentValueSubject(L10n.Scene.Compose.Title.newPost)
case .reply: self.title = CurrentValueSubject(L10n.Scene.Compose.Title.newReply) case .reply: self.title = CurrentValueSubject(L10n.Scene.Compose.Title.newReply)
} }
self.activeAuthentication = CurrentValueSubject(context.authenticationService.activeMastodonAuthentication.value) self.activeAuthentication = CurrentValueSubject(context.authenticationService.activeMastodonAuthentication.value)
self.activeAuthenticationBox = CurrentValueSubject(context.authenticationService.activeMastodonAuthenticationBox.value) self.activeAuthenticationBox = CurrentValueSubject(context.authenticationService.activeMastodonAuthenticationBox.value)
// end init // end init
if case let .mention(mastodonUserObjectID) = composeKind {
context.managedObjectContext.performAndWait {
let mastodonUser = context.managedObjectContext.object(with: mastodonUserObjectID) as! MastodonUser
let initialComposeContent = "@" + mastodonUser.acct + " "
self.composeStatusAttribute.composeContent.value = initialComposeContent
}
}
isCustomEmojiComposing isCustomEmojiComposing
.assign(to: \.value, on: customEmojiPickerInputViewModel.isCustomEmojiComposing) .assign(to: \.value, on: customEmojiPickerInputViewModel.isCustomEmojiComposing)
.store(in: &disposeBag) .store(in: &disposeBag)

View File

@ -429,7 +429,12 @@ extension ProfileViewController {
@objc private func replyBarButtonItemPressed(_ sender: UIBarButtonItem) { @objc private func replyBarButtonItemPressed(_ sender: UIBarButtonItem) {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
// TODO: guard let mastodonUser = viewModel.mastodonUser.value else { return }
let composeViewModel = ComposeViewModel(
context: context,
composeKind: .mention(mastodonUserObjectID: mastodonUser.objectID)
)
coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil))
} }
@objc private func refreshControlValueChanged(_ sender: UIRefreshControl) { @objc private func refreshControlValueChanged(_ sender: UIRefreshControl) {
@ -641,7 +646,7 @@ extension ProfileViewController: ProfileHeaderViewDelegate {
} }
func profileHeaderView(_ profileHeaderView: ProfileHeaderView, profileStatusDashboardView: ProfileStatusDashboardView, postDashboardMeterViewDidPressed dashboardMeterView: ProfileStatusDashboardMeterView) { func profileHeaderView(_ profileHeaderView: ProfileHeaderView, profileStatusDashboardView: ProfileStatusDashboardView, postDashboardMeterViewDidPressed dashboardMeterView: ProfileStatusDashboardMeterView) {
} }
func profileHeaderView(_ profileHeaderView: ProfileHeaderView, profileStatusDashboardView: ProfileStatusDashboardView, followingDashboardMeterViewDidPressed dwingDashboardMeterView: ProfileStatusDashboardMeterView) { func profileHeaderView(_ profileHeaderView: ProfileHeaderView, profileStatusDashboardView: ProfileStatusDashboardView, followingDashboardMeterViewDidPressed dwingDashboardMeterView: ProfileStatusDashboardMeterView) {