From a14859d8c0a7e8bafc0ed315be0c60aa3611f83a Mon Sep 17 00:00:00 2001 From: JRoberts <8711996+jr-simplex@users.noreply.github.com> Date: Tue, 2 Aug 2022 17:00:12 +0400 Subject: [PATCH] mobile: developer tools (#867) --- .../java/chat/simplex/app/model/SimpleXAPI.kt | 2 ++ .../chat/simplex/app/views/chat/ChatInfoView.kt | 16 +++++++++++----- .../app/views/chat/group/GroupChatInfoView.kt | 16 +++++++++++----- .../app/views/chat/group/GroupMemberInfoView.kt | 16 +++++++++++----- .../app/views/usersettings/SettingsView.kt | 5 +++++ .../app/src/main/res/values-ru/strings.xml | 1 + apps/android/app/src/main/res/values/strings.xml | 1 + apps/ios/Shared/Views/Chat/ChatInfoView.swift | 9 ++++++--- .../Views/Chat/Group/GroupChatInfoView.swift | 9 ++++++--- .../Views/Chat/Group/GroupMemberInfoView.swift | 9 ++++++--- .../Shared/Views/UserSettings/SettingsView.swift | 8 +++++++- 11 files changed, 67 insertions(+), 25 deletions(-) diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt index d0d3c7fe0b..7b4812450b 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt @@ -85,6 +85,7 @@ class AppPreferences(val context: Context) { val chatArchiveTime = mkDatePreference(SHARED_PREFS_CHAT_ARCHIVE_TIME, null) val chatLastStart = mkDatePreference(SHARED_PREFS_CHAT_LAST_START, null) val useSocksProxy = mkBoolPreference(SHARED_PREFS_USE_SOCKS_PROXY, false) + val developerTools = mkBoolPreference(SHARED_PREFS_DEVELOPER_TOOLS, false) private fun mkIntPreference(prefName: String, default: Int) = Preference( @@ -130,6 +131,7 @@ class AppPreferences(val context: Context) { private const val SHARED_PREFS_CHAT_ARCHIVE_TIME = "ChatArchiveTime" private const val SHARED_PREFS_CHAT_LAST_START = "ChatLastStart" private const val SHARED_PREFS_USE_SOCKS_PROXY = "UseSocksProxy" + private const val SHARED_PREFS_DEVELOPER_TOOLS = "DeveloperTools" } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt index 74de681ae4..7580abdce2 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt @@ -30,10 +30,12 @@ import chat.simplex.app.views.helpers.* fun ChatInfoView(chatModel: ChatModel, connStats: ConnectionStats?, close: () -> Unit) { BackHandler(onBack = close) val chat = chatModel.chats.firstOrNull { it.id == chatModel.chatId.value } + val developerTools = chatModel.controller.appPrefs.developerTools.get() if (chat != null) { ChatInfoLayout( chat, connStats, + developerTools, deleteContact = { deleteContactDialog(chat.chatInfo, chatModel, close) }, clearChat = { clearChatDialog(chat.chatInfo, chatModel, close) } ) @@ -81,6 +83,7 @@ fun clearChatDialog(chatInfo: ChatInfo, chatModel: ChatModel, close: (() -> Unit fun ChatInfoLayout( chat: Chat, connStats: ConnectionStats?, + developerTools: Boolean, deleteContact: () -> Unit, clearChat: () -> Unit ) { @@ -128,12 +131,14 @@ fun ChatInfoLayout( } SectionSpacer() - SectionView(title = stringResource(R.string.section_title_for_console)) { - InfoRow(stringResource(R.string.info_row_local_name), chat.chatInfo.localDisplayName) - SectionDivider() - InfoRow(stringResource(R.string.info_row_database_id), chat.chatInfo.apiId.toString()) + if (developerTools) { + SectionView(title = stringResource(R.string.section_title_for_console)) { + InfoRow(stringResource(R.string.info_row_local_name), chat.chatInfo.localDisplayName) + SectionDivider() + InfoRow(stringResource(R.string.info_row_database_id), chat.chatInfo.apiId.toString()) + } + SectionSpacer() } - SectionSpacer() } } @@ -267,6 +272,7 @@ fun PreviewChatInfoLayout() { chatItems = arrayListOf(), serverInfo = Chat.ServerInfo(Chat.NetworkStatus.Error("agent BROKER TIMEOUT")) ), + developerTools = false, connStats = null, deleteContact = {}, clearChat = {} ) diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt index 9931455cae..2fec78b4d7 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt @@ -31,12 +31,14 @@ import chat.simplex.app.views.helpers.* fun GroupChatInfoView(chatModel: ChatModel, close: () -> Unit) { BackHandler(onBack = close) val chat = chatModel.chats.firstOrNull { it.id == chatModel.chatId.value } + val developerTools = chatModel.controller.appPrefs.developerTools.get() if (chat != null && chat.chatInfo is ChatInfo.Group) { val groupInfo = chat.chatInfo.groupInfo GroupChatInfoLayout( chat, groupInfo, members = chatModel.groupMembers.sortedBy { it.displayName.lowercase() }, + developerTools, addMembers = { withApi { populateGroupMembers(groupInfo, chatModel) @@ -111,6 +113,7 @@ fun GroupChatInfoLayout( chat: Chat, groupInfo: GroupInfo, members: List, + developerTools: Boolean, addMembers: () -> Unit, showMemberInfo: (GroupMember) -> Unit, editGroupProfile: () -> Unit, @@ -172,12 +175,14 @@ fun GroupChatInfoLayout( } SectionSpacer() - SectionView(title = stringResource(R.string.section_title_for_console)) { - InfoRow(stringResource(R.string.info_row_local_name), groupInfo.localDisplayName) - SectionDivider() - InfoRow(stringResource(R.string.info_row_database_id), groupInfo.apiId.toString()) + if (developerTools) { + SectionView(title = stringResource(R.string.section_title_for_console)) { + InfoRow(stringResource(R.string.info_row_local_name), groupInfo.localDisplayName) + SectionDivider() + InfoRow(stringResource(R.string.info_row_database_id), groupInfo.apiId.toString()) + } + SectionSpacer() } - SectionSpacer() } } @@ -312,6 +317,7 @@ fun PreviewGroupChatInfoLayout() { ), groupInfo = GroupInfo.sampleData, members = listOf(GroupMember.sampleData, GroupMember.sampleData, GroupMember.sampleData), + developerTools = false, addMembers = {}, showMemberInfo = {}, editGroupProfile = {}, deleteGroup = {}, clearChat = {}, leaveGroup = {} ) } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt index 4a565ee745..1f303e63db 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt @@ -30,11 +30,13 @@ import chat.simplex.app.views.helpers.* fun GroupMemberInfoView(groupInfo: GroupInfo, member: GroupMember, connStats: ConnectionStats?, chatModel: ChatModel, close: () -> Unit) { BackHandler(onBack = close) val chat = chatModel.chats.firstOrNull { it.id == chatModel.chatId.value } + val developerTools = chatModel.controller.appPrefs.developerTools.get() if (chat != null) { GroupMemberInfoLayout( groupInfo, member, connStats, + developerTools, removeMember = { removeMemberDialog(member, chatModel, close) } ) } @@ -59,6 +61,7 @@ fun GroupMemberInfoLayout( groupInfo: GroupInfo, member: GroupMember, connStats: ConnectionStats?, + developerTools: Boolean, removeMember: () -> Unit, ) { Column( @@ -116,12 +119,14 @@ fun GroupMemberInfoLayout( SectionSpacer() } - SectionView(title = stringResource(R.string.section_title_for_console)) { - InfoRow(stringResource(R.string.info_row_local_name), member.localDisplayName) - SectionDivider() - InfoRow(stringResource(R.string.info_row_database_id), member.groupMemberId.toString()) + if (developerTools) { + SectionView(title = stringResource(R.string.section_title_for_console)) { + InfoRow(stringResource(R.string.info_row_local_name), member.localDisplayName) + SectionDivider() + InfoRow(stringResource(R.string.info_row_database_id), member.groupMemberId.toString()) + } + SectionSpacer() } - SectionSpacer() } } @@ -175,6 +180,7 @@ fun PreviewGroupMemberInfoLayout() { groupInfo = GroupInfo.sampleData, member = GroupMember.sampleData, connStats = null, + developerTools = false, removeMember = {} ) } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt index 2dfdcd7ecb..49a52784ef 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt @@ -51,6 +51,7 @@ fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit) { profile = user.profile, stopped, runServiceInBackground = chatModel.runServiceInBackground, + developerTools = chatModel.controller.appPrefs.developerTools, setRunServiceInBackground = ::setRunServiceInBackground, setPerformLA = setPerformLA, showModal = { modalView -> { ModalManager.shared.showModal { modalView(chatModel) } } }, @@ -98,6 +99,7 @@ fun SettingsLayout( profile: Profile, stopped: Boolean, runServiceInBackground: MutableState, + developerTools: Preference, setRunServiceInBackground: (Boolean) -> Unit, setPerformLA: (Boolean) -> Unit, showModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), @@ -162,6 +164,8 @@ fun SettingsLayout( SectionView(stringResource(R.string.settings_section_title_develop)) { ChatConsoleItem(showTerminal, stopped) SectionDivider() + SettingsPreferenceItem(Icons.Outlined.Construction, stringResource(R.string.settings_developer_tools), developerTools) + SectionDivider() InstallTerminalAppItem(uriHandler) SectionDivider() // SettingsActionItem(Icons.Outlined.Science, stringResource(R.string.settings_experimental_features), showSettingsModal { ExperimentalFeaturesView(it, enableCalls) }) @@ -344,6 +348,7 @@ fun PreviewSettingsLayout() { profile = Profile.sampleData, stopped = false, runServiceInBackground = remember { mutableStateOf(true) }, + developerTools = Preference({ false }, {}), setRunServiceInBackground = {}, setPerformLA = {}, showModal = { {} }, diff --git a/apps/android/app/src/main/res/values-ru/strings.xml b/apps/android/app/src/main/res/values-ru/strings.xml index 7bbd37d7a0..6aa9b2cd01 100644 --- a/apps/android/app/src/main/res/values-ru/strings.xml +++ b/apps/android/app/src/main/res/values-ru/strings.xml @@ -452,6 +452,7 @@ ДЛЯ РАЗРАБОТЧИКОВ УСТРОЙСТВО ЧАТЫ + Инструменты разработчика Экспериментальные функции SOCKS ПРОКСИ diff --git a/apps/android/app/src/main/res/values/strings.xml b/apps/android/app/src/main/res/values/strings.xml index 4187bbe569..87aaceec13 100644 --- a/apps/android/app/src/main/res/values/strings.xml +++ b/apps/android/app/src/main/res/values/strings.xml @@ -454,6 +454,7 @@ DEVELOP DEVICE CHATS + Developer tools Experimental features SOCKS PROXY diff --git a/apps/ios/Shared/Views/Chat/ChatInfoView.swift b/apps/ios/Shared/Views/Chat/ChatInfoView.swift index ac165845c4..253ccb0f15 100644 --- a/apps/ios/Shared/Views/Chat/ChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatInfoView.swift @@ -48,6 +48,7 @@ struct ChatInfoView: View { @ObservedObject var chat: Chat var connectionStats: ConnectionStats? @State private var alert: ChatInfoViewAlert? = nil + @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false enum ChatInfoViewAlert: Identifiable { case deleteContactAlert @@ -79,9 +80,11 @@ struct ChatInfoView: View { deleteContactButton() } - Section(header: Text("For console")) { - infoRow("Local name", chat.chatInfo.localDisplayName) - infoRow("Database ID", "\(chat.chatInfo.apiId)") + if developerTools { + Section(header: Text("For console")) { + infoRow("Local name", chat.chatInfo.localDisplayName) + infoRow("Database ID", "\(chat.chatInfo.apiId)") + } } } .navigationBarHidden(true) diff --git a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift index fd5dee7a35..5b563aa5c4 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift @@ -21,6 +21,7 @@ struct GroupChatInfoView: View { @State private var selectedMember: GroupMember? = nil @State private var showGroupProfile: Bool = false @State private var connectionStats: ConnectionStats? + @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false enum GroupChatInfoViewAlert: Identifiable { case deleteGroupAlert @@ -78,9 +79,11 @@ struct GroupChatInfoView: View { } } - Section(header: Text("For console")) { - infoRow("Local name", chat.chatInfo.localDisplayName) - infoRow("Database ID", "\(chat.chatInfo.apiId)") + if developerTools { + Section(header: Text("For console")) { + infoRow("Local name", chat.chatInfo.localDisplayName) + infoRow("Database ID", "\(chat.chatInfo.apiId)") + } } } .navigationBarHidden(true) diff --git a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift index b3759f83f2..3ace3a9788 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift @@ -16,6 +16,7 @@ struct GroupMemberInfoView: View { var member: GroupMember var connectionStats: ConnectionStats? @State private var alert: GroupMemberInfoViewAlert? + @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false enum GroupMemberInfoViewAlert: Identifiable { case removeMemberAlert @@ -54,9 +55,11 @@ struct GroupMemberInfoView: View { } } - Section("For console") { - infoRow("Local name", member.localDisplayName) - infoRow("Database ID", "\(member.groupMemberId)") + if developerTools { + Section("For console") { + infoRow("Local name", member.localDisplayName) + infoRow("Database ID", "\(member.groupMemberId)") + } } } .navigationBarHidden(true) diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift index d074589c1c..ef96939799 100644 --- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift +++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift @@ -26,6 +26,7 @@ let DEFAULT_EXPERIMENTAL_CALLS = "experimentalCalls" let DEFAULT_CHAT_ARCHIVE_NAME = "chatArchiveName" let DEFAULT_CHAT_ARCHIVE_TIME = "chatArchiveTime" let DEFAULT_CHAT_V3_DB_MIGRATION = "chatV3DBMigration" +let DEFAULT_DEVELOPER_TOOLS = "developerTools" let appDefaults: [String: Any] = [ DEFAULT_SHOW_LA_NOTICE: false, @@ -36,7 +37,8 @@ let appDefaults: [String: Any] = [ DEFAULT_PRIVACY_ACCEPT_IMAGES: true, DEFAULT_PRIVACY_LINK_PREVIEWS: true, DEFAULT_EXPERIMENTAL_CALLS: false, - DEFAULT_CHAT_V3_DB_MIGRATION: "offer" + DEFAULT_CHAT_V3_DB_MIGRATION: "offer", + DEFAULT_DEVELOPER_TOOLS: false ] private var indent: CGFloat = 36 @@ -52,6 +54,7 @@ struct SettingsView: View { @EnvironmentObject var chatModel: ChatModel @Binding var showSettings: Bool @AppStorage(DEFAULT_PENDING_CONNECTIONS) private var pendingConnections = true + @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false var body: some View { let user: User = chatModel.currentUser! @@ -169,6 +172,9 @@ struct SettingsView: View { settingsRow("terminal") { Text("Chat console") } } .disabled(chatModel.chatRunning != true) + settingsRow("gear") { + Toggle("Developer tools", isOn: $developerTools) + } ZStack(alignment: .leading) { Image(colorScheme == .dark ? "github_light" : "github") .resizable()