~ knotless Search/
↑↓ move↵ open⇧↵ all results

grain.social/grain-ios

1 collaborator
0
1
main
97 lines · 2.8 KB Raw History
import SwiftUI

/// Full content warning overlay — hides all content behind a reveal button.
struct ContentWarningOverlay: View {
    let name: String
    let action: LabelAction
    let onReveal: () -> Void

    var body: some View {
        VStack(spacing: 12) {
            Image(systemName: action == .hide ? "eye.slash.fill" : "exclamationmark.triangle.fill")
                .font(.title2)
                .foregroundStyle(.secondary)
            Text(name)
                .font(.subheadline.weight(.semibold))
                .foregroundStyle(.primary)
            Text("This content has been flagged.")
                .font(.caption)
                .foregroundStyle(.secondary)
            Button("Show anyway") {
                onReveal()
            }
            .font(.caption.weight(.medium))
            .buttonStyle(.bordered)
            .tint(.secondary)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(.ultraThinMaterial)
    }
}

/// Media warning overlay — centered bar with label name and Show button (Bluesky-style).
struct MediaWarningOverlay: View {
    let name: String
    let onReveal: () -> Void

    var body: some View {
        VStack {
            Spacer()
            HStack {
                Image(systemName: "info.circle.fill")
                    .foregroundStyle(.secondary)
                Text(name)
                    .font(.subheadline.weight(.medium))
                Spacer()
                Button("Show") {
                    onReveal()
                }
                .font(.subheadline.weight(.medium))
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 12)
            .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 10))
            .padding(.horizontal, 12)
            Spacer()
        }
    }
}

/// Small inline badge for low-severity labels.
struct LabelBadge: View {
    let name: String

    var body: some View {
        HStack(spacing: 4) {
            Image(systemName: "exclamationmark.triangle.fill")
                .font(.system(size: 10))
            Text(name)
                .font(.caption2)
        }
        .foregroundStyle(.secondary)
        .padding(.horizontal, 8)
        .padding(.vertical, 3)
        .background(.quaternary, in: .capsule)
    }
}

#Preview {
    VStack(spacing: 24) {
        ContentWarningOverlay(name: "Nudity", action: .hide) {}
            .frame(height: 200)

        MediaWarningOverlay(name: "Sexual Content") {}
            .frame(height: 200)
            .background(Color.gray.opacity(0.2))

        HStack {
            LabelBadge(name: "sensitive")
            LabelBadge(name: "gore")
        }
        .padding()
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(Color.black)
    .preferredColorScheme(.dark)
    .tint(Color.accentColor)
}