chore: Remove the Browser from the app completely for now
- completely removes the `ui/app/AppLayouts/Browser` QML app section - removes the `app_service/service/bookmarks`, `app/modules/main/browser_section` and `src/app_service/service/dapp_permissions` NIM modules - remove the Browser settings page and associated popups/components - HTML links now always open in an external browser - adjust the section indexes in `Constants` - fixup the e2e tests Fixes #14614
This commit is contained in:
parent
b8bcab79a9
commit
ed650d32dd
|
@ -14,8 +14,6 @@ import app_service/service/collectible/service as collectible_service
|
|||
import app_service/service/currency/service as currency_service
|
||||
import app_service/service/transaction/service as transaction_service
|
||||
import app_service/service/wallet_account/service as wallet_account_service
|
||||
import app_service/service/bookmarks/service as bookmark_service
|
||||
import app_service/service/dapp_permissions/service as dapp_permissions_service
|
||||
import app_service/service/privacy/service as privacy_service
|
||||
import app_service/service/provider/service as provider_service
|
||||
import app_service/service/node/service as node_service
|
||||
|
@ -81,8 +79,6 @@ type
|
|||
currencyService: currency_service.Service
|
||||
transactionService: transaction_service.Service
|
||||
walletAccountService: wallet_account_service.Service
|
||||
bookmarkService: bookmark_service.Service
|
||||
dappPermissionsService: dapp_permissions_service.Service
|
||||
providerService: provider_service.Service
|
||||
profileService: profile_service.Service
|
||||
settingsService: settings_service.Service
|
||||
|
@ -204,7 +200,6 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
|||
result.communityService = community_service.newService(statusFoundation.events,
|
||||
statusFoundation.threadpool, result.chatService, result.activityCenterService, result.messageService)
|
||||
result.transactionService = transaction_service.newService(statusFoundation.events, statusFoundation.threadpool, result.networkService, result.settingsService, result.tokenService)
|
||||
result.bookmarkService = bookmark_service.newService(statusFoundation.events)
|
||||
result.profileService = profile_service.newService(statusFoundation.events, statusFoundation.threadpool, result.settingsService)
|
||||
result.stickersService = stickers_service.newService(
|
||||
statusFoundation.events,
|
||||
|
@ -217,7 +212,6 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
|||
result.tokenService
|
||||
)
|
||||
result.aboutService = about_service.newService(statusFoundation.events, statusFoundation.threadpool)
|
||||
result.dappPermissionsService = dapp_permissions_service.newService()
|
||||
result.languageService = language_service.newService(statusFoundation.events)
|
||||
# result.mnemonicService = mnemonic_service.newService()
|
||||
result.privacyService = privacy_service.newService(statusFoundation.events, result.settingsService,
|
||||
|
@ -265,12 +259,10 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
|||
result.currencyService,
|
||||
result.transactionService,
|
||||
result.walletAccountService,
|
||||
result.bookmarkService,
|
||||
result.profileService,
|
||||
result.settingsService,
|
||||
result.contactsService,
|
||||
result.aboutService,
|
||||
result.dappPermissionsService,
|
||||
result.languageService,
|
||||
# result.mnemonicService,
|
||||
result.privacyService,
|
||||
|
@ -304,7 +296,6 @@ proc delete*(self: AppController) =
|
|||
self.notificationsManager.delete
|
||||
self.keychainService.delete
|
||||
self.contactsService.delete
|
||||
self.bookmarkService.delete
|
||||
self.gifService.delete
|
||||
if not self.startupModule.isNil:
|
||||
self.startupModule.delete
|
||||
|
@ -331,7 +322,6 @@ proc delete*(self: AppController) =
|
|||
self.aboutService.delete
|
||||
self.networkService.delete
|
||||
self.activityCenterService.delete
|
||||
self.dappPermissionsService.delete
|
||||
self.providerService.delete
|
||||
self.nodeConfigurationService.delete
|
||||
self.nodeService.delete
|
||||
|
@ -431,8 +421,6 @@ proc load(self: AppController) =
|
|||
self.chatService.init()
|
||||
self.messageService.init()
|
||||
self.communityService.init()
|
||||
self.bookmarkService.init()
|
||||
self.dappPermissionsService.init()
|
||||
self.providerService.init()
|
||||
self.transactionService.init()
|
||||
self.stickersService.init()
|
||||
|
|
|
@ -4,7 +4,6 @@ import base
|
|||
|
||||
import ../../../../app_service/service/message/dto/[message, pinned_message_update, reaction, removed_message]
|
||||
import ../../../../app_service/service/chat/dto/[chat]
|
||||
import ../../../../app_service/service/bookmarks/dto/[bookmark]
|
||||
import ../../../../app_service/service/community/dto/[community]
|
||||
import ../../../../app_service/service/activity_center/dto/[notification]
|
||||
import ../../../../app_service/service/contacts/dto/[contacts, status_update]
|
||||
|
@ -14,7 +13,6 @@ import ../../../../app_service/service/saved_address/dto as saved_address_dto
|
|||
import ../../../../app_service/service/wallet_account/dto/[keypair_dto]
|
||||
|
||||
type MessageSignal* = ref object of Signal
|
||||
bookmarks*: seq[BookmarkDto]
|
||||
messages*: seq[MessageDto]
|
||||
pinnedMessages*: seq[PinnedMessageUpdateDto]
|
||||
chats*: seq[ChatDto]
|
||||
|
@ -88,11 +86,6 @@ proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal =
|
|||
var currentStatus = e["currentStatus"].toStatusUpdateDto()
|
||||
signal.currentStatus.add(currentStatus)
|
||||
|
||||
if e.contains("bookmarks"):
|
||||
for jsonBookmark in e["bookmarks"]:
|
||||
var bookmark = jsonBookmark.toBookmarkDto()
|
||||
signal.bookmarks.add(bookmark)
|
||||
|
||||
if e.contains("installations"):
|
||||
for jsonDevice in e["installations"]:
|
||||
signal.installations.add(jsonDevice.toInstallationDto())
|
||||
|
|
|
@ -11,10 +11,6 @@ const WALLET_SECTION_ID* = "wallet"
|
|||
const WALLET_SECTION_NAME* = "Wallet"
|
||||
const WALLET_SECTION_ICON* = "wallet"
|
||||
|
||||
const BROWSER_SECTION_ID* = "browser"
|
||||
const BROWSER_SECTION_NAME* = "Browser"
|
||||
const BROWSER_SECTION_ICON* = "browser"
|
||||
|
||||
const NODEMANAGEMENT_SECTION_ID* = "nodeManagement"
|
||||
const NODEMANAGEMENT_SECTION_NAME* = "Node Management"
|
||||
const NODEMANAGEMENT_SECTION_ICON* = "node"
|
||||
|
|
|
@ -14,8 +14,6 @@ const LSS_KEY_NODE_MANAGEMENT_ENABLED* = "nodeManagementEnabled"
|
|||
const DEFAULT_NODE_MANAGEMENT_ENABLED = false
|
||||
const LSS_KEY_ENS_COMMUNITY_PERMISSIONS_ENABLED* = "ensCommunityPermissionsEnabled"
|
||||
const DEFAULT_COMMUNITY_PERMISSIONS_ENABLED = false
|
||||
const LSS_KEY_IS_BROWSER_ENABLED* = "isExperimentalBrowserEnabled"
|
||||
const DEFAULT_IS_BROWSER_ENABLED = false
|
||||
const LSS_KEY_SHOW_ONLINE_USERS* = "showOnlineUsers"
|
||||
const DEFAULT_SHOW_ONLINE_USERS = true
|
||||
const LSS_KEY_EXPAND_USERS_LIST* = "expandUsersList"
|
||||
|
@ -49,18 +47,6 @@ const LSS_KEY_ACTIVE_SECTION* = "activeSection"
|
|||
const DEFAULT_ACTIVE_SECTION = ""
|
||||
const LAST_SECTION_CHAT = "LastSectionChat"
|
||||
const DEFAULT_ACTIVE_CHAT = ""
|
||||
const LSS_KEY_SHOW_BROWSER_SELECTOR* = "showBrowserSelector"
|
||||
const DEFAULT_SHOW_BROWSER_SELECTOR = true
|
||||
const LSS_KEY_OPEN_LINKS_IN_STATUS* = "openLinksInStatus"
|
||||
const DEFAULT_OPEN_LINKS_IN_STATUS = true
|
||||
const LSS_KEY_SHOULD_SHOW_FAVORITES_BAR* = "shouldShowFavoritesBar"
|
||||
const DEFAULT_SHOULD_SHOW_FAVORITES_BAR = true
|
||||
const LSS_KEY_BROWSER_HOMEPAGE* = "browserHomepage"
|
||||
const DEFAULT_BROWSER_HOMEPAGE = ""
|
||||
const LSS_KEY_SHOULD_SHOW_BROWSER_SEARCH_ENGINE* = "shouldShowBrowserSearchEngine"
|
||||
const DEFAULT_SHOULD_SHOW_BROWSER_SEARCH_ENGINE = 3 #browserSearchEngineDuckDuckGo from qml
|
||||
const LSS_KEY_USE_BROWSER_ETHEREUM_EXPLORER* = "useBrowserEthereumExplorer"
|
||||
const DEFAULT_USE_BROWSER_ETHEREUM_EXPLORER = 1 #browserEthereumExplorerEtherscan from qml
|
||||
const LSS_KEY_AUTO_LOAD_IMAGES* = "autoLoadImages"
|
||||
const DEFAULT_AUTO_LOAD_IMAGES = true
|
||||
const LSS_KEY_JAVA_SCRIPT_ENABLED* = "javaScriptEnabled"
|
||||
|
@ -233,18 +219,6 @@ QtObject:
|
|||
write = setNodeManagementEnabled
|
||||
notify = nodeManagementEnabledChanged
|
||||
|
||||
proc isBrowserEnabledChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getIsBrowserEnabled*(self: LocalAccountSensitiveSettings): bool {.slot.} =
|
||||
getSettingsProp[bool](self, LSS_KEY_IS_BROWSER_ENABLED, newQVariant(DEFAULT_IS_BROWSER_ENABLED))
|
||||
proc setIsBrowserEnabled*(self: LocalAccountSensitiveSettings, value: bool) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_IS_BROWSER_ENABLED, newQVariant(value)):
|
||||
self.isBrowserEnabledChanged()
|
||||
|
||||
QtProperty[bool] isBrowserEnabled:
|
||||
read = getIsBrowserEnabled
|
||||
write = setIsBrowserEnabled
|
||||
notify = isBrowserEnabledChanged
|
||||
|
||||
proc ensCommunityPermissionsEnabledChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getEnsCommunityPermissionsEnabled*(self: LocalAccountSensitiveSettings): bool {.slot.} =
|
||||
getSettingsProp[bool](self, LSS_KEY_ENS_COMMUNITY_PERMISSIONS_ENABLED, newQVariant(DEFAULT_COMMUNITY_PERMISSIONS_ENABLED))
|
||||
|
@ -448,85 +422,6 @@ QtObject:
|
|||
write = setActiveSection
|
||||
notify = activeSectionChanged
|
||||
|
||||
proc showBrowserSelectorChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getShowBrowserSelector*(self: LocalAccountSensitiveSettings): bool {.slot.} =
|
||||
# getSettingsProp[bool](self, LSS_KEY_SHOW_BROWSER_SELECTOR, newQVariant(DEFAULT_SHOW_BROWSER_SELECTOR)) # https://github.com/status-im/status-desktop/issues/8568
|
||||
return false
|
||||
proc setShowBrowserSelector*(self: LocalAccountSensitiveSettings, value: bool) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_SHOW_BROWSER_SELECTOR, newQVariant(value)):
|
||||
self.showBrowserSelectorChanged()
|
||||
|
||||
QtProperty[bool] showBrowserSelector:
|
||||
read = getShowBrowserSelector
|
||||
write = setShowBrowserSelector
|
||||
notify = showBrowserSelectorChanged
|
||||
|
||||
|
||||
proc openLinksInStatusChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getOpenLinksInStatus*(self: LocalAccountSensitiveSettings): bool {.slot.} =
|
||||
# getSettingsProp[bool](self, LSS_KEY_OPEN_LINKS_IN_STATUS, newQVariant(DEFAULT_OPEN_LINKS_IN_STATUS)) # https://github.com/status-im/status-desktop/issues/8568
|
||||
return false
|
||||
proc setOpenLinksInStatus*(self: LocalAccountSensitiveSettings, value: bool) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_OPEN_LINKS_IN_STATUS, newQVariant(value)):
|
||||
self.openLinksInStatusChanged()
|
||||
|
||||
QtProperty[bool] openLinksInStatus:
|
||||
read = getOpenLinksInStatus
|
||||
write = setOpenLinksInStatus
|
||||
notify = openLinksInStatusChanged
|
||||
|
||||
|
||||
proc shouldShowFavoritesBarChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getShouldShowFavoritesBar*(self: LocalAccountSensitiveSettings): bool {.slot.} =
|
||||
getSettingsProp[bool](self, LSS_KEY_SHOULD_SHOW_FAVORITES_BAR, newQVariant(DEFAULT_SHOULD_SHOW_FAVORITES_BAR))
|
||||
proc setShouldShowFavoritesBar*(self: LocalAccountSensitiveSettings, value: bool) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_SHOULD_SHOW_FAVORITES_BAR, newQVariant(value)):
|
||||
self.shouldShowFavoritesBarChanged()
|
||||
|
||||
QtProperty[bool] shouldShowFavoritesBar:
|
||||
read = getShouldShowFavoritesBar
|
||||
write = setShouldShowFavoritesBar
|
||||
notify = shouldShowFavoritesBarChanged
|
||||
|
||||
|
||||
proc browserHomepageChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getBrowserHomepage*(self: LocalAccountSensitiveSettings): string {.slot.} =
|
||||
getSettingsProp[string](self, LSS_KEY_BROWSER_HOMEPAGE, newQVariant(DEFAULT_BROWSER_HOMEPAGE))
|
||||
proc setBrowserHomepage*(self: LocalAccountSensitiveSettings, value: string) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_BROWSER_HOMEPAGE, newQVariant(value)):
|
||||
self.browserHomepageChanged()
|
||||
|
||||
QtProperty[string] browserHomepage:
|
||||
read = getBrowserHomepage
|
||||
write = setBrowserHomepage
|
||||
notify = browserHomepageChanged
|
||||
|
||||
|
||||
proc shouldShowBrowserSearchEngineChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getShouldShowBrowserSearchEngine*(self: LocalAccountSensitiveSettings): int {.slot.} =
|
||||
getSettingsProp[int](self, LSS_KEY_SHOULD_SHOW_BROWSER_SEARCH_ENGINE, newQVariant(DEFAULT_SHOULD_SHOW_BROWSER_SEARCH_ENGINE))
|
||||
proc setShouldShowBrowserSearchEngine*(self: LocalAccountSensitiveSettings, value: int) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_SHOULD_SHOW_BROWSER_SEARCH_ENGINE, newQVariant(value)):
|
||||
self.shouldShowBrowserSearchEngineChanged()
|
||||
|
||||
QtProperty[int] shouldShowBrowserSearchEngine:
|
||||
read = getShouldShowBrowserSearchEngine
|
||||
write = setShouldShowBrowserSearchEngine
|
||||
notify = shouldShowBrowserSearchEngineChanged
|
||||
|
||||
|
||||
proc useBrowserEthereumExplorerChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getUseBrowserEthereumExplorer*(self: LocalAccountSensitiveSettings): int {.slot.} =
|
||||
getSettingsProp[int](self, LSS_KEY_USE_BROWSER_ETHEREUM_EXPLORER, newQVariant(DEFAULT_USE_BROWSER_ETHEREUM_EXPLORER))
|
||||
proc setUseBrowserEthereumExplorer*(self: LocalAccountSensitiveSettings, value: int) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_USE_BROWSER_ETHEREUM_EXPLORER, newQVariant(value)):
|
||||
self.useBrowserEthereumExplorerChanged()
|
||||
|
||||
QtProperty[int] useBrowserEthereumExplorer:
|
||||
read = getUseBrowserEthereumExplorer
|
||||
write = setUseBrowserEthereumExplorer
|
||||
notify = useBrowserEthereumExplorerChanged
|
||||
|
||||
|
||||
proc autoLoadImagesChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getAutoLoadImages*(self: LocalAccountSensitiveSettings): bool {.slot.} =
|
||||
|
@ -706,7 +601,6 @@ QtObject:
|
|||
of LSS_KEY_PROFILE_SPLIT_VIEW: self.profileSplitViewChanged()
|
||||
of LSS_KEY_NODE_MANAGEMENT_ENABLED: self.nodeManagementEnabledChanged()
|
||||
of LSS_KEY_ENS_COMMUNITY_PERMISSIONS_ENABLED: self.ensCommunityPermissionsEnabledChanged()
|
||||
of LSS_KEY_IS_BROWSER_ENABLED: self.isBrowserEnabledChanged()
|
||||
of LSS_KEY_SHOW_ONLINE_USERS: self.showOnlineUsersChanged()
|
||||
of LSS_KEY_EXPAND_USERS_LIST: self.expandUsersListChanged()
|
||||
of LSS_KEY_RECENT_EMOJIS: self.recentEmojisChanged()
|
||||
|
@ -722,12 +616,6 @@ QtObject:
|
|||
of LSS_KEY_SHOW_DELETE_MESSAGE_WARNING: self.showDeleteMessageWarningChanged()
|
||||
of LSS_KEY_DOWNLOAD_CHANNEL_MESSAGES_ENABLED: self.downloadChannelMessagesEnabledChanged()
|
||||
of LSS_KEY_ACTIVE_SECTION: self.activeSectionChanged()
|
||||
of LSS_KEY_SHOW_BROWSER_SELECTOR: self.showBrowserSelectorChanged()
|
||||
of LSS_KEY_OPEN_LINKS_IN_STATUS: self.openLinksInStatusChanged()
|
||||
of LSS_KEY_SHOULD_SHOW_FAVORITES_BAR: self.shouldShowFavoritesBarChanged()
|
||||
of LSS_KEY_BROWSER_HOMEPAGE: self.browserHomepageChanged()
|
||||
of LSS_KEY_SHOULD_SHOW_BROWSER_SEARCH_ENGINE: self.shouldShowBrowserSearchEngineChanged()
|
||||
of LSS_KEY_USE_BROWSER_ETHEREUM_EXPLORER: self.useBrowserEthereumExplorerChanged()
|
||||
of LSS_KEY_AUTO_LOAD_IMAGES: self.autoLoadImagesChanged()
|
||||
of LSS_KEY_JAVA_SCRIPT_ENABLED: self.javaScriptEnabledChanged()
|
||||
of LSS_KEY_ERROR_PAGE_ENABLED: self.errorPageEnabledChanged()
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
import results
|
||||
import io_interface
|
||||
|
||||
import ../../../../../app_service/service/bookmarks/service as bookmark_service
|
||||
import ../../../../core/eventemitter
|
||||
|
||||
type
|
||||
Controller* = ref object of RootObj
|
||||
delegate: io_interface.AccessInterface
|
||||
events: EventEmitter
|
||||
bookmarkService: bookmark_service.Service
|
||||
|
||||
proc newController*(delegate: io_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
bookmarkService: bookmark_service.Service):
|
||||
Controller =
|
||||
result = Controller()
|
||||
result.events = events
|
||||
result.delegate = delegate
|
||||
result.bookmarkService = bookmarkService
|
||||
|
||||
proc delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
proc init*(self: Controller) =
|
||||
self.events.on(SIGNAL_BOOKMARK_REMOVED) do(e: Args):
|
||||
let args = BookmarkRemovedArgs(e)
|
||||
self.delegate.onBookmarkDeleted(args.url)
|
||||
|
||||
self.events.on(SIGNAL_BOOKMARK_ADDED) do(e: Args):
|
||||
let args = BookmarkArgs(e)
|
||||
self.delegate.onBoomarkStored(args.bookmark.url, args.bookmark.name, args.bookmark.imageUrl)
|
||||
|
||||
self.events.on(SIGNAL_BOOKMARK_UPDATED) do(e: Args):
|
||||
let args = BookmarkArgs(e)
|
||||
self.delegate.onBookmarkUpdated(args.bookmark.url, args.bookmark.url, args.bookmark.name, args.bookmark.imageUrl)
|
||||
|
||||
proc getBookmarks*(self: Controller): seq[bookmark_service.BookmarkDto] =
|
||||
return self.bookmarkService.getBookmarks()
|
||||
|
||||
proc storeBookmark*(self: Controller, url, name: string) =
|
||||
let b = self.bookmarkService.storeBookmark(url, name)
|
||||
if b.isOk:
|
||||
self.delegate.onBoomarkStored(url, name, b.get().imageUrl)
|
||||
|
||||
proc deleteBookmark*(self: Controller, url: string) =
|
||||
if self.bookmarkService.deleteBookmark(url):
|
||||
self.delegate.onBookmarkDeleted(url)
|
||||
|
||||
proc 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)
|
|
@ -1,40 +0,0 @@
|
|||
import ../../../../../app_service/service/bookmarks/service as bookmark_service
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onActivated*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getBookmarks*(self: AccessInterface): seq[bookmark_service.BookmarkDto] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method storeBookmark*(self: AccessInterface, url, name: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method deleteBookmark*(self: AccessInterface, url: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method updateBookmark*(self: AccessInterface, oldUrl, newUrl, newName: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onBoomarkStored*(self: AccessInterface, url: string, name: string, imageUrl: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onBookmarkDeleted*(self: AccessInterface, url: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onBookmarkUpdated*(self: AccessInterface, oldUrl: string, newUrl: string, newName: string, newImageUrl: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -1,28 +0,0 @@
|
|||
import stew/shims/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
|
|
@ -1,118 +0,0 @@
|
|||
import NimQml, Tables, strutils, stew/shims/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 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)
|
||||
self.modelChanged()
|
|
@ -1,77 +0,0 @@
|
|||
import NimQml
|
||||
import io_interface
|
||||
import ../io_interface as delegate_interface
|
||||
import item
|
||||
import view
|
||||
import controller
|
||||
import ../../../../global/global_singleton
|
||||
import ../../../../../app_service/service/bookmarks/service as bookmark_service
|
||||
import ../../../../core/eventemitter
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
moduleLoaded: bool
|
||||
bookmarksLoaded: bool
|
||||
controller: Controller
|
||||
|
||||
proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, bookmarkService: bookmark_service.Service): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.moduleLoaded = false
|
||||
result.bookmarksLoaded = false
|
||||
result.controller = controller.newController(result, events, 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.controller.init()
|
||||
self.view.load()
|
||||
|
||||
method onActivated*(self: Module) =
|
||||
if self.bookmarksLoaded:
|
||||
return
|
||||
|
||||
let bookmarks = self.controller.getBookmarks()
|
||||
for b in bookmarks:
|
||||
self.view.addItem(initItem(b.name, b.url, b.imageUrl))
|
||||
|
||||
self.bookmarksLoaded = true
|
||||
|
||||
method isLoaded*(self: Module): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
self.moduleLoaded = true
|
||||
self.delegate.bookmarkDidLoad()
|
||||
|
||||
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))
|
|
@ -1,56 +0,0 @@
|
|||
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)
|
|
@ -1,63 +0,0 @@
|
|||
import io_interface
|
||||
import app_service/service/wallet_account/service as wallet_account_service
|
||||
import app_service/service/network/service as network_service
|
||||
import app_service/service/token/service as token_service
|
||||
import app_service/service/currency/service as currency_service
|
||||
|
||||
type
|
||||
Controller* = ref object of RootObj
|
||||
delegate: io_interface.AccessInterface
|
||||
walletAccountService: wallet_account_service.Service
|
||||
networkService: network_service.Service
|
||||
tokenService: token_service.Service
|
||||
currencyService: currency_service.Service
|
||||
|
||||
proc newController*(
|
||||
delegate: io_interface.AccessInterface,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
networkService: network_service.Service,
|
||||
tokenService: token_service.Service,
|
||||
currencyService: currency_service.Service,
|
||||
): Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.walletAccountService = walletAccountService
|
||||
result.networkService = networkService
|
||||
result.tokenService = tokenService
|
||||
result.currencyService = currencyService
|
||||
|
||||
proc delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
proc init*(self: Controller) =
|
||||
discard
|
||||
|
||||
proc getWalletAccount*(self: Controller, accountIndex: int): wallet_account_service.WalletAccountDto =
|
||||
return self.walletAccountService.getWalletAccount(accountIndex)
|
||||
|
||||
proc isKeycardAccount*(self: Controller, account: WalletAccountDto): bool =
|
||||
return self.walletAccountService.isKeycardAccount(account)
|
||||
|
||||
proc getIndex*(self: Controller, address: string): int =
|
||||
return self.walletAccountService.getIndex(address)
|
||||
|
||||
proc getChainIds*(self: Controller): seq[int] =
|
||||
return self.networkService.getCurrentNetworksChainIds()
|
||||
|
||||
proc getEnabledChainIds*(self: Controller): seq[int] =
|
||||
return self.networkService.getEnabledChainIds()
|
||||
|
||||
proc getCurrentCurrency*(self: Controller): string =
|
||||
return self.walletAccountService.getCurrency()
|
||||
|
||||
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
|
||||
return self.currencyService.getCurrencyFormat(symbol)
|
||||
|
||||
proc areTestNetworksEnabled*(self: Controller): bool =
|
||||
return self.walletAccountService.areTestNetworksEnabled()
|
||||
|
||||
proc getTotalCurrencyBalance*(self: Controller, address: string, chainIds: seq[int]): float64 =
|
||||
return self.walletAccountService.getTotalCurrencyBalance(@[address], chainIds)
|
||||
|
||||
proc getTokensMarketValuesLoading*(self: Controller): bool =
|
||||
return self.walletAccountService.getTokensMarketValuesLoading()
|
|
@ -1,21 +0,0 @@
|
|||
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 switchAccountByAddress*(self: AccessInterface, address: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
# View Delegate Interface
|
||||
# Delegate for the view must be declared here due to use of QtObject and multi
|
||||
# inheritance, which is not well supported in Nim.
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -1,106 +0,0 @@
|
|||
import NimQml, strutils
|
||||
|
||||
import app/global/global_singleton
|
||||
import app/core/eventemitter
|
||||
import app_service/service/wallet_account/service as wallet_account_service
|
||||
import app_service/service/network/service as network_service
|
||||
import app_service/service/token/service as token_service
|
||||
import app_service/service/currency/service as currency_service
|
||||
import app/modules/shared/wallet_utils
|
||||
|
||||
import ./io_interface, ./view, ./controller
|
||||
import ../io_interface as delegate_interface
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
events: EventEmitter
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
controller: Controller
|
||||
moduleLoaded: bool
|
||||
currentAccountIndex: int
|
||||
|
||||
proc newModule*(
|
||||
delegate: delegate_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
networkService: network_service.Service,
|
||||
tokenService: token_service.Service,
|
||||
currencyService: currency_service.Service,
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.currentAccountIndex = 0
|
||||
result.view = newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = newController(result, walletAccountService, networkService, tokenService, currencyService)
|
||||
result.moduleLoaded = false
|
||||
|
||||
method delete*(self: Module) =
|
||||
self.viewVariant.delete
|
||||
self.view.delete
|
||||
|
||||
proc switchAccount*(self: Module, accountIndex: int) =
|
||||
self.currentAccountIndex = accountIndex
|
||||
|
||||
let walletAccount = self.controller.getWalletAccount(accountIndex)
|
||||
if walletAccount.isNil:
|
||||
return
|
||||
let keycardAccount = self.controller.isKeycardAccount(walletAccount)
|
||||
let currency = self.controller.getCurrentCurrency()
|
||||
let enabledChainIds = self.controller.getEnabledChainIds()
|
||||
let chainIds = self.controller.getChainIds()
|
||||
let areTestNetworksEnabled = self.controller.areTestNetworksEnabled()
|
||||
let currencyFormat = self.controller.getCurrencyFormat(currency)
|
||||
let currencyBalance = self.controller.getTotalCurrencyBalance(walletAccount.address, enabledChainIds)
|
||||
|
||||
let accountItem = walletAccountToWalletAccountsItem(
|
||||
walletAccount,
|
||||
keycardAccount,
|
||||
chainIds,
|
||||
enabledChainIds,
|
||||
currencyBalance,
|
||||
currencyFormat,
|
||||
areTestNetworksEnabled,
|
||||
self.controller.getTokensMarketValuesLoading()
|
||||
)
|
||||
|
||||
self.view.setData(accountItem)
|
||||
|
||||
method load*(self: Module) =
|
||||
singletonInstance.engine.setRootContextProperty("browserSectionCurrentAccount", self.viewVariant)
|
||||
|
||||
self.events.on(SIGNAL_KEYPAIR_SYNCED) do(e: Args):
|
||||
let args = KeypairArgs(e)
|
||||
let walletAccount = self.controller.getWalletAccount(self.currentAccountIndex)
|
||||
if walletAccount.isNil:
|
||||
self.switchAccount(0)
|
||||
return
|
||||
for acc in args.keypair.accounts:
|
||||
if cmpIgnoreCase(acc.address, walletAccount.address) == 0:
|
||||
return
|
||||
self.switchAccount(0)
|
||||
self.view.connectedAccountDeleted()
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e:Args):
|
||||
if(self.view.isAddressCurrentAccount(AccountArgs(e).account.address)):
|
||||
self.switchAccount(0)
|
||||
self.view.connectedAccountDeleted()
|
||||
|
||||
self.controller.init()
|
||||
self.view.load()
|
||||
self.switchAccount(0)
|
||||
|
||||
method isLoaded*(self: Module): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
self.moduleLoaded = true
|
||||
|
||||
method switchAccountByAddress*(self: Module, address: string) =
|
||||
let accountIndex = self.controller.getIndex(address)
|
||||
self.switchAccount(accountIndex)
|
|
@ -1,121 +0,0 @@
|
|||
import NimQml, sequtils
|
||||
|
||||
import ./io_interface
|
||||
import ../../../shared_models/currency_amount
|
||||
|
||||
import ../../wallet_section/accounts/item as account_item
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
name: string
|
||||
address: string
|
||||
path: string
|
||||
colorId: string
|
||||
walletType: string
|
||||
currencyBalance: CurrencyAmount
|
||||
emoji: string
|
||||
|
||||
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.setup()
|
||||
result.delegate = delegate
|
||||
|
||||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
||||
|
||||
proc getName(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.name)
|
||||
|
||||
proc nameChanged(self: View) {.signal.}
|
||||
|
||||
QtProperty[QVariant] name:
|
||||
read = getName
|
||||
notify = nameChanged
|
||||
|
||||
proc getAddress(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.address)
|
||||
|
||||
proc addressChanged(self: View) {.signal.}
|
||||
|
||||
QtProperty[QVariant] address:
|
||||
read = getAddress
|
||||
notify = addressChanged
|
||||
|
||||
proc getPath(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.path)
|
||||
|
||||
proc pathChanged(self: View) {.signal.}
|
||||
|
||||
QtProperty[QVariant] path:
|
||||
read = getPath
|
||||
notify = pathChanged
|
||||
|
||||
proc getColorId(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.colorId)
|
||||
|
||||
proc colorIdChanged(self: View) {.signal.}
|
||||
|
||||
QtProperty[QVariant] colorId:
|
||||
read = getColorId
|
||||
notify = colorIdChanged
|
||||
|
||||
proc getWalletType(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.walletType)
|
||||
|
||||
proc walletTypeChanged(self: View) {.signal.}
|
||||
|
||||
QtProperty[QVariant] walletType:
|
||||
read = getWalletType
|
||||
notify = walletTypeChanged
|
||||
|
||||
proc getCurrencyBalance(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.currencyBalance)
|
||||
|
||||
proc currencyBalanceChanged(self: View) {.signal.}
|
||||
|
||||
QtProperty[QVariant] currencyBalance:
|
||||
read = getCurrencyBalance
|
||||
notify = currencyBalanceChanged
|
||||
|
||||
proc getEmoji(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.emoji)
|
||||
|
||||
proc emojiChanged(self: View) {.signal.}
|
||||
|
||||
QtProperty[QVariant] emoji:
|
||||
read = getEmoji
|
||||
notify = emojiChanged
|
||||
|
||||
proc switchAccountByAddress*(self: View, address: string) {.slot.} =
|
||||
self.delegate.switchAccountByAddress(address)
|
||||
|
||||
|
||||
proc connectedAccountDeleted*(self: View) {.signal.}
|
||||
|
||||
proc setData*(self: View, item: account_item.Item) =
|
||||
self.name = item.name()
|
||||
self.nameChanged()
|
||||
self.address = item.address()
|
||||
self.addressChanged()
|
||||
self.path = item.path()
|
||||
self.pathChanged()
|
||||
self.colorId = item.colorId()
|
||||
self.colorIdChanged()
|
||||
self.walletType = item.walletType()
|
||||
self.walletTypeChanged()
|
||||
self.currencyBalance = item.currencyBalance()
|
||||
self.currencyBalanceChanged()
|
||||
self.emoji = item.emoji()
|
||||
self.emojiChanged()
|
||||
|
||||
proc isAddressCurrentAccount*(self: View, address: string): bool =
|
||||
return self.address == address
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
import NimQml, Tables, strutils, stew/shims/strformat
|
||||
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
Name = UserRole + 1
|
||||
Address
|
||||
ColorId
|
||||
Emoji
|
||||
|
||||
QtObject:
|
||||
type
|
||||
AccountsModel* = ref object of QAbstractListModel
|
||||
items: seq[WalletAccountDto]
|
||||
|
||||
proc delete(self: AccountsModel) =
|
||||
self.items = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: AccountsModel) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc newAccountsModel*(): AccountsModel =
|
||||
new(result, delete)
|
||||
result.setup
|
||||
|
||||
proc `$`*(self: AccountsModel): string =
|
||||
for i in 0 ..< self.items.len:
|
||||
result &= fmt"""
|
||||
[{i}]:({$self.items[i].name})
|
||||
"""
|
||||
|
||||
proc modelChanged(self: AccountsModel) {.signal.}
|
||||
proc countChanged(self: AccountsModel) {.signal.}
|
||||
|
||||
proc getCount(self: AccountsModel): int {.slot.} =
|
||||
self.items.len
|
||||
|
||||
QtProperty[int] count:
|
||||
read = getCount
|
||||
notify = countChanged
|
||||
|
||||
method rowCount(self: AccountsModel, index: QModelIndex = nil): int =
|
||||
return self.items.len
|
||||
|
||||
method roleNames(self: AccountsModel): Table[int, string] =
|
||||
{
|
||||
ModelRole.Name.int:"name",
|
||||
ModelRole.Address.int:"address",
|
||||
ModelRole.ColorId.int:"colorId",
|
||||
ModelRole.Emoji.int:"emoji"
|
||||
}.toTable
|
||||
|
||||
method data(self: AccountsModel, 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.name)
|
||||
of ModelRole.Address:
|
||||
result = newQVariant(item.address)
|
||||
of ModelRole.ColorId:
|
||||
result = newQVariant(item.colorId)
|
||||
of ModelRole.Emoji:
|
||||
result = newQVariant(item.emoji)
|
||||
|
||||
proc addItem*(self: AccountsModel, item: WalletAccountDto) =
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
for i in self.items:
|
||||
if i == item:
|
||||
return
|
||||
|
||||
self.beginInsertRows(parentModelIndex, self.items.len, self.items.len)
|
||||
self.items.add(item)
|
||||
self.endInsertRows()
|
||||
self.modelChanged()
|
||||
self.countChanged()
|
||||
|
||||
proc clear*(self: AccountsModel) {.slot.} =
|
||||
self.beginResetModel()
|
||||
self.items = @[]
|
||||
self.endResetModel()
|
||||
self.countChanged()
|
|
@ -1,51 +0,0 @@
|
|||
import io_interface
|
||||
import options
|
||||
import ../../../../../app_service/service/dapp_permissions/service as dapp_permissions_service
|
||||
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
|
||||
|
||||
type
|
||||
Controller* = ref object of RootObj
|
||||
delegate: io_interface.AccessInterface
|
||||
dappPermissionsService: dapp_permissions_service.Service
|
||||
walletAccountService: wallet_account_service.Service
|
||||
|
||||
proc newController*(
|
||||
delegate: io_interface.AccessInterface,
|
||||
dappPermissionsService: dapp_permissions_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
): Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.dappPermissionsService = dappPermissionsService
|
||||
result.walletAccountService = walletAccountService
|
||||
|
||||
proc delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
proc init*(self: Controller) =
|
||||
discard
|
||||
|
||||
proc getDapps*(self: Controller): seq[dapp_permissions_service.Dapp] =
|
||||
return self.dappPermissionsService.getDapps()
|
||||
|
||||
proc getDapp*(self: Controller, dapp:string, address: string): Option[dapp_permissions_service.Dapp] =
|
||||
return self.dappPermissionsService.getDapp(dapp, address)
|
||||
|
||||
proc hasPermission*(self: Controller, dapp: string, address: string, permission: dapp_permissions_service.Permission):bool =
|
||||
return self.dappPermissionsService.hasPermission(dapp, address, permission)
|
||||
|
||||
proc addPermission*(self: Controller, dapp: string, address: string, permission: dapp_permissions_service.Permission) =
|
||||
discard self.dappPermissionsService.addPermission(dapp, address, permission)
|
||||
|
||||
proc disconnectAddress*(self: Controller, dappName: string, address: string) =
|
||||
discard self.dappPermissionsService.disconnectAddress(dappName, address)
|
||||
|
||||
proc disconnect*(self: Controller, dappName: string) =
|
||||
discard self.dappPermissionsService.disconnect(dappName)
|
||||
|
||||
proc removePermission*(self: Controller, dappName: string, address: string, permission: dapp_permissions_service.Permission) =
|
||||
discard self.dappPermissionsService.removePermission(dappName, address, permission)
|
||||
|
||||
proc getAccountForAddress*(self: Controller, address: string): WalletAccountDto =
|
||||
return self.walletAccountService.getAccountByAddress(address)
|
|
@ -1,84 +0,0 @@
|
|||
import NimQml, Tables, strutils, stew/shims/strformat, json
|
||||
import ./item
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
Name = UserRole + 1
|
||||
Accounts
|
||||
|
||||
QtObject:
|
||||
type
|
||||
DappsModel* = ref object of QAbstractListModel
|
||||
items: seq[Item]
|
||||
|
||||
proc delete(self: DappsModel) =
|
||||
self.items = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: DappsModel) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc newDappsModel*(): DappsModel =
|
||||
new(result, delete)
|
||||
result.setup
|
||||
|
||||
proc `$`*(self: DappsModel): string =
|
||||
for i in 0 ..< self.items.len:
|
||||
result &= fmt"""
|
||||
[{i}]:({$self.items[i]})
|
||||
"""
|
||||
|
||||
proc modelChanged(self: DappsModel) {.signal.}
|
||||
|
||||
proc countChanged(self: DappsModel) {.signal.}
|
||||
|
||||
proc getCount(self: DappsModel): int {.slot.} =
|
||||
self.items.len
|
||||
|
||||
QtProperty[int] count:
|
||||
read = getCount
|
||||
notify = countChanged
|
||||
|
||||
method rowCount(self: DappsModel, index: QModelIndex = nil): int =
|
||||
return self.items.len
|
||||
|
||||
method roleNames(self: DappsModel): Table[int, string] =
|
||||
{
|
||||
ModelRole.Name.int:"name",
|
||||
ModelRole.Accounts.int:"accounts"
|
||||
}.toTable
|
||||
|
||||
method data(self: DappsModel, 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.name)
|
||||
of ModelRole.Accounts:
|
||||
result = newQVariant(item.accounts)
|
||||
|
||||
proc addItem*(self: DappsModel, item: Item) =
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
||||
for i in self.items:
|
||||
if i == item:
|
||||
return
|
||||
|
||||
self.beginInsertRows(parentModelIndex, self.items.len, self.items.len)
|
||||
self.items.add(item)
|
||||
self.endInsertRows()
|
||||
self.modelChanged()
|
||||
self.countChanged()
|
||||
|
||||
proc clear*(self: DappsModel) =
|
||||
self.beginResetModel()
|
||||
self.items = @[]
|
||||
self.endResetModel()
|
||||
self.countChanged()
|
|
@ -1,41 +0,0 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
||||
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 onActivated*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method loadDapps*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method hasPermission*(self: AccessInterface, hostname: string, address: string, permission: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method disconnectAddress*(self: AccessInterface, dapp: string, address: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method removePermission*(self: AccessInterface, dapp: string, address: string, permission: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method disconnect*(self: AccessInterface, dapp: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method fetchDapps*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method fetchPermissions*(self: AccessInterface, dapp: string, address: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method addPermission*(self: AccessInterface, hostname: string, address: string, permission: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -1,28 +0,0 @@
|
|||
import stew/shims/strformat
|
||||
import ./permissions
|
||||
import ./accounts
|
||||
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
|
||||
type
|
||||
Item* = object
|
||||
name*: string
|
||||
accounts*: AccountsModel
|
||||
permissions*: PermissionsModel
|
||||
|
||||
proc initItem*(
|
||||
name: string,
|
||||
permissions: seq[string]
|
||||
): Item =
|
||||
result.name = name
|
||||
result.accounts = newAccountsModel()
|
||||
result.permissions = newPermissionsModel()
|
||||
for p in permissions:
|
||||
result.permissions.addItem(p)
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""Dapps(
|
||||
name: {self.name}
|
||||
]"""
|
||||
|
||||
proc addAccount*(self: Item, account: WalletAccountDto): void =
|
||||
self.accounts.addItem(account)
|
|
@ -1,111 +0,0 @@
|
|||
import NimQml
|
||||
import io_interface
|
||||
import sequtils
|
||||
import ../io_interface as delegate_interface
|
||||
import view
|
||||
import ./item
|
||||
import sets
|
||||
import controller
|
||||
import ../../../../global/global_singleton
|
||||
import ../../../../../app_service/service/dapp_permissions/service as dapp_permissions_service
|
||||
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
moduleLoaded: bool
|
||||
dappsLoaded: bool
|
||||
controller: Controller
|
||||
|
||||
proc newModule*(
|
||||
delegate: delegate_interface.AccessInterface,
|
||||
dappPermissionsService: dapp_permissions_service.Service,
|
||||
walletAccountServive: wallet_account_service.Service,
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.moduleLoaded = false
|
||||
result.dappsLoaded = false
|
||||
result.controller = controller.newController(result, dappPermissionsService, walletAccountServive)
|
||||
|
||||
method delete*(self: Module) =
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
self.controller.delete
|
||||
|
||||
method fetchDapps*(self: Module) =
|
||||
self.view.clearDapps()
|
||||
let dapps = self.controller.getDapps()
|
||||
var items: seq[Item] = @[]
|
||||
|
||||
for dapp in dapps:
|
||||
var found = false
|
||||
for item in items:
|
||||
if item.name == dapp.name:
|
||||
found = true
|
||||
|
||||
let account = self.controller.getAccountForAddress(dapp.address)
|
||||
if account.isNil:
|
||||
break
|
||||
|
||||
item.addAccount(account)
|
||||
break
|
||||
|
||||
if not found:
|
||||
let item = initItem(
|
||||
dapp.name, dapp.permissions.mapIt($it)
|
||||
)
|
||||
items.add(item)
|
||||
let account = self.controller.getAccountForAddress(dapp.address)
|
||||
item.addAccount(account)
|
||||
|
||||
for item in items:
|
||||
self.view.addDapp(item)
|
||||
|
||||
method load*(self: Module) =
|
||||
singletonInstance.engine.setRootContextProperty("dappPermissionsModule", self.viewVariant)
|
||||
self.view.load()
|
||||
|
||||
method isLoaded*(self: Module): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
self.moduleLoaded = true
|
||||
self.delegate.dappsDidLoad()
|
||||
|
||||
|
||||
method loadDapps*(self: Module) =
|
||||
if self.dappsLoaded:
|
||||
return
|
||||
|
||||
self.fetchDapps()
|
||||
|
||||
self.dappsLoaded = true
|
||||
|
||||
method onActivated*(self: Module) =
|
||||
self.loadDapps()
|
||||
|
||||
method hasPermission*(self: Module, hostname: string, address: string, permission: string): bool =
|
||||
self.controller.hasPermission(hostname, address, permission.toPermission())
|
||||
|
||||
method addPermission*(self: Module, hostname: string, address: string, permission: string) =
|
||||
self.controller.addPermission(hostname, address, permission.toPermission())
|
||||
self.fetchDapps()
|
||||
|
||||
method removePermission*(self: Module, dapp: string, address: string, permission: string) =
|
||||
self.controller.removePermission(dapp, address, permission.toPermission())
|
||||
self.fetchDapps()
|
||||
|
||||
method disconnectAddress*(self: Module, dapp: string, address: string) =
|
||||
self.controller.disconnectAddress(dapp, address)
|
||||
self.fetchDapps()
|
||||
|
||||
method disconnect*(self: Module, dapp: string) =
|
||||
self.controller.disconnect(dapp)
|
||||
self.fetchDapps()
|
|
@ -1,69 +0,0 @@
|
|||
import NimQml, Tables, strutils, stew/shims/strformat
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
Name = UserRole + 1
|
||||
|
||||
QtObject:
|
||||
type
|
||||
PermissionsModel* = ref object of QAbstractListModel
|
||||
items: seq[string]
|
||||
|
||||
proc delete(self: PermissionsModel) =
|
||||
self.items = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: PermissionsModel) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc newPermissionsModel*(): PermissionsModel =
|
||||
new(result, delete)
|
||||
result.setup
|
||||
|
||||
proc `$`*(self: PermissionsModel): string =
|
||||
for i in 0 ..< self.items.len:
|
||||
result &= fmt"""
|
||||
[{i}]:({$self.items[i]})
|
||||
"""
|
||||
|
||||
proc modelChanged(self: PermissionsModel) {.signal.}
|
||||
|
||||
proc getCount(self: PermissionsModel): int {.slot.} =
|
||||
self.items.len
|
||||
|
||||
QtProperty[int] count:
|
||||
read = getCount
|
||||
notify = countChanged
|
||||
|
||||
method rowCount(self: PermissionsModel, index: QModelIndex = nil): int =
|
||||
return self.items.len
|
||||
|
||||
method roleNames(self: PermissionsModel): Table[int, string] =
|
||||
{
|
||||
ModelRole.Name.int:"name"
|
||||
}.toTable
|
||||
|
||||
method data(self: PermissionsModel, index: QModelIndex, role: int): QVariant =
|
||||
if (not index.isValid):
|
||||
return
|
||||
|
||||
if (index.row < 0 or index.row >= self.items.len):
|
||||
return
|
||||
result = newQVariant(self.items[index.row])
|
||||
|
||||
proc addItem*(self: PermissionsModel, item: string) =
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
for i in self.items:
|
||||
if i == item:
|
||||
return
|
||||
|
||||
self.beginInsertRows(parentModelIndex, self.items.len, self.items.len)
|
||||
self.items.add(item)
|
||||
self.endInsertRows()
|
||||
self.modelChanged()
|
||||
|
||||
proc clear*(self: PermissionsModel) {.slot.} =
|
||||
self.beginResetModel()
|
||||
self.items = @[]
|
||||
self.endResetModel()
|
|
@ -1,65 +0,0 @@
|
|||
import NimQml
|
||||
import io_interface
|
||||
import ./dapps
|
||||
import ./item
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
dappsModel: DappsModel
|
||||
dappsModelVariant: QVariant
|
||||
|
||||
proc setup(self: View) =
|
||||
self.QObject.setup
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.dappsModel.delete
|
||||
self.dappsModelVariant.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||
new(result, delete)
|
||||
result.delegate = delegate
|
||||
result.dappsModel = newDappsModel()
|
||||
result.dappsModelVariant = newQVariant(result.dappsModel)
|
||||
result.setup()
|
||||
|
||||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
||||
|
||||
proc addDapp*(self: View, item: Item) =
|
||||
self.dappsModel.addItem(item)
|
||||
|
||||
proc modelChanged*(self: View) {.signal.}
|
||||
|
||||
proc getDappsModel(self: View): QVariant {.slot.} =
|
||||
return self.dappsModelVariant
|
||||
|
||||
QtProperty[QVariant] dapps:
|
||||
read = getDappsModel
|
||||
notify = modelChanged
|
||||
|
||||
proc loadDapps(self: View) {.slot.} =
|
||||
self.delegate.loadDapps()
|
||||
|
||||
proc hasPermission(self: View, hostname: string, address: string, permission: string): bool {.slot.} =
|
||||
return self.delegate.hasPermission(hostname, address, permission)
|
||||
|
||||
proc addPermission(self: View, hostname: string, address: string, permission: string) {.slot.} =
|
||||
self.delegate.addPermission(hostname, address, permission)
|
||||
|
||||
proc removePermission(self: View, dapp: string, address: string, permission: string): string {.slot.} =
|
||||
self.delegate.removePermission(dapp, address, permission)
|
||||
|
||||
proc disconnectAddress(self: View, dapp: string, address: string): string {.slot.} =
|
||||
self.delegate.disconnectAddress(dapp, address)
|
||||
|
||||
proc disconnect(self: View, dapp: string) {.slot.} =
|
||||
self.delegate.disconnect(dapp)
|
||||
|
||||
proc clearDapps*(self: View) =
|
||||
self.dappsModel.clear()
|
||||
|
||||
proc fetchDapps(self: View) {.slot.} =
|
||||
self.delegate.fetchDapps()
|
|
@ -1,29 +0,0 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onActivated*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method bookmarkDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method dappsDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method providerDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method openUrl*(self: AccessInterface, url: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -1,108 +0,0 @@
|
|||
import NimQml
|
||||
import io_interface
|
||||
import ../io_interface as delegate_interface
|
||||
import view
|
||||
import ../../../global/global_singleton
|
||||
import ../../../core/eventemitter
|
||||
import provider/module as provider_module
|
||||
import bookmark/module as bookmark_module
|
||||
import dapps/module as dapps_module
|
||||
import current_account/module as current_account_module
|
||||
import ../../../../app_service/service/bookmarks/service as bookmark_service
|
||||
import ../../../../app_service/service/settings/service as settings_service
|
||||
import ../../../../app_service/service/network/service as network_service
|
||||
import ../../../../app_service/service/dapp_permissions/service as dapp_permissions_service
|
||||
import ../../../../app_service/service/provider/service as provider_service
|
||||
import ../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ../../../../app_service/service/token/service as token_service
|
||||
import ../../../../app_service/service/currency/service as currency_service
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
events: EventEmitter
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
moduleLoaded: bool
|
||||
providerModule: provider_module.AccessInterface
|
||||
bookmarkModule: bookmark_module.AccessInterface
|
||||
dappsModule: dapps_module.AccessInterface
|
||||
currentAccountModule: current_account_module.AccessInterface
|
||||
|
||||
proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
bookmarkService: bookmark_service.Service,
|
||||
settingsService: settings_service.Service,
|
||||
networkService: network_service.Service,
|
||||
dappPermissionsService: dapp_permissions_service.Service,
|
||||
providerService: provider_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
tokenService: token_service.Service,
|
||||
currencyService: currency_service.Service
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.moduleLoaded = false
|
||||
result.providerModule = provider_module.newModule(result, events, settingsService, networkService, providerService)
|
||||
result.bookmarkModule = bookmark_module.newModule(result, events, bookmarkService)
|
||||
result.dappsModule = dapps_module.newModule(result, dappPermissionsService, walletAccountService)
|
||||
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService, networkService, tokenService, currencyService)
|
||||
|
||||
method delete*(self: Module) =
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
self.providerModule.delete
|
||||
self.bookmarkModule.delete
|
||||
self.dappsModule.delete
|
||||
self.currentAccountModule.delete
|
||||
|
||||
method load*(self: Module) =
|
||||
singletonInstance.engine.setRootContextProperty("browserSection", self.viewVariant)
|
||||
self.currentAccountModule.load()
|
||||
self.providerModule.load()
|
||||
self.bookmarkModule.load()
|
||||
self.dappsModule.load()
|
||||
self.view.load()
|
||||
|
||||
method onActivated*(self: Module) =
|
||||
self.bookmarkModule.onActivated()
|
||||
self.dappsModule.onActivated()
|
||||
|
||||
method isLoaded*(self: Module): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
proc checkIfModuleDidLoad(self: Module) =
|
||||
if(not self.providerModule.isLoaded()):
|
||||
return
|
||||
|
||||
if(not self.bookmarkModule.isLoaded()):
|
||||
return
|
||||
|
||||
if(not self.dappsModule.isLoaded()):
|
||||
return
|
||||
|
||||
if(not self.currentAccountModule.isLoaded()):
|
||||
return
|
||||
|
||||
self.moduleLoaded = true
|
||||
self.delegate.browserSectionDidLoad()
|
||||
|
||||
method providerDidLoad*(self: Module) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method bookmarkDidLoad*(self: Module) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method dappsDidLoad*(self: Module) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method openUrl*(self: Module, url: string) =
|
||||
self.view.sendOpenUrlSignal(url)
|
|
@ -1,71 +0,0 @@
|
|||
import io_interface
|
||||
|
||||
import ../../../../core/eventemitter
|
||||
import ../../../../../app_service/service/network/service as network_service
|
||||
import ../../../../../app_service/service/settings/service as settings_service
|
||||
import ../../../../../app_service/service/provider/service as provider_service
|
||||
import ../../../../../app_service/service/wallet_account/service
|
||||
import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_module
|
||||
import app_service/service/network/network_item
|
||||
|
||||
const UNIQUE_BROWSER_SECTION_TRANSACTION_MODULE_IDENTIFIER* = "BrowserSection-TransactionModule"
|
||||
|
||||
type
|
||||
Controller* = ref object of RootObj
|
||||
delegate: io_interface.AccessInterface
|
||||
events: EventEmitter
|
||||
settingsService: settings_service.Service
|
||||
networkService: network_service.Service
|
||||
providerService: provider_service.Service
|
||||
|
||||
proc newController*(
|
||||
delegate: io_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
networkService: network_service.Service,
|
||||
providerService: provider_service.Service,
|
||||
): Controller =
|
||||
result = Controller()
|
||||
result.events = events
|
||||
result.delegate = delegate
|
||||
result.settingsService = settingsService
|
||||
result.networkService = networkService
|
||||
result.providerService = providerService
|
||||
|
||||
proc delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
proc getAppNetwork*(self: Controller): NetworkItem =
|
||||
return self.networkService.getAppNetwork()
|
||||
|
||||
proc init*(self: Controller) =
|
||||
self.events.on(PROVIDER_SIGNAL_ON_POST_MESSAGE) do(e:Args):
|
||||
let args = OnPostMessageArgs(e)
|
||||
self.delegate.onPostMessage(args.payloadMethod, args.result, args.chainId)
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e: Args):
|
||||
self.delegate.updateNetwork(self.getAppNetwork())
|
||||
|
||||
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
|
||||
let args = SharedKeycarModuleArgs(e)
|
||||
if args.uniqueIdentifier != UNIQUE_BROWSER_SECTION_TRANSACTION_MODULE_IDENTIFIER:
|
||||
return
|
||||
self.delegate.onUserAuthenticated(args.password)
|
||||
|
||||
proc getDappsAddress*(self: Controller): string =
|
||||
return self.settingsService.getDappsAddress()
|
||||
|
||||
proc setDappsAddress*(self: Controller, address: string) =
|
||||
if self.settingsService.saveDappsAddress(address):
|
||||
self.delegate.onDappAddressChanged(address)
|
||||
|
||||
proc postMessage*(self: Controller, payloadMethod: string, requestType: string, message: string) =
|
||||
self.providerService.postMessage(payloadMethod, requestType, message)
|
||||
|
||||
proc ensResourceURL*(self: Controller, ens: string, url: string): (string, string, string, string, bool) =
|
||||
return self.providerService.ensResourceURL(ens, url)
|
||||
|
||||
proc authenticateUser*(self: Controller, keyUid = "") =
|
||||
let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_BROWSER_SECTION_TRANSACTION_MODULE_IDENTIFIER,
|
||||
keyUid: keyUid)
|
||||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
|
|
@ -1,43 +0,0 @@
|
|||
import app_service/service/network/network_item
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
||||
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 setDappsAddress*(self: AccessInterface, newDappAddress: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onDappAddressChanged*(self: AccessInterface, newDappAddress: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method disconnect*(self: AccessInterface, dappName: string, address: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method postMessage*(self: AccessInterface, payloadMethod: string, requestType: string, message: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method ensResourceURL*(self: AccessInterface, ens: string, url: string): (string, string, string, string, bool) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onPostMessage*(self: AccessInterface, payloadMethod: string, result: string, chainId: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method updateNetwork*(self: AccessInterface, network: NetworkItem) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method authenticateToPostMessage*(self: AccessInterface, payloadMethod: string, requestType: string, message: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onUserAuthenticated*(self: AccessInterface, password: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -1,104 +0,0 @@
|
|||
import NimQml
|
||||
import io_interface
|
||||
import view
|
||||
import controller
|
||||
import std/json
|
||||
import ../../../../core/eventemitter
|
||||
|
||||
import ../io_interface as delegate_interface
|
||||
import app_service/service/settings/service as settings_service
|
||||
import app_service/service/network/service as network_service
|
||||
import app_service/service/provider/service as provider_service
|
||||
import app_service/service/network/network_item
|
||||
import app/global/global_singleton
|
||||
export io_interface
|
||||
|
||||
# Shouldn't be public ever, use only within this module.
|
||||
type TmpSendTransactionDetails = object
|
||||
payloadMethod: string
|
||||
requestType: string
|
||||
message: string
|
||||
|
||||
type
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
moduleLoaded: bool
|
||||
controller: Controller
|
||||
tmpSendTransactionDetails: TmpSendTransactionDetails
|
||||
|
||||
proc newModule*(
|
||||
delegate: delegate_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
networkService: network_service.Service,
|
||||
providerService: provider_service.Service
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.view = newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.moduleLoaded = false
|
||||
result.controller = controller.newController(result, events, settingsService, networkService, providerService)
|
||||
|
||||
method delete*(self: Module) =
|
||||
self.controller.delete
|
||||
self.viewVariant.delete
|
||||
self.view.delete
|
||||
|
||||
method load*(self: Module) =
|
||||
singletonInstance.engine.setRootContextProperty("providerModule", self.viewVariant)
|
||||
self.view.dappsAddress = self.controller.getDappsAddress()
|
||||
let network = self.controller.getAppNetwork()
|
||||
self.view.chainId = network.chainId
|
||||
self.view.chainName = network.chainName
|
||||
self.view.load()
|
||||
self.controller.init()
|
||||
|
||||
method isLoaded*(self: Module): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
method setDappsAddress*(self: Module, value: string) =
|
||||
self.controller.setDappsAddress(value)
|
||||
|
||||
method onDappAddressChanged*(self: Module, value: string) =
|
||||
self.view.dappsAddress = value
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
self.moduleLoaded = true
|
||||
self.delegate.providerDidLoad()
|
||||
|
||||
method postMessage*(self: Module, payloadMethod: string, requestType: string, message: string) =
|
||||
self.controller.postMessage(payloadMethod, requestType, message)
|
||||
|
||||
method onPostMessage*(self: Module, payloadMethod: string, result: string, chainId: string) =
|
||||
self.view.postMessageResult(payloadMethod, result, chainId)
|
||||
|
||||
method ensResourceURL*(self: Module, ens: string, url: string): (string, string, string, string, bool) =
|
||||
return self.controller.ensResourceURL(ens, url)
|
||||
|
||||
method updateNetwork*(self: Module, network: NetworkItem) =
|
||||
self.view.chainId = network.chainId
|
||||
self.view.chainName = network.chainName
|
||||
|
||||
method authenticateToPostMessage*(self: Module, payloadMethod: string, requestType: string, message: string) {.slot.} =
|
||||
self.tmpSendTransactionDetails.payloadMethod = payloadMethod
|
||||
self.tmpSendTransactionDetails.requestType = requestType
|
||||
self.tmpSendTransactionDetails.message = message
|
||||
|
||||
if singletonInstance.userProfile.getIsKeycardUser():
|
||||
let keyUid = singletonInstance.userProfile.getKeyUid()
|
||||
self.controller.authenticateUser(keyUid)
|
||||
else:
|
||||
self.controller.authenticateUser()
|
||||
|
||||
method onUserAuthenticated*(self: Module, password: string) =
|
||||
let jsonNode = parseJson(self.tmpSendTransactionDetails.message)
|
||||
|
||||
if jsonNode.kind == JObject and jsonNode.contains("payload"):
|
||||
jsonNode["payload"]["password"] = %* password
|
||||
self.tmpSendTransactionDetails.message = $jsonNode
|
||||
self.postMessage(self.tmpSendTransactionDetails.payloadMethod,
|
||||
self.tmpSendTransactionDetails.requestType,
|
||||
self.tmpSendTransactionDetails.message)
|
|
@ -1,91 +0,0 @@
|
|||
import NimQml, strutils
|
||||
|
||||
import ./io_interface
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
dappsAddress: string
|
||||
chainId: int
|
||||
chainName: string
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.QObject.delete
|
||||
|
||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.delegate = delegate
|
||||
|
||||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
||||
|
||||
proc dappsAddressChanged(self: View, value: string) {.signal.}
|
||||
|
||||
proc `dappsAddress=`*(self: View, value: string) =
|
||||
self.dappsAddress = value
|
||||
self.dappsAddressChanged(value)
|
||||
|
||||
proc dappsAddress*(self: View): string {.slot.} =
|
||||
result = self.dappsAddress
|
||||
|
||||
proc setDappsAddress(self: View, value: string) {.slot.} =
|
||||
self.delegate.setDappsAddress(value)
|
||||
|
||||
QtProperty[string] dappsAddress:
|
||||
read = dappsAddress
|
||||
write = setDappsAddress
|
||||
notify = dappsAddressChanged
|
||||
|
||||
proc chainIdChanged(self: View, chainId: int) {.signal.}
|
||||
|
||||
proc `chainId=`*(self: View, value: int) =
|
||||
self.chainId = value
|
||||
self.chainIdChanged(value)
|
||||
|
||||
proc chainId*(self: View): int {.slot.} =
|
||||
result = self.chainId
|
||||
|
||||
QtProperty[int] chainId:
|
||||
read = chainId
|
||||
notify = chainIdChanged
|
||||
|
||||
proc chainNameChanged(self: View) {.signal.}
|
||||
|
||||
proc `chainName=`*(self: View, value: string) =
|
||||
self.chainName = value
|
||||
self.chainNameChanged()
|
||||
|
||||
proc chainName*(self: View): string {.slot.} =
|
||||
result = self.chainName
|
||||
|
||||
QtProperty[string] chainName:
|
||||
read = chainName
|
||||
notify = chainNameChanged
|
||||
|
||||
proc replaceHostByENS*(self: View, url: string, ens: string): string {.slot.} =
|
||||
result = url_replaceHostAndAddPath(url, ens)
|
||||
|
||||
proc getHost*(self: View, url: string): string {.slot.} =
|
||||
result = url_host(url)
|
||||
|
||||
proc postMessageResult*(self: View, payloadMethod: string, result: string, chainId: string) {.signal.}
|
||||
|
||||
proc postMessage*(self: View, payloadMethod: string, requestType: string, message: string) {.slot.} =
|
||||
self.delegate.postMessage(payloadMethod, requestType, message)
|
||||
|
||||
proc ensResourceURL*(self: View, ens: string, url: string): string {.slot.} =
|
||||
let (url, base, http_scheme, _, hasContentHash) = self.delegate.ensResourceURL(ens, url)
|
||||
var newHost = url_host(base)
|
||||
if hasContentHash:
|
||||
if strutils.endsWith(base, "/"):
|
||||
newHost = base[0.. ^2]
|
||||
else:
|
||||
newHost = base
|
||||
|
||||
result = url_replaceHostAndAddPath(url, newHost, http_scheme, "")
|
||||
|
||||
proc authenticateToPostMessage*(self: View, payloadMethod: string, requestType: string, message: string) {.slot.} =
|
||||
self.delegate.authenticateToPostMessage(payloadMethod, requestType, message)
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
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()
|
||||
|
||||
proc openUrl*(self: View, url: string) {.signal.}
|
||||
proc sendOpenUrlSignal*(self: View, url: string) =
|
||||
self.openUrl(url)
|
|
@ -69,9 +69,6 @@ method profileSectionDidLoad*(self: AccessInterface) {.base.} =
|
|||
method walletSectionDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method browserSectionDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method networkConnectionModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ import chat_section/model as chat_model
|
|||
import chat_section/item as chat_item
|
||||
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 profile_section/module as profile_section_module
|
||||
import app_search/module as app_search_module
|
||||
import stickers/module as stickers_module
|
||||
|
@ -41,8 +40,6 @@ import ../../../app_service/service/collectible/service as collectible_service
|
|||
import ../../../app_service/service/currency/service as currency_service
|
||||
import ../../../app_service/service/transaction/service as transaction_service
|
||||
import ../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ../../../app_service/service/bookmarks/service as bookmark_service
|
||||
import ../../../app_service/service/dapp_permissions/service as dapp_permissions_service
|
||||
import ../../../app_service/service/provider/service as provider_service
|
||||
import ../../../app_service/service/profile/service as profile_service
|
||||
import ../../../app_service/service/accounts/service as accounts_service
|
||||
|
@ -104,7 +101,6 @@ type
|
|||
keychainService: keychain_service.Service
|
||||
networkConnectionService: network_connection_service.Service
|
||||
walletSectionModule: wallet_section_module.AccessInterface
|
||||
browserSectionModule: browser_section_module.AccessInterface
|
||||
profileSectionModule: profile_section_module.AccessInterface
|
||||
stickersModule: stickers_module.AccessInterface
|
||||
gifsModule: gifs_module.AccessInterface
|
||||
|
@ -146,12 +142,10 @@ proc newModule*[T](
|
|||
currencyService: currency_service.Service,
|
||||
transactionService: transaction_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
bookmarkService: bookmark_service.Service,
|
||||
profileService: profile_service.Service,
|
||||
settingsService: settings_service.Service,
|
||||
contactsService: contacts_service.Service,
|
||||
aboutService: about_service.Service,
|
||||
dappPermissionsService: dapp_permissions_service.Service,
|
||||
languageService: language_service.Service,
|
||||
privacyService: privacy_service.Service,
|
||||
providerService: provider_service.Service,
|
||||
|
@ -219,11 +213,6 @@ proc newModule*[T](
|
|||
keycardService, nodeService, networkConnectionService, devicesService,
|
||||
communityTokensService, threadpool
|
||||
)
|
||||
result.browserSectionModule = browser_section_module.newModule(
|
||||
result, events, bookmarkService, settingsService, networkService,
|
||||
dappPermissionsService, providerService, walletAccountService,
|
||||
tokenService, currencyService
|
||||
)
|
||||
result.profileSectionModule = profile_section_module.newModule(
|
||||
result, events, accountsService, settingsService, stickersService,
|
||||
profileService, contactsService, aboutService, languageService, privacyService, nodeConfigurationService,
|
||||
|
@ -254,7 +243,6 @@ method delete*[T](self: Module[T]) =
|
|||
cModule.delete
|
||||
self.chatSectionModules.clear
|
||||
self.walletSectionModule.delete
|
||||
self.browserSectionModule.delete
|
||||
self.appSearchModule.delete
|
||||
self.nodeSectionModule.delete
|
||||
if not self.keycardSharedModuleForAuthenticationOrSigning.isNil:
|
||||
|
@ -539,27 +527,6 @@ method load*[T](
|
|||
if(activeSectionId == walletSectionItem.id):
|
||||
activeSection = walletSectionItem
|
||||
|
||||
# Browser Section
|
||||
let browserSectionItem = initItem(
|
||||
conf.BROWSER_SECTION_ID,
|
||||
SectionType.Browser,
|
||||
conf.BROWSER_SECTION_NAME,
|
||||
memberRole = MemberRole.Owner,
|
||||
description = "",
|
||||
introMessage = "",
|
||||
outroMessage = "",
|
||||
image = "",
|
||||
icon = conf.BROWSER_SECTION_ICON,
|
||||
color = "",
|
||||
hasNotification = false,
|
||||
notificationsCount = 0,
|
||||
active = false,
|
||||
enabled = singletonInstance.localAccountSensitiveSettings.getIsBrowserEnabled(),
|
||||
)
|
||||
self.view.model().addItem(browserSectionItem)
|
||||
if(activeSectionId == browserSectionItem.id):
|
||||
activeSection = browserSectionItem
|
||||
|
||||
# Node Management Section
|
||||
let nodeManagementSectionItem = initItem(
|
||||
conf.NODEMANAGEMENT_SECTION_ID,
|
||||
|
@ -602,7 +569,6 @@ method load*[T](
|
|||
if(activeSectionId == profileSettingsSectionItem.id):
|
||||
activeSection = profileSettingsSectionItem
|
||||
|
||||
self.browserSectionModule.load()
|
||||
self.profileSectionModule.load()
|
||||
self.stickersModule.load()
|
||||
self.gifsModule.load()
|
||||
|
@ -803,9 +769,6 @@ proc checkIfModuleDidLoad [T](self: Module[T]) =
|
|||
if (not self.walletSectionModule.isLoaded()):
|
||||
return
|
||||
|
||||
if(not self.browserSectionModule.isLoaded()):
|
||||
return
|
||||
|
||||
if(not self.nodeSectionModule.isLoaded()):
|
||||
return
|
||||
|
||||
|
@ -860,9 +823,6 @@ method communitiesModuleDidLoad*[T](self: Module[T]) =
|
|||
method walletSectionDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method browserSectionDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method profileSectionDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
|
@ -921,8 +881,6 @@ method activeSectionSet*[T](self: Module[T], sectionId: string, skipSavingInSett
|
|||
case sectionId:
|
||||
of conf.COMMUNITIESPORTAL_SECTION_ID:
|
||||
self.communitiesModule.onActivated()
|
||||
of conf.BROWSER_SECTION_ID:
|
||||
self.browserSectionModule.onActivated()
|
||||
|
||||
self.view.model().setActiveSection(sectionId)
|
||||
self.view.activeSectionSet(item)
|
||||
|
@ -939,11 +897,7 @@ proc setSectionAvailability[T](self: Module[T], sectionType: SectionType, availa
|
|||
self.view.model().disableSection(sectionType)
|
||||
|
||||
method toggleSection*[T](self: Module[T], sectionType: SectionType) =
|
||||
if (sectionType == SectionType.Browser):
|
||||
let enabled = singletonInstance.localAccountSensitiveSettings.getIsBrowserEnabled()
|
||||
self.setSectionAvailability(sectionType, not enabled)
|
||||
singletonInstance.localAccountSensitiveSettings.setIsBrowserEnabled(not enabled)
|
||||
elif (sectionType == SectionType.NodeManagement):
|
||||
if (sectionType == SectionType.NodeManagement):
|
||||
let enabled = singletonInstance.localAccountSensitiveSettings.getNodeManagementEnabled()
|
||||
self.setSectionAvailability(sectionType, not enabled)
|
||||
singletonInstance.localAccountSensitiveSettings.setNodeManagementEnabled(not enabled)
|
||||
|
@ -1518,12 +1472,6 @@ method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, commun
|
|||
else:
|
||||
return
|
||||
|
||||
# enable after MVP
|
||||
#else(action == StatusUrlAction.OpenLinkInBrowser and singletonInstance.localAccountSensitiveSettings.getIsBrowserEnabled()):
|
||||
# let item = self.view.model().getItemById(conf.BROWSER_SECTION_ICON)
|
||||
# self.setActiveSection(item)
|
||||
# self.browserSectionModule.openUrl(url)
|
||||
|
||||
################################################################################
|
||||
## keycard shared module - authentication/sign purpose
|
||||
################################################################################
|
||||
|
|
|
@ -134,9 +134,6 @@ proc toggleCommunitiesPortalSection*(self: Controller) =
|
|||
proc toggleWalletSection*(self: Controller) =
|
||||
self.events.emit(TOGGLE_SECTION, ToggleSectionArgs(sectionType: SectionType.Wallet))
|
||||
|
||||
proc toggleBrowserSection*(self: Controller) =
|
||||
self.events.emit(TOGGLE_SECTION, ToggleSectionArgs(sectionType: SectionType.Browser))
|
||||
|
||||
proc toggleCommunitySection*(self: Controller) =
|
||||
self.events.emit(TOGGLE_SECTION, ToggleSectionArgs(sectionType: SectionType.Community))
|
||||
|
||||
|
|
|
@ -93,9 +93,6 @@ method toggleCommunitiesPortalSection*(self: AccessInterface) {.base.} =
|
|||
method toggleWalletSection*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method toggleBrowserSection*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method toggleCommunitySection*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -131,9 +131,6 @@ method disableCommunityHistoryArchiveSupport*(self: Module) =
|
|||
method toggleWalletSection*(self: Module) =
|
||||
self.controller.toggleWalletSection()
|
||||
|
||||
method toggleBrowserSection*(self: Module) =
|
||||
self.controller.toggleBrowserSection()
|
||||
|
||||
method toggleCommunitySection*(self: Module) =
|
||||
self.controller.toggleCommunitySection()
|
||||
|
||||
|
|
|
@ -119,9 +119,6 @@ QtObject:
|
|||
proc toggleWalletSection*(self: View) {.slot.} =
|
||||
self.delegate.toggleWalletSection()
|
||||
|
||||
proc toggleBrowserSection*(self: View) {.slot.} =
|
||||
self.delegate.toggleBrowserSection()
|
||||
|
||||
proc toggleCommunitySection*(self: View) {.slot.} =
|
||||
self.delegate.toggleCommunitySection()
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ type
|
|||
Chat = 0
|
||||
Community,
|
||||
Wallet,
|
||||
Browser,
|
||||
ProfileSettings,
|
||||
NodeManagement,
|
||||
CommunitiesPortal
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
import json
|
||||
|
||||
include ../../../common/json_utils
|
||||
|
||||
type BookmarkDto* = object
|
||||
name*: string
|
||||
url*: string
|
||||
imageUrl*: string
|
||||
removed*: bool
|
||||
deletedAt*: int
|
||||
|
||||
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)
|
||||
discard jsonObj.getProp("removed", result.removed)
|
||||
discard jsonObj.getProp("deletedAt", result.deletedAt)
|
|
@ -1,133 +0,0 @@
|
|||
import Tables, json, sequtils, chronicles, strutils
|
||||
import results
|
||||
include ../../common/json_utils
|
||||
import ./dto/bookmark as bookmark_dto
|
||||
import ../../../app/core/eventemitter
|
||||
import ../../../app/core/signals/types
|
||||
import ../../../backend/backend
|
||||
import ../../../backend/browser
|
||||
|
||||
export bookmark_dto
|
||||
|
||||
logScope:
|
||||
topics = "bookmarks-service"
|
||||
|
||||
const SIGNAL_BOOKMARK_ADDED* = "bookmarkAdded"
|
||||
const SIGNAL_BOOKMARK_REMOVED* = "bookmarkRemoved"
|
||||
const SIGNAL_BOOKMARK_UPDATED* = "bookmarkUpdated"
|
||||
|
||||
type
|
||||
Service* = ref object of RootObj
|
||||
bookmarks: Table[string, BookmarkDto] # [url, BookmarkDto]
|
||||
bookmarksFetched: bool
|
||||
events: EventEmitter
|
||||
|
||||
type R = Result[BookmarkDto, string]
|
||||
|
||||
type
|
||||
BookmarkArgs* = ref object of Args
|
||||
bookmark*: BookmarkDto
|
||||
|
||||
type
|
||||
BookmarkRemovedArgs* = ref object of Args
|
||||
url*: string
|
||||
|
||||
proc delete*(self: Service) =
|
||||
discard
|
||||
|
||||
proc newService*(events: EventEmitter): Service =
|
||||
result = Service()
|
||||
result.events = events
|
||||
result.bookmarks = initTable[string, BookmarkDto]()
|
||||
result.bookmarksFetched = false
|
||||
|
||||
proc init*(self: Service) =
|
||||
self.events.on(SignalType.Message.event) do(e: Args):
|
||||
var receivedData = MessageSignal(e)
|
||||
if receivedData.bookmarks.len > 0:
|
||||
for bookmark in receivedData.bookmarks:
|
||||
let url = bookmark.url
|
||||
if bookmark.removed and not self.bookmarks.hasKey(url):
|
||||
return
|
||||
|
||||
if self.bookmarks.hasKey(url) and bookmark.removed:
|
||||
self.bookmarks.del(url)
|
||||
self.events.emit(SIGNAL_BOOKMARK_REMOVED, BookmarkRemovedArgs(url: url))
|
||||
return
|
||||
|
||||
let emitUpdateEvent = self.bookmarks.hasKey(url)
|
||||
|
||||
self.bookmarks[url] = BookmarkDto()
|
||||
self.bookmarks[url].url = bookmark.url
|
||||
self.bookmarks[url].name = bookmark.name
|
||||
self.bookmarks[url].imageUrl = bookmark.imageUrl
|
||||
self.bookmarks[url].removed = bookmark.removed
|
||||
|
||||
if emitUpdateEvent:
|
||||
self.events.emit(SIGNAL_BOOKMARK_UPDATED, BookmarkArgs(bookmark: self.bookmarks[url]))
|
||||
return
|
||||
|
||||
self.events.emit(SIGNAL_BOOKMARK_ADDED, BookmarkArgs(bookmark: self.bookmarks[url]))
|
||||
|
||||
proc fetchBookmarks*(self: Service) =
|
||||
# TODO later we can make this async, but it's not worth it for now
|
||||
try:
|
||||
let response = backend.getBookmarks()
|
||||
for bookmark in response.result.getElems().mapIt(it.toBookmarkDto()):
|
||||
if not bookmark.removed:
|
||||
self.bookmarks[bookmark.url] = bookmark
|
||||
self.bookmarksFetched = true
|
||||
except Exception as e:
|
||||
error "error fetching bookmarks: ", msg=e.msg
|
||||
|
||||
proc getBookmarks*(self: Service): seq[BookmarkDto] =
|
||||
if not self.bookmarksFetched:
|
||||
self.fetchBookmarks()
|
||||
return toSeq(self.bookmarks.values)
|
||||
|
||||
proc storeBookmark*(self: Service, url, name: string): R =
|
||||
try:
|
||||
if not url.isEmptyOrWhitespace:
|
||||
let response = browser.addBookmark(backend.Bookmark(name: name, url: url)).result
|
||||
self.bookmarks[url] = BookmarkDto()
|
||||
self.bookmarks[url].url = url
|
||||
self.bookmarks[url].name = name
|
||||
discard response.getProp("imageUrl", self.bookmarks[url].imageUrl)
|
||||
discard response.getProp("removed", self.bookmarks[url].removed)
|
||||
discard response.getProp("deletedAt", self.bookmarks[url].deletedAt)
|
||||
result.ok self.bookmarks[url]
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error: ", errDescription
|
||||
result.err errDescription
|
||||
|
||||
proc deleteBookmark*(self: Service, url: string): bool =
|
||||
try:
|
||||
if not self.bookmarks.hasKey(url):
|
||||
return
|
||||
discard browser.removeBookmark(url).result
|
||||
self.bookmarks.del(url)
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error: ", errDescription
|
||||
return
|
||||
return true
|
||||
|
||||
proc updateBookmark*(self: Service, oldUrl, newUrl, newName: string): R =
|
||||
try:
|
||||
if not self.bookmarks.hasKey(oldUrl):
|
||||
return
|
||||
|
||||
let response = browser.updateBookmark(oldUrl, backend.Bookmark(name: newName, url: newUrl)).result
|
||||
self.bookmarks.del(oldUrl)
|
||||
self.bookmarks[newUrl] = BookmarkDto()
|
||||
self.bookmarks[newUrl].url = newUrl
|
||||
self.bookmarks[newUrl].name = newName
|
||||
discard response.getProp("imageUrl", self.bookmarks[newurl].imageUrl)
|
||||
discard response.getProp("removed", self.bookmarks[newurl].removed)
|
||||
discard response.getProp("deletedAt", self.bookmarks[newurl].deletedAt)
|
||||
result.ok self.bookmarks[newUrl]
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error: ", errDescription
|
||||
result.err errDescription
|
|
@ -1,17 +0,0 @@
|
|||
import json
|
||||
import sets
|
||||
import permission
|
||||
include ../../../common/json_utils
|
||||
|
||||
type Dapp* = object
|
||||
name*: string
|
||||
address*: string
|
||||
permissions*: HashSet[Permission]
|
||||
|
||||
proc toDapp*(jsonObj: JsonNode): Dapp =
|
||||
result = Dapp()
|
||||
result.permissions = initHashSet[Permission]()
|
||||
discard jsonObj.getProp("dapp", result.name)
|
||||
discard jsonObj.getProp("address", result.address)
|
||||
for permission in jsonObj["permissions"].getElems():
|
||||
result.permissions.incl(permission.getStr().toPermission())
|
|
@ -1,17 +0,0 @@
|
|||
import json
|
||||
import chronicles
|
||||
import strutils
|
||||
include ../../../common/json_utils
|
||||
|
||||
type
|
||||
Permission* {.pure.} = enum
|
||||
Web3 = "web3",
|
||||
ContactCode = "contact-code"
|
||||
Unknown = "unknown"
|
||||
|
||||
proc toPermission*(value: string): Permission =
|
||||
result = Permission.Unknown
|
||||
try:
|
||||
result = parseEnum[Permission](value)
|
||||
except:
|
||||
warn "Unknown permission requested", value
|
|
@ -1,141 +0,0 @@
|
|||
import Tables, json, sequtils, chronicles
|
||||
import sets
|
||||
import results
|
||||
import options
|
||||
include ../../common/json_utils
|
||||
import ../../../backend/backend
|
||||
import dto/dapp
|
||||
import dto/permission
|
||||
|
||||
export dapp
|
||||
export permission
|
||||
|
||||
logScope:
|
||||
topics = "dapp-permissions-service"
|
||||
|
||||
type
|
||||
Service* = ref object
|
||||
dapps: Table[string, Dapp]
|
||||
permissionsFetched: bool
|
||||
|
||||
type R = Result[Dapp, string]
|
||||
|
||||
proc delete*(self: Service) =
|
||||
discard
|
||||
|
||||
proc newService*(): Service =
|
||||
result = Service()
|
||||
result.dapps = initTable[string, Dapp]()
|
||||
result.permissionsFetched = false
|
||||
|
||||
proc init*(self: Service) =
|
||||
discard
|
||||
|
||||
proc fetchDappPermissions*(self: Service) =
|
||||
# TODO later we can make this async, but it's not worth it for now
|
||||
try:
|
||||
let response = backend.getDappPermissions()
|
||||
for dapp in response.result.getElems().mapIt(it.toDapp()):
|
||||
if dapp.address == "":
|
||||
continue
|
||||
|
||||
self.dapps[dapp.name & dapp.address] = dapp
|
||||
self.permissionsFetched = true
|
||||
except Exception as e:
|
||||
error "error fetching permissions: ", msg=e.msg
|
||||
|
||||
proc getDapps*(self: Service): seq[Dapp] =
|
||||
if not self.permissionsFetched:
|
||||
self.fetchDappPermissions()
|
||||
return toSeq(self.dapps.values)
|
||||
|
||||
proc getDapp*(self: Service, name: string, address: string): Option[Dapp] =
|
||||
let key = name & address
|
||||
if self.dapps.hasKey(key):
|
||||
return some(self.dapps[key])
|
||||
|
||||
return none(Dapp)
|
||||
|
||||
proc addPermission*(self: Service, name: string, address: string, perm: permission.Permission): R =
|
||||
let key = name & address
|
||||
|
||||
try:
|
||||
if not self.dapps.hasKey(key):
|
||||
self.dapps[key] = Dapp(
|
||||
name: name,
|
||||
address: address,
|
||||
permissions: initHashSet[permission.Permission]()
|
||||
)
|
||||
|
||||
self.dapps[key].permissions.incl(perm)
|
||||
let permissions = self.dapps[key].permissions.toSeq().mapIt($it)
|
||||
discard backend.addDappPermissions(backend.Permission(
|
||||
dapp: name,
|
||||
address: address,
|
||||
permissions: permissions
|
||||
))
|
||||
result.ok self.dapps[key]
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error: ", errDescription
|
||||
result.err errDescription
|
||||
|
||||
|
||||
proc hasPermission*(self: Service, dapp: string, address: string, perm: permission.Permission): bool =
|
||||
let key = dapp & address
|
||||
if not self.dapps.hasKey(key):
|
||||
return false
|
||||
return self.dapps[key].permissions.contains(perm)
|
||||
|
||||
proc disconnect*(self: Service, dappName: string): bool =
|
||||
try:
|
||||
var addresses: seq[string] = @[]
|
||||
for dapp in self.dapps.values:
|
||||
if dapp.name != dappName:
|
||||
continue
|
||||
|
||||
discard backend.deleteDappPermissionsByNameAndAddress(dapp.name, dapp.address)
|
||||
addresses.add(dapp.address)
|
||||
|
||||
for address in addresses:
|
||||
self.dapps.del(dappName & address)
|
||||
|
||||
return true
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error: ", errDescription
|
||||
|
||||
proc disconnectAddress*(self: Service, dappName: string, address: string): bool =
|
||||
let key = dappName & address
|
||||
if not self.dapps.hasKey(key):
|
||||
return
|
||||
|
||||
try:
|
||||
discard backend.deleteDappPermissionsByNameAndAddress(dappName, address)
|
||||
self.dapps.del(key)
|
||||
return true
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error: ", errDescription
|
||||
|
||||
proc removePermission*(self: Service, name: string, address: string, perm: permission.Permission): bool =
|
||||
let key = name & address
|
||||
if not self.dapps.hasKey(key):
|
||||
return
|
||||
|
||||
try:
|
||||
if self.dapps[key].permissions.contains(perm):
|
||||
self.dapps[key].permissions.excl(perm)
|
||||
if self.dapps[key].permissions.len > 0:
|
||||
discard backend.addDappPermissions(backend.Permission(
|
||||
dapp: name,
|
||||
address: address,
|
||||
permissions: self.dapps[key].permissions.toSeq().mapIt($it)
|
||||
))
|
||||
else:
|
||||
discard backend.deleteDappPermissionsByNameAndAddress(name, address)
|
||||
self.dapps.del(key)
|
||||
return true
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error: ", errDescription
|
|
@ -1,5 +1,4 @@
|
|||
import json
|
||||
import ../dapp_permissions/service as dapp_permissions_service
|
||||
|
||||
const HTTPS_SCHEME* = "https"
|
||||
const IPFS_GATEWAY* = ".infura.status.im"
|
||||
|
|
|
@ -15,18 +15,6 @@ type
|
|||
decimals* {.serializedFieldName("decimals").}: int
|
||||
color* {.serializedFieldName("color").}: string
|
||||
|
||||
Bookmark* = ref object of RootObj
|
||||
name* {.serializedFieldName("name").}: string
|
||||
url* {.serializedFieldName("url").}: string
|
||||
imageUrl* {.serializedFieldName("imageUrl").}: string
|
||||
removed* {.serializedFieldName("removed").}: bool
|
||||
deletedAt* {.serializedFieldName("deletedAt").}: int
|
||||
|
||||
Permission* = ref object of RootObj
|
||||
dapp* {.serializedFieldName("dapp").}: string
|
||||
address* {.serializedFieldName("address").}: string
|
||||
permissions* {.serializedFieldName("permissions").}: seq[string]
|
||||
|
||||
Network* = ref object of RootObj
|
||||
chainId* {.serializedFieldName("chainId").}: int
|
||||
nativeCurrencyDecimals* {.serializedFieldName("nativeCurrencyDecimals").}: int
|
||||
|
@ -187,19 +175,6 @@ rpc(hasUnseenActivityCenterNotifications, "wakuext"):
|
|||
rpc(markAsSeenActivityCenterNotifications, "wakuext"):
|
||||
discard
|
||||
|
||||
rpc(getBookmarks, "browsers"):
|
||||
discard
|
||||
|
||||
rpc(storeBookmark, "browsers"):
|
||||
bookmark: Bookmark
|
||||
|
||||
rpc(updateBookmark, "browsers"):
|
||||
originalUrl: string
|
||||
bookmark: Bookmark
|
||||
|
||||
rpc(deleteBookmark, "browsers"):
|
||||
url: string
|
||||
|
||||
rpc(setTenorAPIKey, "gif"):
|
||||
key: string
|
||||
|
||||
|
@ -218,16 +193,6 @@ rpc(getRecentGifs, "gif"):
|
|||
rpc(getFavoriteGifs, "gif"):
|
||||
discard
|
||||
|
||||
rpc(getDappPermissions, "permissions"):
|
||||
discard
|
||||
|
||||
rpc(addDappPermissions, "permissions"):
|
||||
permission: Permission
|
||||
|
||||
rpc(deleteDappPermissionsByNameAndAddress, "permissions"):
|
||||
dapp: string
|
||||
address: string
|
||||
|
||||
rpc(fetchMarketValues, "wallet"):
|
||||
symbols: seq[string]
|
||||
currencies: seq[string]
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
import json
|
||||
import core, ../app_service/common/utils
|
||||
import response_type
|
||||
import ./backend
|
||||
|
||||
export response_type
|
||||
|
||||
|
||||
proc addBookmark*(bookmark: backend.Bookmark): RpcResponse[JsonNode] =
|
||||
result = callPrivateRPC("addBookmark".prefix, %*[{
|
||||
"url": bookmark.url,
|
||||
"name": bookmark.name,
|
||||
"imageUrl": bookmark.imageUrl,
|
||||
"removed": bookmark.removed,
|
||||
"deletedAt": bookmark.deletedAt
|
||||
}])
|
||||
|
||||
proc removeBookmark*(url: string): RpcResponse[JsonNode] =
|
||||
result = callPrivateRPC("removeBookmark".prefix, %*[url])
|
||||
|
||||
proc updateBookmark*(oldUrl: string, bookmark: backend.Bookmark): RpcResponse[JsonNode] =
|
||||
result = callPrivateRPC("updateBookmark".prefix, %*[oldUrl, {
|
||||
"url": bookmark.url,
|
||||
"name": bookmark.name,
|
||||
"imageUrl": bookmark.imageUrl,
|
||||
"removed": bookmark.removed,
|
||||
"deletedAt": bookmark.deletedAt
|
||||
}])
|
|
@ -1,157 +0,0 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import AppLayouts.Profile.views 1.0
|
||||
import AppLayouts.Profile.stores 1.0
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
SplitView {
|
||||
Logs { id: logs }
|
||||
|
||||
ListModel {
|
||||
id: dappsModel
|
||||
|
||||
ListElement {
|
||||
name: "http://simpledapp.eth"
|
||||
accounts: [
|
||||
ListElement {
|
||||
name: "Main Account"
|
||||
address: "0x2B748A02e06B159C7C3E98F5064577B96E55A7b4"
|
||||
color: "#4360DF"
|
||||
emoji: "😎"
|
||||
},
|
||||
ListElement {
|
||||
name: "Account 2"
|
||||
address: "0x5aD88F52b5cb0E4120c0Dd32CFeE782436F492E5"
|
||||
color: "#887AF9"
|
||||
emoji: "😋"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
property QtObject mockData: QtObject {
|
||||
property QtObject accountSettings: QtObject {
|
||||
property string browserHomepage: "https://status.im/"
|
||||
property int shouldShowBrowserSearchEngine: 3
|
||||
property bool shouldShowFavoritesBar: true
|
||||
property int useBrowserEthereumExplorer: 1
|
||||
}
|
||||
}
|
||||
SplitView {
|
||||
orientation: Qt.Vertical
|
||||
SplitView.fillWidth: true
|
||||
|
||||
BrowserView {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
contentWidth: parent.width
|
||||
sectionTitle: "Browser section"
|
||||
|
||||
accountSettings: mockData.accountSettings
|
||||
|
||||
store: ProfileSectionStore {
|
||||
property WalletStore walletStore: WalletStore {
|
||||
property var accountSensitiveSettings: mockData.accountSettings
|
||||
property var dappList: dappsModel
|
||||
|
||||
function disconnect(dappName) {
|
||||
for (let i = 0; i < dappsModel.count; i++) {
|
||||
if (dappsModel.get(i).name === dappName) {
|
||||
dappsModel.remove(i)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
function disconnectAddress(dappName, address) {
|
||||
for (let i = 0; i < dappsModel.count; i++) {
|
||||
const dapp = dappsModel.get(i)
|
||||
if (dapp.name === dappName) {
|
||||
for (let i = 0; i < dapp.accounts.count; i++) {
|
||||
if (dapp.accounts.get(i).address === address) {
|
||||
dapp.accounts.remove(i)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogsAndControlsPanel {
|
||||
id: logsAndControlsPanel
|
||||
|
||||
SplitView.minimumHeight: 100
|
||||
SplitView.preferredHeight: 200
|
||||
|
||||
logsView.logText: logs.logText
|
||||
}
|
||||
}
|
||||
|
||||
Pane {
|
||||
SplitView.minimumWidth: 300
|
||||
SplitView.preferredWidth: 300
|
||||
|
||||
font.pixelSize: 13
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 6
|
||||
|
||||
Label {
|
||||
text: "Browser Homepage"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
text: mockData.accountSettings.browserHomepage
|
||||
onTextChanged: mockData.accountSettings.browserHomepage = text
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Browser Search Engine ID"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
text: mockData.accountSettings.shouldShowBrowserSearchEngine
|
||||
onTextChanged: {
|
||||
if (text !== "") {
|
||||
mockData.accountSettings.shouldShowBrowserSearchEngine = parseInt(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Browser Ethereum Explorer ID"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
text: mockData.accountSettings.useBrowserEthereumExplorer
|
||||
onTextChanged: {
|
||||
if (text !== "") {
|
||||
mockData.accountSettings.useBrowserEthereumExplorer = parseInt(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: "Should show Favorites bar"
|
||||
checked: mockData.accountSettings.shouldShowFavoritesBar
|
||||
onToggled: mockData.accountSettings.shouldShowFavoritesBar = !mockData.accountSettings.shouldShowFavoritesBar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// category: Components
|
||||
|
||||
// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=448%3A36296
|
||||
// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1573%3A296338
|
|
@ -15,7 +15,7 @@ mainWindow_Settings_StatusNavigationPanelHeadline = {"container": mainWindow_Lef
|
|||
mainWindow_scrollView_StatusScrollView = {"container": mainWindow_LeftTabView, "id": "scrollView", "type": "StatusScrollView", "unnamed": 1, "visible": True}
|
||||
scrollView_MenuItem_StatusNavigationListItem = {"container": mainWindow_scrollView_StatusScrollView, "type": "StatusNavigationListItem", "visible": True}
|
||||
scrollView_Flickable = {"container": mainWindow_scrollView_StatusScrollView, "type": "Flickable", "unnamed": 1, "visible": True}
|
||||
settingsBackUpSeedPhraseOption = {"container": mainWindow_scrollView_StatusScrollView, "objectName": "19-MainMenuItem", "type": "StatusNavigationListItem", "visible": True}
|
||||
settingsBackUpSeedPhraseOption = {"container": mainWindow_scrollView_StatusScrollView, "objectName": "18-MainMenuItem", "type": "StatusNavigationListItem", "visible": True}
|
||||
settingsWalletOption = {"container": LeftTabView_ScrollView, "objectName": "5-AppMenuItem", "type": "StatusNavigationListItem", "visible": True}
|
||||
|
||||
# Communities View
|
||||
|
|
|
@ -67,7 +67,7 @@ class LeftPanel(QObject):
|
|||
return MessagingSettingsView()
|
||||
|
||||
@allure.step('Open communities settings')
|
||||
@handle_settings_opening(CommunitiesSettingsView, '13-AppMenuItem')
|
||||
@handle_settings_opening(CommunitiesSettingsView, '12-AppMenuItem')
|
||||
def open_communities_settings(self, attempts: int = 2) -> 'CommunitiesSettingsView':
|
||||
assert CommunitiesSettingsView().exists, 'Community settings view was not opened'
|
||||
return CommunitiesSettingsView()
|
||||
|
@ -91,7 +91,7 @@ class LeftPanel(QObject):
|
|||
return ChangePasswordView()
|
||||
|
||||
@allure.step('Choose back up seed phrase in settings')
|
||||
@handle_settings_opening(BackUpYourSeedPhrasePopUp, '19-MainMenuItem')
|
||||
@handle_settings_opening(BackUpYourSeedPhrasePopUp, '18-MainMenuItem')
|
||||
def open_back_up_seed_phrase(self, click_attempts: int = 2) -> 'BackUpYourSeedPhrasePopUp':
|
||||
assert BackUpYourSeedPhrasePopUp().exists, 'Back up your seed phrase modal was not opened'
|
||||
return BackUpYourSeedPhrasePopUp()
|
||||
|
@ -103,13 +103,13 @@ class LeftPanel(QObject):
|
|||
return SyncingSettingsView()
|
||||
|
||||
@allure.step('Choose sign out and quit in settings')
|
||||
@handle_settings_opening(SignOutPopup, '18-ExtraMenuItem')
|
||||
@handle_settings_opening(SignOutPopup, '17-ExtraMenuItem')
|
||||
def open_sign_out_and_quit(self, click_attempts: int = 2) -> 'SignOutPopup':
|
||||
assert SignOutPopup().exists, 'Sign out modal was not opened'
|
||||
return SignOutPopup()
|
||||
|
||||
@allure.step('Open keycard settings')
|
||||
@handle_settings_opening(KeycardSettingsView, '14-MainMenuItem')
|
||||
@handle_settings_opening(KeycardSettingsView, '13-MainMenuItem')
|
||||
def open_keycard_settings(self, click_attempts: int = 2) -> 'KeycardSettingsView':
|
||||
assert KeycardSettingsView().wait_until_appears(), f'Keycard settings view was not opened'
|
||||
return KeycardSettingsView()
|
||||
|
@ -121,7 +121,7 @@ class LeftPanel(QObject):
|
|||
return ENSSettingsView()
|
||||
|
||||
@allure.step('Open advanced settings')
|
||||
@handle_settings_opening(AdvancedSettingsView, '11-SettingsMenuItem')
|
||||
@handle_settings_opening(AdvancedSettingsView, '10-SettingsMenuItem')
|
||||
def open_advanced_settings(self, click_attempts: int = 2) -> 'AdvancedSettingsView':
|
||||
assert AdvancedSettingsView().exists, 'Advanced settings view was not opened'
|
||||
return AdvancedSettingsView()
|
||||
|
|
|
@ -1,616 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
import QtWebEngine 1.10
|
||||
import QtWebChannel 1.13
|
||||
import Qt.labs.settings 1.0
|
||||
import QtQuick.Controls.Styles 1.0
|
||||
import QtQuick.Dialogs 1.2
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Layout 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared.controls 1.0
|
||||
import shared 1.0
|
||||
import shared.status 1.0
|
||||
import shared.popups.send 1.0
|
||||
import shared.stores.send 1.0
|
||||
|
||||
import "popups"
|
||||
import "controls"
|
||||
import "views"
|
||||
import "panels"
|
||||
import "stores"
|
||||
|
||||
// Code based on https://code.qt.io/cgit/qt/qtwebengine.git/tree/examples/webengine/quicknanobrowser/BrowserWindow.qml?h=5.15
|
||||
// Licensed under BSD
|
||||
|
||||
StatusSectionLayout {
|
||||
id: root
|
||||
|
||||
property var globalStore
|
||||
property var sendTransactionModal
|
||||
required property TransactionStore transactionStore
|
||||
required property var assetsStore
|
||||
required property var currencyStore
|
||||
required property var tokensStore
|
||||
|
||||
function openUrlInNewTab(url) {
|
||||
var tab = _internal.addNewTab()
|
||||
tab.item.url = _internal.determineRealURL(url)
|
||||
}
|
||||
|
||||
notificationCount: activityCenterStore.unreadNotificationsCount
|
||||
hasUnseenNotifications: activityCenterStore.hasUnseenNotifications
|
||||
onNotificationButtonClicked: Global.openActivityCenterPopup()
|
||||
|
||||
QtObject {
|
||||
id: _internal
|
||||
|
||||
property Item currentWebView: tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null
|
||||
|
||||
property Component browserDialogComponent: BrowserDialog {
|
||||
onClosing: destroy()
|
||||
}
|
||||
|
||||
property Component jsDialogComponent: JSDialogWindow {}
|
||||
|
||||
property Component accessDialogComponent: BrowserConnectionModal {
|
||||
currentTab: tabs.getTab(tabs.currentIndex) && tabs.getTab(tabs.currentIndex).item
|
||||
parent: browserWindow
|
||||
x: browserWindow.width - width - Style.current.halfPadding
|
||||
y: browserWindow.y + browserHeader.height + Style.current.halfPadding
|
||||
web3Response: function(message) {
|
||||
provider.web3Response(message)
|
||||
}
|
||||
}
|
||||
|
||||
property Component sendTransactionModalComponent: SendModal {
|
||||
anchors.centerIn: parent
|
||||
preSelectedHoldingID: "ETH"
|
||||
preSelectedHoldingType: Constants.TokenType.ERC20
|
||||
store: root.transactionStore
|
||||
}
|
||||
|
||||
property Component signMessageModalComponent: SignMessageModal {}
|
||||
|
||||
property MessageDialog sendingError: MessageDialog {
|
||||
title: qsTr("Error sending the transaction")
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
property MessageDialog signingError: MessageDialog {
|
||||
title: qsTr("Error signing message")
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
property QtObject defaultProfile: WebEngineProfile {
|
||||
storageName: "Profile"
|
||||
offTheRecord: false
|
||||
httpUserAgent: {
|
||||
if (localAccountSensitiveSettings.compatibilityMode) {
|
||||
// Google doesn't let you connect if the user agent is Chrome-ish and doesn't satisfy some sort of hidden requirement
|
||||
return "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
useForGlobalCertificateVerification: true
|
||||
userScripts: [
|
||||
WebEngineScript {
|
||||
injectionPoint: WebEngineScript.DocumentCreation
|
||||
sourceUrl: Qt.resolvedUrl("./helpers/provider.js")
|
||||
worldId: WebEngineScript.MainWorld // TODO: check https://doc.qt.io/qt-5/qml-qtwebengine-webenginescript.html#worldId-prop
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
property QtObject otrProfile: WebEngineProfile {
|
||||
offTheRecord: true
|
||||
persistentCookiesPolicy: WebEngineProfile.NoPersistentCookies
|
||||
httpUserAgent: _internal.defaultProfile.httpUserAgent
|
||||
userScripts: [
|
||||
WebEngineScript {
|
||||
injectionPoint: WebEngineScript.DocumentCreation
|
||||
sourceUrl: Qt.resolvedUrl("./helpers/provider.js")
|
||||
worldId: WebEngineScript.MainWorld // TODO: check https://doc.qt.io/qt-5/qml-qtwebengine-webenginescript.html#worldId-prop
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function addNewDownloadTab() {
|
||||
tabs.createDownloadTab(tabs.count !== 0 ? currentWebView.profile : defaultProfile);
|
||||
tabs.currentIndex = tabs.count - 1;
|
||||
}
|
||||
|
||||
function addNewTab() {
|
||||
var tab = tabs.createEmptyTab(tabs.count !== 0 ? currentWebView.profile : defaultProfile);
|
||||
tabs.currentIndex = tabs.count - 1;
|
||||
browserHeader.addressBar.forceActiveFocus();
|
||||
browserHeader.addressBar.selectAll();
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
function onDownloadRequested(download) {
|
||||
downloadBar.isVisible = true
|
||||
download.accept();
|
||||
DownloadsStore.addDownload(download)
|
||||
}
|
||||
|
||||
function determineRealURL(url) {
|
||||
return Web3ProviderStore.determineRealURL(url)
|
||||
}
|
||||
|
||||
onCurrentWebViewChanged: {
|
||||
findBar.reset();
|
||||
browserHeader.addressBar.text = Web3ProviderStore.obtainAddress(currentWebView.url)
|
||||
}
|
||||
}
|
||||
|
||||
centerPanel: Rectangle {
|
||||
id: browserWindow
|
||||
anchors.fill: parent
|
||||
color: Style.current.inputBackground
|
||||
|
||||
WebProviderObj {
|
||||
id: provider
|
||||
createAccessDialogComponent: function() {
|
||||
return _internal.accessDialogComponent.createObject(root)
|
||||
}
|
||||
createSendTransactionModalComponent: function(request) {
|
||||
return _internal.sendTransactionModalComponent.createObject(root, {
|
||||
preSelectedRecipient: request.payload.params[0].to,
|
||||
preDefinedAmountToSend: LocaleUtils.numberToLocaleString(RootStore.getWei2Eth(request.payload.params[0].value, 18)),
|
||||
})
|
||||
}
|
||||
createSignMessageModalComponent: function(request) {
|
||||
return _internal.signMessageModalComponent.createObject(root, {
|
||||
request,
|
||||
selectedAccount: {
|
||||
name: WalletStore.dappBrowserAccount.name,
|
||||
iconColor: Utils.getColorForId(WalletStore.dappBrowserAccount.colorId)
|
||||
}
|
||||
})
|
||||
}
|
||||
showSendingError: function(message) {
|
||||
_internal.sendingError.text = message
|
||||
return _internal.sendingError.open()
|
||||
}
|
||||
showSigningError: function(message) {
|
||||
_internal.signingError.text = message
|
||||
return _internal.signingError.open()
|
||||
}
|
||||
showToastMessage: function(result, chainId) {
|
||||
let url = "%1/%2".arg(WalletStore.getEtherscanLink(chainId)).arg(result)
|
||||
Global.displayToastMessage(qsTr("Transaction pending..."),
|
||||
qsTr("View on etherscan"),
|
||||
"",
|
||||
true,
|
||||
Constants.ephemeralNotificationType.normal,
|
||||
url);
|
||||
}
|
||||
}
|
||||
|
||||
BrowserShortcutActions {
|
||||
id: keyboardShortcutActions
|
||||
currentWebView: _internal.currentWebView
|
||||
findBarComponent: findBar
|
||||
browserHeaderComponent: browserHeader
|
||||
onAddNewDownloadTab: _internal.addNewDownloadTab()
|
||||
onRemoveView: tabs.removeView(tabs.currentIndex)
|
||||
}
|
||||
|
||||
WebChannel {
|
||||
id: channel
|
||||
registeredObjects: [provider]
|
||||
}
|
||||
|
||||
BrowserHeader {
|
||||
id: browserHeader
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: tabs.tabHeight + tabs.anchors.topMargin
|
||||
z: 52
|
||||
favoriteComponent: favoritesBar
|
||||
currentFavorite: _internal.currentWebView && BookmarksStore.getCurrentFavorite(_internal.currentWebView.url)
|
||||
dappBrowserAccName: WalletStore.dappBrowserAccount.name
|
||||
dappBrowserAccIcon: Utils.getColorForId(WalletStore.dappBrowserAccount.colorId)
|
||||
settingMenu: settingsMenu
|
||||
currentUrl: !!_internal.currentWebView ? _internal.currentWebView.url : ""
|
||||
isLoading: (!!_internal.currentWebView && _internal.currentWebView.loading)
|
||||
canGoBack: (!!_internal.currentWebView && _internal.currentWebView.canGoBack)
|
||||
canGoForward: (!!_internal.currentWebView && _internal.currentWebView.canGoForward)
|
||||
currentTabConnected: RootStore.currentTabConnected
|
||||
onOpenHistoryPopup: historyMenu.popup(xPos, yPos)
|
||||
onGoBack: _internal.currentWebView.goBack()
|
||||
onGoForward: _internal.currentWebView.goForward()
|
||||
onReload: _internal.currentWebView.reload()
|
||||
onStopLoading: _internal.currentWebView.stop()
|
||||
onAddNewFavoritelClicked: {
|
||||
Global.openPopup(addFavoriteModal,
|
||||
{
|
||||
x: xPos - 30,
|
||||
y: browserHeader.y + browserHeader.height + 4,
|
||||
modifiyModal: browserHeader.currentFavorite,
|
||||
toolbarMode: true,
|
||||
ogUrl: browserHeader.currentFavorite ? browserHeader.currentFavorite.url : _internal.currentWebView.url,
|
||||
ogName: browserHeader.currentFavorite ? browserHeader.currentFavorite.name : _internal.currentWebView.title
|
||||
})
|
||||
}
|
||||
onLaunchInBrowser: {
|
||||
// TODO: disable browsing local files? file://
|
||||
if (localAccountSensitiveSettings.useBrowserEthereumExplorer !== Constants.browserEthereumExplorerNone && url.startsWith("0x")) {
|
||||
_internal.currentWebView.url = RootStore.get0xFormedUrl(localAccountSensitiveSettings.useBrowserEthereumExplorer, url)
|
||||
return
|
||||
}
|
||||
if (localAccountSensitiveSettings.shouldShowBrowserSearchEngine !== Constants.browserSearchEngineNone && !Utils.isURL(url) && !Utils.isURLWithOptionalProtocol(url)) {
|
||||
_internal.currentWebView.url = RootStore.getFormedUrl(localAccountSensitiveSettings.shouldShowBrowserSearchEngine, url)
|
||||
return
|
||||
} else if (Utils.isURLWithOptionalProtocol(url)) {
|
||||
url = "https://" + url
|
||||
}
|
||||
_internal.currentWebView.url = _internal.determineRealURL(url);
|
||||
}
|
||||
onOpenWalletMenu: Global.openPopup(browserWalletMenu)
|
||||
}
|
||||
|
||||
BrowserTabView {
|
||||
id: tabs
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
anchors.bottom: devToolsView.top
|
||||
anchors.bottomMargin: browserHeader.height
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
z: 50
|
||||
tabComponent: !!webEngineView ? webEngineView : null
|
||||
currentWebEngineProfile: _internal.currentWebView.profile
|
||||
determineRealURL: function(url) {
|
||||
return _internal.determineRealURL(url)
|
||||
}
|
||||
onOpenNewTabTriggered: _internal.addNewTab()
|
||||
Component.onCompleted: {
|
||||
_internal.defaultProfile.downloadRequested.connect(_internal.onDownloadRequested);
|
||||
_internal.otrProfile.downloadRequested.connect(_internal.onDownloadRequested);
|
||||
var tab = createEmptyTab(_internal.defaultProfile);
|
||||
// For Devs: Uncomment the next lien if you want to use the simpeldapp on first load
|
||||
// tab.item.url = Web3ProviderStore.determineRealURL("https://simpledapp.eth");
|
||||
}
|
||||
}
|
||||
|
||||
ProgressBar {
|
||||
id: progressBar
|
||||
height: 3
|
||||
from: 0
|
||||
to: 100
|
||||
visible: value != 0 && value != 100
|
||||
value: (_internal.currentWebView && _internal.currentWebView.loadProgress < 100) ? _internal.currentWebView.loadProgress : 0
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Style.current.padding
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
}
|
||||
|
||||
WebEngineView {
|
||||
id: devToolsView
|
||||
visible: localAccountSensitiveSettings.devToolsEnabled
|
||||
height: visible ? 400 : 0
|
||||
inspectedView: visible && tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
onNewViewRequested: function(request) {
|
||||
var tab = tabs.createEmptyTab(_internal.currentWebView.profile);
|
||||
tabs.currentIndex = tabs.count - 1;
|
||||
request.openIn(tab.item);
|
||||
}
|
||||
z: 100
|
||||
}
|
||||
|
||||
FavoriteMenu {
|
||||
id: favoriteMenu
|
||||
openInNewTab: function (url) {
|
||||
root.openUrlInNewTab(url)
|
||||
}
|
||||
onEditFavoriteTriggered: {
|
||||
Global.openPopup(addFavoriteModal, {
|
||||
modifiyModal: true,
|
||||
ogUrl: favoriteMenu.currentFavorite ? favoriteMenu.currentFavorite.url : _internal.currentWebView.url,
|
||||
ogName: favoriteMenu.currentFavorite ? favoriteMenu.currentFavorite.name : _internal.currentWebView.title})
|
||||
}
|
||||
}
|
||||
DownloadBar {
|
||||
id: downloadBar
|
||||
anchors.bottom: parent.bottom
|
||||
z: 60
|
||||
downloadsModel: DownloadsStore.downloadModel
|
||||
downloadsMenu: downloadMenu
|
||||
onOpenDownloadClicked: {
|
||||
if (downloadComplete) {
|
||||
return DownloadsStore.openFile(index)
|
||||
}
|
||||
DownloadsStore.openDirectory(index)
|
||||
}
|
||||
onAddNewDownloadTab: _internal.addNewDownloadTab()
|
||||
}
|
||||
|
||||
FindBar {
|
||||
id: findBar
|
||||
visible: false
|
||||
anchors.right: parent.right
|
||||
anchors.top: browserHeader.bottom
|
||||
z: 60
|
||||
|
||||
onFindNext: {
|
||||
if (text)
|
||||
_internal.currentWebView && _internal.currentWebView.findText(text);
|
||||
else if (!visible)
|
||||
visible = true;
|
||||
}
|
||||
onFindPrevious: {
|
||||
if (text)
|
||||
_internal.currentWebView && _internal.currentWebView.findText(text, WebEngineView.FindBackward);
|
||||
else if (!visible)
|
||||
visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: statusBubble
|
||||
color: "oldlace"
|
||||
property int padding: 8
|
||||
visible: false
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.bottom
|
||||
width: statusText.paintedWidth + padding
|
||||
height: statusText.paintedHeight + padding
|
||||
|
||||
Text {
|
||||
id: statusText
|
||||
anchors.centerIn: statusBubble
|
||||
elide: Qt.ElideMiddle
|
||||
|
||||
Timer {
|
||||
id: hideStatusText
|
||||
interval: 750
|
||||
onTriggered: {
|
||||
statusText.text = "";
|
||||
statusBubble.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DownloadMenu {
|
||||
id: downloadMenu
|
||||
}
|
||||
|
||||
BrowserSettingsMenu {
|
||||
id: settingsMenu
|
||||
x: parent.width - width
|
||||
y: browserHeader.y + (localAccountSensitiveSettings.shouldShowFavoritesBar ? browserHeader.height - 38 : browserHeader.height)
|
||||
isIncognito: _internal.currentWebView && _internal.currentWebView.profile === _internal.otrProfile
|
||||
onAddNewTab: _internal.addNewTab()
|
||||
onGoIncognito: {
|
||||
if (_internal.currentWebView) {
|
||||
_internal.currentWebView.profile = checked ? _internal.otrProfile : _internal.defaultProfile;
|
||||
}
|
||||
}
|
||||
onZoomIn: {
|
||||
const newZoom = _internal.currentWebView.zoomFactor + 0.1
|
||||
_internal.currentWebView.changeZoomFactor(newZoom)
|
||||
}
|
||||
onZoomOut: {
|
||||
const newZoom = currentWebView.zoomFactor - 0.1
|
||||
_internal.currentWebView.changeZoomFactor(newZoom)
|
||||
}
|
||||
onChangeZoomFactor: _internal.currentWebView.changeZoomFactor(1.0)
|
||||
onLaunchFindBar: {
|
||||
if (!findBar.visible) {
|
||||
findBar.visible = true;
|
||||
findBar.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
onToggleCompatibilityMode: {
|
||||
for (let i = 0; i < tabs.count; ++i){
|
||||
tabs.getTab(i).item.stop() // Stop all loading tabs
|
||||
}
|
||||
|
||||
localAccountSensitiveSettings.compatibilityMode = checked;
|
||||
|
||||
for (let i = 0; i < tabs.count; ++i){
|
||||
tabs.getTab(i).item.reload() // Reload them with new user agent
|
||||
}
|
||||
}
|
||||
onLaunchBrowserSettings: {
|
||||
Global.changeAppSectionBySectionType(Constants.appSection.profile, Constants.settingsSubsection.browserSettings);
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: browserWalletMenu
|
||||
BrowserWalletMenu {
|
||||
assetsStore: root.assetsStore
|
||||
currencyStore: root.currencyStore
|
||||
tokensStore: root.tokensStore
|
||||
property point headerPoint: Qt.point(browserHeader.x, browserHeader.y)
|
||||
x: (parent.width - width - Style.current.halfPadding)
|
||||
y: (Math.abs(browserHeader.mapFromGlobal(headerPoint).y) +
|
||||
browserHeader.anchors.topMargin + Style.current.halfPadding)
|
||||
onSendTriggered: {
|
||||
sendTransactionModal.preSelectedAccountAddress = selectedAccount.address
|
||||
sendTransactionModal.open()
|
||||
}
|
||||
onReload: {
|
||||
for (let i = 0; i < tabs.count; ++i){
|
||||
tabs.getTab(i).item.reload();
|
||||
}
|
||||
}
|
||||
onDisconnect: {
|
||||
Web3ProviderStore.disconnect(Utils.getHostname(browserHeader.addressBar.text))
|
||||
provider.postMessage("web3-disconnect-account", "{}");
|
||||
_internal.currentWebView.reload()
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: addFavoriteModal
|
||||
AddFavoriteModal {}
|
||||
}
|
||||
|
||||
MessageDialog {
|
||||
id: sslDialog
|
||||
|
||||
property var certErrors: []
|
||||
icon: StandardIcon.Warning
|
||||
standardButtons: StandardButton.No | StandardButton.Yes
|
||||
title: qsTr("Server's certificate not trusted")
|
||||
text: qsTr("Do you wish to continue?")
|
||||
detailedText: qsTr("If you wish so, you may continue with an unverified certificate. Accepting an unverified certificate means you may not be connected with the host you tried to connect to.\nDo you wish to override the security check and continue?")
|
||||
onYes: {
|
||||
certErrors.shift().ignoreCertificateError();
|
||||
presentError();
|
||||
}
|
||||
onNo: reject()
|
||||
onRejected: reject()
|
||||
|
||||
function reject(){
|
||||
certErrors.shift().rejectCertificate();
|
||||
presentError();
|
||||
}
|
||||
function enqueue(error){
|
||||
certErrors.push(error);
|
||||
presentError();
|
||||
}
|
||||
function presentError(){
|
||||
visible = certErrors.length > 0
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: historyMenu
|
||||
Instantiator {
|
||||
model: _internal.currentWebView && _internal.currentWebView.navigationHistory.items
|
||||
MenuItem {
|
||||
text: model.title
|
||||
onTriggered: _internal.currentWebView.goBackOrForward(model.offset)
|
||||
checkable: !enabled
|
||||
checked: !enabled
|
||||
enabled: model.offset
|
||||
}
|
||||
onObjectAdded: function(index, object) {
|
||||
historyMenu.insertItem(index, object)
|
||||
}
|
||||
onObjectRemoved: function(index, object) {
|
||||
historyMenu.removeItem(object)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: favoritesBar
|
||||
FavoritesBar {
|
||||
bookmarkModel: BookmarksStore.bookmarksModel
|
||||
favoritesMenu: favoriteMenu
|
||||
setAsCurrentWebUrl: function(url) {
|
||||
_internal.currentWebView.url = _internal.determineRealURL(url)
|
||||
}
|
||||
addFavModal: function() {
|
||||
Global.openPopup(addFavoriteModal, {toolbarMode: true,
|
||||
ogUrl: browserHeader.currentFavorite ? browserHeader.currentFavorite.url : _internal.currentWebView.url,
|
||||
ogName: browserHeader.currentFavorite ? browserHeader.currentFavorite.name : _internal.currentWebView.title})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: webEngineView
|
||||
BrowserWebEngineView {
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: browserHeader.height
|
||||
currentWebView: _internal.currentWebView
|
||||
webChannel: channel
|
||||
findBarComp: findBar
|
||||
favMenu: favoriteMenu
|
||||
addFavModal: addFavoriteModal
|
||||
downloadsMenu: downloadMenu
|
||||
determineRealURLFn: function(url) {
|
||||
return _internal.determineRealURL(url)
|
||||
}
|
||||
onLinkHovered: function(hoveredUrl) {
|
||||
if (hoveredUrl === "")
|
||||
hideStatusText.start();
|
||||
else {
|
||||
statusText.text = hoveredUrl;
|
||||
statusBubble.visible = true;
|
||||
hideStatusText.stop();
|
||||
}
|
||||
}
|
||||
onSetCurrentWebUrl: {
|
||||
_internal.currentWebView.url = url
|
||||
}
|
||||
onWindowCloseRequested: tabs.removeView(tabs.indexOfView(webEngineView))
|
||||
onNewViewRequested: function(request) {
|
||||
if (!request.userInitiated) {
|
||||
print("Warning: Blocked a popup window.");
|
||||
} else if (request.destination === WebEngineView.NewViewInTab) {
|
||||
var tab = tabs.createEmptyTab(_internal.currentWebView.profile);
|
||||
tabs.currentIndex = tabs.count - 1;
|
||||
request.openIn(tab.item);
|
||||
} else if (request.destination === WebEngineView.NewViewInBackgroundTab) {
|
||||
var backgroundTab = tabs.createEmptyTab(_internal.currentWebView.profile);
|
||||
request.openIn(backgroundTab.item);
|
||||
// Disabling popups temporarily since we need to set that webengineview settings / channel and other properties
|
||||
/*} else if (request.destination === WebEngineView.NewViewInDialog) {
|
||||
var dialog = browserDialogComponent.createObject();
|
||||
dialog.currentWebView.profile = currentWebView.profile;
|
||||
dialog.currentWebView.webChannel = channel;
|
||||
request.openIn(dialog.currentWebView);*/
|
||||
} else {
|
||||
// Instead of opening a new window, we open a new tab
|
||||
// TODO: remove "open in new window" from context menu
|
||||
var tab = tabs.createEmptyTab(_internal.currentWebView.profile);
|
||||
tabs.currentIndex = tabs.count - 1;
|
||||
request.openIn(tab.item);
|
||||
}
|
||||
}
|
||||
onCertificateError: function(error) {
|
||||
error.defer();
|
||||
sslDialog.enqueue(error);
|
||||
}
|
||||
onJavaScriptDialogRequested: function(request) {
|
||||
request.accepted = true;
|
||||
var dialog = _internal.jsDialogComponent.createObject(root, {"request": request});
|
||||
dialog.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: _internal.currentWebView
|
||||
function onUrlChanged() {
|
||||
browserHeader.addressBar.text = Web3ProviderStore.obtainAddress(_internal.currentWebView.url)
|
||||
RootStore.currentTabConnected = Web3ProviderStore.hasWalletConnected(Utils.getHostname(_internal.currentWebView.url))
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: BookmarksStore.bookmarksModel
|
||||
function onModelChanged() {
|
||||
browserHeader.currentFavorite = Qt.binding(function () {return BookmarksStore.getCurrentFavorite(_internal.currentWebView.url)})
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: browserSection
|
||||
function onOpenUrl(url: string) {
|
||||
root.openUrlInNewTab(url);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
|
||||
import StatusQ.Components 0.1 as StatusQ
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import shared 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.status 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
Item {
|
||||
property url webUrl
|
||||
property url source
|
||||
property string text
|
||||
signal clicked(mouse: var)
|
||||
signal rightClicked(mouse: var)
|
||||
|
||||
id: root
|
||||
width: 74
|
||||
height: 48 + Style.current.halfPadding
|
||||
|
||||
SVGImage {
|
||||
id: bookmarkImage
|
||||
width: 48
|
||||
height: 48
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
source: !!root.source && !!root.source.toString() ? root.source : Style.svg("compassActive")
|
||||
visible: root.source && root.source.toString()
|
||||
}
|
||||
|
||||
StatusQ.StatusRoundIcon {
|
||||
id: addButton
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
asset.name: "add"
|
||||
asset.color: Theme.palette.baseColor1
|
||||
color: Theme.palette.baseColor2
|
||||
visible: !webUrl.toString()
|
||||
}
|
||||
|
||||
StatusQ.StatusLetterIdenticon {
|
||||
id: identicon
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
letterIdenticonColor: Theme.palette.baseColor2
|
||||
identiconText.text: text.charAt(0)
|
||||
identiconText.color: Theme.palette.baseColor1
|
||||
visible: !bookmarkImage.visible && !addButton.visible
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: bookmarkName
|
||||
text: root.text
|
||||
width: 67
|
||||
anchors.top: bookmarkImage.bottom
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: Style.current.additionalTextSize
|
||||
wrapMode: Text.WordWrap
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
maximumLineCount: 2
|
||||
elide: Text.ElideRight
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
root.rightClicked(mouse)
|
||||
} else {
|
||||
root.clicked(mouse)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
import QtQuick 2.1
|
||||
import QtQuick.Controls 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared.panels 1.0
|
||||
|
||||
Rectangle {
|
||||
property bool downloadComplete: false
|
||||
property bool isCanceled: false
|
||||
property bool isPaused: false
|
||||
property bool hovered: false
|
||||
// use this to place the newest downloads first
|
||||
property int reversedIndex: listView.count - 1 - index
|
||||
property string primaryText: ""
|
||||
property string downloadText: ""
|
||||
|
||||
signal optionsButtonClicked(var xVal)
|
||||
signal itemClicked()
|
||||
|
||||
id: root
|
||||
width: 272
|
||||
height: 40
|
||||
border.width: 0
|
||||
color: hovered ? Style.current.backgroundHover : Style.current.transparent
|
||||
radius: Style.current.radius
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
root.hovered = true
|
||||
}
|
||||
onExited: {
|
||||
root.hovered = false
|
||||
}
|
||||
onClicked: {
|
||||
itemClicked()
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: iconLoader
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.smallPadding
|
||||
active: root.visible
|
||||
sourceComponent: {
|
||||
if (downloadComplete || isPaused || isCanceled) {
|
||||
return fileImageComponent
|
||||
}
|
||||
return loadingImageComponent
|
||||
}
|
||||
|
||||
Component {
|
||||
id: loadingImageComponent
|
||||
StatusLoadingIndicator {}
|
||||
}
|
||||
Component {
|
||||
id: fileImageComponent
|
||||
SVGImage {
|
||||
source: Style.svg("browser/file")
|
||||
width: 24
|
||||
height: 24
|
||||
ColorOverlay {
|
||||
anchors.fill: parent
|
||||
source: parent
|
||||
color: downloadComplete ? Style.current.transparent : Style.current.darkGrey
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: filenameText
|
||||
text: primaryText
|
||||
elide: Text.ElideRight
|
||||
anchors.left: iconLoader.right
|
||||
anchors.right: optionsBtn.left
|
||||
anchors.top: downloadComplete ? undefined : parent.top
|
||||
anchors.verticalCenter: downloadComplete ? parent.verticalCenter : undefined
|
||||
minimumPixelSize: 13
|
||||
anchors.leftMargin: Style.current.smallPadding
|
||||
anchors.topMargin: 2
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: progressText
|
||||
visible: !downloadComplete
|
||||
color: Style.current.secondaryText
|
||||
text: downloadText
|
||||
elide: Text.ElideRight
|
||||
anchors.left: iconLoader.right
|
||||
anchors.right: optionsBtn.left
|
||||
anchors.bottom: parent.bottom
|
||||
minimumPixelSize: 13
|
||||
anchors.leftMargin: Style.current.smallPadding
|
||||
anchors.bottomMargin: 2
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
width: 32
|
||||
height: 32
|
||||
id: optionsBtn
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
icon.name: "more"
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
onClicked: optionsButtonClicked(optionsBtn.x)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
|
||||
import shared 1.0
|
||||
import utils 1.0
|
||||
|
||||
Image {
|
||||
id: faviconImage
|
||||
|
||||
property var currentTab
|
||||
|
||||
width: 24
|
||||
height: 24
|
||||
sourceSize: Qt.size(width, height)
|
||||
// TODO find a better default favicon
|
||||
source: faviconImage.currentTab && !!faviconImage.currentTab.icon.toString() ? faviconImage.currentTab.icon : Style.svg("compassActive")
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls.Styles 1.0
|
||||
|
||||
import shared 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.status 1.0
|
||||
import "../"
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
TabViewStyle {
|
||||
id: tabViewStyle
|
||||
|
||||
property color fillColor: Style.current.background
|
||||
property color nonSelectedColor: Qt.darker(Style.current.background, 1.2)
|
||||
|
||||
frameOverlap: 1
|
||||
tabsMovable: true
|
||||
|
||||
frame: Rectangle {
|
||||
color: Style.current.transparent
|
||||
border.width: 0
|
||||
}
|
||||
|
||||
tab: Item {
|
||||
implicitWidth: tabRectangle.implicitWidth + 5 + (newTabloader.active ? newTabloader.width + Style.current.halfPadding : 0)
|
||||
implicitHeight: tabRectangle.implicitHeight
|
||||
Rectangle {
|
||||
id: tabRectangle
|
||||
color: styleData.selected ? fillColor : nonSelectedColor
|
||||
border.width: 0
|
||||
implicitWidth: 240
|
||||
implicitHeight: control.tabHeight
|
||||
radius: Style.current.radius
|
||||
|
||||
// This rectangle is to hide the bottom radius
|
||||
Rectangle {
|
||||
width: parent.implicitWidth
|
||||
height: 5
|
||||
color: parent.color
|
||||
border.width: 0
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
|
||||
FaviconImage {
|
||||
id: faviconImage
|
||||
currentTab: control.getTab(styleData.index) && control.getTab(styleData.index).item
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.halfPadding
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: text
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: faviconImage.right
|
||||
anchors.leftMargin: Style.current.halfPadding
|
||||
anchors.right: closeTabBtn.left
|
||||
anchors.rightMargin: Style.current.halfPadding
|
||||
text: styleData.title
|
||||
// TODO the elide probably doesn't work. Set a Max width
|
||||
elide: Text.ElideRight
|
||||
color: Style.current.textColor
|
||||
}
|
||||
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: closeTabBtn
|
||||
width: 16
|
||||
height: 16
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.halfPadding
|
||||
icon.name: "close"
|
||||
type: StatusFlatRoundButton.Type.Quaternary
|
||||
visible: control.count > 1 || styleData.title !== qsTr("Start Page")
|
||||
enabled: visible
|
||||
onClicked: control.closeButtonClicked(styleData.index)
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: newTabloader
|
||||
active: styleData.index === control.count - 1
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
|
||||
sourceComponent: Component {
|
||||
StatusFlatRoundButton {
|
||||
id: addButton
|
||||
width: 16
|
||||
height: 16
|
||||
icon.name: "close"
|
||||
icon.rotation: 45
|
||||
color: "transparent"
|
||||
type: StatusFlatRoundButton.Type.Quaternary
|
||||
onClicked: control.openNewTabClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,218 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
import Qt.labs.settings 1.0
|
||||
import QtQuick.Controls.Styles 1.0
|
||||
import QtWebEngine 1.10
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import shared.controls 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../popups"
|
||||
import "../controls"
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property alias favoriteComponent: favoritesBarLoader.sourceComponent
|
||||
property alias addressBar: addressBar
|
||||
|
||||
property var currentUrl
|
||||
property bool isLoading: false
|
||||
property bool canGoBack: false
|
||||
property bool canGoForward: false
|
||||
property var currentFavorite
|
||||
property bool currentTabConnected: false
|
||||
property string dappBrowserAccName: ""
|
||||
property string dappBrowserAccIcon: ""
|
||||
property var settingMenu
|
||||
|
||||
signal addNewFavoritelClicked(var xPos)
|
||||
signal launchInBrowser(var url)
|
||||
signal openHistoryPopup(var xPos, var yPos)
|
||||
signal goForward()
|
||||
signal goBack()
|
||||
signal reload()
|
||||
signal stopLoading()
|
||||
signal openWalletMenu()
|
||||
|
||||
QtObject {
|
||||
id: _internal
|
||||
readonly property int innerMargin: 12
|
||||
}
|
||||
|
||||
width: parent.width
|
||||
height: barRow.height + (favoritesBarLoader.active ? favoritesBarLoader.height : 0)
|
||||
color: Style.current.background
|
||||
border.width: 0
|
||||
|
||||
RowLayout {
|
||||
id: barRow
|
||||
width: parent.width
|
||||
height: 45
|
||||
spacing: _internal.innerMargin
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: backButton
|
||||
Layout.preferredWidth: 32
|
||||
Layout.preferredHeight: 32
|
||||
icon.height: 20
|
||||
icon.width: 20
|
||||
icon.name: "arrow-left"
|
||||
icon.disabledColor: Style.current.lightGrey
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
enabled: canGoBack
|
||||
Layout.leftMargin: _internal.innerMargin
|
||||
onClicked: goBack()
|
||||
onPressAndHold: {
|
||||
if (canGoBack || canGoForward) {
|
||||
openHistoryPopup(backButton.x, backButton.y + backButton.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: forwardButton
|
||||
Layout.preferredWidth: 32
|
||||
Layout.preferredHeight: 32
|
||||
icon.width: 20
|
||||
icon.height: 20
|
||||
icon.name: "arrow-right"
|
||||
icon.disabledColor: Style.current.lightGrey
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
enabled: canGoForward
|
||||
Layout.leftMargin: -_internal.innerMargin/2
|
||||
onClicked: goForward()
|
||||
onPressAndHold: {
|
||||
if (canGoBack || canGoForward) {
|
||||
openHistoryPopup(backButton.x, backButton.y + backButton.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledTextField {
|
||||
id: addressBar
|
||||
Layout.preferredHeight: 40
|
||||
Layout.fillWidth: true
|
||||
background: Rectangle {
|
||||
color: Style.current.inputBackground
|
||||
border.color: Style.current.inputBorderFocus
|
||||
border.width: activeFocus ? 1 : 0
|
||||
radius: 20
|
||||
}
|
||||
leftPadding: Style.current.padding
|
||||
rightPadding: addFavoriteBtn.width + reloadBtn.width + Style.current.bigPadding
|
||||
placeholderText: qsTr("Enter URL")
|
||||
focus: true
|
||||
text: ""
|
||||
color: Style.current.textColor
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
addressBar.selectAll()
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|
||||
launchInBrowser(text)
|
||||
}
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: addFavoriteBtn
|
||||
width: 24
|
||||
height: 24
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: reloadBtn.left
|
||||
anchors.rightMargin: Style.current.halfPadding
|
||||
visible: !!currentUrl
|
||||
icon.source: !!root.currentFavorite ? Style.svg("browser/favoriteActive") : Style.svg("browser/favorite")
|
||||
color: "transparent"
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
onClicked: addNewFavoritelClicked(addFavoriteBtn.x)
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: reloadBtn
|
||||
width: 24
|
||||
height: 24
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.halfPadding
|
||||
icon.name: isLoading ? "close-circle" : "refresh"
|
||||
color: "transparent"
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
onClicked: isLoading ? stopLoading(): reload()
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
Layout.preferredWidth: 44
|
||||
Layout.preferredHeight: 44
|
||||
active: true
|
||||
sourceComponent: currentTabConnected ? connectedBtnComponent : notConnectedBtnCompoent
|
||||
}
|
||||
|
||||
Component {
|
||||
id: notConnectedBtnCompoent
|
||||
StatusFlatRoundButton {
|
||||
id: accountBtn
|
||||
width: 24
|
||||
height: 24
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.name: "filled-account"
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
onPressed: {
|
||||
root.openWalletMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: connectedBtnComponent
|
||||
StatusFlatButton {
|
||||
id: accountBtnConnected
|
||||
icon.name: "wallet"
|
||||
icon.width: 18
|
||||
icon.height: 18
|
||||
icon.color: dappBrowserAccIcon
|
||||
text: dappBrowserAccName
|
||||
onPressed: {
|
||||
root.openWalletMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: settingsMenuButton
|
||||
Layout.preferredHeight: 32
|
||||
Layout.preferredWidth: 32
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.name: "more"
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
Layout.rightMargin: _internal.innerMargin
|
||||
onClicked: {
|
||||
if (settingMenu.opened) {
|
||||
settingMenu.close()
|
||||
} else {
|
||||
settingMenu.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: favoritesBarLoader
|
||||
active: localAccountSensitiveSettings.shouldShowFavoritesBar
|
||||
anchors.top: barRow.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.smallPadding
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 1.0 as QQC1
|
||||
|
||||
import utils 1.0
|
||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||
|
||||
import "../controls/styles"
|
||||
|
||||
QQC1.TabView {
|
||||
id: tabs
|
||||
|
||||
property var currentWebEngineProfile
|
||||
property var tabComponent
|
||||
property var determineRealURL: function(url) {}
|
||||
readonly property int tabHeight: 40
|
||||
|
||||
signal openNewTabTriggered()
|
||||
|
||||
function createEmptyTab(profile, createAsStartPage) {
|
||||
var tab = addTab("", tabComponent);
|
||||
// We must do this first to make sure that tab.active gets set so that tab.item gets instantiated immediately.
|
||||
tab.active = true;
|
||||
createAsStartPage = createAsStartPage || tabs.count === 1
|
||||
tab.title = Qt.binding(function() {
|
||||
var tabTitle = ""
|
||||
if (tab.item.title) {
|
||||
tabTitle = tab.item.title
|
||||
}
|
||||
else if (createAsStartPage) {
|
||||
tabTitle = qsTr("Start Page")
|
||||
}
|
||||
else {
|
||||
tabTitle = qsTr("New Tab")
|
||||
}
|
||||
|
||||
return SQUtils.StringUtils.escapeHtml(tabTitle);
|
||||
})
|
||||
|
||||
if (createAsStartPage) {
|
||||
tab.item.url = "https://dap.ps"
|
||||
}
|
||||
|
||||
tab.item.profile = profile;
|
||||
if (localAccountSensitiveSettings.browserHomepage !== "") {
|
||||
tab.item.url = determineRealURL(localAccountSensitiveSettings.browserHomepage)
|
||||
}
|
||||
return tab;
|
||||
}
|
||||
|
||||
function createDownloadTab(profile) {
|
||||
var tab = addTab("", tabComponent);
|
||||
tab.active = true;
|
||||
tab.title = qsTr("Downloads Page")
|
||||
tab.item.profile = profile
|
||||
tab.item.url = "status://downloads";
|
||||
}
|
||||
|
||||
function indexOfView(view) {
|
||||
for (let i = 0; i < tabs.count; ++i)
|
||||
if (tabs.getTab(i).item === view)
|
||||
return i
|
||||
return -1
|
||||
}
|
||||
|
||||
function openNewTabClicked() {
|
||||
openNewTabTriggered()
|
||||
}
|
||||
|
||||
function removeView(index) {
|
||||
if (tabs.count === 1) {
|
||||
tabs.createEmptyTab(currentWebEngineProfile, true)
|
||||
}
|
||||
tabs.removeTab(index)
|
||||
}
|
||||
|
||||
function closeButtonClicked(index) {
|
||||
removeView(index)
|
||||
}
|
||||
|
||||
style: BrowserTabStyle {}
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
import QtQuick 2.1
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../controls"
|
||||
|
||||
Rectangle {
|
||||
|
||||
id: downloadBar
|
||||
|
||||
property bool isVisible: false
|
||||
property var downloadsModel
|
||||
property var downloadsMenu
|
||||
|
||||
signal openDownloadClicked(bool downloadComplete, int index)
|
||||
signal addNewDownloadTab()
|
||||
|
||||
visible: isVisible && !!listView.count
|
||||
color: Style.current.background
|
||||
width: parent.width
|
||||
height: 56
|
||||
border.width: 1
|
||||
border.color: Style.current.border
|
||||
|
||||
// This container is to contain the downloaded elements between the parent buttons and hide the overflow
|
||||
Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.smallPadding
|
||||
anchors.right: showAllBtn.left
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
height: listView.height
|
||||
clip: true
|
||||
|
||||
StatusListView {
|
||||
id: listView
|
||||
orientation: ListView.Horizontal
|
||||
model: downloadsModel
|
||||
height: currentItem ? currentItem.height : 0
|
||||
// This makes it show the newest on the right
|
||||
layoutDirection: Qt.RightToLeft
|
||||
spacing: Style.current.smallPadding
|
||||
anchors.left: parent.left
|
||||
width: {
|
||||
// Children rect shows a warning but this works ¯\_(ツ)_/¯
|
||||
let w = 0
|
||||
for (let i = 0; i < count; i++) {
|
||||
w += this.itemAtIndex(i).width + this.spacing
|
||||
}
|
||||
return w
|
||||
}
|
||||
interactive: false
|
||||
delegate: DownloadElement {
|
||||
id: downloadElement
|
||||
isPaused: downloadsModel.downloads[index] && downloadsModel.downloads[index].isPaused
|
||||
primaryText: downloadFileName
|
||||
downloadText: {
|
||||
if (isCanceled) {
|
||||
return qsTr("Cancelled")
|
||||
}
|
||||
if (isPaused) {
|
||||
return qsTr("Paused")
|
||||
}
|
||||
return `${downloadsModel.downloads[index] ? (downloadsModel.downloads[index].receivedBytes / 1000000).toFixed(2) : 0}/${downloadsModel.downloads[index] ? (downloadsModel.downloads[index].totalBytes / 1000000).toFixed(2) : 0} MB` //"14.4/109 MB, 26 sec left"
|
||||
}
|
||||
downloadComplete: {
|
||||
// listView.count ensures a value is returned even when index is undefined
|
||||
return listView.count > 0 && !!downloadsModel.downloads && !!downloadsModel.downloads[index] &&
|
||||
downloadsModel.downloads[index].receivedBytes >= downloadsModel.downloads[index].totalBytes
|
||||
}
|
||||
onItemClicked: {
|
||||
openDownloadClicked(downloadComplete, index)
|
||||
}
|
||||
onOptionsButtonClicked: {
|
||||
downloadsMenu.index = index
|
||||
downloadsMenu.downloadComplete = Qt.binding(function() {return downloadElement.downloadComplete})
|
||||
downloadsMenu.parent = downloadElement
|
||||
downloadsMenu.x = xVal + 20
|
||||
downloadsMenu.y = -downloadsMenu.height
|
||||
downloadsMenu.open()
|
||||
}
|
||||
Connections {
|
||||
target: downloadsMenu
|
||||
function onCancelClicked() {
|
||||
isCanceled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
id: showAllBtn
|
||||
size: StatusBaseButton.Size.Small
|
||||
text: qsTr("Show All")
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: closeBtn.left
|
||||
anchors.rightMargin: Style.current.padding
|
||||
onClicked: {
|
||||
addNewDownloadTab()
|
||||
}
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: closeBtn
|
||||
width: 32
|
||||
height: 32
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
icon.name: "close"
|
||||
type: StatusFlatRoundButton.Type.Quaternary
|
||||
onClicked: downloadBar.isVisible = false
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
import QtQuick 2.1
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../controls"
|
||||
|
||||
Rectangle {
|
||||
id: downloadView
|
||||
|
||||
property alias downloadsModel: listView.model
|
||||
|
||||
property var downloadsMenu
|
||||
|
||||
signal openDownloadClicked(bool downloadComplete, int index)
|
||||
|
||||
color: Style.current.background
|
||||
|
||||
StatusListView {
|
||||
id: listView
|
||||
anchors {
|
||||
topMargin: Style.current.bigPadding
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
bottomMargin: Style.current.bigPadding * 2
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
width: 624
|
||||
spacing: Style.current.padding
|
||||
|
||||
delegate: DownloadElement {
|
||||
id: downloadElement
|
||||
width: parent.width
|
||||
isPaused: downloadsModel.downloads[index] && downloadsModel.downloads[index].isPaused
|
||||
primaryText: downloadFileName
|
||||
downloadText: {
|
||||
if (isCanceled) {
|
||||
return qsTr("Cancelled")
|
||||
}
|
||||
if (isPaused) {
|
||||
return qsTr("Paused")
|
||||
}
|
||||
return `${downloadsModel.downloads[index] ? (downloadsModel.downloads[index].receivedBytes / 1000000).toFixed(2) : 0}/${downloadsModel.downloads[index] ? (downloadsModel.downloads[index].totalBytes / 1000000).toFixed(2) : 0} MB` //"14.4/109 MB, 26 sec left"
|
||||
}
|
||||
downloadComplete: {
|
||||
// listView.count ensures a value is returned even when index is undefined
|
||||
return listView.count > 0 && !!downloadsModel.downloads && !!downloadsModel.downloads[index] &&
|
||||
downloadsModel.downloads[index].receivedBytes >= downloadsModel.downloads[index].totalBytes
|
||||
}
|
||||
onItemClicked: {
|
||||
openDownloadClicked(downloadComplete, index)
|
||||
}
|
||||
onOptionsButtonClicked: {
|
||||
downloadsMenu.index = index
|
||||
downloadsMenu.downloadComplete = Qt.binding(function() {return downloadElement.downloadComplete})
|
||||
downloadsMenu.parent = downloadElement
|
||||
downloadsMenu.x = xVal
|
||||
downloadsMenu.y = downloadView.y - downloadsMenu.height
|
||||
downloadsMenu.open()
|
||||
}
|
||||
Connections {
|
||||
target: downloadsMenu
|
||||
function onCancelClicked() {
|
||||
isCanceled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
visible: !listView.count
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 15
|
||||
text: qsTr("Downloaded files will appear here.")
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
RowLayout {
|
||||
id: favoritesBar
|
||||
|
||||
property alias bookmarkModel: bookmarkList.model
|
||||
|
||||
property var favoritesMenu
|
||||
property var setAsCurrentWebUrl: function(url){}
|
||||
property var addFavModal: function(){}
|
||||
|
||||
spacing: 0
|
||||
height: 38
|
||||
|
||||
StatusListView {
|
||||
id: bookmarkList
|
||||
spacing: Style.current.halfPadding
|
||||
orientation : ListView.Horizontal
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
delegate: StatusFlatButton {
|
||||
id: favoriteBtn
|
||||
height: 32
|
||||
icon.source: imageUrl
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
// Limit long named tabs. StatusFlatButton is not well-behaved control
|
||||
// implicitWidth doesn't work. Also avoid breaking visualization by escaping HTML
|
||||
text: SQUtils.StringUtils.escapeHtml(Utils.elideIfTooLong(name, 40))
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
z: 51
|
||||
onClicked: function (mouse) {
|
||||
const isAddBookmarkButton = url === Constants.newBookmark
|
||||
if (mouse.button === Qt.RightButton && isAddBookmarkButton) {
|
||||
return
|
||||
}
|
||||
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
favoritesMenu.url = url
|
||||
favoritesMenu.x = favoriteBtn.x + mouse.x
|
||||
favoritesMenu.y = Qt.binding(function () {return mouse.y + favoritesMenu.height})
|
||||
favoritesMenu.open()
|
||||
return
|
||||
}
|
||||
|
||||
if (isAddBookmarkButton) {
|
||||
addFavModal()
|
||||
return
|
||||
}
|
||||
|
||||
setAsCurrentWebUrl(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../controls"
|
||||
|
||||
StatusGridView {
|
||||
id: bookmarkGrid
|
||||
|
||||
property var determineRealURLFn: function(url){}
|
||||
property var setAsCurrentWebUrl: function(url){}
|
||||
property var favMenu
|
||||
property var addFavModal
|
||||
|
||||
cellWidth: 100
|
||||
cellHeight: 100
|
||||
|
||||
delegate: BookmarkButton {
|
||||
id: bookmarkBtn
|
||||
text: name
|
||||
source: imageUrl
|
||||
webUrl: determineRealURLFn(url)
|
||||
onClicked: {
|
||||
if (!webUrl.toString()) {
|
||||
Global.openPopup(addFavModal)
|
||||
} else {
|
||||
setAsCurrentWebUrl(webUrl)
|
||||
}
|
||||
}
|
||||
onRightClicked: {
|
||||
favMenu.url = url
|
||||
favMenu.x = bookmarkGrid.x + bookmarkBtn.x + mouse.x
|
||||
favMenu.y = Qt.binding(function () {return bookmarkGrid.y + mouse.y + favMenu.height})
|
||||
favMenu.open()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtWebEngine module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import shared.controls 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property int numberOfMatches: 0
|
||||
property int activeMatch: 0
|
||||
property alias text: findTextField.text
|
||||
|
||||
function reset() {
|
||||
numberOfMatches = 0;
|
||||
activeMatch = 0;
|
||||
visible = false;
|
||||
}
|
||||
|
||||
signal findNext()
|
||||
signal findPrevious()
|
||||
|
||||
width: 300
|
||||
height: 40
|
||||
radius: Style.current.radius
|
||||
|
||||
border.width: 0
|
||||
color: Style.current.background
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow{
|
||||
width: root.width
|
||||
height: root.height
|
||||
x: root.x
|
||||
y: root.y + 10
|
||||
visible: root.visible
|
||||
source: root
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 2
|
||||
radius: 10
|
||||
samples: 15
|
||||
color: "#22000000"
|
||||
}
|
||||
|
||||
function forceActiveFocus() {
|
||||
findTextField.forceActiveFocus();
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible)
|
||||
forceActiveFocus()
|
||||
}
|
||||
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 5
|
||||
anchors.bottomMargin: 5
|
||||
anchors.leftMargin: 10
|
||||
anchors.rightMargin: 10
|
||||
|
||||
spacing: 5
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
StyledTextField {
|
||||
id: findTextField
|
||||
anchors.fill: parent
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
border.width: 0
|
||||
}
|
||||
|
||||
onAccepted: root.findNext()
|
||||
onTextChanged: root.findNext()
|
||||
onActiveFocusChanged: activeFocus ? selectAll() : deselect()
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: activeMatch + "/" + numberOfMatches
|
||||
visible: findTextField.text !== ""
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
border.color: Style.current.border
|
||||
width: 2
|
||||
height: parent.height
|
||||
anchors.topMargin: 5
|
||||
anchors.bottomMargin: 5
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: prevBtn
|
||||
implicitWidth: 32
|
||||
implicitHeight: 32
|
||||
icon.name: "previous"
|
||||
enabled: numberOfMatches > 0
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
onClicked: root.findPrevious()
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: nextBtn
|
||||
implicitWidth: 32
|
||||
implicitHeight: 32
|
||||
icon.name: "next"
|
||||
enabled: numberOfMatches > 0
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
onClicked: root.findNext()
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: closeBtn
|
||||
implicitWidth: 32
|
||||
implicitHeight: 32
|
||||
icon.name: "close-circle"
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
onClicked: root.visible = false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
|
||||
import shared.popups 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
property string ogUrl: ""
|
||||
property string ogName: ""
|
||||
property bool modifiyModal: false
|
||||
property bool toolbarMode: false
|
||||
|
||||
id: popup
|
||||
width: toolbarMode ? 345 : 480
|
||||
height: toolbarMode ? 400 : 480
|
||||
|
||||
modal: !toolbarMode
|
||||
|
||||
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: Style.current.dropShadow
|
||||
}
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
urlInput.input.text = ogUrl
|
||||
nameInput.input.text = ogName
|
||||
urlInput.input.forceActiveFocus(Qt.MouseFocusReason)
|
||||
}
|
||||
|
||||
onClosed: {
|
||||
reset()
|
||||
}
|
||||
|
||||
function reset() {
|
||||
modifiyModal = false
|
||||
toolbarMode = false
|
||||
urlInput.reset()
|
||||
nameInput.reset()
|
||||
ogUrl = ""
|
||||
ogName = ""
|
||||
x = Math.round(((parent ? parent.width : 0) - width) / 2)
|
||||
y = Math.round(((parent ? parent.height : 0) - height) / 2)
|
||||
}
|
||||
|
||||
title: modifiyModal ?
|
||||
toolbarMode ?
|
||||
qsTr("Favorite added") :
|
||||
qsTr("Edit")
|
||||
: qsTr("Add favorite")
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Style.current.padding
|
||||
|
||||
StatusInput {
|
||||
id: urlInput
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
label: qsTr("URL")
|
||||
input.text: ogUrl
|
||||
placeholderText: qsTr("Paste URL")
|
||||
input.rightComponent: StatusButton {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
borderColor: Theme.palette.primaryColor1
|
||||
size: StatusBaseButton.Size.Tiny
|
||||
text: qsTr("Paste")
|
||||
onClicked: {
|
||||
text = qsTr("Pasted")
|
||||
urlInput.input.edit.paste()
|
||||
}
|
||||
}
|
||||
validators: [
|
||||
StatusUrlValidator {
|
||||
errorMessage: qsTr("Please enter a valid URL")
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: nameInput
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
label: qsTr("Name")
|
||||
input.text: ogName
|
||||
placeholderText: qsTr("Name of the website")
|
||||
validators: [
|
||||
StatusMinLengthValidator {
|
||||
errorMessage: qsTr("Please enter a name")
|
||||
minLength: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
footer: Item {
|
||||
width: parent.width
|
||||
height: removeBtn.height
|
||||
|
||||
StatusButton {
|
||||
id: removeBtn
|
||||
anchors.right: addBtn.left
|
||||
anchors.rightMargin: Style.current.padding
|
||||
visible: popup.modifiyModal
|
||||
text: qsTr("Remove")
|
||||
anchors.bottom: parent.bottom
|
||||
type: StatusBaseButton.Type.Danger
|
||||
onClicked: {
|
||||
BookmarksStore.deleteBookmark(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
|
||||
enabled: nameInput.valid && !!nameInput.text && urlInput.valid && !!urlInput.text
|
||||
onClicked: {
|
||||
if (!popup.modifiyModal) {
|
||||
// remove "add favorite" button at the end, add new bookmark, add "add favorite" button back
|
||||
BookmarksStore.deleteBookmark(Constants.newBookmark)
|
||||
BookmarksStore.addBookmark(urlInput.input.text, nameInput.input.text)
|
||||
BookmarksStore.addBookmark(Constants.newBookmark, qsTr("Add Favorite"))
|
||||
} else if (popup.ogName !== nameInput.input.text || popup.ogUrl !== urlInput.input.text) {
|
||||
BookmarksStore.updateBookmark(popup.ogUrl, urlInput.input.text, nameInput.input.text)
|
||||
}
|
||||
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,183 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
|
||||
import utils 1.0
|
||||
import shared.panels 1.0
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import "../controls"
|
||||
import "../stores"
|
||||
|
||||
StatusModal {
|
||||
id: browserConnectionModal
|
||||
|
||||
property var currentTab
|
||||
property var request: ({"hostname": "", "address": "", "title": "", "permission": ""})
|
||||
property string currentAddress: ""
|
||||
property bool interactedWith: false
|
||||
property var web3Response: function(){}
|
||||
|
||||
width: 360
|
||||
height: 480
|
||||
showHeader: false
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
|
||||
function postMessage(isAllowed){
|
||||
console.log(isAllowed)
|
||||
interactedWith = true
|
||||
RootStore.currentTabConnected = isAllowed
|
||||
if(isAllowed){
|
||||
Web3ProviderStore.addPermission(request.hostname, request.address, request.permission)
|
||||
}
|
||||
Web3ProviderStore.web3ProviderInst.postMessage("", Constants.api_request, JSON.stringify(request))
|
||||
}
|
||||
|
||||
onClosed: {
|
||||
if(!interactedWith){
|
||||
RootStore.currentTabConnected = false
|
||||
postMessage(false);
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.current.bigPadding
|
||||
anchors.centerIn: parent
|
||||
|
||||
RowLayout {
|
||||
property int imgSize: 40
|
||||
|
||||
id: logoHeader
|
||||
spacing: Style.current.halfPadding
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
|
||||
FaviconImage {
|
||||
id: siteImg
|
||||
}
|
||||
|
||||
SVGImage {
|
||||
id: dots1
|
||||
source: Style.svg("dots-icon")
|
||||
}
|
||||
|
||||
RoundedIcon {
|
||||
source: Style.svg("check")
|
||||
iconColor: Style.current.primary
|
||||
color: Style.current.secondaryBackground
|
||||
}
|
||||
|
||||
SVGImage {
|
||||
id: dots2
|
||||
source: Style.svg("dots-icon")
|
||||
}
|
||||
|
||||
RoundedIcon {
|
||||
source: Style.svg("walletIcon")
|
||||
iconHeight: 18
|
||||
iconWidth: 18
|
||||
iconColor: accountSelector.selectedAccount.iconColor || Style.current.primary
|
||||
color: Style.current.background
|
||||
border.width: 1
|
||||
border.color: Style.current.border
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: titleText
|
||||
text: qsTr("'%1' would like to connect to").arg(request.title)
|
||||
wrapMode: Text.WordWrap
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 17
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
Layout.maximumWidth: browserConnectionModal.width - Style.current.padding
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
|
||||
StatusAccountSelector {
|
||||
id: accountSelector
|
||||
label: ""
|
||||
implicitWidth: 300
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
showAccountDetails: false
|
||||
accounts: WalletStore.accounts
|
||||
selectedAccount: WalletStore.dappBrowserAccount
|
||||
currency: WalletStore.defaultCurrency
|
||||
onSelectedAccountChanged: {
|
||||
if (!browserConnectionModal.currentAddress) {
|
||||
// We just set the account for the first time. Nothing to do here
|
||||
browserConnectionModal.currentAddress = selectedAccount.address
|
||||
return
|
||||
}
|
||||
if (browserConnectionModal.currentAddress === selectedAccount.address) {
|
||||
return
|
||||
}
|
||||
|
||||
browserConnectionModal.currentAddress = selectedAccount.address
|
||||
Web3ProviderStore.web3ProviderInst.dappsAddress = selectedAccount.address;
|
||||
|
||||
if (selectedAccount.address) {
|
||||
Web3ProviderStore.web3ProviderInst.dappsAddress = selectedAccount.address;
|
||||
WalletStore.switchAccountByAddress(selectedAccount.address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: infoText
|
||||
text: {
|
||||
switch(request.permission){
|
||||
case Constants.permission_web3: return qsTr("Allowing authorizes this DApp to retrieve your wallet address and enable Web3");
|
||||
case Constants.permission_contactCode: return qsTr("Granting access authorizes this DApp to retrieve your chat key");
|
||||
default: return qsTr("Unknown permission: " + request.permission);
|
||||
}
|
||||
}
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: 15
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: Theme.palette.baseColor1
|
||||
Layout.maximumWidth: browserConnectionModal.width - Style.current.padding
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: Style.current.padding
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
|
||||
StatusButton {
|
||||
type: StatusBaseButton.Type.Danger
|
||||
width: 151
|
||||
text: qsTr("Deny")
|
||||
onClicked: {
|
||||
postMessage(false);
|
||||
browserConnectionModal.close();
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
normalColor: Utils.setColorAlpha(Style.current.success, 0.1)
|
||||
textColor: Style.current.success
|
||||
width: 151
|
||||
text: qsTr("Allow")
|
||||
onClicked: {
|
||||
postMessage(true);
|
||||
browserConnectionModal.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.3
|
||||
import QtWebEngine 1.9
|
||||
|
||||
import shared 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.status 1.0
|
||||
import shared.popups 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
// TODO: replace with StatusMenu
|
||||
PopupMenu {
|
||||
id: browserSettingsMenu
|
||||
|
||||
property bool isIncognito: false
|
||||
|
||||
signal addNewTab()
|
||||
signal goIncognito(bool checked)
|
||||
signal zoomIn()
|
||||
signal zoomOut()
|
||||
signal changeZoomFactor()
|
||||
signal launchFindBar()
|
||||
signal toggleCompatibilityMode(bool checked)
|
||||
signal launchBrowserSettings()
|
||||
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||
|
||||
Action {
|
||||
text: qsTr("New Tab")
|
||||
shortcut: StandardKey.AddTab
|
||||
onTriggered: addNewTab()
|
||||
}
|
||||
|
||||
Action {
|
||||
id: offTheRecordEnabled
|
||||
// TODO show an indicator on the browser or tab?
|
||||
text: checked ?
|
||||
qsTr("Exit Incognito mode") :
|
||||
qsTr("Go Incognito")
|
||||
checkable: true
|
||||
checked: isIncognito
|
||||
onToggled: goIncognito(checked)
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
// TODO find a way to put both in one button
|
||||
Action {
|
||||
text: qsTr("Zoom In")
|
||||
shortcut: StandardKey.ZoomIn
|
||||
onTriggered: zoomIn()
|
||||
}
|
||||
|
||||
Action {
|
||||
text: qsTr("Zoom Out")
|
||||
shortcut: StandardKey.ZoomOut
|
||||
onTriggered: zoomOut()
|
||||
}
|
||||
|
||||
Action {
|
||||
shortcut: "Ctrl+0"
|
||||
onTriggered: changeZoomFactor()
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
Action {
|
||||
text: qsTr("Find")
|
||||
shortcut: StandardKey.Find
|
||||
onTriggered: launchFindBar()
|
||||
}
|
||||
|
||||
Action {
|
||||
text: qsTr("Compatibility mode")
|
||||
checkable: true
|
||||
checked: true
|
||||
onToggled: toggleCompatibilityMode(checked)
|
||||
}
|
||||
|
||||
Action {
|
||||
text: qsTr("Developer Tools")
|
||||
shortcut: "F12"
|
||||
onTriggered: {
|
||||
localAccountSensitiveSettings.devToolsEnabled = !localAccountSensitiveSettings.devToolsEnabled
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
Action {
|
||||
text: qsTr("Settings")
|
||||
shortcut: "Ctrl+,"
|
||||
onTriggered: launchBrowserSettings()
|
||||
}
|
||||
}
|
|
@ -1,226 +0,0 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
import shared.controls 1.0
|
||||
import shared.views 1.0
|
||||
import utils 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusMenu
|
||||
Dialog {
|
||||
id: popup
|
||||
|
||||
required property var assetsStore
|
||||
required property var currencyStore
|
||||
required property var tokensStore
|
||||
|
||||
signal sendTriggered(var selectedAccount)
|
||||
signal disconnect()
|
||||
signal reload()
|
||||
|
||||
modal: false
|
||||
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
parent: Overlay.overlay
|
||||
width: 360
|
||||
height: 480
|
||||
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: Style.current.dropShadow
|
||||
}
|
||||
}
|
||||
padding: Style.current.padding
|
||||
|
||||
Item {
|
||||
id: walletHeader
|
||||
width: parent.width
|
||||
height: networkText.height
|
||||
|
||||
Rectangle {
|
||||
id: networkColorCircle
|
||||
width: 8
|
||||
height: 8
|
||||
radius: width / 2
|
||||
color: {
|
||||
switch (Web3ProviderStore.chainName) {
|
||||
case Constants.networkMainnet: return Style.current.green;
|
||||
case Constants.networkRopsten: return Style.current.turquoise;
|
||||
default: return Style.current.red
|
||||
}
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: networkText
|
||||
text: {
|
||||
switch (Web3ProviderStore.chainName) {
|
||||
case Constants.networkMainnet: return qsTr("Mainnet");
|
||||
case Constants.networkRopsten: return qsTr("Ropsten");
|
||||
default: return qsTr("Unknown")
|
||||
}
|
||||
}
|
||||
font.pixelSize: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: networkColorCircle.right
|
||||
anchors.leftMargin: Style.current.halfPadding
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: disconectBtn
|
||||
text: qsTr("Disconnect")
|
||||
font.pixelSize: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
color: Style.current.danger
|
||||
visible: RootStore.currentTabConnected
|
||||
|
||||
MouseArea {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
anchors.fill: parent
|
||||
onClicked: disconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Connections {
|
||||
target: WalletStore.dappBrowserAccount
|
||||
function onConnectedAccountDeleted() {
|
||||
popup.reload()
|
||||
// This is done because when an account is deleted and the account is updated to default one,
|
||||
// only the properties are updated and we need to listen to those events and update the selected account
|
||||
accountSelectorRow.currentAddress = ""
|
||||
accountSelector.selectedAccount = Qt.binding(function () {return WalletStore.dappBrowserAccount})
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
property string currentAddress: ""
|
||||
id: accountSelectorRow
|
||||
width: parent.width
|
||||
height: accountSelector.height
|
||||
anchors.top: walletHeader.bottom
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
|
||||
StatusAccountSelector {
|
||||
id: accountSelector
|
||||
label: ""
|
||||
anchors.left: parent.left
|
||||
anchors.right: copyBtn.left
|
||||
anchors.rightMargin: Style.current.padding
|
||||
accounts: WalletStore.accounts
|
||||
selectedAccount: WalletStore.dappBrowserAccount
|
||||
currency: WalletStore.defaultCurrency
|
||||
onSelectedAccountChanged: {
|
||||
if (!accountSelectorRow.currentAddress) {
|
||||
// We just set the account for the first time. Nothing to do here
|
||||
accountSelectorRow.currentAddress = selectedAccount.address
|
||||
return
|
||||
}
|
||||
if (accountSelectorRow.currentAddress === selectedAccount.address) {
|
||||
return
|
||||
}
|
||||
|
||||
accountSelectorRow.currentAddress = selectedAccount.address
|
||||
Web3ProviderStore.web3ProviderInst.dappsAddress = selectedAccount.address;
|
||||
WalletStore.switchAccountByAddress(selectedAccount.address)
|
||||
reload()
|
||||
}
|
||||
}
|
||||
|
||||
CopyToClipBoardButton {
|
||||
id: copyBtn
|
||||
width: 20
|
||||
height: 20
|
||||
anchors.right: sendBtn.left
|
||||
anchors.rightMargin: Style.current.padding
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.padding
|
||||
color: Style.current.transparent
|
||||
textToCopy: accountSelector.selectedAccount.address
|
||||
onCopyClicked: RootStore.copyToClipboard(textToCopy)
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: sendBtn
|
||||
width: 40
|
||||
height: 40
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
icon.name: "send"
|
||||
onClicked: sendTriggered(accountSelector.selectedAccount)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: walletInfoContent
|
||||
width: parent.width
|
||||
anchors.top: accountSelectorRow.bottom
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
StatusTabBar {
|
||||
id: walletTabBar
|
||||
width: parent.width
|
||||
anchors.top: parent.top
|
||||
|
||||
StatusTabButton {
|
||||
id: assetBtn
|
||||
width: implicitWidth
|
||||
text: qsTr("Assets")
|
||||
}
|
||||
StatusTabButton {
|
||||
id: historyBtn
|
||||
width: implicitWidth
|
||||
text: qsTr("History")
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: stackLayout
|
||||
width: parent.width
|
||||
anchors.top: walletTabBar.bottom
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
anchors.bottom: parent.bottom
|
||||
currentIndex: walletTabBar.currentIndex
|
||||
|
||||
// Disable because the refactored version of AssetView requires specific
|
||||
// integration but the old version was not working properly neither.
|
||||
//AssetsView {
|
||||
// id: assetsTab
|
||||
// controller: popup.assetsStore.assetsController
|
||||
// currencyStore: popup.currencyStore
|
||||
// tokensStore: popup.tokensStore
|
||||
//}
|
||||
HistoryView {
|
||||
id: historyTab
|
||||
overview: WalletStore.dappBrowserAccount
|
||||
}
|
||||
}
|
||||
}
|
||||
onClosed: {
|
||||
popup.destroy();
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusMenu
|
||||
PopupMenu {
|
||||
id: downloadMenu
|
||||
|
||||
property int index: -1
|
||||
property bool downloadComplete: false
|
||||
property var download: DownloadsStore.getDownload(index)
|
||||
|
||||
signal cancelClicked()
|
||||
|
||||
Action {
|
||||
enabled: downloadComplete
|
||||
icon.source: Style.svg("browser/file")
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
text: qsTr("Open")
|
||||
onTriggered: DownloadsStore.openFile(index)
|
||||
}
|
||||
Action {
|
||||
icon.source: Style.svg("add_watch_only")
|
||||
icon.width: 13
|
||||
icon.height: 9
|
||||
text: qsTr("Show in folder")
|
||||
onTriggered: DownloadsStore.openDirectory(index)
|
||||
}
|
||||
Action {
|
||||
enabled: !downloadComplete && !!download && !download.isPaused
|
||||
icon.source: Style.svg("browser/pause")
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
text: qsTr("Pause")
|
||||
onTriggered: {
|
||||
download.pause()
|
||||
}
|
||||
}
|
||||
Action {
|
||||
enabled: !downloadComplete && !!download && download.isPaused
|
||||
icon.source: Style.svg("browser/play")
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
text: qsTr("Resume")
|
||||
onTriggered: {
|
||||
download.resume()
|
||||
}
|
||||
}
|
||||
Separator {
|
||||
visible: !downloadComplete
|
||||
}
|
||||
Action {
|
||||
enabled: !downloadComplete
|
||||
icon.source: Style.svg("block-icon")
|
||||
icon.width: 13
|
||||
icon.height: 13
|
||||
text: qsTr("Cancel")
|
||||
onTriggered: {
|
||||
download.cancel()
|
||||
cancelClicked()
|
||||
}
|
||||
icon.color: Style.current.red
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusMenu
|
||||
PopupMenu {
|
||||
id: favoritePopupMenu
|
||||
|
||||
property var openInNewTab: function () {}
|
||||
property string url
|
||||
property var currentFavorite: BookmarksStore.getCurrentFavorite(url)
|
||||
|
||||
signal editFavoriteTriggered()
|
||||
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
|
||||
Action {
|
||||
text: qsTr("Open in new Tab")
|
||||
icon.source: Style.svg("generate_account")
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
onTriggered: {
|
||||
openInNewTab(favoritePopupMenu.url)
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
Action {
|
||||
text: qsTr("Edit")
|
||||
icon.source: Style.svg("edit")
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
onTriggered: {
|
||||
// Force reloading current favorite as it could have been modified when edited:
|
||||
favoritePopupMenu.currentFavorite = BookmarksStore.getCurrentFavorite(url)
|
||||
editFavoriteTriggered()
|
||||
}
|
||||
}
|
||||
|
||||
Action {
|
||||
text: qsTr("Remove")
|
||||
icon.source: Style.svg("remove")
|
||||
icon.color: Style.current.danger
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
onTriggered: {
|
||||
BookmarksStore.deleteBookmark(favoritePopupMenu.url)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
import QtWebEngine 1.10
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import shared.controls 1.0
|
||||
import shared.popups 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
id: root
|
||||
property QtObject request
|
||||
height: 286
|
||||
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
onClosed: {
|
||||
request.dialogReject();
|
||||
root.destroy();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.title = request.securityOrigin;
|
||||
message.text = request.message;
|
||||
if(request.type === JavaScriptDialogRequest.DialogTypeAlert){
|
||||
cancelButton.visible = false;
|
||||
}
|
||||
if(request.type === JavaScriptDialogRequest.DialogTypePrompt){
|
||||
prompt.text = request.defaultText;
|
||||
prompt.visible = true;
|
||||
svMessage.height = 75;
|
||||
}
|
||||
}
|
||||
|
||||
StatusScrollView {
|
||||
id: svMessage
|
||||
width: parent.width
|
||||
height: 100
|
||||
TextArea {
|
||||
id: message
|
||||
wrapMode: TextEdit.Wrap
|
||||
readOnly: true
|
||||
text: ""
|
||||
}
|
||||
}
|
||||
|
||||
Input {
|
||||
id: prompt
|
||||
text: ""
|
||||
visible: false
|
||||
anchors.top: svMessage.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
}
|
||||
|
||||
footer: Item {
|
||||
width: parent.width
|
||||
height: okButton.height
|
||||
|
||||
StatusButton {
|
||||
id: okButton
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Ok")
|
||||
anchors.bottom: parent.bottom
|
||||
onClicked: {
|
||||
request.dialogAccept(prompt.text);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
StatusFlatButton {
|
||||
id: cancelButton
|
||||
anchors.right: okButton.left
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
text: qsTr("Cancel")
|
||||
anchors.bottom: parent.bottom
|
||||
onClicked: {
|
||||
request.dialogReject();
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,236 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
import QtQuick.Dialogs 1.3
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared 1.0
|
||||
import shared.views 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
StatusModal {
|
||||
property var request
|
||||
property var selectedAccount
|
||||
|
||||
readonly property int bytes32Length: 66
|
||||
|
||||
property bool interactedWith: false
|
||||
property bool showSigningPhrase: false
|
||||
|
||||
property alias transactionSigner: transactionSigner
|
||||
|
||||
property var signMessage: function(enteredPassword) {}
|
||||
|
||||
property var web3Response
|
||||
|
||||
|
||||
anchors.centerIn: parent
|
||||
id: root
|
||||
|
||||
headerSettings.title: qsTr("Signature request")
|
||||
height: 504
|
||||
|
||||
onClosed: {
|
||||
if(!interactedWith){
|
||||
web3Response(JSON.stringify({
|
||||
"type": "web3-send-async-callback",
|
||||
"messageId": request.messageId,
|
||||
"error": {
|
||||
"code": 4100
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
showSigningPhrase = false;
|
||||
}
|
||||
|
||||
function displayValue(input){
|
||||
if(Utils.isHex(input) && Utils.startsWith0x(input)){
|
||||
if (input.length === bytes32Length){
|
||||
return input;
|
||||
}
|
||||
return RootStore.getHex2Ascii(input)
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
function messageToSign(){
|
||||
switch(request.payload.method){
|
||||
case Constants.personal_sign:
|
||||
return displayValue(request.payload.params[0]);
|
||||
case Constants.eth_sign:
|
||||
return displayValue(request.payload.params[1]);
|
||||
case Constants.eth_signTypedData:
|
||||
case Constants.eth_signTypedData_v3:
|
||||
return JSON.stringify(request.payload.params[1]); // TODO: requires design
|
||||
default:
|
||||
return JSON.stringify(request.payload.params); // support for any unhandled sign method
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
width: root.width
|
||||
|
||||
TransactionSigner {
|
||||
id: transactionSigner
|
||||
width: parent.width
|
||||
signingPhrase: WalletStore.signingPhrase
|
||||
visible: showSigningPhrase
|
||||
}
|
||||
|
||||
Column {
|
||||
id: content
|
||||
visible: !showSigningPhrase
|
||||
width: root.width - Style.current.padding * 2
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
|
||||
LabelValueRow {
|
||||
label: qsTr("From")
|
||||
value: Item {
|
||||
id: itmFromValue
|
||||
anchors.fill: parent
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Row {
|
||||
spacing: Style.current.halfPadding
|
||||
rightPadding: 0
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
StyledText {
|
||||
font.pixelSize: 15
|
||||
height: 22
|
||||
text: selectedAccount.name
|
||||
elide: Text.ElideRight
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
horizontalAlignment: Text.AlignRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
SVGImage {
|
||||
id: imgFromWallet
|
||||
sourceSize.height: 18
|
||||
sourceSize.width: 18
|
||||
visible: true
|
||||
horizontalAlignment: Image.AlignLeft
|
||||
width: undefined
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: Style.svg("walletIcon")
|
||||
ColorOverlay {
|
||||
visible: parent.visible
|
||||
anchors.fill: parent
|
||||
source: parent
|
||||
color: selectedAccount.iconColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LabelValueRow {
|
||||
label: qsTr("Data")
|
||||
value: Item {
|
||||
anchors.fill: parent
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
// TODO; replace with StatusModal
|
||||
ModalPopup {
|
||||
id: messagePopup
|
||||
title: qsTr("Message")
|
||||
height: 286
|
||||
width: 400
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.rightMargin: Style.current.padding
|
||||
StatusScrollView {
|
||||
width: parent.width
|
||||
height: 150
|
||||
TextArea {
|
||||
wrapMode: TextEdit.Wrap
|
||||
readOnly: true
|
||||
text: messageToSign()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: Style.current.halfPadding
|
||||
rightPadding: 0
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
StyledText {
|
||||
width: 250
|
||||
font.pixelSize: 15
|
||||
height: 22
|
||||
text: messageToSign()
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
horizontalAlignment: Text.AlignRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
SVGImage {
|
||||
width: 13
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: Style.svg("caret")
|
||||
rotation: 270
|
||||
ColorOverlay {
|
||||
anchors.fill: parent
|
||||
source: parent
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
visible: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: messagePopup.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
leftButtons: [
|
||||
StatusFlatButton {
|
||||
id: btnReject
|
||||
text: qsTr("Reject")
|
||||
type: StatusBaseButton.Type.Danger
|
||||
onClicked: close()
|
||||
}
|
||||
]
|
||||
|
||||
rightButtons: [
|
||||
StatusButton {
|
||||
id: btnNext
|
||||
text: showSigningPhrase ?
|
||||
qsTr("Sign") :
|
||||
qsTr("Sign with password")
|
||||
onClicked: {
|
||||
if(!showSigningPhrase){
|
||||
showSigningPhrase = true;
|
||||
transactionSigner.forceActiveFocus(Qt.MouseFocusReason)
|
||||
} else {
|
||||
root.signMessage(transactionSigner.enteredPassword)
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
BrowserLayout 1.0 BrowserLayout.qml
|
|
@ -1,49 +0,0 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick 2.15
|
||||
|
||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property var bookmarksModel: bookmarkModule.model
|
||||
|
||||
function addBookmark(url, name)
|
||||
{
|
||||
bookmarkModule.addBookmark(url, name)
|
||||
}
|
||||
|
||||
function deleteBookmark(url)
|
||||
{
|
||||
bookmarkModule.deleteBookmark(url)
|
||||
}
|
||||
|
||||
function updateBookmark(originalUrl, newUrl, newName)
|
||||
{
|
||||
bookmarkModule.updateBookmark(originalUrl, newUrl, newName)
|
||||
}
|
||||
|
||||
function getBookmarkIndexByUrl(url)
|
||||
{
|
||||
return bookmarkModule.model.getBookmarkIndexByUrl(url)
|
||||
}
|
||||
|
||||
function getCurrentFavorite(url) {
|
||||
if (!url) {
|
||||
return null
|
||||
}
|
||||
const index = bookmarkModule.model.getBookmarkIndexByUrl(url)
|
||||
if (index === -1) {
|
||||
return null
|
||||
}
|
||||
|
||||
const item = SQUtils.ModelUtils.get(bookmarkModule.model, index)
|
||||
|
||||
return {
|
||||
url: url,
|
||||
name: item.name,
|
||||
image: item.imageUrl
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick 2.13
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property ListModel downloadModel : ListModel {
|
||||
property var downloads: []
|
||||
}
|
||||
|
||||
function getDownload(index) {
|
||||
return downloadModel.downloads[index]
|
||||
}
|
||||
|
||||
function removeDownloadFromModel(index) {
|
||||
downloadModel.downloads = downloadModel.downloads.filter(function (el) {
|
||||
return el.id !== downloadModel.downloads[index].id;
|
||||
});
|
||||
downloadModel.remove(index);
|
||||
}
|
||||
|
||||
function addDownload(download) {
|
||||
downloadModel.append(download);
|
||||
downloadModel.downloads.push(download);
|
||||
}
|
||||
|
||||
function openFile(index) {
|
||||
Qt.openUrlExternally(`file://${downloadModel.downloads[index].downloadDirectory}/${downloadModel.downloads[index].downloadFileName}`)
|
||||
root.removeDownloadFromModel(index)
|
||||
}
|
||||
// TODO check if this works in Windows and Mac
|
||||
function openDirectory(index) {
|
||||
Qt.openUrlExternally("file://" + downloadModel.downloads[index].downloadDirectory)
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick 2.13
|
||||
|
||||
import utils 1.0
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
// Not Refactored Yet
|
||||
// property string activeChannelName: chatsModel.channelView.activeChannel.name
|
||||
|
||||
property bool currentTabConnected: false
|
||||
|
||||
function getUrlFromUserInput(input) {
|
||||
return globalUtils.urlFromUserInput(input)
|
||||
}
|
||||
|
||||
function getAscii2Hex(input) {
|
||||
return globalUtils.ascii2Hex(input)
|
||||
}
|
||||
|
||||
function getHex2Ascii(input) {
|
||||
return globalUtils.hex2Ascii(input)
|
||||
}
|
||||
|
||||
function getWei2Eth(wei,decimals) {
|
||||
return globalUtils.wei2Eth(wei,decimals)
|
||||
}
|
||||
|
||||
function getEth2Hex(eth) {
|
||||
return globalUtils.eth2Hex(eth)
|
||||
}
|
||||
|
||||
function getGwei2Hex(gwei){
|
||||
return globalUtils.gwei2Hex(gwei)
|
||||
}
|
||||
|
||||
function generateAlias(pk) {
|
||||
return globalUtils.generateAlias(pk)
|
||||
}
|
||||
|
||||
function get0xFormedUrl(browserExplorer, url) {
|
||||
var tempUrl = ""
|
||||
switch (browserExplorer) {
|
||||
case Constants.browserEthereumExplorerEtherscan:
|
||||
if (url.length > 42) {
|
||||
tempUrl = "https://etherscan.io/tx/" + url; break;
|
||||
} else {
|
||||
tempUrl = "https://etherscan.io/address/" + url; break;
|
||||
}
|
||||
case Constants.browserEthereumExplorerEthplorer:
|
||||
if (url.length > 42) {
|
||||
tempUrl = "https://ethplorer.io/tx/" + url; break;
|
||||
} else {
|
||||
tempUrl = "https://ethplorer.io/address/" + url; break;
|
||||
}
|
||||
case Constants.browserEthereumExplorerBlockchair:
|
||||
if (url.length > 42) {
|
||||
tempUrl = "https://blockchair.com/ethereum/transaction/" + url; break;
|
||||
} else {
|
||||
tempUrl = "https://blockchair.com/ethereum/address/" + url; break;
|
||||
}
|
||||
}
|
||||
return tempUrl
|
||||
}
|
||||
|
||||
function getFormedUrl(shouldShowBrowserSearchEngine, url) {
|
||||
var tempUrl = ""
|
||||
switch (localAccountSensitiveSettings.shouldShowBrowserSearchEngine) {
|
||||
case Constants.browserSearchEngineGoogle: tempUrl = "https://www.google.com/search?q=" + url; break;
|
||||
case Constants.browserSearchEngineYahoo: tempUrl = "https://search.yahoo.com/search?p=" + url; break;
|
||||
case Constants.browserSearchEngineDuckDuckGo: tempUrl = "https://duckduckgo.com/?q=" + url; break;
|
||||
}
|
||||
return tempUrl
|
||||
}
|
||||
|
||||
function copyToClipboard(text) {
|
||||
globalUtils.copyToClipboard(text)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick 2.13
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property var dappBrowserAccount: browserSectionCurrentAccount
|
||||
property var accounts: walletSectionAccounts.model
|
||||
property string defaultCurrency: walletSection.currentCurrency
|
||||
property string signingPhrase: walletSection.signingPhrase
|
||||
|
||||
function getEtherscanLink(chainID) {
|
||||
return networksModule.getBlockExplorerURL(chainID)
|
||||
}
|
||||
|
||||
function switchAccountByAddress(address) {
|
||||
browserSectionCurrentAccount.switchAccountByAddress(address)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick 2.13
|
||||
|
||||
import utils 1.0
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property var web3ProviderInst: providerModule
|
||||
property var urlENSDictionary: ({})
|
||||
|
||||
property int chainId: providerModule.chainId
|
||||
property string chainName: providerModule.chainName
|
||||
|
||||
function disconnectAddress(dappName, address){
|
||||
dappPermissionsModule.disconnectAddress(dappName, address)
|
||||
}
|
||||
|
||||
function disconnect(hostname) {
|
||||
dappPermissionsModule.disconnect(hostname)
|
||||
}
|
||||
|
||||
function addPermission(hostname, address, permission){
|
||||
dappPermissionsModule.addPermission(hostname, address, permission)
|
||||
}
|
||||
|
||||
function hasPermission(hostname, address, permission){
|
||||
return dappPermissionsModule.hasPermission(hostname, address, permission)
|
||||
}
|
||||
|
||||
function hasWalletConnected(hostname) {
|
||||
return hasPermission(hostname, WalletStore.dappBrowserAccount.address, "web3")
|
||||
}
|
||||
|
||||
function determineRealURL(text){
|
||||
var url = RootStore.getUrlFromUserInput(text);
|
||||
var host = providerModule.getHost(url);
|
||||
if(host.endsWith(".eth")){
|
||||
var ensResource = providerModule.ensResourceURL(host, url);
|
||||
|
||||
if(/^https\:\/\/swarm\-gateways\.net\/bzz:\/([0-9a-fA-F]{64}|.+\.eth)(\/?)/.test(ensResource)){
|
||||
// TODO: populate urlENSDictionary for prettier url instead of swarm-gateway big URL
|
||||
return ensResource;
|
||||
} else {
|
||||
urlENSDictionary[providerModule.getHost(ensResource)] = host;
|
||||
}
|
||||
url = ensResource;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
function obtainAddress(url) {
|
||||
var ensAddr = urlENSDictionary[providerModule.getHost(url)];
|
||||
return ensAddr ? providerModule.replaceHostByENS( url, ensAddr) : url;
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
singleton RootStore 1.0 RootStore.qml
|
||||
singleton Web3ProviderStore 1.0 Web3ProviderStore.qml
|
||||
singleton BookmarksStore 1.0 BookmarksStore.qml
|
||||
singleton DownloadsStore 1.0 DownloadsStore.qml
|
||||
singleton WalletStore 1.0 WalletStore.qml
|
|
@ -1,74 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtWebEngine module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.13
|
||||
import QtQuick.Window 2.13
|
||||
import QtWebEngine 1.9
|
||||
|
||||
Window {
|
||||
id: window
|
||||
property alias currentWebView: webView
|
||||
flags: Qt.Dialog | Qt.WindowStaysOnTopHint
|
||||
width: 800
|
||||
height: 600
|
||||
visible: true
|
||||
onClosing: destroy()
|
||||
WebEngineView {
|
||||
id: webView
|
||||
anchors.fill: parent
|
||||
|
||||
onGeometryChangeRequested: function(geometry) {
|
||||
window.x = geometry.x
|
||||
window.y = geometry.y
|
||||
window.width = geometry.width
|
||||
window.height = geometry.height
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtWebEngine module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.14
|
||||
import QtWebEngine 1.10
|
||||
|
||||
Item {
|
||||
id: shortcutActions
|
||||
|
||||
property var currentWebView
|
||||
property var findBarComponent
|
||||
property var browserHeaderComponent
|
||||
|
||||
signal addNewDownloadTab()
|
||||
signal removeView()
|
||||
|
||||
Action {
|
||||
shortcut: "Ctrl+D"
|
||||
onTriggered: {
|
||||
addNewDownloadTab()
|
||||
}
|
||||
}
|
||||
Action {
|
||||
shortcut: "Ctrl+L"
|
||||
onTriggered: {
|
||||
browserHeaderComponent.addressBar.forceActiveFocus();
|
||||
browserHeaderComponent.addressBar.selectAll();
|
||||
}
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.Refresh
|
||||
onTriggered: {
|
||||
if (currentWebView)
|
||||
currentWebView.reload();
|
||||
}
|
||||
}
|
||||
Action {
|
||||
shortcut: "Ctrl+W"
|
||||
onTriggered: removeView()
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.Close
|
||||
onTriggered: {
|
||||
currentWebView.triggerWebAction(WebEngineView.RequestClose);
|
||||
}
|
||||
}
|
||||
Action {
|
||||
shortcut: "Escape"
|
||||
onTriggered: {
|
||||
if (findBarComponent.visible)
|
||||
findBarComponent.visible = false;
|
||||
}
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.Copy
|
||||
onTriggered: currentWebView.triggerWebAction(WebEngineView.Copy)
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.Cut
|
||||
onTriggered: currentWebView.triggerWebAction(WebEngineView.Cut)
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.Paste
|
||||
onTriggered: currentWebView.triggerWebAction(WebEngineView.Paste)
|
||||
}
|
||||
Action {
|
||||
shortcut: "Shift+"+StandardKey.Paste
|
||||
onTriggered: currentWebView.triggerWebAction(WebEngineView.PasteAndMatchStyle)
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.SelectAll
|
||||
onTriggered: currentWebView.triggerWebAction(WebEngineView.SelectAll)
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.Undo
|
||||
onTriggered: currentWebView.triggerWebAction(WebEngineView.Undo)
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.Redo
|
||||
onTriggered: currentWebView.triggerWebAction(WebEngineView.Redo)
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.Back
|
||||
onTriggered: currentWebView.triggerWebAction(WebEngineView.Back)
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.Forward
|
||||
onTriggered: currentWebView.triggerWebAction(WebEngineView.Forward)
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.FindNext
|
||||
onTriggered: findBarComponent.findNext()
|
||||
}
|
||||
Action {
|
||||
shortcut: StandardKey.FindPrevious
|
||||
onTriggered: findBarComponent.findPrevious()
|
||||
}
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtWebEngine 1.10
|
||||
|
||||
import shared.controls 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../panels"
|
||||
import "../stores"
|
||||
|
||||
WebEngineView {
|
||||
id: webEngineView
|
||||
|
||||
property var currentWebView
|
||||
property var findBarComp
|
||||
property var favMenu
|
||||
property var addFavModal
|
||||
property var downloadsMenu
|
||||
property var determineRealURLFn: function(url){}
|
||||
|
||||
signal setCurrentWebUrl(var url)
|
||||
|
||||
focus: true
|
||||
|
||||
function changeZoomFactor(newFactor) {
|
||||
// FIXME there seems to be a bug in the WebEngine where the zoomFactor only update 1/2 times
|
||||
zoomFactor = newFactor
|
||||
zoomFactor = newFactor
|
||||
zoomFactor = newFactor
|
||||
}
|
||||
|
||||
settings.autoLoadImages: localAccountSensitiveSettings.autoLoadImages
|
||||
settings.javascriptEnabled: localAccountSensitiveSettings.javaScriptEnabled
|
||||
settings.errorPageEnabled: localAccountSensitiveSettings.errorPageEnabled
|
||||
settings.pluginsEnabled: localAccountSensitiveSettings.pluginsEnabled
|
||||
settings.autoLoadIconsForPage: localAccountSensitiveSettings.autoLoadIconsForPage
|
||||
settings.touchIconsEnabled: localAccountSensitiveSettings.touchIconsEnabled
|
||||
settings.webRTCPublicInterfacesOnly: localAccountSensitiveSettings.webRTCPublicInterfacesOnly
|
||||
settings.pdfViewerEnabled: localAccountSensitiveSettings.pdfViewerEnabled
|
||||
settings.focusOnNavigationEnabled: true
|
||||
|
||||
onQuotaRequested: function(request) {
|
||||
if (request.requestedSize <= 5 * 1024 * 1024)
|
||||
request.accept();
|
||||
else
|
||||
request.reject();
|
||||
}
|
||||
|
||||
onRegisterProtocolHandlerRequested: function(request) {
|
||||
console.log("accepting registerProtocolHandler request for "
|
||||
+ request.scheme + " from " + request.origin);
|
||||
request.accept();
|
||||
}
|
||||
|
||||
onRenderProcessTerminated: function(terminationStatus, exitCode) {
|
||||
var status = "";
|
||||
switch (terminationStatus) {
|
||||
case WebEngineView.NormalTerminationStatus:
|
||||
status = "(normal exit)";
|
||||
break;
|
||||
case WebEngineView.AbnormalTerminationStatus:
|
||||
status = "(abnormal exit)";
|
||||
break;
|
||||
case WebEngineView.CrashedTerminationStatus:
|
||||
status = "(crashed)";
|
||||
break;
|
||||
case WebEngineView.KilledTerminationStatus:
|
||||
status = "(killed)";
|
||||
break;
|
||||
}
|
||||
|
||||
print("Render process exited with code " + exitCode + " " + status);
|
||||
reloadTimer.running = true;
|
||||
}
|
||||
|
||||
onSelectClientCertificate: function(selection) {
|
||||
selection.certificates[0].select();
|
||||
}
|
||||
|
||||
onFindTextFinished: function(result) {
|
||||
if (!findBarComp.visible)
|
||||
findBarComp.visible = true;
|
||||
|
||||
findBarComp.numberOfMatches = result.numberOfMatches;
|
||||
findBarComp.activeMatch = result.activeMatch;
|
||||
}
|
||||
|
||||
onLoadingChanged: function(loadRequest) {
|
||||
if (loadRequest.status === WebEngineView.LoadStartedStatus)
|
||||
findBarComp.reset();
|
||||
}
|
||||
|
||||
onNavigationRequested: {
|
||||
if(request.url.toString().startsWith("file://")){
|
||||
console.log("Local file browsing is disabled" )
|
||||
request.action = WebEngineNavigationRequest.IgnoreRequest;
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: webEngineView.url.toString() === "status://downloads"
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
z: 54
|
||||
sourceComponent: DownloadView {
|
||||
id: downloadView
|
||||
downloadsModel: DownloadsStore.downloadModel
|
||||
downloadsMenu: webEngineView.downloadsMenu
|
||||
onOpenDownloadClicked: {
|
||||
if (downloadComplete) {
|
||||
return DownloadsStore.openFile(index)
|
||||
}
|
||||
DownloadsStore.openDirectory(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: !webEngineView.url.toString()
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
z: 54
|
||||
|
||||
sourceComponent: Item {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Image {
|
||||
id: emptyPageImage
|
||||
source: Style.png("browser/compass")
|
||||
width: 294
|
||||
height: 294
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 60
|
||||
cache: false
|
||||
}
|
||||
|
||||
FavoritesList {
|
||||
id: bookmarkListContainer
|
||||
anchors.horizontalCenter: emptyPageImage.horizontalCenter
|
||||
anchors.top: emptyPageImage.bottom
|
||||
anchors.topMargin: 30
|
||||
width: (parent.width < 700) ? (Math.floor(parent.width/cellWidth)*cellWidth) : 700
|
||||
height: parent.height - emptyPageImage.height - 20
|
||||
model: BookmarksStore.bookmarksModel
|
||||
favMenu: webEngineView.favMenu
|
||||
addFavModal: webEngineView.addFavModal
|
||||
determineRealURLFn: function(url) {
|
||||
return webEngineView.determineRealURLFn(url)
|
||||
}
|
||||
setAsCurrentWebUrl: function(url) {
|
||||
webEngineView.setCurrentWebUrl(url)
|
||||
}
|
||||
Component.onCompleted: {
|
||||
// Add fav button at the end of the grid
|
||||
var index = BookmarksStore.getBookmarkIndexByUrl(Constants.newBookmark)
|
||||
if (index !== -1) { BookmarksStore.deleteBookmark(Constants.newBookmark) }
|
||||
BookmarksStore.addBookmark(Constants.newBookmark, qsTr("Add Favorite"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: reloadTimer
|
||||
interval: 0
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: currentWebView.reload()
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtWebChannel 1.13
|
||||
import QtQuick.Dialogs 1.2
|
||||
|
||||
import utils 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
QtObject {
|
||||
id: provider
|
||||
|
||||
property var createAccessDialogComponent: function(){}
|
||||
property var createSendTransactionModalComponent: function(){}
|
||||
property var createSignMessageModalComponent: function(){}
|
||||
property var showSendingError: function(){}
|
||||
property var showSigningError: function(){}
|
||||
property var showToastMessage: function(){}
|
||||
property int chainId: (Web3ProviderStore && Web3ProviderStore.chainId) || 1
|
||||
|
||||
signal web3Response(string data);
|
||||
|
||||
function signValue(input){
|
||||
if(Utils.isHex(input) && Utils.startsWith0x(input)){
|
||||
return input
|
||||
}
|
||||
return RootStore.getAscii2Hex(input)
|
||||
}
|
||||
|
||||
property Connections conn: Connections {
|
||||
target: Web3ProviderStore.web3ProviderInst
|
||||
|
||||
function onPostMessageResult(payloadMethod: string, result: string, chainId: string) {
|
||||
web3Response(result)
|
||||
const isSign = ["eth_sign", "personal_sign", "eth_signTypedData", "eth_signTypedData_v3"].indexOf(payloadMethod) > -1
|
||||
const isTx = payloadMethod === "eth_sendTransaction"
|
||||
try {
|
||||
let responseObj = JSON.parse(result)
|
||||
if (responseObj.error) {
|
||||
throw new Error(responseObj.error)
|
||||
}
|
||||
|
||||
if (isTx) {
|
||||
showToastMessage(responseObj.result.result, chainId)
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
if (isTx) {
|
||||
showSendingError(e.message)
|
||||
} else if (isSign) {
|
||||
showSigningError(e.message.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function postMessage(requestType, data) {
|
||||
var request;
|
||||
try {
|
||||
request = JSON.parse(data)
|
||||
} catch (e) {
|
||||
console.error("Error parsing the message data", e)
|
||||
return;
|
||||
}
|
||||
request.address = WalletStore.dappBrowserAccount.address
|
||||
if (!request.payload) {
|
||||
request.payload = {}
|
||||
}
|
||||
request.payload.chainId = provider.chainId
|
||||
|
||||
var ensAddr = Web3ProviderStore.urlENSDictionary[request.hostname];
|
||||
if (ensAddr) {
|
||||
request.hostname = ensAddr;
|
||||
}
|
||||
|
||||
if (requestType === Constants.web3DisconnectAccount) {
|
||||
RootStore.currentTabConnected = false
|
||||
web3Response(JSON.stringify({type: Constants.web3DisconnectAccount}));
|
||||
} else if (requestType === Constants.api_request) {
|
||||
if (!Web3ProviderStore.hasPermission(request.hostname, request.address, request.permission)) {
|
||||
RootStore.currentTabConnected = false
|
||||
var dialog = createAccessDialogComponent()
|
||||
dialog.request = request;
|
||||
dialog.open();
|
||||
} else {
|
||||
RootStore.currentTabConnected = true
|
||||
Web3ProviderStore.web3ProviderInst.postMessage("", requestType, JSON.stringify(request));
|
||||
}
|
||||
} else if (requestType === Constants.web3SendAsyncReadOnly &&
|
||||
request.payload.method === "eth_sendTransaction") {
|
||||
var acc = WalletStore.dappBrowserAccount
|
||||
const value = RootStore.getWei2Eth(request.payload.params[0].value, 18);
|
||||
const sendDialog = createSendTransactionModalComponent(request, requestType)
|
||||
|
||||
sendDialog.sendTransaction = function () {
|
||||
if(sendDialog.bestRoutes.length === 1) {
|
||||
let path = sendDialog.bestRoutes[0]
|
||||
let eip1559Enabled = path.gasFees.eip1559Enabled
|
||||
let maxFeePerGas = path.gasFees.maxFeePerGasM
|
||||
let trx = request.payload.params[0]
|
||||
// TODO: use bignumber instead of floats
|
||||
trx.value = RootStore.getEth2Hex(parseFloat(value))
|
||||
trx.gas = "0x" + parseInt(path.gasAmount, 10).toString(16)
|
||||
trx.maxPriorityFeePerGas = RootStore.getGwei2Hex(parseFloat(eip1559Enabled ? path.gasFees.maxPriorityFeePerGas : "0"))
|
||||
trx.maxFeePerGas = RootStore.getGwei2Hex(parseFloat(eip1559Enabled ? maxFeePerGas : path.gasFees.gasPrice))
|
||||
|
||||
request.payload.params[0] = trx
|
||||
|
||||
Web3ProviderStore.web3ProviderInst.authenticateToPostMessage(request.payload.method, requestType, JSON.stringify(request))
|
||||
sendDialog.close()
|
||||
}
|
||||
}
|
||||
|
||||
sendDialog.open();
|
||||
} else if (requestType === Constants.web3SendAsyncReadOnly && ["eth_sign", "personal_sign", "eth_signTypedData", "eth_signTypedData_v3"].indexOf(request.payload.method) > -1) {
|
||||
const signDialog = createSignMessageModalComponent(request)
|
||||
signDialog.web3Response = web3Response
|
||||
signDialog.signMessage = function (enteredPassword) {
|
||||
signDialog.interactedWith = true;
|
||||
request.payload.password = enteredPassword;
|
||||
request.payload.from = WalletStore.dappBrowserAccount.address;
|
||||
switch(request.payload.method){
|
||||
case Constants.personal_sign:
|
||||
request.payload.params[0] = signValue(request.payload.params[0]);
|
||||
case Constants.eth_sign:
|
||||
request.payload.params[1] = signValue(request.payload.params[1]);
|
||||
}
|
||||
Web3ProviderStore.web3ProviderInst.postMessage(request.payload.method, requestType, JSON.stringify(request));
|
||||
signDialog.close()
|
||||
signDialog.destroy()
|
||||
}
|
||||
|
||||
|
||||
signDialog.open();
|
||||
} else if (request.type === Constants.web3DisconnectAccount) {
|
||||
web3Response(data);
|
||||
} else {
|
||||
Web3ProviderStore.web3ProviderInst.postMessage(request.payload.method, requestType, JSON.stringify(request));
|
||||
}
|
||||
}
|
||||
|
||||
WebChannel.id: "backend"
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
|
||||
StatusDialog {
|
||||
id: root
|
||||
|
||||
property string link
|
||||
|
||||
title: qsTr("Choose browser")
|
||||
width: 400
|
||||
footer: null
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 20
|
||||
|
||||
Image {
|
||||
source: Style.png("browser/chooseBrowserImage@2x")
|
||||
Layout.preferredWidth: 240
|
||||
Layout.preferredHeight: 148
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
cache: false
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Open in Status")
|
||||
font.weight: Font.Medium
|
||||
onClicked: {
|
||||
localAccountSensitiveSettings.showBrowserSelector = !rememberChoiceCheckBox.checked
|
||||
if (rememberChoiceCheckBox.checked) {
|
||||
localAccountSensitiveSettings.openLinksInStatus = true
|
||||
}
|
||||
Global.changeAppSectionBySectionType(Constants.appSection.browser)
|
||||
Global.openLinkInBrowser(root.link)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
|
||||
StatusFlatButton {
|
||||
text: qsTr("Open in my default browser")
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
font.weight: Font.Medium
|
||||
onClicked: {
|
||||
localAccountSensitiveSettings.showBrowserSelector = !rememberChoiceCheckBox.checked
|
||||
if (rememberChoiceCheckBox.checked) {
|
||||
localAccountSensitiveSettings.openLinksInStatus = false
|
||||
}
|
||||
Qt.openUrlExternally(root.link)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
|
||||
StatusCheckBox {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.bottomMargin: Style.current.smallPadding
|
||||
id: rememberChoiceCheckBox
|
||||
font.pixelSize: 13
|
||||
text: qsTr("Remember my choice. To override it, go to settings.")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,2 +1 @@
|
|||
PinnedMessagesPopup 1.0 PinnedMessagesPopup.qml
|
||||
ChooseBrowserPopup 1.0 ChooseBrowserPopup.qml
|
||||
|
|
|
@ -71,7 +71,7 @@ Item {
|
|||
StyledText {
|
||||
id: txtDesc1
|
||||
color: Style.current.secondaryText
|
||||
text: qsTr("Your fully decentralized gateway to Ethereum and Web3. Crypto wallet, privacy first group chat, and dApp browser.")
|
||||
text: qsTr("Your fully decentralized gateway to Ethereum and Web3. Crypto wallet, privacy first group chat, and communities.")
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
anchors.right: parent.right
|
||||
|
|
|
@ -316,20 +316,6 @@ StatusSectionLayout {
|
|||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: false
|
||||
asynchronous: true
|
||||
sourceComponent: BrowserView {
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: parent.height
|
||||
|
||||
store: root.store
|
||||
accountSettings: localAccountSensitiveSettings
|
||||
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.browserSettings)
|
||||
contentWidth: d.contentWidth
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: false
|
||||
asynchronous: true
|
||||
|
|
|
@ -20,7 +20,6 @@ Column {
|
|||
property alias extraMenuItems: extraMenuItems.model
|
||||
property alias appsMenuItems: appsMenuItems.model
|
||||
|
||||
property bool browserMenuItemEnabled: false
|
||||
property bool walletMenuItemEnabled: false
|
||||
|
||||
signal menuItemClicked(var menu_item)
|
||||
|
@ -87,8 +86,7 @@ Column {
|
|||
selected: Global.settingsSubsection === model.subsection
|
||||
onClicked: root.menuItemClicked(model)
|
||||
visible: {
|
||||
(model.subsection !== Constants.settingsSubsection.browserSettings && model.subsection !== Constants.settingsSubsection.wallet) ||
|
||||
(model.subsection === Constants.settingsSubsection.browserSettings && root.browserMenuItemEnabled) ||
|
||||
(model.subsection !== Constants.settingsSubsection.wallet) ||
|
||||
(model.subsection === Constants.settingsSubsection.communitiesSettings) ||
|
||||
(model.subsection === Constants.settingsSubsection.wallet && root.walletMenuItemEnabled)
|
||||
}
|
||||
|
@ -118,7 +116,6 @@ Column {
|
|||
asset.name: model.icon
|
||||
selected: Global.settingsSubsection === model.subsection
|
||||
onClicked: root.menuItemClicked(model)
|
||||
visible: model.subsection !== Constants.settingsSubsection.browserSettings || root.browserMenuItemEnabled
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +133,6 @@ Column {
|
|||
title: model.text
|
||||
asset.name: model.icon
|
||||
selected: Global.settingsSubsection === model.subsection
|
||||
visible: model.subsection !== Constants.settingsSubsection.browserSettings || root.browserMenuItemEnabled
|
||||
onClicked: root.menuItemClicked(model)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
|
||||
import utils 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
id: popup
|
||||
|
||||
property var accountSettings
|
||||
|
||||
title: qsTr("Search engine")
|
||||
|
||||
onClosed: {
|
||||
destroy()
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
spacing: 0
|
||||
|
||||
ButtonGroup {
|
||||
id: searchEnginGroup
|
||||
}
|
||||
|
||||
RadioButtonSelector {
|
||||
title: qsTr("None")
|
||||
buttonGroup: searchEnginGroup
|
||||
checked: accountSettings.shouldShowBrowserSearchEngine === Constants.browserSearchEngineNone
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
accountSettings.shouldShowBrowserSearchEngine = Constants.browserSearchEngineNone
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RadioButtonSelector {
|
||||
title: "Google"
|
||||
buttonGroup: searchEnginGroup
|
||||
checked: accountSettings.shouldShowBrowserSearchEngine === Constants.browserSearchEngineGoogle
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
accountSettings.shouldShowBrowserSearchEngine = Constants.browserSearchEngineGoogle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RadioButtonSelector {
|
||||
title: "Yahoo!"
|
||||
buttonGroup: searchEnginGroup
|
||||
checked: accountSettings.shouldShowBrowserSearchEngine === Constants.browserSearchEngineYahoo
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
accountSettings.shouldShowBrowserSearchEngine = Constants.browserSearchEngineYahoo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RadioButtonSelector {
|
||||
title: "DuckDuckGo"
|
||||
buttonGroup: searchEnginGroup
|
||||
checked: accountSettings.shouldShowBrowserSearchEngine === Constants.browserSearchEngineDuckDuckGo
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
accountSettings.shouldShowBrowserSearchEngine = Constants.browserSearchEngineDuckDuckGo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@ QtObject {
|
|||
readonly property bool createCommunityEnabled: localAppSettings.createCommunityEnabled ?? false
|
||||
property bool isManageCommunityOnTestModeEnabled: false
|
||||
readonly property QtObject experimentalFeatures: QtObject {
|
||||
readonly property string browser: "browser"
|
||||
readonly property string communities: "communities"
|
||||
readonly property string activityCenter: "activityCenter"
|
||||
readonly property string nodeManagement: "nodeManagement"
|
||||
|
@ -120,10 +119,7 @@ QtObject {
|
|||
if(!root.advancedModule)
|
||||
return
|
||||
|
||||
if (feature === experimentalFeatures.browser) {
|
||||
advancedModule.toggleBrowserSection()
|
||||
}
|
||||
else if (feature === experimentalFeatures.communities) {
|
||||
if (feature === experimentalFeatures.communities) {
|
||||
advancedModule.toggleCommunitySection()
|
||||
}
|
||||
else if (feature === experimentalFeatures.communitiesPortal) {
|
||||
|
|
|
@ -77,7 +77,6 @@ QtObject {
|
|||
stickersModule: stickersModuleInst
|
||||
}
|
||||
|
||||
property bool browserMenuItemEnabled: Global.appIsReady? localAccountSensitiveSettings.isBrowserEnabled : false
|
||||
property bool walletMenuItemEnabled: profileStore.isWalletEnabled
|
||||
|
||||
property var communitiesModuleInst: Global.appIsReady? communitiesModule : null
|
||||
|
@ -128,9 +127,6 @@ QtObject {
|
|||
append({subsection: Constants.settingsSubsection.wallet,
|
||||
text: qsTr("Wallet"),
|
||||
icon: "wallet"})
|
||||
append({subsection: Constants.settingsSubsection.browserSettings,
|
||||
text: qsTr("Browser"),
|
||||
icon: "browser"})
|
||||
append({subsection: Constants.settingsSubsection.communitiesSettings,
|
||||
text: qsTr("Communities"),
|
||||
icon: "communities"})
|
||||
|
|
|
@ -132,23 +132,6 @@ SettingsContentBase {
|
|||
bottomPadding: Style.current.padding
|
||||
}
|
||||
|
||||
// TODO: replace with StatusQ component
|
||||
StatusSettingsLineButton {
|
||||
anchors.leftMargin: 0
|
||||
anchors.rightMargin: 0
|
||||
text: qsTr("Dapp Browser")
|
||||
isSwitch: true
|
||||
switchChecked: localAccountSensitiveSettings.isBrowserEnabled
|
||||
onClicked: {
|
||||
if (!localAccountSensitiveSettings.isBrowserEnabled) {
|
||||
confirmationPopup.experimentalFeature = root.advancedStore.experimentalFeatures.browser
|
||||
confirmationPopup.open()
|
||||
} else {
|
||||
root.advancedStore.toggleExperimentalFeature(root.advancedStore.experimentalFeatures.browser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: replace with StatusQ component
|
||||
StatusSettingsLineButton {
|
||||
anchors.leftMargin: 0
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.status 1.0
|
||||
|
||||
import AppLayouts.Profile.stores 1.0
|
||||
|
||||
import "../popups"
|
||||
import "browser"
|
||||
import "wallet"
|
||||
|
||||
SettingsContentBase {
|
||||
id: root
|
||||
|
||||
property ProfileSectionStore store
|
||||
property var accountSettings
|
||||
|
||||
property Component searchEngineModal: SearchEngineModal {
|
||||
accountSettings: root.accountSettings
|
||||
}
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
width: root.contentWidth
|
||||
height: childrenRect.height
|
||||
|
||||
Column {
|
||||
id: layout
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
width: parent.width
|
||||
spacing: 10
|
||||
|
||||
HomePageView {
|
||||
id: homePageView
|
||||
accountSettings: root.accountSettings
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.rightMargin: Style.current.padding
|
||||
}
|
||||
|
||||
// TODO: Replace with StatusQ StatusListItem component
|
||||
StatusSettingsLineButton {
|
||||
anchors.leftMargin: 0
|
||||
anchors.rightMargin: 0
|
||||
text: qsTr("Search engine used in the address bar")
|
||||
currentValue: {
|
||||
switch (accountSettings.shouldShowBrowserSearchEngine) {
|
||||
case Constants.browserSearchEngineGoogle: return "Google"
|
||||
case Constants.browserSearchEngineYahoo: return "Yahoo!"
|
||||
case Constants.browserSearchEngineDuckDuckGo: return "DuckDuckGo"
|
||||
case Constants.browserSearchEngineNone:
|
||||
default: return qsTr("None")
|
||||
}
|
||||
}
|
||||
onClicked: searchEngineModal.createObject(root).open()
|
||||
}
|
||||
|
||||
DefaultDAppExplorerView {
|
||||
id: dAppExplorerView
|
||||
accountSettings: root.accountSettings
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.rightMargin: Style.current.padding
|
||||
}
|
||||
|
||||
StatusListItem {
|
||||
id: showFavouritesItem
|
||||
width: parent.width
|
||||
title: qsTr("Show Favorites Bar")
|
||||
components: [
|
||||
StatusSwitch {
|
||||
checked: accountSettings.shouldShowFavoritesBar
|
||||
onToggled: { accountSettings.shouldShowFavoritesBar = checked }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Separator {
|
||||
id: separator1
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Connected DApps")
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.baseColor1
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.rightMargin: Style.current.padding
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
implicitHeight: col1.height + 2 * Style.current.padding
|
||||
visible: root.store.walletStore.dappList.count === 0
|
||||
radius: Constants.settingsSection.radius
|
||||
color: Theme.palette.baseColor4
|
||||
|
||||
ColumnLayout {
|
||||
id: col1
|
||||
width: parent.width - 2 * (Style.current.padding + Style.current.xlPadding)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: Constants.settingsSection.infoSpacing
|
||||
|
||||
StatusBaseText {
|
||||
Layout.preferredWidth: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: qsTr("No connected dApps")
|
||||
font.pixelSize: 15
|
||||
lineHeight: Constants.settingsSection.infoLineHeight
|
||||
lineHeightMode: Text.FixedHeight
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.preferredWidth: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: qsTr("Connecting a dApp grants it permission to view your address and balances,"+
|
||||
" and to send you transaction requests")
|
||||
lineHeight: Constants.settingsSection.infoLineHeight
|
||||
lineHeightMode: Text.FixedHeight
|
||||
color: Theme.palette.baseColor1
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PermissionsListView {
|
||||
id: permissionListView
|
||||
walletStore: root.store.walletStore
|
||||
visible: root.store.walletStore.dappList.count > 0
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.rightMargin: Style.current.padding
|
||||
}
|
||||
} // Column
|
||||
} // Item
|
||||
} // ScrollView
|
|
@ -47,7 +47,6 @@ Item {
|
|||
settingsMenuItems: store.settingsMenuItems
|
||||
extraMenuItems: store.extraMenuItems
|
||||
appsMenuItems: store.appsMenuItems
|
||||
browserMenuItemEnabled: store.browserMenuItemEnabled
|
||||
walletMenuItemEnabled: store.walletMenuItemEnabled
|
||||
|
||||
objectName: "leftTabViewProfileMenu"
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property var accountSettings
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Default DApp explorer")
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: explorerGroup
|
||||
buttons: [
|
||||
noneRadioButton,
|
||||
etherscanRadioButton,
|
||||
ethplorerRadioButton,
|
||||
blockchairRadioButton
|
||||
]
|
||||
exclusive: true
|
||||
}
|
||||
|
||||
StatusRadioButton {
|
||||
id: noneRadioButton
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.topMargin: 10
|
||||
checked: accountSettings.useBrowserEthereumExplorer === Constants.browserEthereumExplorerNone
|
||||
text: qsTr("None")
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
accountSettings.useBrowserEthereumExplorer = Constants.browserEthereumExplorerNone
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusRadioButton {
|
||||
id: etherscanRadioButton
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.topMargin: 10
|
||||
checked: accountSettings.useBrowserEthereumExplorer === Constants.browserEthereumExplorerEtherscan
|
||||
text: "etherscan.io"
|
||||
onCheckedChanged: {
|
||||
if (checked && accountSettings.useBrowserEthereumExplorer !== Constants.browserEthereumExplorerEtherscan) {
|
||||
accountSettings.useBrowserEthereumExplorer = Constants.browserEthereumExplorerEtherscan
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusRadioButton {
|
||||
id: ethplorerRadioButton
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.topMargin: 10
|
||||
checked: accountSettings.useBrowserEthereumExplorer === Constants.browserEthereumExplorerEthplorer
|
||||
text: "ethplorer.io"
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
accountSettings.useBrowserEthereumExplorer = Constants.browserEthereumExplorerEthplorer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusRadioButton {
|
||||
id: blockchairRadioButton
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.topMargin: 10
|
||||
checked: accountSettings.useBrowserEthereumExplorer === Constants.browserEthereumExplorerBlockchair
|
||||
text: "blockchair.com"
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
accountSettings.useBrowserEthereumExplorer = Constants.browserEthereumExplorerBlockchair
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // Column
|
|
@ -1,57 +0,0 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property var accountSettings
|
||||
|
||||
spacing: 0
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Homepage")
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: homepageGroup
|
||||
buttons: [defaultRadioButton, customRadioButton]
|
||||
exclusive: true
|
||||
}
|
||||
|
||||
StatusRadioButton {
|
||||
id: defaultRadioButton
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.topMargin: 10
|
||||
checked: root.accountSettings.browserHomepage === ""
|
||||
text: qsTr("System default")
|
||||
}
|
||||
|
||||
StatusRadioButton {
|
||||
id: customRadioButton
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.topMargin: 10
|
||||
checked: root.accountSettings.browserHomepage !== ""
|
||||
text: qsTr("Other")
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: customUrlInput
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.topMargin: 10
|
||||
visible: customRadioButton.checked
|
||||
placeholderText: qsTr("Example: duckduckgo.com")
|
||||
text: root.accountSettings.browserHomepage
|
||||
onTextChanged: {
|
||||
root.accountSettings.browserHomepage = text
|
||||
}
|
||||
}
|
||||
|
||||
} // Column
|
|
@ -1,6 +1,5 @@
|
|||
AboutView 1.0 AboutView.qml
|
||||
AppearanceView 1.0 AppearanceView.qml
|
||||
BrowserView 1.0 BrowserView.qml
|
||||
ChangePasswordView 1.0 ChangePasswordView.qml
|
||||
CommunitiesView 1.0 CommunitiesView.qml
|
||||
LanguageView 1.0 LanguageView.qml
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||
|
||||
/// Helper item to clone a model and alter its data without affecting the original model
|
||||
/// \beware this is not a proxy model. It clones the initial state
|
||||
/// and every time the instance changes and doesn't adapt when the data
|
||||
/// in the source model \c allNetworksModel changes
|
||||
/// \beware use it with small models and in temporary views (e.g. popups)
|
||||
/// \note tried to use SortFilterProxyModel with but it complicates implementation too much
|
||||
ListModel {
|
||||
id: root
|
||||
|
||||
required property var sourceModel
|
||||
|
||||
/// Roles to clone
|
||||
required property var roles
|
||||
|
||||
/// Roles to override or add of the form { role: "roleName", transform: function(modelData) { return newValue } }
|
||||
property var rolesOverride: []
|
||||
|
||||
Component.onCompleted: cloneModel(sourceModel)
|
||||
onSourceModelChanged: cloneModel(sourceModel)
|
||||
|
||||
function findIndexForRole(roleName, value) {
|
||||
for (let i = 0; i < count; i++) {
|
||||
if(get(i)[roleName] === value) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
function cloneModel(model) {
|
||||
clear()
|
||||
if (!model) {
|
||||
console.warn("Missing valid data model to clone. The CloneModel is useless")
|
||||
return
|
||||
}
|
||||
|
||||
for (let i = 0; i < model.count; i++) {
|
||||
const clonedItem = new Object()
|
||||
for (var propName of roles) {
|
||||
clonedItem[propName] = SQUtils.ModelUtils.get(model, i, propName)
|
||||
}
|
||||
for (var newProp of rolesOverride) {
|
||||
clonedItem[newProp.role] = newProp.transform(clonedItem)
|
||||
}
|
||||
append(clonedItem)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -171,9 +171,6 @@ QtObject {
|
|||
|
||||
property var savedAddressesModel: walletSectionSavedAddresses.model
|
||||
|
||||
readonly property bool showBrowserSelector: localAccountSensitiveSettings.showBrowserSelector
|
||||
readonly property bool openLinksInStatus: false
|
||||
|
||||
property var flatNetworks: networksModule.flatNetworks
|
||||
|
||||
function getEtherscanLink(chainID) {
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
RootStore 1.0 RootStore.qml
|
||||
CloneModel 1.0 CloneModel.qml
|
||||
|
|
|
@ -9,7 +9,6 @@ import QtQml 2.15
|
|||
|
||||
import AppLayouts.Wallet 1.0
|
||||
import AppLayouts.Node 1.0
|
||||
import AppLayouts.Browser 1.0
|
||||
import AppLayouts.Chat 1.0
|
||||
import AppLayouts.Chat.views 1.0
|
||||
import AppLayouts.Profile 1.0
|
||||
|
@ -39,7 +38,6 @@ import StatusQ.Layout 0.1
|
|||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
|
||||
import AppLayouts.Browser.stores 1.0 as BrowserStores
|
||||
import AppLayouts.stores 1.0
|
||||
import AppLayouts.Chat.stores 1.0 as ChatStores
|
||||
import AppLayouts.Communities.stores 1.0
|
||||
|
@ -413,11 +411,6 @@ Item {
|
|||
id: globalConns
|
||||
target: Global
|
||||
|
||||
function onOpenLinkInBrowser(link: string) {
|
||||
changeAppSectionBySectionId(Constants.appSection.browser)
|
||||
Qt.callLater(() => browserLayoutContainer.item.openUrlInNewTab(link));
|
||||
}
|
||||
|
||||
function onOpenCreateChatView() {
|
||||
createChatView.opened = true
|
||||
}
|
||||
|
@ -433,18 +426,8 @@ Item {
|
|||
function onOpenLink(link: string) {
|
||||
// Qt sometimes inserts random HTML tags; and this will break on invalid URL inside QDesktopServices::openUrl(link)
|
||||
link = appMain.rootStore.plainText(link)
|
||||
|
||||
if (appMain.rootStore.showBrowserSelector) {
|
||||
popups.openChooseBrowserPopup(link)
|
||||
} else {
|
||||
if (appMain.rootStore.openLinksInStatus) {
|
||||
globalConns.onAppSectionBySectionTypeChanged(Constants.appSection.browser)
|
||||
globalConns.onOpenLinkInBrowser(link)
|
||||
} else {
|
||||
Qt.openUrlExternally(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onOpenLinkWithConfirmation(link: string, domain: string) {
|
||||
if (appMainLocalSettings.whitelistedUnfurledDomains.includes(domain))
|
||||
|
@ -1264,8 +1247,6 @@ Item {
|
|||
return Constants.appViewStackIndex.communitiesPortal
|
||||
if (activeSectionType === Constants.appSection.wallet)
|
||||
return Constants.appViewStackIndex.wallet
|
||||
if (activeSectionType === Constants.appSection.browser)
|
||||
return Constants.appViewStackIndex.browser
|
||||
if (activeSectionType === Constants.appSection.profile)
|
||||
return Constants.appViewStackIndex.profile
|
||||
if (activeSectionType === Constants.appSection.node)
|
||||
|
@ -1404,29 +1385,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: browserLayoutContainer
|
||||
active: appView.currentIndex === Constants.appViewStackIndex.browser
|
||||
asynchronous: true
|
||||
sourceComponent: BrowserLayout {
|
||||
globalStore: appMain.rootStore
|
||||
sendTransactionModal: sendModal
|
||||
transactionStore: appMain.transactionStore
|
||||
assetsStore: appMain.walletAssetsStore
|
||||
currencyStore: appMain.currencyStore
|
||||
tokensStore: appMain.tokensStore
|
||||
}
|
||||
// Loaders do not have access to the context, so props need to be set
|
||||
// Adding a "_" to avoid a binding loop
|
||||
// Not Refactored Yet
|
||||
// property var _chatsModel: chatsModel.messageView
|
||||
// Not Refactored Yet
|
||||
// property var _walletModel: walletModel
|
||||
// Not Refactored Yet
|
||||
// property var _utilsModel: utilsModel
|
||||
// property var _web3Provider: BrowserStores.Web3ProviderStore.web3ProviderInst
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: appView.currentIndex === Constants.appViewStackIndex.profile
|
||||
asynchronous: true
|
||||
|
|
|
@ -58,7 +58,6 @@ QtObject {
|
|||
Global.openInviteFriendsToCommunityByIdPopup.connect(openInviteFriendsToCommunityByIdPopup)
|
||||
Global.openContactRequestPopup.connect(openContactRequestPopup)
|
||||
Global.openReviewContactRequestPopup.connect(openReviewContactRequestPopup)
|
||||
Global.openChooseBrowserPopup.connect(openChooseBrowserPopup)
|
||||
Global.openDownloadModalRequested.connect(openDownloadModal)
|
||||
Global.openImagePopup.connect(openImagePopup)
|
||||
Global.openVideoPopup.connect(openVideoPopup)
|
||||
|
@ -122,10 +121,6 @@ QtObject {
|
|||
root.currentPopup.close();
|
||||
}
|
||||
|
||||
function openChooseBrowserPopup(link: string) {
|
||||
openPopup(chooseBrowserPopupComponent, {link: link})
|
||||
}
|
||||
|
||||
function openDownloadModal(available: bool, version: string, url: string) {
|
||||
const popupProperties = {
|
||||
newVersionAvailable: available,
|
||||
|
@ -624,13 +619,6 @@ QtObject {
|
|||
}
|
||||
},
|
||||
|
||||
Component {
|
||||
id: chooseBrowserPopupComponent
|
||||
ChooseBrowserPopup {
|
||||
onClosed: destroy()
|
||||
}
|
||||
},
|
||||
|
||||
Component {
|
||||
id: communityProfilePopup
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 68 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.2 MiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue