IceCubesApp/Packages/Account/Sources/Account/AccountsList/AccountsListRow.swift

126 lines
4.3 KiB
Swift
Raw Normal View History

import Combine
import DesignSystem
import EmojiText
2023-01-17 10:36:01 +00:00
import Env
import Models
import Network
import Observation
2023-01-17 10:36:01 +00:00
import SwiftUI
@MainActor
@Observable public class AccountsListRowViewModel {
var client: Client?
2023-01-17 10:36:01 +00:00
var account: Account
var relationShip: Relationship?
2023-01-17 10:36:01 +00:00
public init(account: Account, relationShip: Relationship? = nil) {
self.account = account
self.relationShip = relationShip
}
}
2022-12-23 17:47:19 +00:00
public struct AccountsListRow: View {
@EnvironmentObject private var theme: Theme
@Environment(CurrentAccount.self) private var currentAccount
@Environment(RouterPath.self) private var routerPath
@Environment(Client.self) private var client
2023-01-17 10:36:01 +00:00
@State var viewModel: AccountsListRowViewModel
2023-03-13 12:38:28 +00:00
@State private var isEditingRelationshipNote: Bool = false
2023-03-13 12:38:28 +00:00
let isFollowRequest: Bool
let requestUpdated: (() -> Void)?
2023-01-17 10:36:01 +00:00
public init(viewModel: AccountsListRowViewModel, isFollowRequest: Bool = false, requestUpdated: (() -> Void)? = nil) {
self.viewModel = viewModel
self.isFollowRequest = isFollowRequest
self.requestUpdated = requestUpdated
2022-12-23 17:47:19 +00:00
}
2023-01-17 10:36:01 +00:00
2022-12-23 17:47:19 +00:00
public var body: some View {
2023-02-24 16:16:39 +00:00
HStack(alignment: .top) {
AvatarView(url: viewModel.account.avatar, size: .status)
VStack(alignment: .leading, spacing: 2) {
EmojiTextApp(.init(stringValue: viewModel.account.safeDisplayName), emojis: viewModel.account.emojis)
.font(.scaledSubheadline)
.emojiSize(Font.scaledSubheadlineFont.emojiSize)
.emojiBaselineOffset(Font.scaledSubheadlineFont.emojiBaselineOffset)
.fontWeight(.semibold)
Text("@\(viewModel.account.acct)")
.font(.scaledFootnote)
.foregroundColor(.gray)
2023-06-26 13:54:56 +00:00
// First parameter is the number for the plural
// Second parameter is the formatted string to show
2023-07-04 06:37:30 +00:00
Text("account.label.followers \(viewModel.account.followersCount ?? 0) \(viewModel.account.followersCount ?? 0, format: .number.notation(.compactName))")
.font(.scaledFootnote)
2023-06-26 13:54:56 +00:00
if let field = viewModel.account.fields.filter({ $0.verifiedAt != nil }).first {
HStack(spacing: 2) {
Image(systemName: "checkmark.seal")
.font(.scaledFootnote)
.foregroundColor(.green)
EmojiTextApp(field.value, emojis: viewModel.account.emojis)
.font(.scaledFootnote)
.emojiSize(Font.scaledFootnoteFont.emojiSize)
.emojiBaselineOffset(Font.scaledFootnoteFont.emojiBaselineOffset)
.environment(\.openURL, OpenURLAction { url in
routerPath.handle(url: url)
})
}
}
EmojiTextApp(viewModel.account.note, emojis: viewModel.account.emojis, lineLimit: 2)
.font(.scaledCaption)
.emojiSize(Font.scaledFootnoteFont.emojiSize)
.emojiBaselineOffset(Font.scaledFootnoteFont.emojiBaselineOffset)
.environment(\.openURL, OpenURLAction { url in
routerPath.handle(url: url)
})
if isFollowRequest {
FollowRequestButtons(account: viewModel.account,
requestUpdated: requestUpdated)
}
}
Spacer()
if currentAccount.account?.id != viewModel.account.id,
let relationShip = viewModel.relationShip
{
VStack(alignment: .center) {
2023-02-26 05:45:57 +00:00
FollowButton(viewModel: .init(accountId: viewModel.account.id,
relationship: relationShip,
shouldDisplayNotify: false,
relationshipUpdated: { _ in }))
}
2022-12-27 09:04:39 +00:00
}
}
.onAppear {
viewModel.client = client
}
.contentShape(Rectangle())
.onTapGesture {
routerPath.navigate(to: .accountDetailWithAccount(account: viewModel.account))
}
.contextMenu {
AccountDetailContextMenu(viewModel: .init(account: viewModel.account))
} preview: {
List {
AccountDetailHeaderView(viewModel: .init(account: viewModel.account),
account: viewModel.account,
scrollViewProxy: nil)
2023-03-13 12:38:28 +00:00
.applyAccountDetailsRowStyle(theme: theme)
}
.listStyle(.plain)
.scrollContentBackground(.hidden)
.background(theme.primaryBackgroundColor)
.environmentObject(theme)
.environment(currentAccount)
.environment(client)
}
}
}