// // ReportView.swift // Tusker // // Created by Shadowfacts on 1/13/23. // Copyright © 2023 Shadowfacts. All rights reserved. // import SwiftUI struct ReportView: View { let account: AccountMO @ObservedObject var mastodonController: MastodonController @StateObject var report: EditedReport @Environment(\.dismiss) private var dismiss @ObservedObject private var preferences = Preferences.shared @State private var isReporting = false @State private var error: Error? init(report: EditedReport, mastodonController: MastodonController) { self.account = mastodonController.persistentContainer.account(for: report.accountID)! self.mastodonController = mastodonController self._report = StateObject(wrappedValue: report) if mastodonController.instance?.rules == nil { report.reason = .spam } } var body: some View { if #available(iOS 16.0, *) { NavigationStack { navigationViewContent .scrollDismissesKeyboard(.interactively) } } else { NavigationView { navigationViewContent } .navigationViewStyle(.stack) } } private var navigationViewContent: some View { Form { Section { HStack { ComposeAvatarImageView(url: account.avatar) .frame(width: 50, height: 50) .cornerRadius(preferences.avatarStyle.cornerRadiusFraction * 50) VStack(alignment: .leading) { AccountDisplayNameLabel(account: account, textStyle: .headline, emojiSize: 17) Text("@\(account.acct)") .fontWeight(.light) .foregroundColor(.secondary) } } .frame(height: 50) .listRowBackground(EmptyView()) // vertical insets are so the rounded corners fo the section don't affect the avatar .listRowInsets(EdgeInsets(top: 5, leading: 0, bottom: 5, trailing: 0)) } .accessibilityHidden(true) Section { Button { report.reason = .spam } label: { HStack { Text("Spam") Spacer() if case .spam = report.reason { Image(systemName: "checkmark") } } } if mastodonController.instance?.rules != nil { NavigationLink { ReportSelectRulesView(mastodonController: mastodonController, report: report) } label: { HStack { Text("Instance Rule") Spacer() if case .rules(_) = report.reason { Image(systemName: "checkmark") } } .foregroundColor(.accentColor) } } } header: { Text("Reason") } .appGroupedListRowBackground() Section { ComposeTextView(text: $report.comment, placeholder: Text("Add any additional comments")) .backgroundColor(.clear) .listRowInsets(EdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8)) } .appGroupedListRowBackground() Section { ForEach(report.statusIDs, id: \.self) { id in ReportStatusView(status: mastodonController.persistentContainer.status(for: id)!, mastodonController: mastodonController) } .onDelete { indices in report.statusIDs.remove(atOffsets: indices) } NavigationLink { ReportAddStatusView(report: report, mastodonController: mastodonController) } label: { Label("Add Posts…", systemImage: "plus") .foregroundColor(.accentColor) } } footer: { Text("Attach posts to your report to provide additional context for moderators.") } .appGroupedListRowBackground() Section { Toggle("Forward", isOn: $report.forward) } footer: { Text("You can choose to anonymously forward your report to the moderators of **\(account.url.host!)**.") } .appGroupedListRowBackground() Button(action: self.sendReport) { if isReporting { Text("Sending Report") Spacer() ProgressView() .progressViewStyle(.circular) } else { Text("Send Report") } } .disabled(isReporting) .appGroupedListRowBackground() } .listStyle(.insetGrouped) .appGroupedListBackground(container: UIHostingController.self, applyBackground: true) .alertWithData("Error Reporting", data: $error, actions: { error in Button("OK") {} }, message: { error in Text(error.localizedDescription) }) .navigationTitle("Report \(account.displayOrUserName)") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .cancellationAction) { Button("Cancel") { self.dismiss() } } } } private func sendReport() { isReporting = true Task { do { _ = try await mastodonController.run(report.makeRequest()!) self.dismiss() } catch { self.error = error self.isReporting = false } } } } //struct ReportView_Previews: PreviewProvider { // static var previews: some View { // ReportView() // } //}