diff --git a/src/app/boot/app_controller.nim b/src/app/boot/app_controller.nim index e9871700f3..6d3a322bd2 100644 --- a/src/app/boot/app_controller.nim +++ b/src/app/boot/app_controller.nim @@ -3,6 +3,7 @@ import NimQml, os, strformat import ../../app_service/service/keychain/service as keychain_service import ../../app_service/service/accounts/service as accounts_service import ../../app_service/service/contacts/service as contacts_service +import ../../app_service/service/language/service as language_service import ../../app_service/service/chat/service as chat_service import ../../app_service/service/community/service as community_service import ../../app_service/service/token/service as token_service @@ -75,6 +76,7 @@ type profileService: profile_service.Service settingsService: settings_service.Service aboutService: about_service.Service + languageService: language_service.Service # Core localAppSettingsVariant: QVariant @@ -133,6 +135,7 @@ proc newAppController*(appService: AppService): AppController = result.settingsService = settings_service.newService() result.aboutService = about_service.newService() result.dappPermissionsService = dapp_permissions_service.newService() + result.languageService = language_service.newService() # Core result.localAppSettingsVariant = newQVariant(singletonInstance.localAppSettings) @@ -164,6 +167,7 @@ proc newAppController*(appService: AppService): AppController = result.contactsService, result.aboutService, result.dappPermissionsService, + result.languageService ) ################################################# diff --git a/src/app/modules/main/module.nim b/src/app/modules/main/module.nim index 4ba12ae785..ac5c1c671e 100644 --- a/src/app/modules/main/module.nim +++ b/src/app/modules/main/module.nim @@ -26,6 +26,7 @@ import ../../../app_service/service/accounts/service as accounts_service import ../../../app_service/service/settings/service as settings_service import ../../../app_service/service/contacts/service as contacts_service import ../../../app_service/service/about/service as about_service +import ../../../app_service/service/language/service as language_service export io_interface @@ -70,6 +71,7 @@ proc newModule*[T]( contactsService: contacts_service.ServiceInterface, aboutService: about_service.ServiceInterface, dappPermissionsService: dapp_permissions_service.ServiceInterface, + languageService: language_service.ServiceInterface ): Module[T] = result = Module[T]() result.delegate = delegate @@ -100,7 +102,7 @@ proc newModule*[T]( ) result.browserSectionModule = browser_section_module.newModule(result, bookmarkService, settingsService, dappPermissionsService) - result.profileSectionModule = profile_section_module.newModule(result, events, accountsService, settingsService, profileService, contactsService, aboutService) + result.profileSectionModule = profile_section_module.newModule(result, events, accountsService, settingsService, profileService, contactsService, aboutService, languageService) method delete*[T](self: Module[T]) = self.chatSectionModule.delete diff --git a/src/app/modules/main/profile_section/controller.nim b/src/app/modules/main/profile_section/controller.nim index d7e6e47fed..07601d9de2 100644 --- a/src/app/modules/main/profile_section/controller.nim +++ b/src/app/modules/main/profile_section/controller.nim @@ -5,6 +5,7 @@ import controller_interface import ../../../../app_service/service/profile/service as profile_service import ../../../../app_service/service/accounts/service as accounts_service import ../../../../app_service/service/settings/service as settings_service +import ../../../../app_service/service/language/service as language_service export controller_interface @@ -15,13 +16,15 @@ type profileService: profile_service.ServiceInterface settingsService: settings_service.ServiceInterface accountsService: accounts_service.ServiceInterface + languageService: language_service.ServiceInterface -proc newController*[T](delegate: T, accountsService: accounts_service.ServiceInterface, settingsService: settings_service.ServiceInterface, profileService: profile_service.ServiceInterface): Controller[T] = +proc newController*[T](delegate: T, accountsService: accounts_service.ServiceInterface, settingsService: settings_service.ServiceInterface, profileService: profile_service.ServiceInterface, languageService: language_service.ServiceInterface): Controller[T] = result = Controller[T]() result.delegate = delegate result.profileService = profileService result.settingsService = settingsService result.accountsService = accountsService + result.languageService = languageService method delete*[T](self: Controller[T]) = discard diff --git a/src/app/modules/main/profile_section/language/controller.nim b/src/app/modules/main/profile_section/language/controller.nim new file mode 100644 index 0000000000..32fac54ff9 --- /dev/null +++ b/src/app/modules/main/profile_section/language/controller.nim @@ -0,0 +1,22 @@ +import ./controller_interface +import ../../../../../app_service/service/language/service as language_service + +# import ./item as item + +export controller_interface + +type + Controller*[T: controller_interface.DelegateInterface] = ref object of controller_interface.AccessInterface + delegate: T + languageService: language_service.ServiceInterface + +proc newController*[T](delegate: T, languageService: language_service.ServiceInterface): Controller[T] = + result = Controller[T]() + result.delegate = delegate + result.languageService = languageService + +method delete*[T](self: Controller[T]) = + discard + +method changeLanguage*[T](self: Controller[T], locale: string) = + self.languageService.setLanguage(locale) diff --git a/src/app/modules/main/profile_section/language/controller_interface.nim b/src/app/modules/main/profile_section/language/controller_interface.nim new file mode 100644 index 0000000000..d7a5808ff4 --- /dev/null +++ b/src/app/modules/main/profile_section/language/controller_interface.nim @@ -0,0 +1,19 @@ +import ../../../../../app_service/service/language/service as language_service + +type + AccessInterface* {.pure inheritable.} = ref object of RootObj + ## Abstract class for any input/interaction with this module. + +method delete*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method init*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method changeLanguage*(self: AccessInterface, locale: string) {.base.} = + raise newException(ValueError, "No implementation available") + +type + ## Abstract class (concept) which must be implemented by object/s used in this + ## module. + DelegateInterface* = concept c diff --git a/src/app/modules/main/profile_section/language/io_interface.nim b/src/app/modules/main/profile_section/language/io_interface.nim new file mode 100644 index 0000000000..65aba1872c --- /dev/null +++ b/src/app/modules/main/profile_section/language/io_interface.nim @@ -0,0 +1,20 @@ +type + AccessInterface* {.pure inheritable.} = ref object of RootObj + ## Abstract class for any input/interaction with this module. + +method delete*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method load*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method isLoaded*(self: AccessInterface): bool {.base.} = + raise newException(ValueError, "No implementation available") + +method changeLanguage*(self: AccessInterface, locale: string) {.base.} = + raise newException(ValueError, "No implementation available") + +type + ## Abstract class (concept) which must be implemented by object/s used in this + ## module. + DelegateInterface* = concept c diff --git a/src/app/modules/main/profile_section/language/module.nim b/src/app/modules/main/profile_section/language/module.nim new file mode 100644 index 0000000000..1596cd5c77 --- /dev/null +++ b/src/app/modules/main/profile_section/language/module.nim @@ -0,0 +1,38 @@ +import NimQml, Tables + +import ./io_interface, ./view, ./controller +import ../../../../core/global_singleton + +import ../../../../../app_service/service/language/service as language_service + +export io_interface + +type + Module* [T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface + delegate: T + controller: controller.AccessInterface + view: View + viewVariant: QVariant + moduleLoaded: bool + +proc newModule*[T](delegate: T, languageService: language_service.ServiceInterface): Module[T] = + result = Module[T]() + result.delegate = delegate + result.view = newView(result) + result.viewVariant = newQVariant(result.view) + result.controller = controller.newController[Module[T]](result, languageService) + result.moduleLoaded = false + + singletonInstance.engine.setRootContextProperty("languageModule", result.viewVariant) + +method delete*[T](self: Module[T]) = + self.view.delete + +method load*[T](self: Module[T]) = + self.moduleLoaded = true + +method isLoaded*[T](self: Module[T]): bool = + return self.moduleLoaded + +method changeLanguage*[T](self: Module[T], locale: string) = + self.controller.changeLanguage(locale) diff --git a/src/app/modules/main/profile_section/language/view.nim b/src/app/modules/main/profile_section/language/view.nim new file mode 100644 index 0000000000..8257c15e1c --- /dev/null +++ b/src/app/modules/main/profile_section/language/view.nim @@ -0,0 +1,20 @@ +import NimQml + +# import ./controller_interface +import ./io_interface + +QtObject: + type + View* = ref object of QObject + delegate: io_interface.AccessInterface + + proc delete*(self: View) = + self.QObject.delete + + proc newView*(delegate: io_interface.AccessInterface): View = + new(result, delete) + result.QObject.setup + result.delegate = delegate + + proc changeLocale*(self: View, locale: string) {.slot.} = + self.delegate.changeLanguage(locale) diff --git a/src/app/modules/main/profile_section/module.nim b/src/app/modules/main/profile_section/module.nim index b873b05326..c75f688fd7 100644 --- a/src/app/modules/main/profile_section/module.nim +++ b/src/app/modules/main/profile_section/module.nim @@ -7,9 +7,11 @@ import ../../../../app_service/service/accounts/service as accounts_service import ../../../../app_service/service/settings/service as settings_service import ../../../../app_service/service/contacts/service as contacts_service import ../../../../app_service/service/about/service as about_service +import ../../../../app_service/service/language/service as language_service import ./profile/module as profile_module import ./contacts/module as contacts_module +import ./language/module as language_module import ./about/module as about_module import eventemitter @@ -25,6 +27,7 @@ type moduleLoaded: bool profileModule: profile_module.AccessInterface + languageModule: language_module.AccessInterface contactsModule: contacts_module.AccessInterface aboutModule: about_module.AccessInterface @@ -34,17 +37,21 @@ proc newModule*[T](delegate: T, settingsService: settings_service.ServiceInterface, profileService: profile_service.ServiceInterface, contactsService: contacts_service.ServiceInterface, - aboutService: about_service.ServiceInterface): + aboutService: about_service.ServiceInterface, + languageService: language_service.ServiceInterface + ): Module[T] = result = Module[T]() result.delegate = delegate result.view = view.newView() result.viewVariant = newQVariant(result.view) - result.controller = controller.newController[Module[T]](result, accountsService, settingsService, profileService) + result.controller = controller.newController[Module[T]](result, accountsService, settingsService, profileService, languageService) result.moduleLoaded = false result.profileModule = profile_module.newModule(result, accountsService, settingsService, profileService) result.contactsModule = contacts_module.newModule(result, events, contactsService, accountsService) + result.languageModule = language_module.newModule(result, languageService) + result.aboutModule = about_module.newModule(result, aboutService) singletonInstance.engine.setRootContextProperty("profileSectionModule", result.viewVariant) @@ -52,6 +59,7 @@ proc newModule*[T](delegate: T, method delete*[T](self: Module[T]) = self.profileModule.delete self.contactsModule.delete + self.languageModule.delete self.aboutModule.delete self.view.delete @@ -61,6 +69,7 @@ method delete*[T](self: Module[T]) = method load*[T](self: Module[T]) = self.profileModule.load() self.contactsModule.load() + self.languageModule.load() self.aboutModule.load() self.moduleLoaded = true diff --git a/src/app_service/service/language/dto.nim b/src/app_service/service/language/dto.nim new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app_service/service/language/service.nim b/src/app_service/service/language/service.nim new file mode 100644 index 0000000000..137b31580d --- /dev/null +++ b/src/app_service/service/language/service.nim @@ -0,0 +1,49 @@ +import NimQml +import json, json_serialization, sequtils, chronicles, os, strformat +import ./service_interface, ./dto +import ../../../app/core/global_singleton + +export service_interface + +logScope: + topics = "language-service" + +type + Service* = ref object of ServiceInterface + i18nPath*: string + currentLanguageCode*: string + +method delete*(self: Service) = + discard + +proc newService*(): Service = + result = Service() + +method init*(self: Service) = + try: + echo "init" + + self.i18nPath = "" + if defined(development): + self.i18nPath = joinPath(getAppDir(), "../ui/i18n") + elif (defined(windows)): + self.i18nPath = joinPath(getAppDir(), "../resources/i18n") + elif (defined(macosx)): + self.i18nPath = joinPath(getAppDir(), "../i18n") + elif (defined(linux)): + self.i18nPath = joinPath(getAppDir(), "../i18n") + + except Exception as e: + let errDesription = e.msg + error "error: ", errDesription + return + +method setLanguage*(self: Service, locale: string) = + echo "---------------" + echo "--- setting language" + if (locale == self.currentLanguageCode): + return + self.currentLanguageCode = locale + let shouldRetranslate = not defined(linux) + singletonInstance.engine.setTranslationPackage( + joinPath(self.i18nPath, fmt"qml_{locale}.qm"), shouldRetranslate) diff --git a/src/app_service/service/language/service_interface.nim b/src/app_service/service/language/service_interface.nim new file mode 100644 index 0000000000..bea7d86e5f --- /dev/null +++ b/src/app_service/service/language/service_interface.nim @@ -0,0 +1,16 @@ +import dto + +export dto + +type + ServiceInterface* {.pure inheritable.} = ref object of RootObj + ## Abstract class for this service access. + +method delete*(self: ServiceInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method init*(self: ServiceInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method setLanguage*(self: ServiceInterface, language: string) {.base.} = + raise newException(ValueError, "No implementation available") diff --git a/ui/app/AppLayouts/Profile/stores/RootStore.qml b/ui/app/AppLayouts/Profile/stores/RootStore.qml index 6da197c949..86d626c3b0 100644 --- a/ui/app/AppLayouts/Profile/stores/RootStore.qml +++ b/ui/app/AppLayouts/Profile/stores/RootStore.qml @@ -9,6 +9,7 @@ QtObject { property var profile: profileModule property var contactsModuleInst: contactsModule property var aboutModuleInst: aboutModule + property var languageModuleInst: languageModule property var chatsModelInst: chatsModel property var utilsModelInst: utilsModel @@ -279,7 +280,7 @@ QtObject { } function changeLocale(l) { - profileModelInst.changeLocale(l) + languageModuleInst.changeLocale(l) } function getMailserverName(mailserver) {