chore: allow multiple report server rules selection

This commit is contained in:
CMK 2022-05-18 00:28:38 +08:00
parent ca91e756ff
commit 9b4da01c48
8 changed files with 32 additions and 55 deletions

View File

@ -120,26 +120,15 @@ extension ReportViewController: ReportReasonViewControllerDelegate {
// MARK: - ReportServerRulesViewControllerDelegate // MARK: - ReportServerRulesViewControllerDelegate
extension ReportViewController: ReportServerRulesViewControllerDelegate { extension ReportViewController: ReportServerRulesViewControllerDelegate {
func reportServerRulesViewController(_ viewController: ReportServerRulesViewController, nextButtonPressed button: UIButton) { func reportServerRulesViewController(_ viewController: ReportServerRulesViewController, nextButtonPressed button: UIButton) {
if viewController.viewModel.isDislike { guard !viewController.viewModel.selectRules.isEmpty else {
let reportResultViewModel = ReportResultViewModel( return
context: context,
user: viewModel.user,
isReported: false
)
coordinator.present(
scene: .reportResult(viewModel: reportResultViewModel),
from: self,
transition: .show
)
} else if viewController.viewModel.selectRule != nil {
coordinator.present(
scene: .reportStatus(viewModel: viewModel.reportStatusViewModel),
from: self,
transition: .show
)
} else {
assertionFailure()
} }
coordinator.present(
scene: .reportStatus(viewModel: viewModel.reportStatusViewModel),
from: self,
transition: .show
)
} }
} }

View File

@ -136,10 +136,9 @@ extension ReportViewModel {
suffixes.append(reason.rawValue) suffixes.append(reason.rawValue)
case .violateRule: case .violateRule:
suffixes.append(reason.rawValue) suffixes.append(reason.rawValue)
if let rule = self.reportServerRulesViewModel.selectRule {
for rule in self.reportServerRulesViewModel.selectRules {
suffixes.append(rule.text) suffixes.append(rule.text)
} else {
assertionFailure("should select valid rule")
} }
case .dislike: case .dislike:
assertionFailure("should not enter the report flow") assertionFailure("should not enter the report flow")
@ -178,8 +177,8 @@ extension ReportViewModel {
ruleIDs: { ruleIDs: {
switch self.reportReasonViewModel.selectReason { switch self.reportReasonViewModel.selectReason {
case .violateRule: case .violateRule:
guard let rule = self.reportServerRulesViewModel.selectRule else { return nil } let ruleIDs = self.reportServerRulesViewModel.selectRules.map { $0.id }.sorted()
return [rule.id] return ruleIDs
default: default:
return nil return nil
} }

View File

@ -41,9 +41,7 @@ struct ReportReasonView: View {
EmptyView() EmptyView()
default: default:
ReportReasonRowView(reason: reason, isSelect: reason == viewModel.selectReason) ReportReasonRowView(reason: reason, isSelect: reason == viewModel.selectReason)
.background( .contentShape(Rectangle())
Color(viewModel.backgroundColor)
)
.onTapGesture { .onTapGesture {
viewModel.selectReason = reason viewModel.selectReason = reason
} }

View File

@ -138,14 +138,15 @@ struct ReportActionButton: View {
ZStack { ZStack {
ProgressView() ProgressView()
.opacity(isBusy ? 1 : 0) .opacity(isBusy ? 1 : 0)
.progressViewStyle(CircularProgressViewStyle(tint: .gray))
Text(title) Text(title)
.font(.headline) .font(.headline)
.foregroundColor(Color(Asset.Colors.Label.primary.color)) .foregroundColor(Color(UIColor.black))
.opacity(isBusy ? 0 : 1) .opacity(isBusy ? 0 : 1)
} }
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
.padding() .padding()
.background(Color(UIColor.systemBackground)) .background(Color(UIColor.white)) // using white for Light & Dark
.cornerRadius(10) .cornerRadius(10)
.shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 1) .shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 1)
} }

View File

@ -37,27 +37,19 @@ struct ReportServerRulesView: View {
ForEach(viewModel.serverRules, id: \.self) { rule in ForEach(viewModel.serverRules, id: \.self) { rule in
ReportServerRulesRowView( ReportServerRulesRowView(
title: rule.text, title: rule.text,
isSelect: rule == viewModel.selectRule isSelect: viewModel.selectRules.contains(rule)
) )
.background( .background(
Color(viewModel.backgroundColor) Color(viewModel.backgroundColor)
) )
.onTapGesture { .onTapGesture {
viewModel.selectRule = rule if viewModel.selectRules.contains(rule) {
viewModel.isDislike = false viewModel.selectRules.remove(rule)
} else {
viewModel.selectRules.insert(rule)
}
} }
} }
ReportServerRulesRowView(
title: L10n.Scene.Report.StepTwo.iJustDonTLikeIt,
isSelect: viewModel.isDislike
)
.background(
Color(viewModel.backgroundColor)
)
.onTapGesture {
viewModel.selectRule = nil
viewModel.isDislike = true
}
} }
.padding() .padding()
.transition(.opacity) .transition(.opacity)
@ -80,7 +72,7 @@ struct ReportServerRulesRowView: View {
var body: some View { var body: some View {
HStack(spacing: 14) { HStack(spacing: 14) {
Image(systemName: isSelect ? "checkmark.circle.fill" : "circle") Image(systemName: isSelect ? "checkmark.square.fill" : "square")
.resizable() .resizable()
.frame(width: 28, height: 28, alignment: .center) .frame(width: 28, height: 28, alignment: .center)
VStack(alignment: .leading, spacing: 4) { VStack(alignment: .leading, spacing: 4) {

View File

@ -88,13 +88,10 @@ extension ReportServerRulesViewController {
} }
.store(in: &observations) .store(in: &observations)
Publishers.CombineLatest( viewModel.$selectRules
viewModel.$selectRule, .map { !$0.isEmpty }
viewModel.$isDislike .assign(to: \.isEnabled, on: navigationActionView.nextButton)
) .store(in: &disposeBag)
.map { $0 != nil || $1 }
.assign(to: \.isEnabled, on: navigationActionView.nextButton)
.store(in: &disposeBag)
navigationActionView.nextButton.addTarget(self, action: #selector(ReportServerRulesViewController.nextButtonPressed(_:)), for: .touchUpInside) navigationActionView.nextButton.addTarget(self, action: #selector(ReportServerRulesViewController.nextButtonPressed(_:)), for: .touchUpInside)
} }

View File

@ -25,8 +25,7 @@ final class ReportServerRulesViewModel: ObservableObject {
@Published var backgroundColor: UIColor = Asset.Scene.Report.background.color @Published var backgroundColor: UIColor = Asset.Scene.Report.background.color
// output // output
@Published var selectRule: Mastodon.Entity.Instance.Rule? @Published var selectRules: Set<Mastodon.Entity.Instance.Rule> = Set()
@Published var isDislike: Bool = false
init(context: AppContext) { init(context: AppContext) {
self.context = context self.context = context

View File

@ -86,15 +86,17 @@ extension ReportStatusTableViewCell {
separatorLine.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), separatorLine.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
separatorLine.heightAnchor.constraint(equalToConstant: UIView.separatorLineHeight(of: contentView)).priority(.required - 1), separatorLine.heightAnchor.constraint(equalToConstant: UIView.separatorLineHeight(of: contentView)).priority(.required - 1),
]) ])
statusView.isUserInteractionEnabled = false
} }
override func setSelected(_ selected: Bool, animated: Bool) { override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated) super.setSelected(selected, animated: animated)
if selected { if selected {
checkbox.image = UIImage(systemName: "checkmark.circle.fill") checkbox.image = UIImage(systemName: "checkmark.square.fill")
checkbox.tintColor = Asset.Colors.Label.primary.color checkbox.tintColor = Asset.Colors.Label.primary.color
} else { } else {
checkbox.image = UIImage(systemName: "circle") checkbox.image = UIImage(systemName: "square")
checkbox.tintColor = Asset.Colors.Label.secondary.color checkbox.tintColor = Asset.Colors.Label.secondary.color
} }
} }