Settings about section (#1041)

* Fixes #1011 - Add legal information screen in settings, move all settings related screens under Source/Screen/Settings
* Fix warnings after sliding sync api change
This commit is contained in:
Stefan Ceriu
2023-06-07 17:04:42 +03:00
committed by GitHub
parent c0611b4e6b
commit 8ff5c6144c
27 changed files with 408 additions and 123 deletions
@@ -0,0 +1,30 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Combine
import SwiftUI
final class AnalyticsSettingsScreenCoordinator: CoordinatorProtocol {
private let viewModel: AnalyticsSettingsScreenViewModel
init() {
viewModel = AnalyticsSettingsScreenViewModel()
}
func toPresentable() -> AnyView {
AnyView(AnalyticsSettingsScreen(context: viewModel.context))
}
}
@@ -0,0 +1,46 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
struct AnalyticsSettingsScreenViewState: BindableState {
/// Attributed strings created from localized HTML.
let strings: AnalyticsSettingsScreenStrings
var bindings: AnalyticsSettingsScreenViewStateBindings
}
struct AnalyticsSettingsScreenViewStateBindings {
var enableAnalytics: Bool
}
enum AnalyticsSettingsScreenViewAction {
case toggleAnalytics
}
struct AnalyticsSettingsScreenStrings {
let sectionFooter: AttributedString
init(termsURL: URL) {
let content = AttributedString(L10n.screenAnalyticsSettingsHelpUsImprove(InfoPlistReader.main.bundleDisplayName))
// Create the 'read terms' with a placeholder.
let linkPlaceholder = "{link}"
var readTerms = AttributedString(L10n.screenAnalyticsSettingsReadTerms(linkPlaceholder))
readTerms.replace(linkPlaceholder,
with: L10n.screenAnalyticsSettingsReadTermsContentLink,
asLinkTo: termsURL)
sectionFooter = content + "\n\n" + readTerms
}
}
@@ -0,0 +1,46 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Combine
import SwiftUI
typealias AnalyticsSettingsScreenViewModelType = StateStoreViewModel<AnalyticsSettingsScreenViewState, AnalyticsSettingsScreenViewAction>
class AnalyticsSettingsScreenViewModel: AnalyticsSettingsScreenViewModelType, AnalyticsSettingsScreenViewModelProtocol {
init() {
let strings = AnalyticsSettingsScreenStrings(termsURL: ServiceLocator.shared.settings.analyticsConfiguration.termsURL)
let bindings = AnalyticsSettingsScreenViewStateBindings(enableAnalytics: ServiceLocator.shared.analytics.isEnabled)
let state = AnalyticsSettingsScreenViewState(strings: strings, bindings: bindings)
super.init(initialViewState: state)
ServiceLocator.shared.settings.$analyticsConsentState
.map { $0 == .optedIn }
.weakAssign(to: \.state.bindings.enableAnalytics, on: self)
.store(in: &cancellables)
}
override func process(viewAction: AnalyticsSettingsScreenViewAction) {
switch viewAction {
case .toggleAnalytics:
if ServiceLocator.shared.analytics.isEnabled {
ServiceLocator.shared.analytics.optOut()
} else {
ServiceLocator.shared.analytics.optIn()
}
}
}
}
@@ -0,0 +1,22 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Combine
@MainActor
protocol AnalyticsSettingsScreenViewModelProtocol {
var context: AnalyticsSettingsScreenViewModelType.Context { get }
}
@@ -0,0 +1,56 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import SwiftUI
struct AnalyticsSettingsScreen: View {
@ObservedObject var context: AnalyticsSettingsScreenViewModel.Context
var body: some View {
Form {
analyticsSection
}
.compoundForm()
.navigationTitle(L10n.commonAnalytics)
.navigationBarTitleDisplayMode(.inline)
}
var analyticsSection: some View {
Section {
Toggle(isOn: $context.enableAnalytics) {
Label(L10n.screenAnalyticsSettingsShareData, systemImage: "chart.bar")
}
.toggleStyle(.compoundForm)
.onChange(of: context.enableAnalytics) { _ in
context.send(viewAction: .toggleAnalytics)
}
} footer: {
Text(context.viewState.strings.sectionFooter)
.compoundFormSectionFooter()
.tint(.compound.textLinkExternal)
}
.compoundFormSection()
}
}
// MARK: - Previews
struct AnalyticsSettingsScreen_Previews: PreviewProvider {
static var previews: some View {
let viewModel = AnalyticsSettingsScreenViewModel()
AnalyticsSettingsScreen(context: viewModel.context)
}
}