import SwiftUI import OrgSocialKit /// `.sheet(item:)` requires `Identifiable`; the lib's `OrgSocialMood` isn't /// (it doesn't need to be, the App/UI layer supplies the identity instead). struct IdentifiedMood: Identifiable, Equatable { let mood: OrgSocialMood var id: String { mood.emoji } } /// Lists the feed URLs that reacted with a given emoji. The reactor post URL /// shape is `https://host/social.org#`, so we derive both the /// host (shown as the primary label) and the timestamp (shown as a tappable /// link to the reaction post itself) with no extra network round-trips. struct ReactorsSheet: View { let mood: OrgSocialMood @Environment(\.dismiss) private var dismiss var body: some View { NavigationStack { List { Section { ForEach(mood.posts, id: \.self) { reactorPostURL in reactorRow(reactorPostURL) } } header: { Text("\(mood.posts.count) \(mood.posts.count == 1 ? "reaction" : "reactions")") } } .listStyle(.plain) .navigationTitle(Text(EmojiShortcode.resolve(mood.emoji))) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .cancellationAction) { Button("Done") { dismiss() } } } } .presentationDetents([.medium, .large]) } @ViewBuilder private func reactorRow(_ reactorPostURL: String) -> some View { let parts = reactorPostURL.split(separator: "#", maxSplits: 1, omittingEmptySubsequences: false) let feedURLString = parts.first.map(String.init) ?? reactorPostURL let host = URL(string: feedURLString)?.host ?? feedURLString HStack(spacing: 10) { Image(systemName: "person.circle.fill") .foregroundStyle(.secondary) VStack(alignment: .leading, spacing: 2) { Text(host).font(.subheadline.weight(.medium)) Text(feedURLString).font(.caption).foregroundStyle(.secondary).lineLimit(1) } } } }