refactor: creating module for bookmarks and provider

This commit is contained in:
Richard Ramos 2021-10-14 10:29:33 -04:00 committed by Iuri Matias
parent e0deb28e8f
commit 70c1095b60
47 changed files with 764 additions and 207 deletions

3
.gitmodules vendored
View File

@ -40,3 +40,6 @@
[submodule "spellchecking"]
path = spellchecking
url = https://github.com/status-im/desktop-spellchecking.git
[submodule "vendor/nim-result"]
path = vendor/nim-result
url = https://github.com/arnetheduck/nim-result

View File

@ -11,6 +11,7 @@ import ../../app_service/service/transaction/service as transaction_service
import ../../app_service/service/collectible/service as collectible_service
import ../../app_service/service/wallet_account/service as wallet_account_service
import ../../app_service/service/setting/service as setting_service
import ../../app_service/service/bookmarks/service as bookmark_service
import ../core/local_account_settings
import ../modules/startup/module as startup_module
@ -67,6 +68,7 @@ type
collectibleService: collectible_service.Service
walletAccountService: wallet_account_service.Service
settingService: setting_service.Service
bookmarkService: bookmark_service.Service
# Core
localAccountSettings: LocalAccountSettings
@ -127,6 +129,7 @@ proc newAppController*(appService: AppService): AppController =
result.settingService, result.tokenService
)
result.transactionService = transaction_service.newService(result.walletAccountService)
result.bookmarkService = bookmark_service.newService()
# Core
@ -151,6 +154,7 @@ proc newAppController*(appService: AppService): AppController =
result.transactionService,
result.collectibleService,
result.walletAccountService,
result.bookmarkService,
result.settingService
)
@ -163,6 +167,10 @@ proc newAppController*(appService: AppService): AppController =
#################################################
proc delete*(self: AppController) =
self.contactService.delete
self.chatService.delete
self.communityService.delete
self.bookmarkService.delete
self.startupModule.delete
self.mainModule.delete
@ -217,6 +225,7 @@ proc load*(self: AppController) =
self.contactService.init()
self.chatService.init()
self.communityService.init()
self.bookmarkService.init()
self.tokenService.init()
self.walletAccountService.init()
self.transactionService.init()
@ -230,4 +239,4 @@ proc userLoggedIn*(self: AppController) =
let account = Account(name: loggedInUser.name, keyUid: loggedInUser.keyUid)
self.appService.status.events.emit("loginCompleted", AccountArgs(account: account))
#################################################
self.load()
self.load()

View File

@ -1,25 +0,0 @@
import NimQml, chronicles
import status/status
import view
logScope:
topics = "browser"
type BrowserController* = ref object
status*: Status
view*: BrowserView
variant*: QVariant
proc newController*(status: Status): BrowserController =
result = BrowserController()
result.status = status
result.view = newBrowserView(status)
result.variant = newQVariant(result.view)
proc delete*(self: BrowserController) =
delete self.variant
delete self.view
proc init*(self: BrowserController) =
self.view.init()
discard

View File

@ -1,58 +0,0 @@
import NimQml, json, chronicles
import status/[status, browser]
import types/[bookmark]
import views/bookmark_list
QtObject:
type BrowserView* = ref object of QObject
status*: Status
bookmarks*: BookmarkList
proc setup(self: BrowserView) =
self.QObject.setup
proc delete(self: BrowserView) =
self.QObject.delete
self.bookmarks.delete
proc newBrowserView*(status: Status): BrowserView =
new(result, delete)
result.bookmarks = newBookmarkList()
result.status = status
result.setup
proc init*(self: BrowserView) =
let bookmarks = self.status.browser.getBookmarks()
self.bookmarks.setNewData(bookmarks)
proc bookmarksChanged*(self: BrowserView) {.signal.}
proc getBookmarks*(self: BrowserView): QVariant {.slot.} =
return newQVariant(self.bookmarks)
QtProperty[QVariant] bookmarks:
read = getBookmarks
notify = bookmarksChanged
proc addBookmark*(self: BrowserView, url: string, name: string) {.slot.} =
let bookmark = self.status.browser.storeBookmark(Bookmark(url: url, name: name))
self.bookmarks.addBookmarkItemToList(bookmark)
self.bookmarksChanged()
proc removeBookmark*(self: BrowserView, url: string) {.slot.} =
let index = self.bookmarks.getBookmarkIndexByUrl(url)
if index == -1:
return
self.bookmarks.removeBookmarkItemFromList(index)
self.status.browser.deleteBookmark(url)
self.bookmarksChanged()
proc modifyBookmark*(self: BrowserView, originalUrl: string, newUrl: string, newName: string) {.slot.} =
let index = self.bookmarks.getBookmarkIndexByUrl(originalUrl)
if index == -1:
self.addBookmark(newUrl, newName)
return
self.bookmarks.modifyBookmarkItemFromList(index, newUrl, newName)
self.status.browser.updateBookmark(originalUrl, Bookmark(url: newUrl, name: newName))
self.bookmarksChanged()

View File

@ -1,87 +0,0 @@
import NimQml, Tables, chronicles
import sequtils as sequtils
import types/[bookmark]
type
BookmarkRoles {.pure.} = enum
Name = UserRole + 1
Url = UserRole + 2
ImageUrl = UserRole + 3
QtObject:
type
BookmarkList* = ref object of QAbstractListModel
bookmarks*: seq[Bookmark]
proc setup(self: BookmarkList) = self.QAbstractListModel.setup
proc delete(self: BookmarkList) =
self.bookmarks = @[]
self.QAbstractListModel.delete
proc newBookmarkList*(): BookmarkList =
new(result, delete)
result.bookmarks = @[]
result.setup
method rowCount*(self: BookmarkList, index: QModelIndex = nil): int = self.bookmarks.len
proc rowData(self: BookmarkList, index: int, column: string): string {.slot.} =
if (index > self.bookmarks.len - 1):
return
let bookmark = self.bookmarks[index]
case column:
of "name": result = bookmark.name
of "url": result = bookmark.url
of "imageUrl": result = bookmark.imageUrl
method data(self: BookmarkList, index: QModelIndex, role: int): QVariant =
if not index.isValid:
return
if index.row < 0 or index.row >= self.bookmarks.len:
return
let bookmarkItem = self.bookmarks[index.row]
let bookmarkItemRole = role.BookmarkRoles
case bookmarkItemRole:
of BookmarkRoles.Name: result = newQVariant(bookmarkItem.name)
of BookmarkRoles.Url: result = newQVariant(bookmarkItem.url)
of BookmarkRoles.ImageUrl: result = newQVariant(bookmarkItem.imageUrl)
method roleNames(self: BookmarkList): Table[int, string] =
{
BookmarkRoles.Name.int:"name",
BookmarkRoles.ImageUrl.int:"imageUrl",
BookmarkRoles.Url.int:"url"
}.toTable
proc addBookmarkItemToList*(self: BookmarkList, bookmark: Bookmark) =
self.beginInsertRows(newQModelIndex(), self.bookmarks.len, self.bookmarks.len)
self.bookmarks.add(bookmark)
self.endInsertRows()
proc removeBookmarkItemFromList*(self: BookmarkList, index: int) =
self.beginRemoveRows(newQModelIndex(), index, index)
self.bookmarks.delete(index)
self.endRemoveRows()
proc modifyBookmarkItemFromList*(self: BookmarkList, index: int, url: string, name: string) =
let topLeft = self.createIndex(index, index, nil)
let bottomRight = self.createIndex(index, index, nil)
self.bookmarks[index] = Bookmark(url: url, name: name)
self.dataChanged(topLeft, bottomRight, @[BookmarkRoles.Name.int, BookmarkRoles.Url.int])
proc setNewData*(self: BookmarkList, bookmarkList: seq[Bookmark]) =
self.beginResetModel()
self.bookmarks = bookmarkList
self.endResetModel()
proc getBookmarkIndexByUrl*(self: BookmarkList, url: string): int {.slot.} =
var i = 0
for bookmark in self.bookmarks:
if bookmark.url == url:
return i
i = i + 1
return -1

View File

@ -0,0 +1,43 @@
import Tables
import result
import controller_interface
import io_interface
import ../../../../../app_service/service/bookmarks/service as bookmark_service
export controller_interface
type
Controller* = ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface
bookmarkService: bookmark_service.ServiceInterface
proc newController*(delegate: io_interface.AccessInterface,
bookmarkService: bookmark_service.ServiceInterface):
Controller =
result = Controller()
result.delegate = delegate
result.bookmarkService = bookmarkService
method delete*(self: Controller) =
discard
method init*(self: Controller) =
discard
method getBookmarks*(self: Controller): seq[bookmark_service.BookmarkDto] =
return self.bookmarkService.getBookmarks()
method storeBookmark*(self: Controller, url, name: string) =
let b = self.bookmarkService.storeBookmark(url, name)
if b.isOk:
self.delegate.onBoomarkStored(url, name, b.get().imageUrl)
method deleteBookmark*(self: Controller, url: string) =
if self.bookmarkService.deleteBookmark(url):
self.delegate.onBookmarkDeleted(url)
method updateBookmark*(self: Controller, oldUrl, newUrl, newName: string) =
let b = self.bookmarkService.updateBookmark(oldUrl, newUrl, newName)
if b.isOk:
self.delegate.onBookmarkUpdated(oldUrl, newUrl, newName, b.get().imageUrl)

View File

@ -0,0 +1,23 @@
import ../../../../../app_service/service/bookmarks/service_interface as bookmark_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 getBookmarks*(self: AccessInterface): seq[bookmark_service.BookmarkDto] =
raise newException(ValueError, "No implementation available")
method storeBookmark*(self: AccessInterface, url, name: string) =
raise newException(ValueError, "No implementation available")
method deleteBookmark*(self: AccessInterface, url: string) =
raise newException(ValueError, "No implementation available")
method updateBookmark*(self: AccessInterface, oldUrl, newUrl, newName: string) =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,11 @@
import ../../../../../app_service/service/bookmarks/service_interface as bookmark_service
# Defines how parent module accesses this module
include ./private_interfaces/module_base_interface
include ./private_interfaces/module_access_interface
# Defines how this module view communicates with this module
include ./private_interfaces/module_view_delegate_interface
# Defines how this controller communicates with this module
include ./private_interfaces/module_controller_delegate_interface

View File

@ -0,0 +1,28 @@
import json, strformat
type
Item* = object
name: string
url: string
imageUrl: string
proc initItem*(name, url, imageUrl: string): Item =
result.name = name
result.url = url
result.imageUrl = imageUrl
proc `$`*(self: Item): string =
result = fmt"""BrowserItem(
name: {self.name},
url: {self.url},
imageUrl: {self.imageUrl}
]"""
proc getName*(self: Item): string =
return self.name
proc getUrl*(self: Item): string =
return self.url
proc getImageUrl*(self: Item): string =
return self.imageUrl

View File

@ -0,0 +1,128 @@
import NimQml, Tables, strutils, strformat
import item
type
ModelRole {.pure.} = enum
Name = UserRole + 1
Url = UserRole + 2
ImageUrl = UserRole + 3
QtObject:
type
Model* = ref object of QAbstractListModel
items: seq[Item]
proc delete(self: Model) =
self.items = @[]
self.QAbstractListModel.delete
proc setup(self: Model) =
self.QAbstractListModel.setup
proc newModel*(): Model =
new(result, delete)
result.setup
proc `$`*(self: Model): string =
for i in 0 ..< self.items.len:
result &= fmt"""
[{i}]:({$self.items[i]})
"""
proc modelChanged(self: Model) {.signal.}
proc getCount(self: Model): int {.slot.} =
self.items.len
QtProperty[int] count:
read = getCount
notify = countChanged
method rowCount(self: Model, index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: Model): Table[int, string] =
{
ModelRole.Name.int:"name",
ModelRole.Url.int:"url",
ModelRole.ImageUrl.int:"imageUrl"
}.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.items.len):
return
let item = self.items[index.row]
let enumRole = role.ModelRole
case enumRole:
of ModelRole.Name:
result = newQVariant(item.getName())
of ModelRole.Url:
result = newQVariant(item.getUrl())
of ModelRole.ImageUrl:
result = newQVariant(item.getImageUrl())
proc rowData(self: Model, index: int, column: string): string {.slot.} =
if (index > self.items.len - 1):
return
let bookmark = self.items[index]
case column:
of "name": result = bookmark.getName()
of "url": result = bookmark.getUrl()
of "imageUrl": result = bookmark.getImageUrl()
proc addItem*(self: Model, item: Item) =
let parentModelIndex = newQModelIndex()
defer: parentModelIndex.delete
for i in self.items:
if i.getUrl() == item.getUrl():
return
self.beginInsertRows(parentModelIndex, self.items.len, self.items.len)
self.items.add(item)
self.endInsertRows()
self.modelChanged()
proc getBookmarkIndexByUrl*(self: Model, url: string): int {.slot.} =
var index = -1
var i = -1
for item in self.items:
i += 1
if item.getUrl() == url:
index = i
break
return index
proc removeItemByUrl*(self: Model, url: string) =
var index = self.getBookmarkIndexByUrl(url)
if index == -1:
return
let parentModelIndex = newQModelIndex()
defer: parentModelIndex.delete
self.beginRemoveRows(parentModelIndex, index, index)
self.items.delete(index)
self.endRemoveRows()
self.modelChanged()
proc updateItemByUrl*(self: Model, oldUrl: string, item: Item) =
var index = self.getBookmarkIndexByUrl(oldUrl)
if index == -1:
return
let topLeft = self.createIndex(index, index, nil)
let bottomRight = self.createIndex(index, index, nil)
defer: topLeft.delete
defer: bottomRight.delete
self.items[index] = item
self.dataChanged(topLeft, bottomRight, @[ModelRole.Name.int, ModelRole.Url.int, ModelRole.ImageUrl.int])
self.modelChanged()

View File

@ -0,0 +1,72 @@
import NimQml
import io_interface
import ../io_interface as delegate_interface
import item
import view
import controller
import ../../../../core/global_singleton
import ../../../../../app_service/service/bookmarks/service as bookmark_service
export io_interface
type
Module* = ref object of io_interface.AccessInterface
delegate: delegate_interface.AccessInterface
view: View
viewVariant: QVariant
moduleLoaded: bool
controller: controller.AccessInterface
proc newModule*(delegate: delegate_interface.AccessInterface, bookmarkService: bookmark_service.Service): Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.moduleLoaded = false
result.controller = controller.newController(result, bookmarkService)
method delete*(self: Module) =
self.view.delete
self.viewVariant.delete
self.controller.delete
method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("bookmarkModule", self.viewVariant)
self.view.load()
let bookmarks = self.controller.getBookmarks()
for b in bookmarks:
self.view.addItem(initItem(b.name, b.url, b.imageUrl))
method isLoaded*(self: Module): bool =
return self.moduleLoaded
proc checkIfModuleDidLoad(self: Module) =
self.moduleLoaded = true
self.delegate.bookmarkDidLoad()
method providerDidLoad*(self: Module) =
self.checkIfModuleDidLoad()
method viewDidLoad*(self: Module) =
self.checkIfModuleDidLoad()
method storeBookmark*(self: Module, url: string, name: string) =
if url == "":
self.view.addItem(initItem(name, url, "")) # These URLs are not stored but added direclty to the UI
else:
self.controller.storeBookmark(url, name)
method onBoomarkStored*(self: Module, url: string, name: string, imageUrl: string) =
self.view.addItem(initItem(name, url, imageUrl))
method deleteBookmark*(self: Module, url: string) =
self.controller.deleteBookmark(url)
method onBookmarkDeleted*(self: Module, url: string) =
self.view.removeBookmarkByUrl(url)
method updateBookmark*(self: Module, oldUrl: string, newUrl: string, newName: string) =
self.controller.updateBookmark(oldUrl, newUrl, newName)
method onBookmarkUpdated*(self: Module, oldUrl: string, newUrl: string, newName: string, newImageUrl: string) =
self.view.updateBookmarkByUrl(oldUrl, initItem(newName, newUrl, newImageUrl))

View File

@ -0,0 +1,8 @@
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")

View File

@ -0,0 +1,5 @@
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
# Since nim doesn't support using concepts in second level nested types we
# define delegate interfaces within access interface.

View File

@ -0,0 +1,20 @@
method getBookmarks*(self: AccessInterface): seq[bookmark_service.BookmarkDto] =
raise newException(ValueError, "No implementation available")
method storeBookmark*(self: AccessInterface, url, name: string) =
raise newException(ValueError, "No implementation available")
method deleteBookmark*(self: AccessInterface, url: string) =
raise newException(ValueError, "No implementation available")
method updateBookmark*(self: AccessInterface, oldUrl, newUrl, newName: string) =
raise newException(ValueError, "No implementation available")
method onBoomarkStored*(self: AccessInterface, url: string, name: string, imageUrl: string) =
raise newException(ValueError, "No implementation available")
method onBookmarkDeleted*(self: AccessInterface, url: string) =
raise newException(ValueError, "No implementation available")
method onBookmarkUpdated*(self: AccessInterface, oldUrl: string, newUrl: string, newName: string, newImageUrl: string) =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,2 @@
method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,56 @@
import NimQml
import io_interface
import model
import item
QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
model: Model
modelVariant: QVariant
proc setup(self: View) =
self.QObject.setup
proc delete*(self: View) =
self.model.delete
self.modelVariant.delete
self.QObject.delete
proc newView*(delegate: io_interface.AccessInterface): View =
new(result, delete)
result.delegate = delegate
result.model = newModel()
result.modelVariant = newQVariant(result.model)
result.setup()
proc load*(self: View) =
self.delegate.viewDidLoad()
proc addItem*(self: View, item: Item) =
self.model.addItem(item)
proc modelChanged*(self: View) {.signal.}
proc getModel(self: View): QVariant {.slot.} =
return self.modelVariant
QtProperty[QVariant] model:
read = getModel
notify = modelChanged
proc addBookmark(self: View, url: string, name: string,) {.slot.} =
self.delegate.storeBookmark(url, name)
proc deleteBookmark(self: View, url: string) {.slot.} =
self.delegate.deleteBookmark(url)
proc removeBookmarkByUrl*(self: View, url: string) =
self.model.removeItemByUrl(url)
proc updateBookmark(self: View, oldUrl: string, newUrl: string, newName: string) {.slot.} =
self.delegate.updateBookmark(oldUrl, newUrl, newName)
proc updateBookmarkByUrl*(self: View, oldUrl: string, item: Item) =
self.model.updateItemByUrl(oldUrl, item)

View File

@ -0,0 +1,14 @@
# Defines how parent module accesses this module
include ./private_interfaces/module_base_interface
include ./private_interfaces/module_access_interface
# Defines how this module view communicates with this module
include ./private_interfaces/module_view_delegate_interface
# Defines how this controller communicates with this module
include ./private_interfaces/module_controller_delegate_interface
# Defines how submodules of this module communicate with this module
# will be added if needed
include ./private_interfaces/module_provider_delegate_interface
include ./private_interfaces/module_bookmark_delegate_interface

View File

@ -0,0 +1,63 @@
import NimQml
import io_interface
import ../io_interface as delegate_interface
import view
import ../../../core/global_singleton
import provider/module as provider_module
import bookmark/module as bookmark_module
import ../../../../app_service/service/bookmarks/service as bookmark_service
export io_interface
type
Module* = ref object of io_interface.AccessInterface
delegate: delegate_interface.AccessInterface
view: View
viewVariant: QVariant
moduleLoaded: bool
providerModule: provider_module.AccessInterface
bookmarkModule: bookmark_module.AccessInterface
proc newModule*(delegate: delegate_interface.AccessInterface, bookmarkService: bookmark_service.Service): Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.moduleLoaded = false
result.providerModule = provider_module.newModule(result)
result.bookmarkModule = bookmark_module.newModule(result, bookmarkService)
method delete*(self: Module) =
self.view.delete
self.viewVariant.delete
self.providerModule.delete
self.bookmarkModule.delete
method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("browserSection", self.viewVariant)
self.providerModule.load()
self.bookmarkModule.load()
self.view.load()
method isLoaded*(self: Module): bool =
return self.moduleLoaded
proc checkIfModuleDidLoad(self: Module) =
if(not self.providerModule.isLoaded()):
return
if(not self.bookmarkModule.isLoaded()):
return
self.moduleLoaded = true
self.delegate.browserSectionDidLoad()
method providerDidLoad*(self: Module) =
self.checkIfModuleDidLoad()
method bookmarkDidLoad*(self: Module) =
self.checkIfModuleDidLoad()
method viewDidLoad*(self: Module) =
self.checkIfModuleDidLoad()

View File

@ -0,0 +1,8 @@
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")

View File

@ -0,0 +1,5 @@
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
# Since nim doesn't support using concepts in second level nested types we
# define delegate interfaces within access interface.

View File

@ -0,0 +1,2 @@
method bookmarkDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,2 @@
method providerDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,2 @@
method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,6 @@
# Defines how parent module accesses this module
include ./private_interfaces/module_base_interface
include ./private_interfaces/module_access_interface
# Defines how this module view communicates with this module
include ./private_interfaces/module_view_delegate_interface

View File

@ -0,0 +1,25 @@
import io_interface, view
import ../io_interface as delegate_interface
export io_interface
type
Module* = ref object of io_interface.AccessInterface
delegate: delegate_interface.AccessInterface
view: View
moduleLoaded: bool
proc newModule*(delegate: delegate_interface.AccessInterface): Module =
result = Module()
result.delegate = delegate
result.view = newView(result)
result.moduleLoaded = false
method delete*(self: Module) =
self.view.delete
method load*(self: Module) =
self.moduleLoaded = true
self.delegate.providerDidLoad()
method isLoaded*(self: Module): bool =
return self.moduleLoaded

View File

@ -0,0 +1,8 @@
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")

View File

@ -0,0 +1,5 @@
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
# Since nim doesn't support using concepts in second level nested types we
# define delegate interfaces within access interface.

View File

@ -0,0 +1,2 @@
method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,17 @@
import NimQml
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

View File

@ -0,0 +1,21 @@
import NimQml
import io_interface
QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
proc setup(self: View) =
self.QObject.setup
proc delete*(self: View) =
self.QObject.delete
proc newView*(delegate: io_interface.AccessInterface): View =
new(result, delete)
result.delegate = delegate
result.setup()
proc load*(self: View) =
self.delegate.viewDidLoad()

View File

@ -11,6 +11,7 @@ include ./private_interfaces/module_controller_delegate_interface
# Defines how submodules of this module communicate with this module
include ./private_interfaces/module_chat_section_delegate_interface
include ./private_interfaces/module_community_section_delegate_interface
include ./private_interfaces/module_browser_section_delegate_interface
# This way (using concepts) is used only for the modules managed by AppController
type

View File

@ -11,8 +11,8 @@ type
mentionsCount: int
unviewedMessagesCount: int
proc initItem*(id: string, sectionType: int, name, image, icon, color: string,
mentionsCount, unviewedMessagesCount: int): Item =
proc initItem*(id: string, sectionType: int, name, image = "", icon = "", color = "",
mentionsCount:int = 0, unviewedMessagesCount: int = 0): Item =
result.id = id
result.sectionType = sectionType
result.name = name

View File

@ -5,6 +5,7 @@ import ../../core/global_singleton
import chat_section/module as chat_section_module
import wallet_section/module as wallet_section_module
import browser_section/module as browser_section_module
import ../../../app_service/service/keychain/service as keychain_service
import ../../../app_service/service/accounts/service_interface as accounts_service
@ -15,13 +16,14 @@ import ../../../app_service/service/transaction/service as transaction_service
import ../../../app_service/service/collectible/service as collectible_service
import ../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../app_service/service/setting/service as setting_service
import ../../../app_service/service/bookmarks/service as bookmark_service
import eventemitter
export io_interface
type
ChatSectionType* {.pure.} = enum
SectionType* {.pure.} = enum
Chat = 0
Community,
Wallet,
@ -39,6 +41,8 @@ type
chatSectionModule: chat_section_module.AccessInterface
communitySectionsModule: OrderedTable[string, chat_section_module.AccessInterface]
walletSectionModule: wallet_section_module.AccessInterface
browserSectionModule: browser_section_module.AccessInterface
moduleLoaded: bool
proc newModule*[T](
delegate: T,
@ -51,6 +55,7 @@ proc newModule*[T](
transactionService: transaction_service.Service,
collectibleService: collectible_service.Service,
walletAccountService: wallet_account_service.Service,
bookmarkService: bookmark_service.Service,
settingService: setting_service.Service
): Module[T] =
result = Module[T]()
@ -59,6 +64,7 @@ proc newModule*[T](
result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, events, keychainService,
accountsService, communityService)
result.moduleLoaded = false
# Submodules
result.chatSectionModule = chat_section_module.newModule(result, "chat",
@ -79,13 +85,16 @@ proc newModule*[T](
walletAccountService,
settingService
)
result.browserSectionModule = browser_section_module.newModule(result, bookmarkService)
method delete*[T](self: Module[T]) =
self.chatSectionModule.delete
for cModule in self.communitySectionsModule.values:
cModule.delete
self.communitySectionsModule.clear
self.walletSectionModule.delete
self.browserSectionModule.delete
self.view.delete
self.viewVariant.delete
self.controller.delete
@ -95,13 +104,13 @@ method load*[T](self: Module[T]) =
self.controller.init()
self.view.load()
let chatSectionItem = initItem("chat", ChatSectionType.Chat.int, "Chat", "",
let chatSectionItem = initItem("chat", SectionType.Chat.int, "Chat", "",
"chat", "", 0, 0)
self.view.addItem(chatSectionItem)
let communities = self.controller.getCommunities()
for c in communities:
self.view.addItem(initItem(c.id, ChatSectionType.Community.int, c.name,
self.view.addItem(initItem(c.id, SectionType.Community.int, c.name,
if not c.images.isNil: c.images.thumbnail else: "",
"", c.color, 0, 0))
@ -109,13 +118,21 @@ method load*[T](self: Module[T]) =
for cModule in self.communitySectionsModule.values:
cModule.load()
let walletSectionItem = initItem("wallet", ChatSectionType.Wallet.int, "Wallet", "",
let walletSectionItem = initItem("wallet", SectionType.Wallet.int, "Wallet", "",
"wallet", "", 0, 0)
self.view.addItem(chatSectionItem)
self.walletSectionModule.load()
self.browserSectionModule.load()
let browserSectionItem = initItem("browser", SectionType.Browser.int, "Browser")
self.view.addItem(browserSectionItem)
proc checkIfModuleDidLoad [T](self: Module[T]) =
if self.moduleLoaded:
return
if(not self.chatSectionModule.isLoaded()):
return
@ -123,10 +140,13 @@ proc checkIfModuleDidLoad [T](self: Module[T]) =
if(not cModule.isLoaded()):
return
if (not self.walletSectionModule.isLoaded()):
return
if(not self.browserSectionModule.isLoaded()):
return
self.moduleLoaded = true
self.delegate.mainDidLoad()
method chatSectionDidLoad*[T](self: Module[T]) =
@ -138,6 +158,9 @@ method communitySectionDidLoad*[T](self: Module[T]) =
proc walletSectionDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()
method browserSectionDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()
method viewDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()

View File

@ -0,0 +1,2 @@
method browserSectionDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -1,2 +1,2 @@
method chatSectionDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,14 @@
import json
include ../../../common/json_utils
type BookmarkDto* = object
name*: string
url*: string
imageUrl*: string
proc toBookmarkDto*(jsonObj: JsonNode): BookmarkDto =
result = BookmarkDto()
discard jsonObj.getProp("name", result.name)
discard jsonObj.getProp("url", result.url)
discard jsonObj.getProp("imageUrl", result.imageUrl)

View File

@ -0,0 +1,77 @@
import Tables, json, sequtils, strformat, chronicles
import result
include ../../common/json_utils
import service_interface, dto/bookmark
import status/statusgo_backend_new/bookmarks as status_go
export service_interface
logScope:
topics = "bookmarks-service"
type
Service* = ref object of ServiceInterface
bookmarks: Table[string, BookmarkDto] # [url, BookmarkDto]
type R = Result[BookmarkDto, string]
method delete*(self: Service) =
discard
proc newService*(): Service =
result = Service()
result.bookmarks = initTable[string, BookmarkDto]()
method init*(self: Service) =
try:
let response = status_go.getBookmarks()
for bookmark in response.result.getElems().mapIt(it.toBookmarkDto()):
self.bookmarks[bookmark.url] = bookmark
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
method getBookmarks*(self: Service): seq[BookmarkDto] =
return toSeq(self.bookmarks.values)
method storeBookmark*(self: Service, url, name: string): R =
try:
let response = status_go.storeBookmark(url, name).result
self.bookmarks[url] = BookmarkDto()
self.bookmarks[url].url = url
self.bookmarks[url].name = name
discard response.getProp("imageUrl", self.bookmarks[url].imageUrl)
result.ok self.bookmarks[url]
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
result.err errDescription
method deleteBookmark*(self: Service, url: string): bool =
try:
if not self.bookmarks.hasKey(url):
return
discard status_go.deleteBookmark(url)
self.bookmarks.del(url)
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
return
return true
method updateBookmark*(self: Service, oldUrl, newUrl, newName: string): R =
try:
if not self.bookmarks.hasKey(oldUrl):
return
let response = status_go.updateBookmark(oldUrl, newUrl, newName).result
self.bookmarks.del(oldUrl)
self.bookmarks[newUrl].url = newUrl
self.bookmarks[newUrl].name = newName
discard response.getProp("imageUrl", self.bookmarks[newurl].imageUrl)
result.ok self.bookmarks[newUrl]
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
result.err errDescription

View File

@ -0,0 +1,29 @@
import ./dto/bookmark as bookmark_dto
export bookmark_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")
import results
type R = Result[BookmarkDto, string]
method getBookmarks*(self: ServiceInterface): seq[BookmarkDto] {.base.} =
raise newException(ValueError, "No implementation available")
method storeBookmark*(self: ServiceInterface, url, name: string): R {.base.} =
raise newException(ValueError, "No implementation available")
method deleteBookmark*(self: ServiceInterface, url: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
method updateBookmark*(self: ServiceInterface, oldUrl, newUrl, newName: string): R {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -5,7 +5,6 @@ import app/wallet/v1/core as wallet
import app/wallet/v2/core as walletV2
import app/node/core as node
import app/utilsView/core as utilsView
import app/browser/core as browserView
import app/provider/core as provider
import app/keycard/core as keycard
import status/types/[account]
@ -159,10 +158,6 @@ proc mainProc() =
defer: utilsController.delete()
singletonInstance.engine.setRootContextProperty("utilsModel", utilsController.variant)
var browserController = browserView.newController(status)
defer: browserController.delete()
singletonInstance.engine.setRootContextProperty("browserModel", browserController.variant)
var provider = provider.newController(status)
defer: provider.delete()
singletonInstance.engine.setRootContextProperty("web3Provider", provider.variant)
@ -180,7 +175,6 @@ proc mainProc() =
provider.init()
chat.init()
utilsController.init()
browserController.init()
node.init()
wallet.onLogin()

View File

@ -161,7 +161,7 @@ Rectangle {
onAddNewFavoritelClicked: {
if (!browserHeader.currentFavorite) {
// remove "add favorite" button at the end, add new bookmark, add "add favorite" button back
BookmarksStore.removeBookmark("")
BookmarksStore.deleteBookmark("")
BookmarksStore.addBookmark(currentWebView.url, currentWebView.title)
BookmarksStore.addBookmark("", qsTr("Add Favorite"))
}
@ -345,8 +345,8 @@ Rectangle {
}
Connections {
target: BookmarksStore.browserModelInst
onBookmarksChanged: {
target: BookmarksStore.bookmarksModel
onModelChanged: {
browserHeader.currentFavorite = Qt.binding(function () {return BookmarksStore.getCurrentFavorite(currentWebView.url)})
}
}

View File

@ -131,7 +131,7 @@ ModalPopup {
anchors.bottom: parent.bottom
type: StatusBaseButton.Type.Danger
onClicked: {
BookmarksStore.removeBookmark(popup.ogUrl)
BookmarksStore.deleteBookmark(popup.ogUrl)
popup.close()
}
}
@ -153,11 +153,11 @@ ModalPopup {
if (!popup.modifiyModal) {
// remove "add favorite" button at the end, add new bookmark, add "add favorite" button back
BookmarksStore.removeBookmark("")
BookmarksStore.deleteBookmark("")
BookmarksStore.addBookmark(urlInput.text, nameInput.text)
BookmarksStore.addBookmark("", qsTr("Add Favorite"))
} else if (popup.ogName !== nameInput.text || popup.ogUrl !== urlInput.text) {
BookmarksStore.modifyBookmark(popup.ogUrl, urlInput.text, nameInput.text)
BookmarksStore.updateBookmark(popup.ogUrl, urlInput.text, nameInput.text)
}
popup.close()

View File

@ -55,7 +55,7 @@ PopupMenu {
icon.width: 16
icon.height: 16
onTriggered: {
BookmarksStore.removeBookmark(root.url)
BookmarksStore.deleteBookmark(root.url)
}
}
}

View File

@ -5,44 +5,42 @@ import QtQuick 2.13
QtObject {
id: root
property var browserModelInst: browserModel
// Seems like this vould be a BookMarks Store which has everything related to bookmarks
property var bookmarksModel: browserModel.bookmarks
property var bookmarksModel: bookmarkModule.model
function addBookmark(url, name)
{
browserModel.addBookmark(url, name)
bookmarkModule.addBookmark(url, name)
}
function removeBookmark(url)
function deleteBookmark(url)
{
browserModel.removeBookmark(url)
bookmarkModule.deleteBookmark(url)
}
function modifyBookmark(originalUrl, newUrl, newName)
function updateBookmark(originalUrl, newUrl, newName)
{
browserModel.modifyBookmark(originalUrl, newUrl, newName)
bookmarkModule.updateBookmark(originalUrl, newUrl, newName)
}
function getBookmarkIndexByUrl(url)
{
return browserModel.bookmarks.getBookmarkIndexByUrl(url)
return bookmarkModule.model.getBookmarkIndexByUrl(url)
}
function getCurrentFavorite(url) {
if (!url) {
return null
}
const index = browserModel.bookmarks.getBookmarkIndexByUrl(url)
const index = bookmarkModule.model.getBookmarkIndexByUrl(url)
if (index === -1) {
return null
}
return {
url: url,
name: browserModel.bookmarks.rowData(index, 'name'),
image: browserModel.bookmarks.rowData(index, 'imageUrl')
name: bookmarkModule.model.rowData(index, 'name'),
image: bookmarkModule.model.rowData(index, 'imageUrl')
}
}
// END >> Seems like this vould be a BookMarks Store which has everything related to bookmarks

View File

@ -184,7 +184,7 @@ WebEngineView {
Component.onCompleted: {
// Add fav button at the end of the grid
var index = BookmarksStore.getBookmarkIndexByUrl("")
if (index !== -1) { BookmarksStore.removeBookmark("") }
if (index !== -1) { BookmarksStore.deleteBookmark("") }
BookmarksStore.addBookmark("", qsTr("Add Favorite"))
}
}

1
vendor/nim-result vendored Submodule

@ -0,0 +1 @@
Subproject commit 7c5f2423fe6042adc667ce7630a5b13349a13654

2
vendor/status-lib vendored

@ -1 +1 @@
Subproject commit 07593887107520c770da70fc42a597cf275ea68e
Subproject commit b6a5b7e4ed2bf17eae04d54472a1cf4d0605757c