diff --git a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift index 91b778a8..93b12005 100644 --- a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift +++ b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift @@ -108,7 +108,7 @@ struct AccountDetailHeaderView: View { accountAvatarView HStack { VStack(alignment: .leading, spacing: 0) { - EmojiText(account.safeDisplayName, emojis: account.emojis) + EmojiTextApp(account.safeDisplayName.asMarkdown, emojis: account.emojis) .font(.headline) Text("@\(account.acct)") .font(.callout) @@ -123,7 +123,7 @@ struct AccountDetailHeaderView: View { } } } - EmojiText(account.note, emojis: account.emojis) + EmojiTextApp(account.note.asMarkdown, emojis: account.emojis) .font(.body) .padding(.top, 8) .environment(\.openURL, OpenURLAction { url in diff --git a/Packages/Account/Sources/Account/AccountDetailView.swift b/Packages/Account/Sources/Account/AccountDetailView.swift index ef6ee48d..6fba11bd 100644 --- a/Packages/Account/Sources/Account/AccountDetailView.swift +++ b/Packages/Account/Sources/Account/AccountDetailView.swift @@ -216,7 +216,7 @@ public struct AccountDetailView: View { Image(systemName: "checkmark.seal") .foregroundColor(Color.green.opacity(0.80)) } - EmojiText(field.value, emojis: viewModel.account?.emojis ?? []) + EmojiTextApp(field.value.asMarkdown, emojis: viewModel.account?.emojis ?? []) .foregroundColor(theme.tintColor) } .font(.body) @@ -334,7 +334,7 @@ public struct AccountDetailView: View { if scrollOffset < -200 { switch viewModel.accountState { case let .data(account): - EmojiText(account.safeDisplayName, emojis: account.emojis) + EmojiTextApp(account.safeDisplayName.asMarkdown, emojis: account.emojis) .font(.headline) default: EmptyView() diff --git a/Packages/Account/Sources/Account/AccountsLIst/AccountsListRow.swift b/Packages/Account/Sources/Account/AccountsLIst/AccountsListRow.swift index 15031ce8..de0a3d65 100644 --- a/Packages/Account/Sources/Account/AccountsLIst/AccountsListRow.swift +++ b/Packages/Account/Sources/Account/AccountsLIst/AccountsListRow.swift @@ -33,13 +33,13 @@ public struct AccountsListRow: View { HStack(alignment: .top) { AvatarView(url: viewModel.account.avatar, size: .status) VStack(alignment: .leading, spacing: 2) { - EmojiText(viewModel.account.safeDisplayName, emojis: viewModel.account.emojis) + EmojiTextApp(viewModel.account.safeDisplayName.asMarkdown, emojis: viewModel.account.emojis) .font(.subheadline) .fontWeight(.semibold) Text("@\(viewModel.account.acct)") .font(.footnote) .foregroundColor(.gray) - EmojiText(viewModel.account.note, emojis: viewModel.account.emojis) + EmojiTextApp(viewModel.account.note.asMarkdown, emojis: viewModel.account.emojis) .font(.footnote) .lineLimit(3) .environment(\.openURL, OpenURLAction { url in diff --git a/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift b/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift index 27505832..84f036d9 100644 --- a/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift +++ b/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift @@ -26,7 +26,7 @@ public struct AppAccountView: View { } VStack(alignment: .leading) { if let account = viewModel.account { - EmojiText(account.safeDisplayName, emojis: account.emojis) + EmojiTextApp(account.safeDisplayName.asMarkdown, emojis: account.emojis) Text("\(account.username)@\(viewModel.appAccount.server)") .font(.subheadline) .foregroundColor(.gray) diff --git a/Packages/DesignSystem/Sources/DesignSystem/Views/EmojiText.swift b/Packages/DesignSystem/Sources/DesignSystem/Views/EmojiText.swift index baa605e2..16d6a818 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/Views/EmojiText.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/Views/EmojiText.swift @@ -2,10 +2,29 @@ import Foundation import EmojiText import Models import HTML2Markdown +import SwiftUI -public extension EmojiText { - init(_ string: HTMLString, emojis: [Emoji]) { - let markdown = string.asMarkdown - self.init(markdown: markdown, emojis: emojis.map { RemoteEmoji(shortcode: $0.shortcode, url: $0.url) }) +public struct EmojiTextApp: View { + private let markdown: String + private let emojis: [any CustomEmoji] + private let append: (() -> Text)? + + public init(_ markdown: HTMLString, emojis: [Emoji], append: (() -> Text)? = nil) { + self.markdown = markdown + self.emojis = emojis.map { RemoteEmoji(shortcode: $0.shortcode, url: $0.url) } + self.append = append + } + + public var body: some View { + if let append { + EmojiText(markdown: markdown, emojis: emojis) + .append { + append() + } + } else if emojis.isEmpty { + Text(markdown.asSafeAttributedString) + } else { + EmojiText(markdown: markdown, emojis: emojis) } + } } diff --git a/Packages/Lists/Sources/Lists/Edit/ListEditView.swift b/Packages/Lists/Sources/Lists/Edit/ListEditView.swift index fe89766b..fa641c4d 100644 --- a/Packages/Lists/Sources/Lists/Edit/ListEditView.swift +++ b/Packages/Lists/Sources/Lists/Edit/ListEditView.swift @@ -31,7 +31,8 @@ public struct ListEditView: View { HStack { AvatarView(url: account.avatar, size: .status) VStack(alignment: .leading) { - EmojiText(account.safeDisplayName, emojis: account.emojis) + EmojiTextApp(account.safeDisplayName.asMarkdown, + emojis: account.emojis) Text("@\(account.acct)") .foregroundColor(.gray) .font(.footnote) diff --git a/Packages/Notifications/Sources/Notifications/NotificationRowView.swift b/Packages/Notifications/Sources/Notifications/NotificationRowView.swift index 5ce04c64..424fe018 100644 --- a/Packages/Notifications/Sources/Notifications/NotificationRowView.swift +++ b/Packages/Notifications/Sources/Notifications/NotificationRowView.swift @@ -51,8 +51,9 @@ struct NotificationRowView: View { private func makeMainLabel(type: Models.Notification.NotificationType) -> some View { VStack(alignment: .leading, spacing: 0) { HStack(spacing: 0) { - EmojiText(notification.account.safeDisplayName, emojis: notification.account.emojis) - .append { + EmojiTextApp(notification.account.safeDisplayName.asMarkdown, + emojis: notification.account.emojis, + append: { Text(" ") + Text(type.label()) .font(.subheadline) @@ -65,7 +66,7 @@ struct NotificationRowView: View { .font(.footnote) .fontWeight(.regular) .foregroundColor(.gray) - } + }) .font(.subheadline) .fontWeight(.semibold) Spacer() @@ -92,7 +93,8 @@ struct NotificationRowView: View { .foregroundColor(.gray) if type == .follow { - EmojiText(notification.account.note, emojis: notification.account.emojis) + EmojiTextApp(notification.account.note.asMarkdown, + emojis: notification.account.emojis) .lineLimit(3) .font(.callout) .foregroundColor(.gray) diff --git a/Packages/Status/Sources/Status/Editor/Components/StatusEditorAutoCompleteView.swift b/Packages/Status/Sources/Status/Editor/Components/StatusEditorAutoCompleteView.swift index 2a5096bb..286c7a92 100644 --- a/Packages/Status/Sources/Status/Editor/Components/StatusEditorAutoCompleteView.swift +++ b/Packages/Status/Sources/Status/Editor/Components/StatusEditorAutoCompleteView.swift @@ -32,7 +32,8 @@ struct StatusEditorAutoCompleteView: View { HStack { AvatarView(url: account.avatar, size: .badge) VStack(alignment: .leading) { - EmojiText(account.safeDisplayName, emojis: account.emojis) + EmojiTextApp(account.safeDisplayName.asMarkdown, + emojis: account.emojis) .font(.footnote) .foregroundColor(theme.labelColor) Text("@\(account.acct)") diff --git a/Packages/Status/Sources/Status/Embed/StatusEmbededView.swift b/Packages/Status/Sources/Status/Embed/StatusEmbededView.swift index 83a8ce9e..f4983780 100644 --- a/Packages/Status/Sources/Status/Embed/StatusEmbededView.swift +++ b/Packages/Status/Sources/Status/Embed/StatusEmbededView.swift @@ -35,7 +35,7 @@ public struct StatusEmbededView: View { HStack(alignment: .center) { AvatarView(url: account.avatar, size: .embed) VStack(alignment: .leading, spacing: 0) { - EmojiText(status.account.safeDisplayName, emojis: account.emojis) + EmojiTextApp(status.account.safeDisplayName.asMarkdown, emojis: account.emojis) .font(.footnote) .fontWeight(.semibold) Group { diff --git a/Packages/Status/Sources/Status/Row/StatusRowView.swift b/Packages/Status/Sources/Status/Row/StatusRowView.swift index 6540088b..1532cc82 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowView.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowView.swift @@ -98,7 +98,7 @@ public struct StatusRowView: View { HStack(spacing: 2) { Image(systemName:"arrow.left.arrow.right.circle.fill") AvatarView(url: viewModel.status.account.avatar, size: .boost) - EmojiText(viewModel.status.account.safeDisplayName, emojis: viewModel.status.account.emojis) + EmojiTextApp(viewModel.status.account.safeDisplayName.asMarkdown, emojis: viewModel.status.account.emojis) Text("boosted") } .font(.footnote) @@ -172,7 +172,7 @@ public struct StatusRowView: View { private func makeStatusContentView(status: AnyStatus) -> some View { Group { if !status.spoilerText.isEmpty { - EmojiText(status.spoilerText, emojis: status.emojis) + EmojiTextApp(status.spoilerText.asMarkdown, emojis: status.emojis) .font(.body) Button { withAnimation { @@ -185,7 +185,7 @@ public struct StatusRowView: View { } if !viewModel.displaySpoiler { HStack { - EmojiText(status.content, emojis: status.emojis) + EmojiTextApp(status.content.asMarkdown, emojis: status.emojis) .font(.body) .environment(\.openURL, OpenURLAction { url in routeurPath.handleStatus(status: status, url: url) @@ -241,7 +241,7 @@ public struct StatusRowView: View { AvatarView(url: status.account.avatar, size: .status) } VStack(alignment: .leading, spacing: 0) { - EmojiText(status.account.safeDisplayName, emojis: status.account.emojis) + EmojiTextApp(status.account.safeDisplayName.asMarkdown, emojis: status.account.emojis) .font(.headline) .fontWeight(.semibold) Group { diff --git a/README.md b/README.md index d82ba865..e8b94758 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,10 @@ For contributors and myself, here is a todo list of features that could be added - [ ] Editor: Support video types - [ ] Editor: Add photos from camera - [ ] Editor: Support custom emojis -- [ ] Edit profile -- [ ] Handle emoji in status -- [ ] Display & Edit server side features (filter, default visibility, etc...) -- [ ] Edit filters. -- [ ] More context menu everywhere +- [ ] Edit filters - [ ] Support IceCubesApp://any mastodon links -- [ ] Translate button +- [ ] Translate button / display post language / set post language +- [ ] Widgets - [ ] Proper iPad support - [ ] macOS support