From e0c53b7012354023e367c33093598f7523063aa6 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Mon, 13 Sep 2021 13:50:24 +0200 Subject: [PATCH] refactor(@desktop/general): managing local settings added on the nim side From now on we are able to access local settings (settings and global settings) on the nim side, not only through the qml. This change is required as part of the feature issue-2675. --- src/app/login/view.nim | 3 +- src/app/profile/core.nim | 3 + src/app/profile/view.nim | 31 +++++--- src/app/profile/views/profile_settings.nim | 61 ---------------- src/app_service/main.nim | 6 +- .../service/local_settings/service.nim | 73 +++++++++++++++++++ .../service/os_notification/service.nim | 4 +- src/nim_status_client.nim | 10 ++- ui/app/AppMain.qml | 68 +---------------- ui/main.qml | 67 ++++++++++++++++- vendor/DOtherSide | 2 +- vendor/nimqml | 2 +- 12 files changed, 183 insertions(+), 147 deletions(-) delete mode 100644 src/app/profile/views/profile_settings.nim create mode 100644 src/app_service/service/local_settings/service.nim diff --git a/src/app/login/view.nim b/src/app/login/view.nim index 374c2ceed8..1a7101c6d6 100644 --- a/src/app/login/view.nim +++ b/src/app/login/view.nim @@ -1,8 +1,8 @@ import NimQml, Tables, json, nimcrypto, strformat, json_serialization, chronicles import status/accounts as AccountModel import status/types/[account, rpc_response] +import status/[status] import ../onboarding/views/account_info -import status/status type AccountRoles {.pure.} = enum @@ -46,6 +46,7 @@ QtObject: keyUid: currNodeAcct.keyUid, identityImage: currNodeAcct.identityImage )) + self.status.events.emit("currentAccountUpdated", AccountArgs(account: currNodeAcct)) QtProperty[QVariant] currentAccount: read = getCurrentAccount diff --git a/src/app/profile/core.nim b/src/app/profile/core.nim index d28060266f..40f2b832b5 100644 --- a/src/app/profile/core.nim +++ b/src/app/profile/core.nim @@ -35,6 +35,9 @@ proc delete*(self: ProfileController) = delete self.variant delete self.view +proc setSettingsFile*(self: ProfileController, username: string) = + self.view.setSettingsFile(username) + proc init*(self: ProfileController, account: Account) = let profile = account.toProfileModel() diff --git a/src/app/profile/view.nim b/src/app/profile/view.nim index 1d54e8d192..f7504eb63e 100644 --- a/src/app/profile/view.nim +++ b/src/app/profile/view.nim @@ -1,5 +1,5 @@ import NimQml, sequtils, strutils, sugar, os, json, chronicles -import views/[mailservers_list, ens_manager, contacts, devices, mailservers, mnemonic, network, fleets, profile_info, device_list, dapp_list, profile_picture, profile_settings, muted_chats] +import views/[mailservers_list, ens_manager, contacts, devices, mailservers, mnemonic, network, fleets, profile_info, device_list, dapp_list, profile_picture, muted_chats] import chronicles import ../chat/views/channels_list import status/statusgo_backend/accounts as status_accounts @@ -23,7 +23,6 @@ QtObject: type ProfileView* = ref object of QObject profile*: ProfileInfoView profilePicture*: ProfilePictureView - profileSettings*: ProfileSettingsView mutedChats*: MutedChatsView contacts*: ContactsView devices*: DevicesView @@ -45,7 +44,6 @@ QtObject: if not self.devices.isNil: self.devices.delete if not self.ens.isNil: self.ens.delete if not self.profilePicture.isNil: self.profilePicture.delete - if not self.profileSettings.isNil: self.profileSettings.delete if not self.mutedChats.isNil: self.mutedChats.delete if not self.profile.isNil: self.profile.delete if not self.dappList.isNil: self.dappList.delete @@ -60,7 +58,6 @@ QtObject: result = ProfileView() result.profile = newProfileInfoView() result.profilePicture = newProfilePictureView(status, result.profile) - result.profileSettings = newProfileSettingsView(status, result.profile) result.mutedChats = newMutedChatsView(status) result.contacts = newContactsView(status, appService) result.devices = newDevicesView(status) @@ -84,7 +81,6 @@ QtObject: proc setNewProfile*(self: ProfileView, profile: Profile) = self.profile.setProfile(profile) - self.profileSettings.removeUnknownAccountSettings() self.profileChanged() QtProperty[QVariant] profile: @@ -186,11 +182,28 @@ QtObject: QtProperty[QVariant] picture: read = getProfilePicture - proc getProfileSettings*(self: ProfileView): QVariant {.slot.} = - newQVariant(self.profileSettings) + proc settingsFileChanged*(self: ProfileView) {.signal.} + + proc getSettingsFile*(self: ProfileView): string {.slot.} = + self.appService.localSettingsService.getSettingsFilePath + + proc setSettingsFile*(self: ProfileView, username: string) = + if(username.len == 0 or + self.appService.localSettingsService.getSettingsFilePath.endsWith(username)): + return - QtProperty[QVariant] settings: - read = getProfileSettings + self.appService.localSettingsService.updateSettingsFilePath(username) + self.settingsFileChanged() + + QtProperty[string] settingsFile: + read = getSettingsFile + notify = settingsFileChanged + + proc getGlobalSettingsFile*(self: ProfileView): string {.slot.} = + self.appService.localSettingsService.getGlobalSettingsFilePath + + QtProperty[string] globalSettingsFile: + read = getGlobalSettingsFile proc getMutedChats*(self: ProfileView): QVariant {.slot.} = newQVariant(self.mutedChats) diff --git a/src/app/profile/views/profile_settings.nim b/src/app/profile/views/profile_settings.nim deleted file mode 100644 index b96fcfbff0..0000000000 --- a/src/app/profile/views/profile_settings.nim +++ /dev/null @@ -1,61 +0,0 @@ -import NimQml, os -import chronicles -import profile_info -import status/status -import ../../../constants - -logScope: - topics = "profile-settings-view" - -const UNKNOWN_ACCOUNT = "unknownAccount" - -QtObject: - type ProfileSettingsView* = ref object of QObject - status*: Status - profile*: ProfileInfoView - - proc setup(self: ProfileSettingsView) = - self.QObject.setup - - proc delete*(self: ProfileSettingsView) = - self.QObject.delete - - proc newProfileSettingsView*(status: Status, profile: ProfileInfoView): ProfileSettingsView = - new(result, delete) - result.status = status - result.profile = profile - result.setup - - proc settingsFileChanged*(self: ProfileSettingsView) {.signal.} - - proc getSettingsFile(self: ProfileSettingsView): string {.slot.} = - let pubkey = - if (self.profile.pubKey == ""): - UNKNOWN_ACCOUNT - else: - self.profile.pubKey - - return os.joinPath(DATADIR, "qt", pubkey) - - QtProperty[string] settingsFile: - read = getSettingsFile - notify = settingsFileChanged - - proc getGlobalSettingsFile(self: ProfileSettingsView): string {.slot.} = - return os.joinPath(DATADIR, "qt", "global") - - proc globalSettingsFileChanged*(self: ProfileSettingsView) {.signal.} - - QtProperty[string] globalSettingsFile: - read = getGlobalSettingsFile - notify = globalSettingsFileChanged - - proc removeUnknownAccountSettings*(self: ProfileSettingsView) = - # Remove old 'unknownAccount' settings file if it was created - self.settingsFileChanged() - let unknownSettingsPath = os.joinPath(DATADIR, "qt", UNKNOWN_ACCOUNT) - if (not unknownSettingsPath.tryRemoveFile): - # Only fails if the file exists and an there was an error removing it - # More info: https://nim-lang.org/docs/os.html#tryRemoveFile%2Cstring - warn "Failed to remove unused settings file", file=unknownSettingsPath - \ No newline at end of file diff --git a/src/app_service/main.nim b/src/app_service/main.nim index ad60cc5e4b..8dcb512c3d 100644 --- a/src/app_service/main.nim +++ b/src/app_service/main.nim @@ -6,12 +6,13 @@ import ./tasks/threadpool, ./signals/signal_controller +import service/local_settings/service as local_settings_service import service/os_notification/service as os_notification_service import async_service/chat/service as chat_async_service import async_service/wallet/service as wallet_async_service export marathon, task_runner, signal_controller -export os_notification_service +export local_settings_service, os_notification_service export chat_async_service, wallet_async_service logScope: @@ -23,6 +24,7 @@ type AppService* = ref object marathon*: Marathon signalController*: SignalsController # services + localSettingsService*: LocalSettingsService osNotificationService*: OsNotificationService # async services chatService*: ChatService @@ -33,6 +35,7 @@ proc newAppService*(status: Status, worker: MarathonWorker): AppService = result.threadpool = newThreadPool() result.marathon = newMarathon(worker) result.signalController = newSignalsController(status) + result.localSettingsService = newLocalSettingsService() result.osNotificationService = newOsNotificationService(status) result.chatService = newChatService(status, result.threadpool) result.walletService = newWalletService(status, result.threadpool) @@ -41,6 +44,7 @@ proc delete*(self: AppService) = self.threadpool.teardown() self.marathon.teardown() self.signalController.delete() + self.localSettingsService.delete() self.osNotificationService.delete() self.chatService.delete() self.walletService.delete() diff --git a/src/app_service/service/local_settings/service.nim b/src/app_service/service/local_settings/service.nim new file mode 100644 index 0000000000..a0a090d3c3 --- /dev/null +++ b/src/app_service/service/local_settings/service.nim @@ -0,0 +1,73 @@ +import NimQml, os, chronicles +import ../../../constants + +# Local Settings keys: +const LS_KEY_STORE_TO_KEYCHAIN* = "storeToKeychain" +# Local Settings values: +const LS_VALUE_STORE* = "store" + +const UNKNOWN_ACCOUNT = "unknownAccount" + +logScope: + topics = "local-settings" + +QtObject: + type LocalSettingsService* = ref object of QObject + settingsFilePath: string + settings: QSettings + globalSettingsFilePath: string + globalSettings: QSettings + + proc setup(self: LocalSettingsService) = + self.settingsFilePath = os.joinPath(DATADIR, "qt", UNKNOWN_ACCOUNT) + self.settings = newQSettings(self.settingsFilePath, QSettingsFormat.IniFormat) + self.globalSettingsFilePath = os.joinPath(DATADIR, "qt", "global") + self.globalSettings = newQSettings(self.globalSettingsFilePath, QSettingsFormat.IniFormat) + self.QObject.setup + + proc delete*(self: LocalSettingsService) = + self.settings.delete + self.globalSettings.delete + self.QObject.delete + + proc newLocalSettingsService*(): LocalSettingsService = + new(result, delete) + result.setup + + proc getGlobalSettingsFilePath*(self: LocalSettingsService): string = + return self.globalSettingsFilePath + + proc getSettingsFilePath*(self: LocalSettingsService): string = + return self.settingsFilePath + + proc updateSettingsFilePath*(self: LocalSettingsService, username: string) = + if (username.len > 0): + let unknownSettingsPath = os.joinPath(DATADIR, "qt", UNKNOWN_ACCOUNT) + if (not unknownSettingsPath.tryRemoveFile): + # Only fails if the file exists and an there was an error removing it + # More info: https://nim-lang.org/docs/os.html#tryRemoveFile%2Cstring + warn "Failed to remove unused settings file", file=unknownSettingsPath + + self.settings.delete + self.settingsFilePath = os.joinPath(DATADIR, "qt", username) + self.settings = newQSettings(self.settingsFilePath, QSettingsFormat.IniFormat) + + proc setValue*(self: LocalSettingsService, key: string, value: QVariant) = + self.settings.setValue(key, value) + + proc getValue*(self: LocalSettingsService, key: string, + defaultValue: QVariant = newQVariant()): QVariant = + self.settings.value(key, defaultValue) + + proc removeValue*(self: LocalSettingsService, key: string) = + self.settings.remove(key) + + proc setGlobalValue*(self: LocalSettingsService, key: string, value: QVariant) = + self.globalSettings.setValue(key, value) + + proc getGlobalValue*(self: LocalSettingsService, key: string, + defaultValue: QVariant = newQVariant()): QVariant = + self.globalSettings.value(key, defaultValue) + + proc removeGlobalValue*(self: LocalSettingsService, key: string) = + self.globalSettings.remove(key) \ No newline at end of file diff --git a/src/app_service/service/os_notification/service.nim b/src/app_service/service/os_notification/service.nim index 92c5c2017b..5b35d77b92 100644 --- a/src/app_service/service/os_notification/service.nim +++ b/src/app_service/service/os_notification/service.nim @@ -10,12 +10,12 @@ logScope: QtObject: type OsNotificationService* = ref object of QObject status: Status - notification: StatusOSNotificationObject + notification: StatusOSNotification proc setup(self: OsNotificationService, status: Status) = self.QObject.setup self.status = status - self.notification = newStatusOSNotificationObject() + self.notification = newStatusOSNotification() signalConnect(self.notification, "notificationClicked(QString)", self, "onNotificationClicked(QString)", 2) diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim index 9f80e1857e..81cf9869d3 100644 --- a/src/nim_status_client.nim +++ b/src/nim_status_client.nim @@ -186,7 +186,7 @@ proc mainProc() = defer: provider.delete() engine.setRootContextProperty("web3Provider", provider.variant) - var login = login.newController(status) + var login = login.newController(status, appService) defer: login.delete() var onboarding = onboarding.newController(status) defer: onboarding.delete() @@ -204,9 +204,17 @@ proc mainProc() = onboarding.moveToAppState() status.events.emit("loginCompleted", args) + proc updateProfileSettings(account: Account) = + profile.setSettingsFile(account.name) + + status.events.on("currentAccountUpdated") do(a: Args): + var args = AccountArgs(a) + updateProfileSettings(args.account) + status.events.once("loginCompleted") do(a: Args): var args = AccountArgs(a) + updateProfileSettings(args.account) status.startMessenger() profile.init(args.account) wallet.init() diff --git a/ui/app/AppMain.qml b/ui/app/AppMain.qml index db4246bf9d..e745c81d96 100644 --- a/ui/app/AppMain.qml +++ b/ui/app/AppMain.qml @@ -27,7 +27,6 @@ Item { id: appMain anchors.fill: parent - property alias appSettings: appSettings property alias appLayout: appLayout property var newVersionJSON: JSON.parse(utilsModel.newVersion) property bool profilePopupOpened: false @@ -149,67 +148,6 @@ Item { } } - Settings { - id: appSettings - fileName: profileModel.settings.settingsFile - property var chatSplitView - property var walletSplitView - property var profileSplitView - property bool communitiesEnabled: false - property bool isWalletEnabled: false - property bool isWalletV2Enabled: false - property bool nodeManagementEnabled: false - property bool isBrowserEnabled: false - property bool isActivityCenterEnabled: false - property bool showOnlineUsers: false - property bool expandUsersList: false - property bool isGifWidgetEnabled: false - property bool isTenorWarningAccepted: false - property bool displayChatImages: false - property bool useCompactMode: true - property bool timelineEnabled: true - property var recentEmojis: [] - property var hiddenCommunityWelcomeBanners: [] - property var hiddenCommunityBackUpBanners: [] - property real volume: 0.2 - property int notificationSetting: Constants.notifyAllMessages - property bool notificationSoundsEnabled: true - property bool useOSNotifications: true - property int notificationMessagePreviewSetting: Constants.notificationPreviewNameAndMessage - property bool notifyOnNewRequests: true - property var whitelistedUnfurlingSites: ({}) - property bool neverAskAboutUnfurlingAgain: false - property bool hideChannelSuggestions: false - property int fontSize: Constants.fontSizeM - property bool hideSignPhraseModal: false - property bool onlyShowContactsProfilePics: true - property bool quitOnClose: false - property string skinColor: "" - property bool showDeleteMessageWarning: true - property bool downloadChannelMessagesEnabled: false - - // Browser settings - property bool showBrowserSelector: true - property bool openLinksInStatus: true - property bool shouldShowFavoritesBar: true - property string browserHomepage: "" - property int shouldShowBrowserSearchEngine: Constants.browserSearchEngineDuckDuckGo - property int useBrowserEthereumExplorer: Constants.browserEthereumExplorerEtherscan - property bool autoLoadImages: true - property bool javaScriptEnabled: true - property bool errorPageEnabled: true - property bool pluginsEnabled: true - property bool autoLoadIconsForPage: true - property bool touchIconsEnabled: true - property bool webRTCPublicInterfacesOnly: false - property bool devToolsEnabled: false - property bool pdfViewerEnabled: true - property bool compatibilityMode: true - - // Ropsten settings - property bool stickersEnsRopsten: false - } - ErrorSound { id: errorSound } @@ -562,10 +500,8 @@ Item { Connections { - target: profileModel.settings - onGlobalSettingsFileChanged: { - profileModel.changeLocale(globalSettings.locale) - } + target: profileModel + onSettingsFileChanged: { // Since https://github.com/status-im/status-desktop/commit/93668ff75 // we're hiding the setting to change appearance for compact normal mode diff --git a/ui/main.qml b/ui/main.qml index 37a190876a..d1e75d7c9b 100644 --- a/ui/main.qml +++ b/ui/main.qml @@ -29,7 +29,7 @@ StatusWindow { Settings { id: globalSettings category: "global" - fileName: profileModel.settings.globalSettingsFile + fileName: profileModel.globalSettingsFile property string locale: "en" property int theme: 2 @@ -38,6 +38,66 @@ StatusWindow { } } + Settings { + id: appSettings + fileName: profileModel.settingsFile + + property var chatSplitView + property var walletSplitView + property var profileSplitView + property bool communitiesEnabled: false + property bool isWalletEnabled: false + property bool isWalletV2Enabled: false + property bool nodeManagementEnabled: false + property bool isBrowserEnabled: false + property bool isActivityCenterEnabled: false + property bool showOnlineUsers: false + property bool isGifWidgetEnabled: false + property bool isTenorWarningAccepted: false + property bool displayChatImages: false + property bool useCompactMode: true + property bool timelineEnabled: true + property var recentEmojis: [] + property var hiddenCommunityWelcomeBanners: [] + property var hiddenCommunityBackUpBanners: [] + property real volume: 0.2 + property int notificationSetting: Constants.notifyAllMessages + property bool notificationSoundsEnabled: true + property bool useOSNotifications: true + property int notificationMessagePreviewSetting: Constants.notificationPreviewNameAndMessage + property bool notifyOnNewRequests: true + property var whitelistedUnfurlingSites: ({}) + property bool neverAskAboutUnfurlingAgain: false + property bool hideChannelSuggestions: false + property int fontSize: Constants.fontSizeM + property bool hideSignPhraseModal: false + property bool onlyShowContactsProfilePics: true + property bool quitOnClose: false + property string skinColor: "" + property bool showDeleteMessageWarning: true + + // Browser settings + property bool showBrowserSelector: true + property bool openLinksInStatus: true + property bool shouldShowFavoritesBar: true + property string browserHomepage: "" + property int shouldShowBrowserSearchEngine: Constants.browserSearchEngineDuckDuckGo + property int useBrowserEthereumExplorer: Constants.browserEthereumExplorerEtherscan + property bool autoLoadImages: true + property bool javaScriptEnabled: true + property bool errorPageEnabled: true + property bool pluginsEnabled: true + property bool autoLoadIconsForPage: true + property bool touchIconsEnabled: true + property bool webRTCPublicInterfacesOnly: false + property bool devToolsEnabled: false + property bool pdfViewerEnabled: true + property bool compatibilityMode: true + + // Ropsten settings + property bool stickersEnsRopsten: false + } + id: applicationWindow objectName: "mainWindow" minimumWidth: 900 @@ -102,7 +162,7 @@ StatusWindow { close.accepted = false } else if (loader.sourceComponent == app) { - if (loader.item.appSettings.quitOnClose) { + if (appSettings.quitOnClose) { close.accepted = true } else { applicationWindow.visible = false @@ -310,7 +370,6 @@ StatusWindow { Loader { id: loader anchors.fill: parent - property var appSettings } DropArea { @@ -470,7 +529,7 @@ StatusWindow { Qt.quit(); } else if (loader.sourceComponent == app) { - if (loader.item.appSettings.quitOnClose) { + if (appSettings.quitOnClose) { Qt.quit(); } else { applicationWindow.visible = false; diff --git a/vendor/DOtherSide b/vendor/DOtherSide index 0bebd4cc2a..0f8ed95fc7 160000 --- a/vendor/DOtherSide +++ b/vendor/DOtherSide @@ -1 +1 @@ -Subproject commit 0bebd4cc2a67ed3c42f0615450cc0de86c790915 +Subproject commit 0f8ed95fc7a47e4d3efb218ef961d36e60610cb3 diff --git a/vendor/nimqml b/vendor/nimqml index ca381eb8a2..00ee27ca52 160000 --- a/vendor/nimqml +++ b/vendor/nimqml @@ -1 +1 @@ -Subproject commit ca381eb8a20cf02f712a423f85b22901e14fa982 +Subproject commit 00ee27ca52bcf5216c0de0e19e594ddfc1790452