Adjust Server Rules Screen (IOS-220) (#1251)
* Adjust Server Rules Screen (IOS-220) * Update Server Rules (IOS-220) * Use new server rules UI in Server Details (IOS-220) * Improve disclaimer usage (IOS-220) * Fix background in server details (IOS-220)
This commit is contained in:
parent
62cc9105a9
commit
484d72fbdd
|
@ -417,8 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "privacy policy",
|
"privacy_policy": "privacy policy",
|
||||||
|
|
|
@ -417,8 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "privacy policy",
|
"privacy_policy": "privacy policy",
|
||||||
|
|
|
@ -417,8 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "privacy policy",
|
"privacy_policy": "privacy policy",
|
||||||
|
|
|
@ -417,8 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "privacy policy",
|
"privacy_policy": "privacy policy",
|
||||||
|
|
|
@ -417,8 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "privacy policy",
|
"privacy_policy": "privacy policy",
|
||||||
|
|
|
@ -417,8 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "privacy policy",
|
"privacy_policy": "privacy policy",
|
||||||
|
|
|
@ -416,8 +416,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "privacy policy",
|
"privacy_policy": "privacy policy",
|
||||||
|
|
|
@ -417,8 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "գաղտնիութեան քաղաքականութիւն",
|
"privacy_policy": "գաղտնիութեան քաղաքականութիւն",
|
||||||
|
|
|
@ -417,8 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "zasady użytkowania",
|
"terms_of_service": "zasady użytkowania",
|
||||||
"privacy_policy": "polityka prywatności",
|
"privacy_policy": "polityka prywatności",
|
||||||
|
|
|
@ -418,7 +418,7 @@
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Algumas regras básicas.",
|
"title": "Algumas regras básicas.",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "privacy policy",
|
"privacy_policy": "privacy policy",
|
||||||
|
|
|
@ -417,8 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "privacy policy",
|
"privacy_policy": "privacy policy",
|
||||||
|
|
|
@ -417,8 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "සේවාවේ නියම",
|
"terms_of_service": "සේවාවේ නියම",
|
||||||
"privacy_policy": "රහස්යතා ප්රතිපත්තිය",
|
"privacy_policy": "රහස්යතා ප්රතිපත්තිය",
|
||||||
|
|
|
@ -435,13 +435,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"server_rules": {
|
"server_rules": {
|
||||||
"title": "Some ground rules.",
|
"title": "Server Rules",
|
||||||
"subtitle": "These are set and enforced by the %s moderators.",
|
"subtitle": "By continuing, you agree to follow by the following rules set and enforced by the **%s** moderators.",
|
||||||
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
"prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.",
|
||||||
"terms_of_service": "terms of service",
|
"terms_of_service": "terms of service",
|
||||||
"privacy_policy": "privacy policy",
|
"privacy_policy": "privacy policy",
|
||||||
"button": {
|
"button": {
|
||||||
"confirm": "I Agree"
|
"confirm": "I Agree",
|
||||||
|
"disagree": "Disagree"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"confirm_email": {
|
"confirm_email": {
|
||||||
|
|
|
@ -409,8 +409,7 @@ private extension SceneCoordinator {
|
||||||
_viewController.viewModel = viewModel
|
_viewController.viewModel = viewModel
|
||||||
viewController = _viewController
|
viewController = _viewController
|
||||||
case .mastodonServerRules(let viewModel):
|
case .mastodonServerRules(let viewModel):
|
||||||
let _viewController = MastodonServerRulesViewController()
|
let _viewController = MastodonServerRulesViewController(viewModel: viewModel)
|
||||||
_viewController.viewModel = viewModel
|
|
||||||
viewController = _viewController
|
viewController = _viewController
|
||||||
case .mastodonConfirmEmail(let viewModel):
|
case .mastodonConfirmEmail(let viewModel):
|
||||||
let _viewController = MastodonConfirmEmailViewController()
|
let _viewController = MastodonConfirmEmailViewController()
|
||||||
|
|
|
@ -13,22 +13,121 @@ import MetaTextKit
|
||||||
import MastodonAsset
|
import MastodonAsset
|
||||||
import MastodonCore
|
import MastodonCore
|
||||||
import MastodonLocalization
|
import MastodonLocalization
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
final class MastodonServerRulesViewController: UIViewController, NeedsDependency {
|
struct MastodonServerRulesView: View {
|
||||||
|
class ViewModel: ObservableObject {
|
||||||
|
let disclaimer: LocalizedStringKey?
|
||||||
|
let rules: [String]
|
||||||
|
var onAgree: (() -> Void)?
|
||||||
|
var onDisagree: (() -> Void)?
|
||||||
|
|
||||||
|
init(disclaimer: LocalizedStringKey?, rules: [String], onAgree: (() -> Void)?, onDisagree: (() -> Void)?) {
|
||||||
|
self.disclaimer = disclaimer
|
||||||
|
self.rules = rules
|
||||||
|
self.onAgree = onAgree
|
||||||
|
self.onDisagree = onDisagree
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate static var empty: ViewModel {
|
||||||
|
return .init(disclaimer: nil, rules: [], onAgree: nil, onDisagree: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ObservedObject var viewModel: ViewModel = .empty
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ScrollView {
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
if let disclaimer = viewModel.disclaimer {
|
||||||
|
Text(disclaimer)
|
||||||
|
.padding(.bottom, 30)
|
||||||
|
}
|
||||||
|
|
||||||
|
ForEach(Array(viewModel.rules.enumerated()), id: \.offset) { index, rule in
|
||||||
|
ZStack(alignment: .topLeading) {
|
||||||
|
Text("\(index + 1)")
|
||||||
|
.font(.system(size: UIFontMetrics.default.scaledValue(for: 24), weight: .bold))
|
||||||
|
.foregroundStyle(Asset.Colors.Brand.blurple.swiftUIColor)
|
||||||
|
Text(rule)
|
||||||
|
.padding(.leading, 30)
|
||||||
|
}
|
||||||
|
.padding(.bottom, 30)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
.safeAreaInset(edge: .bottom) {
|
||||||
|
if viewModel.onDisagree != nil || viewModel.onAgree != nil {
|
||||||
|
VStack {
|
||||||
|
if let onDisagree = viewModel.onDisagree {
|
||||||
|
Button(role: .cancel) {
|
||||||
|
onDisagree()
|
||||||
|
} label: {
|
||||||
|
Text(L10n.Scene.ServerRules.Button.disagree)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
}
|
||||||
|
.buttonStyle(.borderedProminent)
|
||||||
|
.tint(.clear)
|
||||||
|
.foregroundStyle(Asset.Colors.Brand.blurple.swiftUIColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let onAgree = viewModel.onAgree {
|
||||||
|
Button {
|
||||||
|
onAgree()
|
||||||
|
} label: {
|
||||||
|
Text(L10n.Scene.ServerRules.Button.confirm)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.bold()
|
||||||
|
}
|
||||||
|
.buttonStyle(.borderedProminent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.controlSize(.large)
|
||||||
|
.padding()
|
||||||
|
.background(.ultraThinMaterial)
|
||||||
|
.tint(Asset.Colors.Brand.blurple.swiftUIColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct MastodonServerRulesButton: View {
|
||||||
|
let text: LocalizedStringKey
|
||||||
|
let action: () -> Void
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Button(action: action) {
|
||||||
|
Text(text)
|
||||||
|
.frame(height: 44)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
}
|
||||||
|
.font(Font(UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 16, weight: .semibold))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class MastodonServerRulesViewController: UIHostingController<MastodonServerRulesView>, NeedsDependency {
|
||||||
|
|
||||||
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
||||||
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
||||||
|
|
||||||
var viewModel: MastodonServerRulesViewModel!
|
private var viewModel: MastodonServerRulesViewModel!
|
||||||
|
|
||||||
let tableView: UITableView = {
|
init(viewModel: MastodonServerRulesViewModel) {
|
||||||
let tableView = UITableView(frame: .zero, style: .insetGrouped)
|
super.init(rootView: MastodonServerRulesView())
|
||||||
tableView.register(ServerRulesTableViewCell.self, forCellReuseIdentifier: String(describing: ServerRulesTableViewCell.self))
|
self.viewModel = viewModel
|
||||||
tableView.rowHeight = UITableView.automaticDimension
|
self.rootView.viewModel = .init(
|
||||||
tableView.keyboardDismissMode = .onDrag
|
disclaimer: LocalizedStringKey(L10n.Scene.ServerRules.subtitle(viewModel.domain)),
|
||||||
tableView.sectionHeaderTopPadding = 0
|
rules: viewModel.rules.map({ $0.text }),
|
||||||
return tableView
|
onAgree: { self.nextButtonPressed(nil) },
|
||||||
}()
|
onDisagree: { self.backButtonPressed(nil) })
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required dynamic init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MastodonServerRulesViewController {
|
extension MastodonServerRulesViewController {
|
||||||
|
@ -39,33 +138,17 @@ extension MastodonServerRulesViewController {
|
||||||
setupOnboardingAppearance()
|
setupOnboardingAppearance()
|
||||||
defer { setupNavigationBarBackgroundView() }
|
defer { setupNavigationBarBackgroundView() }
|
||||||
|
|
||||||
tableView.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
view.addSubview(tableView)
|
|
||||||
tableView.pinToParent()
|
|
||||||
|
|
||||||
tableView.delegate = self
|
|
||||||
viewModel.setupDiffableDataSource(tableView: tableView)
|
|
||||||
|
|
||||||
navigationItem.largeTitleDisplayMode = .always
|
navigationItem.largeTitleDisplayMode = .always
|
||||||
|
|
||||||
navigationItem.rightBarButtonItem = UIBarButtonItem(title: L10n.Scene.ServerRules.Button.confirm, style: .done, target: self, action: #selector(MastodonServerRulesViewController.nextButtonPressed(_:)))
|
|
||||||
title = L10n.Scene.ServerRules.title
|
title = L10n.Scene.ServerRules.title
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
|
||||||
super.viewDidAppear(animated)
|
|
||||||
|
|
||||||
tableView.flashScrollIndicators()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MastodonServerRulesViewController {
|
extension MastodonServerRulesViewController {
|
||||||
@objc private func backButtonPressed(_ sender: UIButton) {
|
@objc private func backButtonPressed(_ sender: UIButton?) {
|
||||||
navigationController?.popViewController(animated: true)
|
navigationController?.popViewController(animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func nextButtonPressed(_ sender: UIButton) {
|
@objc private func nextButtonPressed(_ sender: UIButton?) {
|
||||||
let domain = viewModel.domain
|
let domain = viewModel.domain
|
||||||
let viewModel = PrivacyViewModel(domain: domain, authenticateInfo: viewModel.authenticateInfo, rows: [.iOSApp, .server(domain: domain)], instance: viewModel.instance, applicationToken: viewModel.applicationToken)
|
let viewModel = PrivacyViewModel(domain: domain, authenticateInfo: viewModel.authenticateInfo, rows: [.iOSApp, .server(domain: domain)], instance: viewModel.instance, applicationToken: viewModel.applicationToken)
|
||||||
|
|
||||||
|
@ -75,28 +158,3 @@ extension MastodonServerRulesViewController {
|
||||||
|
|
||||||
// MARK: - OnboardingViewControllerAppearance
|
// MARK: - OnboardingViewControllerAppearance
|
||||||
extension MastodonServerRulesViewController: OnboardingViewControllerAppearance { }
|
extension MastodonServerRulesViewController: OnboardingViewControllerAppearance { }
|
||||||
|
|
||||||
// MARK: - UITableViewDelegate
|
|
||||||
extension MastodonServerRulesViewController: UITableViewDelegate {
|
|
||||||
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
|
||||||
let wrapper = UIView()
|
|
||||||
|
|
||||||
let label = UILabel()
|
|
||||||
label.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
label.font = MastodonPickServerViewController.subTitleFont
|
|
||||||
label.textColor = Asset.Colors.Label.primary.color
|
|
||||||
label.adjustsFontForContentSizeCategory = true
|
|
||||||
label.numberOfLines = 0
|
|
||||||
label.text = L10n.Scene.ServerRules.subtitle(viewModel.domain)
|
|
||||||
wrapper.addSubview(label)
|
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
label.topAnchor.constraint(equalTo: wrapper.topAnchor, constant: 16),
|
|
||||||
label.leadingAnchor.constraint(equalTo: wrapper.leadingAnchor),
|
|
||||||
wrapper.trailingAnchor.constraint(equalTo: label.trailingAnchor),
|
|
||||||
wrapper.bottomAnchor.constraint(equalTo: label.bottomAnchor, constant: 16),
|
|
||||||
])
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,57 +2,37 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import MastodonSDK
|
import MastodonSDK
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
protocol InstanceRulesViewControllerDelegate: AnyObject {
|
protocol InstanceRulesViewControllerDelegate: AnyObject {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class InstanceRulesViewController: UIViewController {
|
struct InstanceRulesView: View {
|
||||||
|
|
||||||
weak var delegate: InstanceRulesViewControllerDelegate?
|
var rulesView = MastodonServerRulesView()
|
||||||
let tableView: UITableView
|
|
||||||
var dataSource: UITableViewDiffableDataSource<ServerRuleSection, ServerRuleItem>?
|
|
||||||
|
|
||||||
var sections: [ServerRuleSection] = []
|
var body: some View {
|
||||||
|
rulesView
|
||||||
|
.padding([.top], 16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InstanceRulesViewController: UIHostingController<InstanceRulesView> {
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
tableView = UITableView(frame: .zero, style: .insetGrouped)
|
super.init(rootView: InstanceRulesView())
|
||||||
tableView.translatesAutoresizingMaskIntoConstraints = false
|
view.backgroundColor = .systemGroupedBackground
|
||||||
tableView.register(ServerRulesTableViewCell.self, forCellReuseIdentifier: ServerRulesTableViewCell.reuseIdentifier)
|
|
||||||
|
|
||||||
super.init(nibName: nil, bundle: nil)
|
|
||||||
view.addSubview(tableView)
|
|
||||||
|
|
||||||
let dataSource = ServerRuleSection.tableViewDiffableDataSource(tableView: tableView)
|
|
||||||
|
|
||||||
tableView.dataSource = dataSource
|
|
||||||
self.dataSource = dataSource
|
|
||||||
|
|
||||||
setupConstraints()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||||
|
|
||||||
private func setupConstraints() {
|
|
||||||
let constraints = [
|
|
||||||
tableView.topAnchor.constraint(equalTo: view.topAnchor),
|
|
||||||
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
||||||
view.trailingAnchor.constraint(equalTo: tableView.trailingAnchor),
|
|
||||||
view.bottomAnchor.constraint(equalTo: tableView.bottomAnchor),
|
|
||||||
]
|
|
||||||
|
|
||||||
NSLayoutConstraint.activate(constraints)
|
|
||||||
}
|
|
||||||
|
|
||||||
func update(with instance: Mastodon.Entity.V2.Instance) {
|
func update(with instance: Mastodon.Entity.V2.Instance) {
|
||||||
guard let dataSource, let rules = instance.rules, rules.isNotEmpty else { return }
|
self.rootView.rulesView.viewModel = .init(
|
||||||
|
disclaimer: nil,
|
||||||
var snapshot = NSDiffableDataSourceSnapshot<ServerRuleSection, ServerRuleItem>()
|
rules: instance.rules?.map({ $0.text }) ?? [],
|
||||||
|
onAgree: nil,
|
||||||
snapshot.appendSections([.rules])
|
onDisagree: nil
|
||||||
let ruleItems = rules.enumerated().compactMap { index, rule in ServerRuleItem.rule(index: index, rule: rule) }
|
)
|
||||||
snapshot.appendItems(ruleItems, toSection: .rules)
|
|
||||||
|
|
||||||
dataSource.apply(snapshot)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ class ServerDetailsViewController: UIViewController {
|
||||||
weak var delegate: (ServerDetailsViewControllerDelegate & AboutInstanceViewControllerDelegate & InstanceRulesViewControllerDelegate & MetaLabelDelegate)? {
|
weak var delegate: (ServerDetailsViewControllerDelegate & AboutInstanceViewControllerDelegate & InstanceRulesViewControllerDelegate & MetaLabelDelegate)? {
|
||||||
didSet {
|
didSet {
|
||||||
aboutInstanceViewController.delegate = delegate
|
aboutInstanceViewController.delegate = delegate
|
||||||
instanceRulesViewController.delegate = delegate
|
|
||||||
aboutInstanceViewController.footerView.contentLabel.linkDelegate = delegate
|
aboutInstanceViewController.footerView.contentLabel.linkDelegate = delegate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1455,17 +1455,19 @@ public enum L10n {
|
||||||
public static func prompt(_ p1: Any) -> String {
|
public static func prompt(_ p1: Any) -> String {
|
||||||
return L10n.tr("Localizable", "Scene.ServerRules.Prompt", String(describing: p1), fallback: "By continuing, you’re subject to the terms of service and privacy policy for %@.")
|
return L10n.tr("Localizable", "Scene.ServerRules.Prompt", String(describing: p1), fallback: "By continuing, you’re subject to the terms of service and privacy policy for %@.")
|
||||||
}
|
}
|
||||||
/// These are set and enforced by the %@ moderators.
|
/// By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.
|
||||||
public static func subtitle(_ p1: Any) -> String {
|
public static func subtitle(_ p1: Any) -> String {
|
||||||
return L10n.tr("Localizable", "Scene.ServerRules.Subtitle", String(describing: p1), fallback: "These are set and enforced by the %@ moderators.")
|
return L10n.tr("Localizable", "Scene.ServerRules.Subtitle", String(describing: p1), fallback: "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.")
|
||||||
}
|
}
|
||||||
/// terms of service
|
/// terms of service
|
||||||
public static let termsOfService = L10n.tr("Localizable", "Scene.ServerRules.TermsOfService", fallback: "terms of service")
|
public static let termsOfService = L10n.tr("Localizable", "Scene.ServerRules.TermsOfService", fallback: "terms of service")
|
||||||
/// Some ground rules.
|
/// Server Rules
|
||||||
public static let title = L10n.tr("Localizable", "Scene.ServerRules.Title", fallback: "Some ground rules.")
|
public static let title = L10n.tr("Localizable", "Scene.ServerRules.Title", fallback: "Server Rules")
|
||||||
public enum Button {
|
public enum Button {
|
||||||
/// I Agree
|
/// I Agree
|
||||||
public static let confirm = L10n.tr("Localizable", "Scene.ServerRules.Button.Confirm", fallback: "I Agree")
|
public static let confirm = L10n.tr("Localizable", "Scene.ServerRules.Button.Confirm", fallback: "I Agree")
|
||||||
|
/// Disagree
|
||||||
|
public static let disagree = L10n.tr("Localizable", "Scene.ServerRules.Button.Disagree", fallback: "Disagree")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public enum Settings {
|
public enum Settings {
|
||||||
|
|
|
@ -501,11 +501,12 @@ uploaded to Mastodon.";
|
||||||
"Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "Manual Review";
|
"Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "Manual Review";
|
||||||
"Scene.ServerPicker.Title" = "Pick Server";
|
"Scene.ServerPicker.Title" = "Pick Server";
|
||||||
"Scene.ServerRules.Button.Confirm" = "I Agree";
|
"Scene.ServerRules.Button.Confirm" = "I Agree";
|
||||||
|
"Scene.ServerRules.Button.Disagree" = "Disagree";
|
||||||
"Scene.ServerRules.PrivacyPolicy" = "privacy policy";
|
"Scene.ServerRules.PrivacyPolicy" = "privacy policy";
|
||||||
"Scene.ServerRules.Prompt" = "By continuing, you’re subject to the terms of service and privacy policy for %@.";
|
"Scene.ServerRules.Prompt" = "By continuing, you’re subject to the terms of service and privacy policy for %@.";
|
||||||
"Scene.ServerRules.Subtitle" = "These are set and enforced by the %@ moderators.";
|
"Scene.ServerRules.Subtitle" = "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.";
|
||||||
"Scene.ServerRules.TermsOfService" = "terms of service";
|
"Scene.ServerRules.TermsOfService" = "terms of service";
|
||||||
"Scene.ServerRules.Title" = "Some ground rules.";
|
"Scene.ServerRules.Title" = "Server Rules";
|
||||||
"Scene.Settings.AboutMastodon.ClearMediaStorage" = "Clear Media Storage";
|
"Scene.Settings.AboutMastodon.ClearMediaStorage" = "Clear Media Storage";
|
||||||
"Scene.Settings.AboutMastodon.ContributeToMastodon" = "Contribute to Mastodon";
|
"Scene.Settings.AboutMastodon.ContributeToMastodon" = "Contribute to Mastodon";
|
||||||
"Scene.Settings.AboutMastodon.MoreSettings" = "Even More Settings";
|
"Scene.Settings.AboutMastodon.MoreSettings" = "Even More Settings";
|
||||||
|
|
|
@ -491,9 +491,9 @@ uploaded to Mastodon.";
|
||||||
"Scene.ServerRules.Button.Confirm" = "I Agree";
|
"Scene.ServerRules.Button.Confirm" = "I Agree";
|
||||||
"Scene.ServerRules.PrivacyPolicy" = "privacy policy";
|
"Scene.ServerRules.PrivacyPolicy" = "privacy policy";
|
||||||
"Scene.ServerRules.Prompt" = "By continuing, you’re subject to the terms of service and privacy policy for %@.";
|
"Scene.ServerRules.Prompt" = "By continuing, you’re subject to the terms of service and privacy policy for %@.";
|
||||||
"Scene.ServerRules.Subtitle" = "These are set and enforced by the %@ moderators.";
|
"Scene.ServerRules.Subtitle" = "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.";
|
||||||
"Scene.ServerRules.TermsOfService" = "terms of service";
|
"Scene.ServerRules.TermsOfService" = "terms of service";
|
||||||
"Scene.ServerRules.Title" = "Some ground rules.";
|
"Scene.ServerRules.Title" = "Server Rules";
|
||||||
"Scene.Settings.AboutMastodon.ClearMediaStorage" = "Clear Media Storage";
|
"Scene.Settings.AboutMastodon.ClearMediaStorage" = "Clear Media Storage";
|
||||||
"Scene.Settings.AboutMastodon.ContributeToMastodon" = "Contribute to Mastodon";
|
"Scene.Settings.AboutMastodon.ContributeToMastodon" = "Contribute to Mastodon";
|
||||||
"Scene.Settings.AboutMastodon.MoreSettings" = "Even More Settings";
|
"Scene.Settings.AboutMastodon.MoreSettings" = "Even More Settings";
|
||||||
|
|
|
@ -486,9 +486,9 @@ uploaded to Mastodon.";
|
||||||
"Scene.ServerRules.Button.Confirm" = "I Agree";
|
"Scene.ServerRules.Button.Confirm" = "I Agree";
|
||||||
"Scene.ServerRules.PrivacyPolicy" = "privacy policy";
|
"Scene.ServerRules.PrivacyPolicy" = "privacy policy";
|
||||||
"Scene.ServerRules.Prompt" = "By continuing, you’re subject to the terms of service and privacy policy for %@.";
|
"Scene.ServerRules.Prompt" = "By continuing, you’re subject to the terms of service and privacy policy for %@.";
|
||||||
"Scene.ServerRules.Subtitle" = "These are set and enforced by the %@ moderators.";
|
"Scene.ServerRules.Subtitle" = "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.";
|
||||||
"Scene.ServerRules.TermsOfService" = "terms of service";
|
"Scene.ServerRules.TermsOfService" = "terms of service";
|
||||||
"Scene.ServerRules.Title" = "Some ground rules.";
|
"Scene.ServerRules.Title" = "Server Rules";
|
||||||
"Scene.Settings.AboutMastodon.ClearMediaStorage" = "Clear Media Storage";
|
"Scene.Settings.AboutMastodon.ClearMediaStorage" = "Clear Media Storage";
|
||||||
"Scene.Settings.AboutMastodon.ContributeToMastodon" = "Contribute to Mastodon";
|
"Scene.Settings.AboutMastodon.ContributeToMastodon" = "Contribute to Mastodon";
|
||||||
"Scene.Settings.AboutMastodon.MoreSettings" = "Even More Settings";
|
"Scene.Settings.AboutMastodon.MoreSettings" = "Even More Settings";
|
||||||
|
|
|
@ -491,9 +491,9 @@ uploaded to Mastodon.";
|
||||||
"Scene.ServerRules.Button.Confirm" = "Համաձայն եմ";
|
"Scene.ServerRules.Button.Confirm" = "Համաձայն եմ";
|
||||||
"Scene.ServerRules.PrivacyPolicy" = "գաղտնիութեան քաղաքականութիւն";
|
"Scene.ServerRules.PrivacyPolicy" = "գաղտնիութեան քաղաքականութիւն";
|
||||||
"Scene.ServerRules.Prompt" = "By continuing, you’re subject to the terms of service and privacy policy for %@.";
|
"Scene.ServerRules.Prompt" = "By continuing, you’re subject to the terms of service and privacy policy for %@.";
|
||||||
"Scene.ServerRules.Subtitle" = "These are set and enforced by the %@ moderators.";
|
"Scene.ServerRules.Subtitle" = "By continuing, you agree to follow by the following rules set and enforced by the **%@** moderators.";
|
||||||
"Scene.ServerRules.TermsOfService" = "terms of service";
|
"Scene.ServerRules.TermsOfService" = "terms of service";
|
||||||
"Scene.ServerRules.Title" = "Some ground rules.";
|
"Scene.ServerRules.Title" = "Server Rules";
|
||||||
"Scene.Settings.AboutMastodon.ClearMediaStorage" = "Clear Media Storage";
|
"Scene.Settings.AboutMastodon.ClearMediaStorage" = "Clear Media Storage";
|
||||||
"Scene.Settings.AboutMastodon.ContributeToMastodon" = "Contribute to Mastodon";
|
"Scene.Settings.AboutMastodon.ContributeToMastodon" = "Contribute to Mastodon";
|
||||||
"Scene.Settings.AboutMastodon.MoreSettings" = "Even More Settings";
|
"Scene.Settings.AboutMastodon.MoreSettings" = "Even More Settings";
|
||||||
|
|
Loading…
Reference in New Issue