diff --git a/src/app/browser/core.nim b/src/app/browser/core.nim new file mode 100644 index 0000000000..e6ecd4cce1 --- /dev/null +++ b/src/app/browser/core.nim @@ -0,0 +1,26 @@ +import NimQml, chronicles +import ../../status/status +import ../../status/libstatus/types as status_types +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 diff --git a/src/app/browser/view.nim b/src/app/browser/view.nim new file mode 100644 index 0000000000..f82add47aa --- /dev/null +++ b/src/app/browser/view.nim @@ -0,0 +1,44 @@ +import NimQml, json, chronicles +import ../../status/status +import ../../status/libstatus/types as status_types +import ../../status/libstatus/settings as status_settings +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) = + var bookmarks: seq[Bookmark] = @[] + try: + let bookmarksJSON = status_settings.getSetting[string](Setting.Bookmarks, "[]").parseJson + for bookmark in bookmarksJSON: + bookmarks.add(Bookmark(url: bookmark["url"].getStr, name: bookmark["name"].getStr, image: "")) + except: + # Bad JSON. Just use the empty array + discard + self.bookmarks.setNewData(bookmarks) + + proc getBookmarks*(self: BrowserView): QVariant {.slot.} = + return newQVariant(self.bookmarks) + + QtProperty[QVariant] bookmarks: + read = getBookmarks + + proc addBookmark*(self: BrowserView, url: string, name: string) {.slot.} = + self.bookmarks.addBookmarkItemToList(Bookmark(url: url, name: name, image: "")) + discard status_settings.saveSetting(Setting.Bookmarks, $(%self.bookmarks.bookmarks)) diff --git a/src/app/browser/views/bookmark_list.nim b/src/app/browser/views/bookmark_list.nim new file mode 100644 index 0000000000..c82307bbda --- /dev/null +++ b/src/app/browser/views/bookmark_list.nim @@ -0,0 +1,78 @@ +import NimQml, Tables +import sequtils as sequtils + + +type Bookmark* = ref object + name*: string + url*: string + image*: string + +type + BookmarkRoles {.pure.} = enum + Name = UserRole + 1, + Url = UserRole + 2 + Image = 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 + + 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.Image: result = newQVariant(bookmarkItem.image) + + method roleNames(self: BookmarkList): Table[int, string] = + { + BookmarkRoles.Name.int:"name", + BookmarkRoles.Url.int:"url", + BookmarkRoles.Image.int: "image", + }.toTable + + proc addBookmarkItemToList*(self: BookmarkList, bookmark: Bookmark) = + self.beginInsertRows(newQModelIndex(), self.bookmarks.len, self.bookmarks.len) + self.bookmarks.add(bookmark) + self.endInsertRows() + +# proc getBookmarkIndexByUrl*(self: BookmarkList, bookmark: Bookmark) + + proc removeBookmarkItemFromList*(self: BookmarkList, index: int) = + self.beginRemoveRows(newQModelIndex(), index, index) + self.bookmarks.delete(index) + self.endRemoveRows() + + + proc setNewData*(self: BookmarkList, bookmarkList: seq[Bookmark]) = + self.beginResetModel() + self.bookmarks = bookmarkList + self.endResetModel() + + proc getBookmarkByUrl*(self: BookmarkList, url: string): Bookmark = + for bookmark in self.bookmarks: + if bookmark.url == url: + return bookmark + diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim index 1623937175..6277991d94 100644 --- a/src/nim_status_client.nim +++ b/src/nim_status_client.nim @@ -4,6 +4,7 @@ import app/chat/core as chat import app/wallet/core as wallet import app/node/core as node import app/utilsView/core as utilsView +import app/browser/core as browserView import app/profile/core as profile import app/onboarding/core as onboarding import app/login/core as login @@ -78,6 +79,9 @@ proc mainProc() = var utilsController = utilsView.newController(status) engine.setRootContextProperty("utilsModel", utilsController.variant) + var browserController = browserView.newController(status) + engine.setRootContextProperty("browserModel", browserController.variant) + proc changeLanguage(locale: string) = engine.setTranslationPackage(joinPath(i18nPath, fmt"qml_{locale}.qm")) @@ -102,6 +106,7 @@ proc mainProc() = provider.init() chat.init() utilsController.init() + browserController.init() wallet.checkPendingTransactions() wallet.start() @@ -125,6 +130,7 @@ proc mainProc() = chat.delete() profile.delete() utilsController.delete() + browserController.delete() # Initialize only controllers whose init functions diff --git a/src/status/libstatus/settings.nim b/src/status/libstatus/settings.nim index 9bea2a5be0..d06b0360e1 100644 --- a/src/status/libstatus/settings.nim +++ b/src/status/libstatus/settings.nim @@ -1,5 +1,5 @@ import core, ./types, ../signals/types as statusgo_types, ./accounts/constants, ./utils -import json, tables, sugar, sequtils, strutils +import json, tables, sugar, sequtils, chronicles import json_serialization import locks @@ -28,6 +28,7 @@ proc getSettings*(useCached: bool = true, keepSensitiveData: bool = false): Json withLock settingsLock: if useCached and not dirty and not keepSensitiveData: result = settings + # debug "setting", settings else: result = callPrivateRPC("settings_getSettings").parseJSON()["result"] if (keepSensitiveData): diff --git a/src/status/libstatus/types.nim b/src/status/libstatus/types.nim index 598003961a..69c04a03ff 100644 --- a/src/status/libstatus/types.nim +++ b/src/status/libstatus/types.nim @@ -150,6 +150,7 @@ type Setting* {.pure.} = enum Appearance = "appearance", + Bookmarks = "bookmarks", Currency = "currency" EtherscanLink = "etherscan-link" InstallationId = "installation-id" diff --git a/ui/app/AppLayouts/Browser/BrowserLayout.qml b/ui/app/AppLayouts/Browser/BrowserLayout.qml index 19ec5c4b1e..924c1d7ae2 100644 --- a/ui/app/AppLayouts/Browser/BrowserLayout.qml +++ b/ui/app/AppLayouts/Browser/BrowserLayout.qml @@ -11,6 +11,7 @@ import "../../../shared" import "../../../shared/status" import "../../../imports" import "../Chat/ChatColumn/ChatComponents" +import "./components" // Code based on https://code.qt.io/cgit/qt/qtwebengine.git/tree/examples/webengine/quicknanobrowser/BrowserWindow.qml?h=5.15 // Licensed under BSD @@ -612,37 +613,35 @@ Rectangle { anchors.topMargin: 60 } - Row { + Item { anchors.horizontalCenter: emptyPageImage.horizontalCenter anchors.top: emptyPageImage.bottom anchors.topMargin: 30 - Item { - width: bookmarkItem.width - height: bookmarkItem.height - Item { - id: bookmarkItem - width: childrenRect.width - height: childrenRect.height - SVGImage { - id: bookmarkImage - source: "../../img/globe.svg" - width: 48 - height: 48 - } + width: parent.width - Style.current.bigPadding * 2 - StyledText { - text: "site.com" - anchors.horizontalCenter: bookmarkImage.horizontalCenter - anchors.top: bookmarkImage.bottom - anchors.topMargin: Style.current.halfPadding - } + ListView { + id: bookmarkList + model: browserModel.bookmarks + spacing: Style.current.padding + orientation : ListView.Horizontal + anchors.horizontalCenter: parent.horizontalCenter + anchors.horizontalCenterOffset: -(addBookmarkBtn.width + spacing) /2 + width: Math.min(childrenRect.width, parent.width - addBookmarkBtn.width - spacing) + delegate: BookmarkButton { + text: name + onClicked: Qt.openUrlExternally(url) + } + } + BookmarkButton { + id: addBookmarkBtn + text: qsTr("Add favorite") + onClicked: { + // TODO add a popup + browserModel.addBookmark("https://dap.ps/", "dap.ps") } - MouseArea { - anchors.fill: bookmarkItem - cursorShape: Qt.PointingHandCursor - onClicked: console.log('Go to bookmark') - } + anchors.left: bookmarkList.right + anchors.leftMargin: bookmarkList.spacing } } } diff --git a/ui/app/AppLayouts/Browser/components/BookmarkButton.qml b/ui/app/AppLayouts/Browser/components/BookmarkButton.qml new file mode 100644 index 0000000000..69b8ded2dd --- /dev/null +++ b/ui/app/AppLayouts/Browser/components/BookmarkButton.qml @@ -0,0 +1,38 @@ +import QtQuick 2.13 +import "../../../../shared" +import "../../../../shared/status" +import "../../../../imports" + +Item { + property url source: "../../../img/globe.svg" + property string text + signal clicked + + id: root + width: 74 + height: bookmarkImage.height + bookmarkName.height + Style.current.halfPadding + + SVGImage { + id: bookmarkImage + source: root.source + anchors.horizontalCenter: parent.horizontalCenter + width: 48 + height: 48 + } + + StyledText { + id: bookmarkName + text: root.text + width: parent.width + anchors.top: bookmarkImage.bottom + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + anchors.topMargin: Style.current.halfPadding + } + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: root.clicked() + } +} diff --git a/ui/nim-status-client.pro b/ui/nim-status-client.pro index 591af68cbd..235375e32e 100644 --- a/ui/nim-status-client.pro +++ b/ui/nim-status-client.pro @@ -130,6 +130,7 @@ DISTFILES += \ app/AppLayouts/Browser/DownloadBar.qml \ app/AppLayouts/Browser/DownloadElement.qml \ app/AppLayouts/Browser/FaviconImage.qml \ + app/AppLayouts/Browser/components/BookmarkButton.qml \ app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandButton.qml \ app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandModal.qml \ app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandsPopup.qml \ diff --git a/vendor/status-go b/vendor/status-go index d04e54e54e..b2d8f7f416 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit d04e54e54e8ea85c9bd35aff5482e064f5ee76b0 +Subproject commit b2d8f7f416a276f1e03282cd95cf43b187e12c5f