mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-01-02 20:38:49 +00:00
Support Custom Emojis (#61)
* Support Custom Emojis * Update EmojiText * Update EmojiText * Use EmojiText in StatusEditorAutoCompleteView * Update EmojiText * Display Account displayName without emojis in navigation title Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
This commit is contained in:
parent
150cb5a8c5
commit
3acd5aced4
17 changed files with 78 additions and 68 deletions
|
@ -1,5 +1,14 @@
|
||||||
{
|
{
|
||||||
"pins" : [
|
"pins" : [
|
||||||
|
{
|
||||||
|
"identity" : "emojitext",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/divadretlaw/EmojiText",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "f349e481499d2c832ab9d2dc28af238e53b1f9b4",
|
||||||
|
"version" : "1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "html2markdown",
|
"identity" : "html2markdown",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
@ -23,8 +32,8 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/kean/Nuke",
|
"location" : "https://github.com/kean/Nuke",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "81f6a3dea0c8ce3b87389c241c48601be07af0b1",
|
"revision" : "2e9337168d08acccf72c039bf9324be24a1cf7d7",
|
||||||
"version" : "11.5.1"
|
"version" : "11.5.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -41,8 +50,8 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/scinfu/SwiftSoup.git",
|
"location" : "https://github.com/scinfu/SwiftSoup.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "6778575285177365cbad3e5b8a72f2a20583cfec",
|
"revision" : "f707b8680cddb96dc1855632340a572ef37bbb98",
|
||||||
"version" : "2.4.3"
|
"version" : "2.5.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
|
import EmojiText
|
||||||
|
|
||||||
struct AppAccountView: View {
|
struct AppAccountView: View {
|
||||||
@EnvironmentObject private var routeurPath: RouterPath
|
@EnvironmentObject private var routeurPath: RouterPath
|
||||||
|
@ -21,7 +22,7 @@ struct AppAccountView: View {
|
||||||
}
|
}
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
if let account = viewModel.account {
|
if let account = viewModel.account {
|
||||||
account.displayNameWithEmojis
|
EmojiText(account.safeDisplayName, emojis: account.emojis)
|
||||||
Text("\(account.username)@\(viewModel.appAccount.server)")
|
Text("\(account.username)@\(viewModel.appAccount.server)")
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
import Shimmer
|
import Shimmer
|
||||||
import NukeUI
|
import NukeUI
|
||||||
|
import EmojiText
|
||||||
|
|
||||||
struct AccountDetailHeaderView: View {
|
struct AccountDetailHeaderView: View {
|
||||||
@EnvironmentObject private var theme: Theme
|
@EnvironmentObject private var theme: Theme
|
||||||
|
@ -108,7 +109,7 @@ struct AccountDetailHeaderView: View {
|
||||||
accountAvatarView
|
accountAvatarView
|
||||||
HStack {
|
HStack {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
account.displayNameWithEmojis
|
EmojiText(account.safeDisplayName, emojis: account.emojis)
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
Text("@\(account.acct)")
|
Text("@\(account.acct)")
|
||||||
.font(.callout)
|
.font(.callout)
|
||||||
|
@ -120,7 +121,7 @@ struct AccountDetailHeaderView: View {
|
||||||
relationship: relationship))
|
relationship: relationship))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text(account.note.asSafeAttributedString)
|
EmojiText(account.note, emojis: account.emojis)
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.padding(.top, 8)
|
.padding(.top, 8)
|
||||||
.environment(\.openURL, OpenURLAction { url in
|
.environment(\.openURL, OpenURLAction { url in
|
||||||
|
|
|
@ -5,6 +5,7 @@ import Status
|
||||||
import Shimmer
|
import Shimmer
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
|
import EmojiText
|
||||||
|
|
||||||
public struct AccountDetailView: View {
|
public struct AccountDetailView: View {
|
||||||
@Environment(\.redactionReasons) private var reasons
|
@Environment(\.redactionReasons) private var reasons
|
||||||
|
@ -217,7 +218,7 @@ public struct AccountDetailView: View {
|
||||||
Image(systemName: "checkmark.seal")
|
Image(systemName: "checkmark.seal")
|
||||||
.foregroundColor(Color.green.opacity(0.80))
|
.foregroundColor(Color.green.opacity(0.80))
|
||||||
}
|
}
|
||||||
Text(field.value.asSafeAttributedString)
|
EmojiText(field.value, emojis: viewModel.account?.emojis ?? [])
|
||||||
.foregroundColor(theme.tintColor)
|
.foregroundColor(theme.tintColor)
|
||||||
}
|
}
|
||||||
.font(.body)
|
.font(.body)
|
||||||
|
@ -335,7 +336,8 @@ public struct AccountDetailView: View {
|
||||||
if scrollOffset < -200 {
|
if scrollOffset < -200 {
|
||||||
switch viewModel.accountState {
|
switch viewModel.accountState {
|
||||||
case let .data(account):
|
case let .data(account):
|
||||||
account.displayNameWithEmojis.font(.headline)
|
EmojiText(account.safeDisplayName, emojis: account.emojis)
|
||||||
|
.font(.headline)
|
||||||
default:
|
default:
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import Models
|
||||||
import Network
|
import Network
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
|
import EmojiText
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
public class AccountsListRowViewModel: ObservableObject {
|
public class AccountsListRowViewModel: ObservableObject {
|
||||||
|
@ -32,13 +33,13 @@ public struct AccountsListRow: View {
|
||||||
HStack(alignment: .top) {
|
HStack(alignment: .top) {
|
||||||
AvatarView(url: viewModel.account.avatar, size: .status)
|
AvatarView(url: viewModel.account.avatar, size: .status)
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
viewModel.account.displayNameWithEmojis
|
EmojiText(viewModel.account.safeDisplayName, emojis: viewModel.account.emojis)
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
Text("@\(viewModel.account.acct)")
|
Text("@\(viewModel.account.acct)")
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
Text(viewModel.account.note.asSafeAttributedString)
|
EmojiText(viewModel.account.note, emojis: viewModel.account.emojis)
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
.lineLimit(3)
|
.lineLimit(3)
|
||||||
.environment(\.openURL, OpenURLAction { url in
|
.environment(\.openURL, OpenURLAction { url in
|
||||||
|
|
|
@ -17,7 +17,9 @@ let package = Package(
|
||||||
.package(name: "Models", path: "../Models"),
|
.package(name: "Models", path: "../Models"),
|
||||||
.package(name: "Env", path: "../Env"),
|
.package(name: "Env", path: "../Env"),
|
||||||
.package(url: "https://github.com/markiv/SwiftUI-Shimmer", exact: "1.1.0"),
|
.package(url: "https://github.com/markiv/SwiftUI-Shimmer", exact: "1.1.0"),
|
||||||
.package(url: "https://github.com/kean/Nuke", from: "11.5.0")],
|
.package(url: "https://github.com/kean/Nuke", from: "11.5.0"),
|
||||||
|
.package(url: "https://github.com/divadretlaw/EmojiText", from: "1.1.0")
|
||||||
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
name: "DesignSystem",
|
name: "DesignSystem",
|
||||||
|
@ -26,7 +28,8 @@ let package = Package(
|
||||||
.product(name: "Env", package: "Env"),
|
.product(name: "Env", package: "Env"),
|
||||||
.product(name: "Shimmer", package: "SwiftUI-Shimmer"),
|
.product(name: "Shimmer", package: "SwiftUI-Shimmer"),
|
||||||
.product(name: "NukeUI", package: "Nuke"),
|
.product(name: "NukeUI", package: "Nuke"),
|
||||||
.product(name: "Nuke", package: "Nuke")
|
.product(name: "Nuke", package: "Nuke"),
|
||||||
|
.product(name: "EmojiText", package: "EmojiText")
|
||||||
]),
|
]),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,7 +3,6 @@ import SwiftUI
|
||||||
import NukeUI
|
import NukeUI
|
||||||
import Models
|
import Models
|
||||||
|
|
||||||
@MainActor
|
|
||||||
extension Account {
|
extension Account {
|
||||||
private struct Part: Identifiable {
|
private struct Part: Identifiable {
|
||||||
let id = UUID().uuidString
|
let id = UUID().uuidString
|
||||||
|
@ -16,35 +15,12 @@ extension Account {
|
||||||
}
|
}
|
||||||
return displayName
|
return displayName
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
public var displayNameWithoutEmojis: String {
|
||||||
public var displayNameWithEmojis: some View {
|
var name = safeDisplayName
|
||||||
if displayName.isEmpty {
|
for emoji in emojis {
|
||||||
Text(safeDisplayName)
|
name = name.replacingOccurrences(of: ":\(emoji.shortcode):", with: "")
|
||||||
}
|
|
||||||
let splittedDisplayName = displayName.split(separator: ":").map{ Part(value: $0) }
|
|
||||||
HStack(spacing: 0) {
|
|
||||||
if displayName.isEmpty {
|
|
||||||
Text(" ")
|
|
||||||
}
|
|
||||||
ForEach(splittedDisplayName, id: \.id) { part in
|
|
||||||
if let emoji = emojis.first(where: { $0.shortcode == part.value }) {
|
|
||||||
LazyImage(url: emoji.url) { state in
|
|
||||||
if let image = state.image {
|
|
||||||
image
|
|
||||||
.resizingMode(.aspectFit)
|
|
||||||
} else if state.isLoading {
|
|
||||||
ProgressView()
|
|
||||||
} else {
|
|
||||||
ProgressView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.processors([.resize(size: .init(width: 20, height: 20))])
|
|
||||||
.frame(width: 20, height: 20)
|
|
||||||
} else {
|
|
||||||
Text(part.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return name.split(separator: " ", omittingEmptySubsequences: true).joined(separator: " ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import Foundation
|
||||||
|
import EmojiText
|
||||||
|
import Models
|
||||||
|
import HTML2Markdown
|
||||||
|
|
||||||
|
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) })
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import SwiftUI
|
||||||
import Models
|
import Models
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Network
|
import Network
|
||||||
|
import EmojiText
|
||||||
|
|
||||||
public struct ListEditView: View {
|
public struct ListEditView: View {
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
@ -30,7 +31,7 @@ public struct ListEditView: View {
|
||||||
HStack {
|
HStack {
|
||||||
AvatarView(url: account.avatar, size: .status)
|
AvatarView(url: account.avatar, size: .status)
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
account.displayNameWithEmojis
|
EmojiText(account.safeDisplayName, emojis: account.emojis)
|
||||||
Text("@\(account.acct)")
|
Text("@\(account.acct)")
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
|
|
|
@ -10,6 +10,8 @@ extension HTMLString {
|
||||||
do {
|
do {
|
||||||
let dom = try HTMLParser().parse(html: self)
|
let dom = try HTMLParser().parse(html: self)
|
||||||
return dom.toMarkdown()
|
return dom.toMarkdown()
|
||||||
|
// Add space between hashtags and mentions that follow each other
|
||||||
|
.replacingOccurrences(of: ")[", with: ") [")
|
||||||
} catch {
|
} catch {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
@ -44,9 +46,7 @@ extension HTMLString {
|
||||||
|
|
||||||
public var asSafeAttributedString: AttributedString {
|
public var asSafeAttributedString: AttributedString {
|
||||||
do {
|
do {
|
||||||
// Add space between hashtags and mentions that follow each other
|
|
||||||
let markdown = asMarkdown
|
let markdown = asMarkdown
|
||||||
.replacingOccurrences(of: ")[", with: ") [")
|
|
||||||
let options = AttributedString.MarkdownParsingOptions(allowsExtendedAttributes: true,
|
let options = AttributedString.MarkdownParsingOptions(allowsExtendedAttributes: true,
|
||||||
interpretedSyntax: .inlineOnlyPreservingWhitespace)
|
interpretedSyntax: .inlineOnlyPreservingWhitespace)
|
||||||
return try AttributedString(markdown: markdown, options: options)
|
return try AttributedString(markdown: markdown, options: options)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import Models
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Status
|
import Status
|
||||||
import Env
|
import Env
|
||||||
|
import EmojiText
|
||||||
|
|
||||||
struct NotificationRowView: View {
|
struct NotificationRowView: View {
|
||||||
@EnvironmentObject private var theme: Theme
|
@EnvironmentObject private var theme: Theme
|
||||||
|
@ -50,18 +51,18 @@ struct NotificationRowView: View {
|
||||||
private func makeMainLabel(type: Models.Notification.NotificationType) -> some View {
|
private func makeMainLabel(type: Models.Notification.NotificationType) -> some View {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
Text(notification.account.safeDisplayName)
|
EmojiText(notification.account.safeDisplayName, emojis: notification.account.emojis)
|
||||||
.font(.subheadline)
|
.append {
|
||||||
.fontWeight(.semibold) +
|
Text(" ") +
|
||||||
Text(" ") +
|
Text(type.label())
|
||||||
Text(type.label())
|
.font(.subheadline) +
|
||||||
.font(.subheadline) +
|
Text(" ⸱ ")
|
||||||
Text(" ⸱ ")
|
.font(.footnote)
|
||||||
.font(.footnote)
|
.foregroundColor(.gray) +
|
||||||
.foregroundColor(.gray) +
|
Text(notification.createdAt.formatted)
|
||||||
Text(notification.createdAt.formatted)
|
.font(.footnote)
|
||||||
.font(.footnote)
|
.foregroundColor(.gray)
|
||||||
.foregroundColor(.gray)
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +87,7 @@ struct NotificationRowView: View {
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
|
||||||
if type == .follow {
|
if type == .follow {
|
||||||
Text(notification.account.note.asSafeAttributedString)
|
EmojiText(notification.account.note, emojis: notification.account.emojis)
|
||||||
.lineLimit(3)
|
.lineLimit(3)
|
||||||
.font(.callout)
|
.font(.callout)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
|
|
@ -62,7 +62,7 @@ class StatusDetailViewModel: ObservableObject {
|
||||||
let status: Status = try await client.get(endpoint: Statuses.status(id: statusId))
|
let status: Status = try await client.get(endpoint: Statuses.status(id: statusId))
|
||||||
let context: StatusContext = try await client.get(endpoint: Statuses.context(id: statusId))
|
let context: StatusContext = try await client.get(endpoint: Statuses.context(id: statusId))
|
||||||
state = .display(status: status, context: context)
|
state = .display(status: status, context: context)
|
||||||
title = "Post from \(status.account.displayName)"
|
title = "Post from \(status.account.displayNameWithoutEmojis)"
|
||||||
} catch {
|
} catch {
|
||||||
state = .error(error: error)
|
state = .error(error: error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
|
import EmojiText
|
||||||
|
|
||||||
struct StatusEditorAutoCompleteView: View {
|
struct StatusEditorAutoCompleteView: View {
|
||||||
@EnvironmentObject private var theme: Theme
|
@EnvironmentObject private var theme: Theme
|
||||||
|
@ -31,7 +32,7 @@ struct StatusEditorAutoCompleteView: View {
|
||||||
HStack {
|
HStack {
|
||||||
AvatarView(url: account.avatar, size: .badge)
|
AvatarView(url: account.avatar, size: .badge)
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Text(account.displayName)
|
EmojiText(account.safeDisplayName, emojis: account.emojis)
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
.foregroundColor(theme.labelColor)
|
.foregroundColor(theme.labelColor)
|
||||||
Text("@\(account.acct)")
|
Text("@\(account.acct)")
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Models
|
||||||
import Network
|
import Network
|
||||||
import PhotosUI
|
import PhotosUI
|
||||||
import NukeUI
|
import NukeUI
|
||||||
|
import EmojiText
|
||||||
|
|
||||||
public struct StatusEditorView: View {
|
public struct StatusEditorView: View {
|
||||||
@EnvironmentObject private var preferences: UserPreferences
|
@EnvironmentObject private var preferences: UserPreferences
|
||||||
|
|
|
@ -33,9 +33,9 @@ extension StatusEditorViewModel {
|
||||||
case .edit:
|
case .edit:
|
||||||
return "Editing your post"
|
return "Editing your post"
|
||||||
case let .replyTo(status):
|
case let .replyTo(status):
|
||||||
return "Replying to \(status.reblog?.account.displayName ?? status.account.displayName)"
|
return "Replying to \(status.reblog?.account.displayNameWithoutEmojis ?? status.account.displayNameWithoutEmojis)"
|
||||||
case let .quote(status):
|
case let .quote(status):
|
||||||
return "Quote of \(status.reblog?.account.displayName ?? status.account.displayName)"
|
return "Quote of \(status.reblog?.account.displayNameWithoutEmojis ?? status.account.displayNameWithoutEmojis)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Models
|
import Models
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
|
import EmojiText
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
public struct StatusEmbededView: View {
|
public struct StatusEmbededView: View {
|
||||||
|
@ -34,7 +35,7 @@ public struct StatusEmbededView: View {
|
||||||
HStack(alignment: .center) {
|
HStack(alignment: .center) {
|
||||||
AvatarView(url: account.avatar, size: .embed)
|
AvatarView(url: account.avatar, size: .embed)
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
status.account.displayNameWithEmojis
|
EmojiText(status.account.safeDisplayName, emojis: account.emojis)
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
Group {
|
Group {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Env
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Network
|
import Network
|
||||||
import Shimmer
|
import Shimmer
|
||||||
|
import EmojiText
|
||||||
|
|
||||||
public struct StatusRowView: View {
|
public struct StatusRowView: View {
|
||||||
@Environment(\.redactionReasons) private var reasons
|
@Environment(\.redactionReasons) private var reasons
|
||||||
|
@ -90,7 +91,7 @@ public struct StatusRowView: View {
|
||||||
HStack(spacing: 2) {
|
HStack(spacing: 2) {
|
||||||
Image(systemName:"arrow.left.arrow.right.circle.fill")
|
Image(systemName:"arrow.left.arrow.right.circle.fill")
|
||||||
AvatarView(url: viewModel.status.account.avatar, size: .boost)
|
AvatarView(url: viewModel.status.account.avatar, size: .boost)
|
||||||
viewModel.status.account.displayNameWithEmojis
|
EmojiText(viewModel.status.account.safeDisplayName, emojis: viewModel.status.account.emojis)
|
||||||
Text("boosted")
|
Text("boosted")
|
||||||
}
|
}
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
|
@ -164,7 +165,7 @@ public struct StatusRowView: View {
|
||||||
private func makeStatusContentView(status: AnyStatus) -> some View {
|
private func makeStatusContentView(status: AnyStatus) -> some View {
|
||||||
Group {
|
Group {
|
||||||
if !status.spoilerText.isEmpty {
|
if !status.spoilerText.isEmpty {
|
||||||
Text(status.spoilerText)
|
EmojiText(status.spoilerText, emojis: status.emojis)
|
||||||
.font(.body)
|
.font(.body)
|
||||||
Button {
|
Button {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
|
@ -177,7 +178,7 @@ public struct StatusRowView: View {
|
||||||
}
|
}
|
||||||
if !viewModel.displaySpoiler {
|
if !viewModel.displaySpoiler {
|
||||||
HStack {
|
HStack {
|
||||||
Text(status.content.asSafeAttributedString)
|
EmojiText(status.content, emojis: status.emojis)
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.environment(\.openURL, OpenURLAction { url in
|
.environment(\.openURL, OpenURLAction { url in
|
||||||
routeurPath.handleStatus(status: status, url: url)
|
routeurPath.handleStatus(status: status, url: url)
|
||||||
|
@ -233,7 +234,7 @@ public struct StatusRowView: View {
|
||||||
AvatarView(url: status.account.avatar, size: .status)
|
AvatarView(url: status.account.avatar, size: .status)
|
||||||
}
|
}
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
status.account.displayNameWithEmojis
|
EmojiText(status.account.safeDisplayName, emojis: status.account.emojis)
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
Group {
|
Group {
|
||||||
|
|
Loading…
Reference in a new issue