MESSENGER-4565 Added new developer settings options

This commit is contained in:
Arnfried Griesert
2023-09-19 11:59:20 +00:00
parent e3cfb301a9
commit 49fa198de5
9 changed files with 520 additions and 1 deletions

View File

@@ -52,6 +52,16 @@
"bwi_settings_developer_restrict_user" = "Nutzer einschränken";
"bwi_settings_developer_unrestrict_user" = "Nutzereinschränkung aufheben";
"bwi_settings_developer_unmark_banner" = "Banner als nicht gelesen markieren";
"bwi_settings_developer_well_known" = "Well-Known";
"bwi_settings_developer_capabilities" = "Capabilities";
"bwi_settings_developer_maintenance" = "Maintenance";
"bwi_settings_developer_user_account_data" = "Account Data";
"bwi_settings_developer_user_account_data_type" = "Type";
"bwi_settings_developer_key_backup" = "Key Backup";
"bwi_settings_developer_key_backup_algorithm" = "Algorithmus";
"bwi_settings_developer_key_backup_count" = "Gespeicherte Schlüssel";
"bwi_settings_developer_key_backup_etag" = "ETag";
"bwi_settings_developer_key_backup_version" = "Version";
// MARK: - MDM

View File

@@ -53,6 +53,16 @@
"bwi_settings_developer_restrict_user" = "Restrict user";
"bwi_settings_developer_unrestrict_user" = "Remove user restriction";
"bwi_settings_developer_unmark_banner" = "Unmark Feature Banner";
"bwi_settings_developer_well_known" = "Well-Known";
"bwi_settings_developer_capabilities" = "Capabilities";
"bwi_settings_developer_maintenance" = "Maintenance";
"bwi_settings_developer_user_account_data" = "Account Data";
"bwi_settings_developer_user_account_data_type" = "Type";
"bwi_settings_developer_key_backup" = "Key Backup";
"bwi_settings_developer_key_backup_algorithm" = "Algorithm";
"bwi_settings_developer_key_backup_count" = "Stored Keys";
"bwi_settings_developer_key_backup_etag" = "ETag";
"bwi_settings_developer_key_backup_version" = "Version";
// MARK: - MDM

View File

@@ -94,6 +94,33 @@ struct DeveloperSettingsView: View {
}
}
}
SwiftUI.Section {
NavigationLink {
WellKnownView(session: session)
} label: {
Text(BWIL10n.bwiSettingsDeveloperWellKnown)
}
NavigationLink {
ServerCapabilitiesView(session: session)
} label: {
Text(BWIL10n.bwiSettingsDeveloperCapabilities)
}
NavigationLink {
MaintenanceView(session: session)
} label: {
Text(BWIL10n.bwiSettingsDeveloperMaintenance)
}
NavigationLink {
UserAccountDataView(session: session)
} label: {
Text(BWIL10n.bwiSettingsDeveloperUserAccountData)
}
NavigationLink {
ServerSideKeyBackupView(session: session)
} label: {
Text(BWIL10n.bwiSettingsDeveloperKeyBackup)
}
}
}
.listStyle(.grouped)
.navigationTitle(BWIL10n.bwiSettingsDeveloper)

View File

@@ -0,0 +1,73 @@
//
/*
* Copyright (c) 2022 BWI GmbH
*
* 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 MaintenanceView: View {
@State var jsonString = ""
var session: MXSession?
var body: some View {
ScrollView {
VStack(alignment: .leading) {
HStack {
Text(jsonString)
.font(.caption)
.padding()
Spacer()
}
}
}
.navigationTitle(BWIL10n.bwiSettingsDeveloperMaintenance)
.navigationBarTitleDisplayMode(.inline)
.onAppear {
Task {
await fetchData()
}
}
}
private func fetchData() async {
guard let restClient = session?.matrixRestClient else {
return
}
let responseDict = await withCheckedContinuation { continuation in
restClient.getDowntime { jsonResponse, error in
continuation.resume(returning: jsonResponse)
}
}
await MainActor.run {
do {
if let responseDict = responseDict {
let data = try JSONSerialization.data(withJSONObject: responseDict as Any, options: [.prettyPrinted])
jsonString = String(data: data, encoding: .utf8) ?? ""
} else {
jsonString = ""
}
} catch {
jsonString = ""
}
}
}
}
struct MaintenanceView_Previews: PreviewProvider {
static var previews: some View {
MaintenanceView()
}
}

View File

@@ -0,0 +1,73 @@
//
/*
* Copyright (c) 2022 BWI GmbH
*
* 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 ServerCapabilitiesView: View {
@State var jsonString = ""
var session: MXSession?
var body: some View {
ScrollView {
VStack(alignment: .leading) {
HStack {
Text(jsonString)
.font(.caption)
.padding()
Spacer()
}
}
}
.navigationTitle(BWIL10n.bwiSettingsDeveloperCapabilities)
.navigationBarTitleDisplayMode(.inline)
.onAppear {
Task {
await fetchData()
}
}
}
private func fetchData() async {
guard let restClient = session?.matrixRestClient else {
return
}
let responseDict = await withCheckedContinuation { continuation in
restClient.getServerCapabilities { jsonResponse, error in
continuation.resume(returning: jsonResponse)
}
}
await MainActor.run {
do {
if let responseDict = responseDict {
let data = try JSONSerialization.data(withJSONObject: responseDict as Any, options: [.prettyPrinted])
jsonString = String(data: data, encoding: .utf8) ?? ""
} else {
jsonString = ""
}
} catch {
jsonString = ""
}
}
}
}
struct ServerCapabilitiesView_Previews: PreviewProvider {
static var previews: some View {
ServerCapabilitiesView()
}
}

View File

@@ -0,0 +1,96 @@
//
/*
* Copyright (c) 2022 BWI GmbH
*
* 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 ServerSideKeyBackupView: View {
@State var algorithm: String?
@State var count: Int?
@State var etag: String?
@State var version: String?
var session: MXSession?
var body: some View {
Form {
if let algorithm = algorithm {
TitleAndValueView(title: NSLocalizedString(BWIL10n.bwiSettingsDeveloperKeyBackupAlgorithm, comment: ""), value: algorithm)
}
if let count = count {
TitleAndValueView(title: NSLocalizedString(BWIL10n.bwiSettingsDeveloperKeyBackupCount, comment: ""), value: "\(count)")
}
if let etag = etag {
TitleAndValueView(title: NSLocalizedString(BWIL10n.bwiSettingsDeveloperKeyBackupEtag, comment: ""), value: etag)
}
if let version = version {
TitleAndValueView(title: NSLocalizedString(BWIL10n.bwiSettingsDeveloperKeyBackupVersion, comment: ""), value: version)
}
}
.navigationTitle(BWIL10n.bwiSettingsDeveloperKeyBackup)
.navigationBarTitleDisplayMode(.inline)
.onAppear {
Task {
await fetchData()
}
}
}
private func fetchData() async {
guard let restClient = session?.matrixRestClient else {
return
}
let responseDict = await withCheckedContinuation { continuation in
restClient.getKeyBackupVersion { jsonResponse, error in
continuation.resume(returning: jsonResponse)
}
}
await MainActor.run {
if let responseDict = responseDict {
algorithm = responseDict["algorithm"] as? String
count = responseDict["count"] as? Int
etag = responseDict["etag"] as? String
version = responseDict["version"] as? String
} else {
algorithm = nil
count = nil
etag = nil
version = nil
}
}
}
}
struct TitleAndValueView: View {
var title: String
var value: String
var body: some View {
HStack(alignment: .firstTextBaseline) {
Text(title)
Spacer()
Text(value)
.foregroundColor(.secondary)
}
}
}
struct ServerSideKeyBackupView_Previews: PreviewProvider {
static var previews: some View {
ServerSideKeyBackupView()
}
}

View File

@@ -0,0 +1,96 @@
//
/*
* Copyright (c) 2022 BWI GmbH
*
* 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
fileprivate let availableAccountDataTypes: [String] = [
"de.bwi.personal_notes_room",
"de.bwi.should_show_ios_release_notes",
"de.bwi.notification_times",
"de.bwi.top_banner_features",
"de.bwi.notifications",
"im.vector.setting.integration_provisioning",
"im.vector.setting.allowed_widgets"
]
struct UserAccountDataView: View {
@State var selectedAccountDataType = "de.bwi.personal_notes_room"
@State var jsonString = ""
var session: MXSession?
var body: some View {
Form {
SwiftUI.Section {
Picker(BWIL10n.bwiSettingsDeveloperUserAccountDataType, selection: $selectedAccountDataType) {
ForEach(availableAccountDataTypes, id:\.self) { type in
Text(type).tag(type)
}
}
.onChange(of: selectedAccountDataType) { newValue in
Task {
await fetchData(forType: newValue)
}
}
}
if !jsonString.isEmpty {
SwiftUI.Section {
Text(jsonString)
.font(.caption)
.padding()
}
}
}
.navigationTitle(BWIL10n.bwiSettingsDeveloperUserAccountData)
.navigationBarTitleDisplayMode(.inline)
.onAppear {
Task {
await fetchData(forType: selectedAccountDataType)
}
}
}
private func fetchData(forType accountDataType: String) async {
guard let restClient = session?.matrixRestClient else {
return
}
let responseDict = await withCheckedContinuation { continuation in
restClient.getAccountData(forType: accountDataType) { jsonResponse, error in
continuation.resume(returning: jsonResponse)
}
}
await MainActor.run {
do {
if let responseDict = responseDict {
print(responseDict)
let data = try JSONSerialization.data(withJSONObject: responseDict as Any, options: [.prettyPrinted])
jsonString = String(data: data, encoding: .utf8) ?? ""
} else {
jsonString = ""
}
} catch {
jsonString = ""
}
}
}
}
struct UserAccountDataView_Previews: PreviewProvider {
static var previews: some View {
UserAccountDataView()
}
}

View File

@@ -0,0 +1,73 @@
//
/*
* Copyright (c) 2022 BWI GmbH
*
* 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 WellKnownView: View {
@State var jsonString = ""
var session: MXSession?
var body: some View {
ScrollView {
VStack(alignment: .leading) {
HStack {
Text(jsonString)
.font(.caption)
.padding()
Spacer()
}
}
}
.navigationTitle(BWIL10n.bwiSettingsDeveloperWellKnown)
.navigationBarTitleDisplayMode(.inline)
.onAppear {
Task {
await fetchData()
}
}
}
private func fetchData() async {
guard let restClient = session?.matrixRestClient else {
return
}
let responseDict = await withCheckedContinuation { continuation in
restClient.getWellKnown { jsonResponse, error in
continuation.resume(returning: jsonResponse)
}
}
await MainActor.run {
do {
if let responseDict = responseDict {
let data = try JSONSerialization.data(withJSONObject: responseDict as Any, options: [.prettyPrinted])
jsonString = String(data: data, encoding: .utf8) ?? ""
} else {
jsonString = ""
}
} catch {
jsonString = ""
}
}
}
}
struct WellKnownView_Previews: PreviewProvider {
static var previews: some View {
WellKnownView()
}
}

View File

@@ -17,7 +17,49 @@
import Foundation
public extension MXRestClient {
@discardableResult
func getWellKnown(completion: @escaping (_ jsonResponse: Dictionary<AnyHashable, Any>?, _ error: Error?) -> Void) -> MXHTTPOperation? {
guard let httpClient = httpClient else {
completion(nil, "HTTPClient not available")
return nil
}
let path = ".well-known/matrix/client"
return httpClient.request(withMethod: "GET", path: path, parameters: nil, success: { response in
guard response != nil else {
completion(nil, "Response empty")
return
}
completion(response, nil)
}, failure: { (error) in
completion(nil, error)
})
}
@discardableResult
func getServerCapabilities(completion: @escaping (_ jsonResponse: Dictionary<AnyHashable, Any>?, _ error: Error?) -> Void) -> MXHTTPOperation? {
guard let httpClient = httpClient else {
completion(nil, "HTTPClient not available")
return nil
}
let path = apiPathPrefix + "/capabilities"
return httpClient.request(withMethod: "GET", path: path, parameters: nil, success: { response in
guard response != nil else {
completion(nil, "Response empty")
return
}
completion(response, nil)
}, failure: { (error) in
completion(nil, error)
})
}
@discardableResult
func getAccountData(forType type: String,
completion: @escaping (_ jsonResponse: Dictionary<AnyHashable, Any>?, _ error: Error?) -> Void) -> MXHTTPOperation? {
@@ -73,7 +115,26 @@ public extension MXRestClient {
return nil
}
let path = "_matrix/cmaintenance"
let path = "/_matrix/cmaintenance"
return httpClient.request(withMethod: "GET", path: path, parameters: nil, success: { response in
guard response != nil else {
completion(nil, "Response empty")
return
}
completion(response, nil)
}, failure: { (error) in
completion(nil, error)
})
}
@discardableResult
func getKeyBackupVersion(completion: @escaping (_ jsonResponse: Dictionary<AnyHashable, Any>?, _ error: Error?) -> Void) -> MXHTTPOperation? {
guard let httpClient = httpClient else {
return nil
}
let path = "/_matrix/client/v3/room_keys/version"
return httpClient.request(withMethod: "GET", path: path, parameters: nil, success: { response in
guard response != nil else {