2023-01-14 16:03:39 +00:00
|
|
|
//
|
|
|
|
// ReportView.swift
|
|
|
|
// Tusker
|
|
|
|
//
|
|
|
|
// Created by Shadowfacts on 1/13/23.
|
|
|
|
// Copyright © 2023 Shadowfacts. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import SwiftUI
|
2023-04-16 17:47:06 +00:00
|
|
|
import TuskerComponents
|
2023-01-14 16:03:39 +00:00
|
|
|
|
|
|
|
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)
|
2023-02-24 23:32:29 +00:00
|
|
|
if mastodonController.instance?.rules == nil {
|
2023-01-14 16:03:39 +00:00
|
|
|
report.reason = .spam
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
if #available(iOS 16.0, *) {
|
|
|
|
NavigationStack {
|
2023-02-06 23:42:55 +00:00
|
|
|
navigationViewContent
|
|
|
|
.scrollDismissesKeyboard(.interactively)
|
2023-01-14 16:03:39 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
NavigationView {
|
|
|
|
navigationViewContent
|
|
|
|
}
|
|
|
|
.navigationViewStyle(.stack)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private var navigationViewContent: some View {
|
|
|
|
Form {
|
|
|
|
Section {
|
|
|
|
HStack {
|
2023-04-16 17:47:06 +00:00
|
|
|
AvatarImageView(
|
|
|
|
url: account.avatar,
|
|
|
|
size: 50,
|
|
|
|
style: Preferences.shared.avatarStyle == .circle ? .circle : .roundRect,
|
|
|
|
fetchAvatar: { await ImageCache.avatars.get($0).1 }
|
|
|
|
)
|
|
|
|
|
2023-01-14 16:03:39 +00:00
|
|
|
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")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-24 23:32:29 +00:00
|
|
|
if mastodonController.instance?.rules != nil {
|
2023-01-14 16:03:39 +00:00
|
|
|
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")
|
|
|
|
}
|
2023-02-06 23:42:55 +00:00
|
|
|
.appGroupedListRowBackground()
|
2023-01-14 16:03:39 +00:00
|
|
|
|
|
|
|
Section {
|
2023-04-16 17:47:06 +00:00
|
|
|
ZStack(alignment: .topLeading) {
|
|
|
|
if report.comment.isEmpty {
|
|
|
|
Text("Add any additional comments")
|
|
|
|
.offset(x: 4, y: 8)
|
|
|
|
.foregroundColor(.secondary)
|
|
|
|
}
|
|
|
|
|
|
|
|
TextEditor(text: $report.comment)
|
|
|
|
.background(.clear)
|
|
|
|
.frame(minHeight: 100)
|
|
|
|
}
|
|
|
|
.font(.body)
|
|
|
|
.listRowInsets(EdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8))
|
2023-01-14 16:03:39 +00:00
|
|
|
}
|
2023-02-06 23:42:55 +00:00
|
|
|
.appGroupedListRowBackground()
|
2023-01-14 16:03:39 +00:00
|
|
|
|
|
|
|
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.")
|
|
|
|
}
|
2023-02-06 23:42:55 +00:00
|
|
|
.appGroupedListRowBackground()
|
2023-01-14 16:03:39 +00:00
|
|
|
|
|
|
|
Section {
|
|
|
|
Toggle("Forward", isOn: $report.forward)
|
|
|
|
} footer: {
|
|
|
|
Text("You can choose to anonymously forward your report to the moderators of **\(account.url.host!)**.")
|
|
|
|
}
|
2023-02-06 23:42:55 +00:00
|
|
|
.appGroupedListRowBackground()
|
2023-01-14 16:03:39 +00:00
|
|
|
|
|
|
|
Button(action: self.sendReport) {
|
|
|
|
if isReporting {
|
|
|
|
Text("Sending Report")
|
|
|
|
Spacer()
|
|
|
|
ProgressView()
|
|
|
|
.progressViewStyle(.circular)
|
|
|
|
} else {
|
|
|
|
Text("Send Report")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.disabled(isReporting)
|
2023-02-06 23:42:55 +00:00
|
|
|
.appGroupedListRowBackground()
|
2023-01-14 16:03:39 +00:00
|
|
|
}
|
2023-02-06 23:42:55 +00:00
|
|
|
.listStyle(.insetGrouped)
|
|
|
|
.appGroupedListBackground(container: UIHostingController<ReportView>.self, applyBackground: true)
|
2023-01-14 16:03:39 +00:00
|
|
|
.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()
|
|
|
|
// }
|
|
|
|
//}
|