diff --git a/src/app/browser/view.nim b/src/app/browser/view.nim
index f82add47aa..bc50c34f5d 100644
--- a/src/app/browser/view.nim
+++ b/src/app/browser/view.nim
@@ -33,12 +33,34 @@ QtObject:
discard
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.} =
self.bookmarks.addBookmarkItemToList(Bookmark(url: url, name: name, image: ""))
discard status_settings.saveSetting(Setting.Bookmarks, $(%self.bookmarks.bookmarks))
+ self.bookmarksChanged()
+
+ proc removeBookmark*(self: BrowserView, url: string) {.slot.} =
+ let index = self.bookmarks.getBookmarkIndexByUrl(url)
+ if index == -1:
+ return
+ self.bookmarks.removeBookmarkItemFromList(index)
+ discard status_settings.saveSetting(Setting.Bookmarks, $(%self.bookmarks.bookmarks))
+ self.bookmarksChanged()
+
+ proc modifyBookmark*(self: BrowserView, ogUrl: string, newUrl: string, newName: string) {.slot.} =
+ let index = self.bookmarks.getBookmarkIndexByUrl(ogUrl)
+ if index == -1:
+ # Somehow we don't know this URL. Let's just add it as a new one
+ self.addBookmark(newUrl, newName)
+ return
+ self.bookmarks.modifyBookmarkItemFromList(index, newUrl, newName)
+ discard status_settings.saveSetting(Setting.Bookmarks, $(%self.bookmarks.bookmarks))
+ self.bookmarksChanged()
diff --git a/src/app/browser/views/bookmark_list.nim b/src/app/browser/views/bookmark_list.nim
index c82307bbda..ea61b35b8b 100644
--- a/src/app/browser/views/bookmark_list.nim
+++ b/src/app/browser/views/bookmark_list.nim
@@ -1,4 +1,4 @@
-import NimQml, Tables
+import NimQml, Tables, chronicles
import sequtils as sequtils
@@ -29,9 +29,17 @@ QtObject:
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 "image": result = bookmark.image
+
method data(self: BookmarkList, index: QModelIndex, role: int): QVariant =
if not index.isValid:
return
@@ -58,21 +66,27 @@ QtObject:
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 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, image: "")
+ 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 getBookmarkByUrl*(self: BookmarkList, url: string): Bookmark =
+ proc getBookmarkIndexByUrl*(self: BookmarkList, url: string): int {.slot.} =
+ var i = 0
for bookmark in self.bookmarks:
if bookmark.url == url:
- return bookmark
+ return i
+ i = i + 1
+ return -1
diff --git a/ui/app/AppLayouts/Browser/AddFavoriteModal.qml b/ui/app/AppLayouts/Browser/AddFavoriteModal.qml
index 8d35f5e70b..893ab68be1 100644
--- a/ui/app/AppLayouts/Browser/AddFavoriteModal.qml
+++ b/ui/app/AppLayouts/Browser/AddFavoriteModal.qml
@@ -1,21 +1,52 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
+import QtGraphicalEffects 1.13
import "../../../imports"
import "../../../shared"
+import "../../../shared/status"
ModalPopup {
property string urlError: ""
property string nameError: ""
+ property string ogUrl
+ property string ogName
+ property bool modifiyModal: false
id: popup
- width: 480
- height: 480
+ width: modifiyModal ? 345 : 480
+ height: modifiyModal ? 345 : 480
+
+ modal: !modifiyModal
+
+ background: Rectangle {
+ id: bgPopup
+ color: Style.current.background
+ radius: Style.current.radius
+ layer.enabled: true
+ layer.effect: DropShadow{
+ width: bgPopup.width
+ height: bgPopup.height
+ x: bgPopup.x
+ y: bgPopup.y + 10
+ visible: bgPopup.visible
+ source: bgPopup
+ horizontalOffset: 0
+ verticalOffset: 5
+ radius: 10
+ samples: 15
+ color: "#22000000"
+ }
+ }
onOpened: {
urlInput.forceActiveFocus(Qt.MouseFocusReason)
}
+ onClosed: {
+ reset()
+ }
+
function validate() {
urlError = ""
if (!urlInput.text) {
@@ -29,7 +60,19 @@ ModalPopup {
return !urlError && !nameError
}
- title: qsTr("Add favorite")
+ function reset() {
+ modifiyModal = false
+ urlError = ""
+ nameError = ""
+ ogUrl = ""
+ ogName = ""
+ x = Math.round(((parent ? parent.width : 0) - width) / 2)
+ y = Math.round(((parent ? parent.height : 0) - height) / 2)
+ }
+
+ title: modifiyModal ?
+ qsTr("Favorite added") :
+ qsTr("Add favorite")
Column {
width: parent.width
@@ -41,6 +84,7 @@ ModalPopup {
placeholderText: qsTr("Paste URL")
pasteFromClipboard: true
validationError: popup.urlError
+ text: popup.ogUrl
}
Input {
@@ -48,22 +92,51 @@ ModalPopup {
label: qsTr("Name")
placeholderText: qsTr("Name the website")
validationError: popup.nameError
+ text: popup.ogName
}
}
- footer: StyledButton {
- id: addBtn
- anchors.right: parent.right
- anchors.rightMargin: Style.current.smallPadding
- label: qsTr("Add")
- anchors.bottom: parent.bottom
- onClicked: {
- if (!validate()) {
- return
- }
+ footer: Item {
+ width: parent.width
+ height: parent.height
- browserModel.addBookmark(urlInput.text, nameInput.text)
- popup.close()
+ StatusButton {
+ id: removeBtn
+ anchors.right: addBtn.left
+ anchors.rightMargin: Style.current.padding
+ visible: popup.modifiyModal
+ text: qsTr("Remove")
+ anchors.bottom: parent.bottom
+ color: Style.current.danger
+ bgColor: Utils.setColorAlpha(Style.current.danger, 0.1)
+ bgHoverColor: Utils.setColorAlpha(Style.current.danger, 0.2)
+ onClicked: {
+ browserModel.removeBookmark(popup.ogUrl)
+ popup.close()
+ }
+ }
+
+ StatusButton {
+ id: addBtn
+ anchors.right: parent.right
+ anchors.rightMargin: Style.current.smallPadding
+ text: popup.modifiyModal ?
+ qsTr("Done") :
+ qsTr("Add")
+ anchors.bottom: parent.bottom
+ onClicked: {
+ if (!validate()) {
+ return
+ }
+
+ if (!popup.modifiyModal) {
+ browserModel.addBookmark(urlInput.text, nameInput.text)
+ } else if (popup.ogName !== nameInput.text || popup.ogUrl !== urlInput.text) {
+ browserModel.modifyBookmark(popup.ogUrl, urlInput.text, nameInput.text)
+ }
+
+ popup.close()
+ }
}
}
}
diff --git a/ui/app/AppLayouts/Browser/BrowserHeader.qml b/ui/app/AppLayouts/Browser/BrowserHeader.qml
index bac07a16e4..da573e97ae 100644
--- a/ui/app/AppLayouts/Browser/BrowserHeader.qml
+++ b/ui/app/AppLayouts/Browser/BrowserHeader.qml
@@ -77,7 +77,30 @@ Rectangle {
Layout.leftMargin: -root.innerMargin/2
}
+ Connections {
+ target: browserModel
+ onBookmarksChanged: {
+ addressBar.currentFavorite = getCurrentFavorite()
+ }
+ }
+
StyledTextField {
+ property var currentFavorite: getCurrentFavorite()
+
+ function getCurrentFavorite() {
+ if (!currentWebView || !currentWebView.url) {
+ return false
+ }
+ const index = browserModel.bookmarks.getBookmarkIndexByUrl(currentWebView.url)
+ if (index === -1) {
+ return null
+ }
+ return {
+ url: currentWebView.url,
+ name: browserModel.bookmarks.rowData(index, 'name')
+ }
+ }
+
id: addressBar
height: 40
Layout.fillWidth: true
@@ -100,7 +123,30 @@ Rectangle {
}
StatusIconButton {
- id: chatCommandsBtn
+ id: addFavoriteBtn
+ visible: !!currentWebView && !!currentWebView.url
+ icon.name: !!addressBar.currentFavorite ? "browser/favoriteActive" : "browser/favorite"
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: reloadBtn.left
+ anchors.rightMargin: Style.current.halfPadding
+ onClicked: {
+ if (!addressBar.currentFavorite) {
+ browserModel.addBookmark(currentWebView.url, currentWebView.title)
+ }
+
+ addFavoriteModal.modifiyModal = true
+ addFavoriteModal.x = addFavoriteBtn.x + addFavoriteBtn.width / 2 - addFavoriteBtn.width / 2
+ addFavoriteModal.y = root.y + root.height + 4
+ addFavoriteModal.ogUrl = addressBar.currentFavorite ? addressBar.currentFavorite.url : currentWebView.url
+ addFavoriteModal.ogName = addressBar.currentFavorite ? addressBar.currentFavorite.name : currentWebView.title
+ addFavoriteModal.open()
+ }
+ width: 24
+ height: 24
+ }
+
+ StatusIconButton {
+ id: reloadBtn
icon.name: currentWebView && currentWebView.loading ? "close" : "browser/refresh"
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
diff --git a/ui/app/AppLayouts/Browser/BrowserLayout.qml b/ui/app/AppLayouts/Browser/BrowserLayout.qml
index 4c870600ec..bc69a70921 100644
--- a/ui/app/AppLayouts/Browser/BrowserLayout.qml
+++ b/ui/app/AppLayouts/Browser/BrowserLayout.qml
@@ -633,7 +633,7 @@ Rectangle {
width: Math.min(childrenRect.width, parent.width - addBookmarkBtn.width - spacing)
delegate: BookmarkButton {
text: name
- onClicked: Qt.openUrlExternally(url)
+ onClicked: currentWebView.url = url
}
}
diff --git a/ui/app/img/browser/favorite.svg b/ui/app/img/browser/favorite.svg
new file mode 100644
index 0000000000..a9f9af2a47
--- /dev/null
+++ b/ui/app/img/browser/favorite.svg
@@ -0,0 +1,3 @@
+
diff --git a/ui/app/img/browser/favoriteActive.svg b/ui/app/img/browser/favoriteActive.svg
new file mode 100644
index 0000000000..79712986b9
--- /dev/null
+++ b/ui/app/img/browser/favoriteActive.svg
@@ -0,0 +1,3 @@
+
diff --git a/ui/shared/status/StatusButton.qml b/ui/shared/status/StatusButton.qml
index 83e802ba5f..f60f556a17 100644
--- a/ui/shared/status/StatusButton.qml
+++ b/ui/shared/status/StatusButton.qml
@@ -10,6 +10,8 @@ Button {
property string size: "large"
property string state: "default"
property color color: Style.current.buttonForegroundColor
+ property color bgColor: Style.current.buttonBackgroundColor
+ property color bgHoverColor: Qt.darker(control.bgColor, 1.1)
property int iconRotation: 0
id: control
@@ -89,11 +91,11 @@ Button {
anchors.fill: parent
color: {
if (type === "secondary") {
- return hovered ? Style.current.buttonBackgroundColor : "transparent"
+ return hovered ? control.bgColor : "transparent"
}
return !enabled ? Style.current.buttonDisabledBackgroundColor :
- hovered ? Qt.darker(Style.current.buttonBackgroundColor, 1.1) :
- Style.current.buttonBackgroundColor
+ hovered ? control.bgHoverColor :
+ control.bgColor
}
}