feat: check for updates (using status-go)
This commit is contained in:
parent
04037d1d64
commit
75a3ff858c
|
@ -38,6 +38,7 @@ type SignalType* {.pure.} = enum
|
||||||
HistoryArchivesSeeding = "community.historyArchivesSeeding"
|
HistoryArchivesSeeding = "community.historyArchivesSeeding"
|
||||||
HistoryArchivesUnseeded = "community.historyArchivesUnseeded"
|
HistoryArchivesUnseeded = "community.historyArchivesUnseeded"
|
||||||
HistoryArchiveDownloaded = "community.historyArchiveDownloaded"
|
HistoryArchiveDownloaded = "community.historyArchiveDownloaded"
|
||||||
|
UpdateAvailable = "update.available"
|
||||||
Unknown
|
Unknown
|
||||||
|
|
||||||
proc event*(self:SignalType):string =
|
proc event*(self:SignalType):string =
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import json
|
||||||
|
import base
|
||||||
|
import signal_type
|
||||||
|
|
||||||
|
type UpdateAvailableSignal* = ref object of Signal
|
||||||
|
available*: bool
|
||||||
|
version*: string
|
||||||
|
url*: string
|
||||||
|
|
||||||
|
proc fromEvent*(T: type UpdateAvailableSignal, jsonSignal: JsonNode): UpdateAvailableSignal =
|
||||||
|
result = UpdateAvailableSignal()
|
||||||
|
result.signalType = SignalType.UpdateAvailable
|
||||||
|
if jsonSignal["event"].kind != JNull:
|
||||||
|
result.available = jsonSignal["event"]["available"].getBool()
|
||||||
|
result.version = jsonSignal["event"]["version"].getStr()
|
||||||
|
result.url = jsonSignal["event"]["url"].getStr()
|
||||||
|
|
|
@ -92,6 +92,7 @@ QtObject:
|
||||||
of SignalType.HistoryArchivesSeeding: HistoryArchivesSignal.historyArchivesSeedingFromEvent(jsonSignal)
|
of SignalType.HistoryArchivesSeeding: HistoryArchivesSignal.historyArchivesSeedingFromEvent(jsonSignal)
|
||||||
of SignalType.HistoryArchivesUnseeded: HistoryArchivesSignal.historyArchivesUnseededFromEvent(jsonSignal)
|
of SignalType.HistoryArchivesUnseeded: HistoryArchivesSignal.historyArchivesUnseededFromEvent(jsonSignal)
|
||||||
of SignalType.HistoryArchiveDownloaded: HistoryArchivesSignal.historyArchiveDownloadedFromEvent(jsonSignal)
|
of SignalType.HistoryArchiveDownloaded: HistoryArchivesSignal.historyArchiveDownloadedFromEvent(jsonSignal)
|
||||||
|
of SignalType.UpdateAvailable: UpdateAvailableSignal.fromEvent(jsonSignal)
|
||||||
else: Signal()
|
else: Signal()
|
||||||
|
|
||||||
result.signalType = signalType
|
result.signalType = signalType
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import ./remote_signals/[base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages,
|
import ./remote_signals/[base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages,
|
||||||
peerstats, signal_type, stats, wallet, whisper_filter, keycard]
|
peerstats, signal_type, stats, wallet, whisper_filter, keycard, update_available]
|
||||||
|
|
||||||
export base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages, peerstats,
|
export base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages, peerstats,
|
||||||
signal_type, stats, wallet, whisper_filter, keycard
|
signal_type, stats, wallet, whisper_filter, keycard, update_available
|
||||||
|
|
|
@ -24,7 +24,7 @@ proc delete*(self: Controller) =
|
||||||
proc init*(self: Controller) =
|
proc init*(self: Controller) =
|
||||||
self.events.on(SIGNAL_VERSION_FETCHED) do(e: Args):
|
self.events.on(SIGNAL_VERSION_FETCHED) do(e: Args):
|
||||||
let args = VersionArgs(e)
|
let args = VersionArgs(e)
|
||||||
self.delegate.versionFetched(args.version)
|
self.delegate.versionFetched(args.available, args.version, args.url)
|
||||||
|
|
||||||
proc getAppVersion*(self: Controller): string =
|
proc getAppVersion*(self: Controller): string =
|
||||||
return self.aboutService.getAppVersion()
|
return self.aboutService.getAppVersion()
|
||||||
|
|
|
@ -17,7 +17,7 @@ method getAppVersion*(self: AccessInterface): string {.base.} =
|
||||||
method getNodeVersion*(self: AccessInterface): string {.base.} =
|
method getNodeVersion*(self: AccessInterface): string {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method versionFetched*(self: AccessInterface, version: string) {.base.} =
|
method versionFetched*(self: AccessInterface, available: bool, version: string, url: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method checkForUpdates*(self: AccessInterface) {.base.} =
|
method checkForUpdates*(self: AccessInterface) {.base.} =
|
||||||
|
|
|
@ -55,5 +55,5 @@ method getNodeVersion*(self: Module): string =
|
||||||
method checkForUpdates*(self: Module) =
|
method checkForUpdates*(self: Module) =
|
||||||
self.controller.checkForUpdates()
|
self.controller.checkForUpdates()
|
||||||
|
|
||||||
method versionFetched*(self: Module, version: string) =
|
method versionFetched*(self: Module, available: bool, version: string, url: string) =
|
||||||
self.view.versionFetched(version)
|
self.view.versionFetched(available, version, url)
|
||||||
|
|
|
@ -7,7 +7,6 @@ QtObject:
|
||||||
type
|
type
|
||||||
View* = ref object of QObject
|
View* = ref object of QObject
|
||||||
delegate: io_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
newVersion*: string
|
|
||||||
fetching*: bool
|
fetching*: bool
|
||||||
|
|
||||||
proc delete*(self: View) =
|
proc delete*(self: View) =
|
||||||
|
@ -18,14 +17,6 @@ QtObject:
|
||||||
result.QObject.setup
|
result.QObject.setup
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.fetching = false
|
result.fetching = false
|
||||||
result.newVersion = $(%*{
|
|
||||||
"available": false,
|
|
||||||
"version": "",
|
|
||||||
"url": ""
|
|
||||||
})
|
|
||||||
|
|
||||||
proc load*(self: View) =
|
|
||||||
self.delegate.viewDidLoad()
|
|
||||||
|
|
||||||
proc getCurrentVersion*(self: View): string {.slot.} =
|
proc getCurrentVersion*(self: View): string {.slot.} =
|
||||||
return self.delegate.getAppVersion()
|
return self.delegate.getAppVersion()
|
||||||
|
@ -33,31 +24,26 @@ QtObject:
|
||||||
proc nodeVersion*(self: View): string {.slot.} =
|
proc nodeVersion*(self: View): string {.slot.} =
|
||||||
return self.delegate.getNodeVersion()
|
return self.delegate.getNodeVersion()
|
||||||
|
|
||||||
proc appVersionFetched(self: View) {.signal.}
|
proc appVersionFetched*(self: View, available: bool, version: string, url: string) {.signal.}
|
||||||
|
|
||||||
proc fetchingChanged(self: View) {.signal.}
|
proc fetchingChanged(self: View) {.signal.}
|
||||||
|
|
||||||
proc versionFetched*(self: View, version: string) =
|
proc versionFetched*(self: View, available: bool, version: string, url: string) =
|
||||||
self.newVersion = version
|
|
||||||
self.fetching = false
|
self.fetching = false
|
||||||
self.fetchingChanged()
|
self.fetchingChanged()
|
||||||
self.appVersionFetched()
|
self.appVersionFetched(available, version, url)
|
||||||
|
|
||||||
proc checkForUpdates*(self: View) {.slot.} =
|
proc checkForUpdates*(self: View) {.slot.} =
|
||||||
self.fetching = true
|
self.fetching = true
|
||||||
self.fetchingChanged()
|
self.fetchingChanged()
|
||||||
self.delegate.checkForUpdates()
|
self.delegate.checkForUpdates()
|
||||||
|
|
||||||
proc getNewVersion*(self: View): string {.slot.} =
|
|
||||||
return self.newVersion
|
|
||||||
|
|
||||||
QtProperty[string] newVersion:
|
|
||||||
read = getNewVersion
|
|
||||||
notify = appVersionFetched
|
|
||||||
|
|
||||||
|
|
||||||
proc getFetching*(self: View): bool {.slot.} =
|
proc getFetching*(self: View): bool {.slot.} =
|
||||||
return self.fetching
|
return self.fetching
|
||||||
|
|
||||||
QtProperty[bool] fetching:
|
QtProperty[bool] fetching:
|
||||||
read = getFetching
|
read = getFetching
|
||||||
notify = fetchingChanged
|
notify = fetchingChanged
|
||||||
|
|
||||||
|
proc load*(self: View) =
|
||||||
|
self.delegate.viewDidLoad()
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
include ../../common/json_utils
|
|
||||||
include ../../../app/core/tasks/common
|
|
||||||
|
|
||||||
proc getLatestVersionJSON(): string =
|
|
||||||
var jsonObj = %*{
|
|
||||||
"version": "",
|
|
||||||
"url": ""
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
debug "Getting latest version information"
|
|
||||||
|
|
||||||
let latestVersion = getLatestVersion()
|
|
||||||
|
|
||||||
jsonObj["version"] = %*latestVersion.version
|
|
||||||
jsonObj["url"] = %*latestVersion.url
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
error "Error while getting latest version information", msg = e.msg
|
|
||||||
|
|
||||||
return $jsonObj
|
|
||||||
|
|
||||||
const checkForUpdatesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
|
||||||
debug "Check for updates - async"
|
|
||||||
let arg = decode[QObjectTaskArg](argEncoded)
|
|
||||||
let response = getLatestVersionJSON()
|
|
||||||
arg.finish(response)
|
|
|
@ -1,22 +1,29 @@
|
||||||
import NimQml, json, chronicles
|
import NimQml, json, chronicles
|
||||||
|
|
||||||
import ../../../app/core/eventemitter
|
|
||||||
import ../../../app/core/tasks/[qt, threadpool]
|
|
||||||
import ../../../constants
|
|
||||||
|
|
||||||
import ../settings/service as settings_service
|
import ../settings/service as settings_service
|
||||||
import ../network/types
|
import ../network/types
|
||||||
|
import ../../../app/core/eventemitter
|
||||||
|
import ../../../app/core/tasks/[qt, threadpool]
|
||||||
|
import ../../../app/core/signals/types as signal_types
|
||||||
import ../../../backend/backend
|
import ../../../backend/backend
|
||||||
import ./update
|
import ../../../backend/about as status_about
|
||||||
|
import ../../../constants
|
||||||
include async_tasks
|
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "about-service"
|
topics = "about-service"
|
||||||
|
|
||||||
|
# This is changed during compilation by reading the VERSION file
|
||||||
|
const DESKTOP_VERSION {.strdefine.} = "0.0.0"
|
||||||
|
|
||||||
|
const APP_UPDATES_ENS* = "desktop.status.eth"
|
||||||
|
|
||||||
type
|
type
|
||||||
VersionArgs* = ref object of Args
|
VersionArgs* = ref object of Args
|
||||||
|
available*: bool
|
||||||
version*: string
|
version*: string
|
||||||
|
url*: string
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Signals which may be emitted by this service:
|
# Signals which may be emitted by this service:
|
||||||
const SIGNAL_VERSION_FETCHED* = "versionFetched"
|
const SIGNAL_VERSION_FETCHED* = "versionFetched"
|
||||||
|
@ -28,9 +35,6 @@ QtObject:
|
||||||
threadpool: ThreadPool
|
threadpool: ThreadPool
|
||||||
settingsService: settings_service.Service
|
settingsService: settings_service.Service
|
||||||
|
|
||||||
# Forward declaration
|
|
||||||
proc asyncRequestLatestVersion(self: Service)
|
|
||||||
|
|
||||||
proc delete*(self: Service) =
|
proc delete*(self: Service) =
|
||||||
self.QObject.delete
|
self.QObject.delete
|
||||||
|
|
||||||
|
@ -43,12 +47,6 @@ QtObject:
|
||||||
result.events = events
|
result.events = events
|
||||||
result.threadpool = threadpool
|
result.threadpool = threadpool
|
||||||
|
|
||||||
proc init*(self: Service) =
|
|
||||||
# TODO uncomment this once the latest version calls is fixed
|
|
||||||
# to fix this, you need to re-upload the version and files to IPFS and pin them
|
|
||||||
# self.asyncRequestLatestVersion()
|
|
||||||
discard
|
|
||||||
|
|
||||||
proc getAppVersion*(self: Service): string =
|
proc getAppVersion*(self: Service): string =
|
||||||
return DESKTOP_VERSION
|
return DESKTOP_VERSION
|
||||||
|
|
||||||
|
@ -58,29 +56,19 @@ QtObject:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "Error getting Node version"
|
error "Error getting Node version"
|
||||||
|
|
||||||
proc emitSignal(self: Service, versionJsonObj: JsonNode) =
|
|
||||||
self.events.emit(SIGNAL_VERSION_FETCHED, VersionArgs(version: $versionJsonObj))
|
|
||||||
|
|
||||||
proc asyncRequestLatestVersion(self: Service) =
|
|
||||||
let arg = QObjectTaskArg(
|
|
||||||
tptr: cast[ByteAddress](checkForUpdatesTask),
|
|
||||||
vptr: cast[ByteAddress](self.vptr),
|
|
||||||
slot: "latestVersionSuccess"
|
|
||||||
)
|
|
||||||
self.threadpool.start(arg)
|
|
||||||
|
|
||||||
proc checkForUpdates*(self: Service) =
|
proc checkForUpdates*(self: Service) =
|
||||||
self.asyncRequestLatestVersion()
|
try:
|
||||||
|
discard status_about.checkForUpdates(types.Mainnet, APP_UPDATES_ENS, DESKTOP_VERSION)
|
||||||
|
except Exception as e:
|
||||||
|
error "Error checking for updates", msg=e.msg
|
||||||
|
|
||||||
proc latestVersionSuccess*(self: Service, latestVersionJSON: string) {.slot.} =
|
proc init*(self: Service) =
|
||||||
var latestVersionObj = parseJSON(latestVersionJSON)
|
self.events.on(SignalType.UpdateAvailable.event) do(e: Args):
|
||||||
|
var updateSignal = UpdateAvailableSignal(e)
|
||||||
|
self.events.emit(SIGNAL_VERSION_FETCHED, VersionArgs(
|
||||||
|
available: updateSignal.available,
|
||||||
|
version: updateSignal.version,
|
||||||
|
url: updateSignal.url))
|
||||||
|
|
||||||
var newVersionAvailable = false
|
self.checkForUpdates()
|
||||||
let latestVersion = latestVersionObj{"version"}.getStr()
|
|
||||||
if(latestVersion.len > 0):
|
|
||||||
newVersionAvailable = isNewer(DESKTOP_VERSION, latestVersion)
|
|
||||||
|
|
||||||
latestVersionObj["available"] = newJBool(newVersionAvailable)
|
|
||||||
|
|
||||||
self.emitSignal(latestVersionObj)
|
|
||||||
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
import json, chronicles, httpclient, net, options
|
|
||||||
import strutils
|
|
||||||
import semver
|
|
||||||
|
|
||||||
import ../../../backend/ens as status_ens
|
|
||||||
|
|
||||||
const APP_UPDATES_ENS* = "desktop.status.eth"
|
|
||||||
const CHECK_VERSION_TIMEOUT_MS* = 5000
|
|
||||||
|
|
||||||
type
|
|
||||||
VersionInfo* = object
|
|
||||||
version*: string
|
|
||||||
url*: string
|
|
||||||
|
|
||||||
proc getLatestVersion*(): VersionInfo =
|
|
||||||
let response = status_ens.resourceUrl(chainId=1, username=APP_UPDATES_ENS)
|
|
||||||
let host = response.result{"Host"}.getStr
|
|
||||||
if host == "":
|
|
||||||
raise newException(ValueError, "ENS does not have a content hash")
|
|
||||||
|
|
||||||
let url = "https://" & host & response.result{"Path"}.getStr
|
|
||||||
|
|
||||||
# Read version from folder
|
|
||||||
let secureSSLContext = newContext()
|
|
||||||
let client = newHttpClient(sslContext = secureSSLContext, timeout = CHECK_VERSION_TIMEOUT_MS)
|
|
||||||
result.version = client.getContent(url & "/VERSION").strip()
|
|
||||||
result.url = url
|
|
||||||
|
|
||||||
proc isNewer*(currentVersion, versionToCheck: string): bool =
|
|
||||||
let lastVersion = parseVersion(versionToCheck)
|
|
||||||
let currVersion = parseVersion(currentVersion)
|
|
||||||
result = lastVersion > currVersion
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import json
|
||||||
|
import ./core
|
||||||
|
import response_type
|
||||||
|
|
||||||
|
export response_type
|
||||||
|
|
||||||
|
proc checkForUpdates*(chainId: int, ensAddress: string, currVersion: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
let payload = %* [chainId, ensAddress, currVersion]
|
||||||
|
result = callPrivateRPC("updates_check", payload)
|
|
@ -9,6 +9,20 @@ QtObject {
|
||||||
property var communitiesModuleInst: communitiesModule
|
property var communitiesModuleInst: communitiesModule
|
||||||
property var observedCommunity: communitiesModuleInst.observedCommunity
|
property var observedCommunity: communitiesModuleInst.observedCommunity
|
||||||
|
|
||||||
|
property bool newVersionAvailable: false
|
||||||
|
property string latestVersion
|
||||||
|
property string downloadURL
|
||||||
|
|
||||||
|
function setLatestVersionInfo(newVersionAvailable, latestVersion, downloadURL) {
|
||||||
|
root.newVersionAvailable = newVersionAvailable;
|
||||||
|
root.latestVersion = latestVersion;
|
||||||
|
root.downloadURL = downloadURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetLastVersion(){
|
||||||
|
root.newVersionAvailable = false
|
||||||
|
}
|
||||||
|
|
||||||
property AppSearchStore appSearchStore: AppSearchStore {
|
property AppSearchStore appSearchStore: AppSearchStore {
|
||||||
appSearchModule: root.mainModuleInst.appSearchModule
|
appSearchModule: root.mainModuleInst.appSearchModule
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,21 +43,14 @@ Item {
|
||||||
property RootStore rootStore: RootStore { }
|
property RootStore rootStore: RootStore { }
|
||||||
// set from main.qml
|
// set from main.qml
|
||||||
property var sysPalette
|
property var sysPalette
|
||||||
property var newVersionJSON: {
|
|
||||||
try {
|
|
||||||
return JSON.parse(rootStore.aboutModuleInst.newVersion)
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Error parsing version data", e)
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
signal openContactsPopup()
|
signal openContactsPopup()
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: rootStore.aboutModuleInst
|
target: rootStore.aboutModuleInst
|
||||||
onAppVersionFetched: {
|
onAppVersionFetched: {
|
||||||
if (!newVersionJSON.available) {
|
rootStore.setLatestVersionInfo(available, version, url);
|
||||||
|
if (!available) {
|
||||||
versionUpToDate.show()
|
versionUpToDate.show()
|
||||||
} else {
|
} else {
|
||||||
versionWarning.show()
|
versionWarning.show()
|
||||||
|
@ -81,10 +74,10 @@ Item {
|
||||||
onOpenDownloadModalRequested: {
|
onOpenDownloadModalRequested: {
|
||||||
const downloadPage = downloadPageComponent.createObject(appMain,
|
const downloadPage = downloadPageComponent.createObject(appMain,
|
||||||
{
|
{
|
||||||
newVersionAvailable: newVersionJSON.available,
|
newVersionAvailable: available,
|
||||||
downloadURL: newVersionJSON.url,
|
downloadURL: url,
|
||||||
currentVersion: rootStore.profileSectionStore.getCurrentVersion(),
|
currentVersion: rootStore.profileSectionStore.getCurrentVersion(),
|
||||||
newVersion: newVersionJSON.version
|
newVersion: version
|
||||||
})
|
})
|
||||||
return downloadPage
|
return downloadPage
|
||||||
}
|
}
|
||||||
|
@ -414,13 +407,16 @@ Item {
|
||||||
id: versionWarning
|
id: versionWarning
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 32
|
height: 32
|
||||||
visible: !!newVersionJSON.available
|
visible: appMain.rootStore.newVersionAvailable
|
||||||
color: Style.current.green
|
color: Style.current.green
|
||||||
btnWidth: 100
|
btnWidth: 100
|
||||||
text: qsTr("A new version of Status (%1) is available").arg(newVersionJSON.version)
|
text: qsTr("A new version of Status (%1) is available").arg(appMain.rootStore.latestVersion)
|
||||||
btnText: qsTr("Download")
|
btnText: qsTr("Download")
|
||||||
onClick: function(){
|
onClick: function(){
|
||||||
Global.openDownloadModal()
|
Global.openDownloadModal(appMain.rootStore.newVersionAvailable, appMain.rootStore.latestVersion, appMain.rootStore.downloadURL)
|
||||||
|
}
|
||||||
|
onClosed: {
|
||||||
|
appMain.rootStore.resetLastVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
|
|
|
@ -10,20 +10,23 @@ import "./"
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
height: visible ? 32 : 0
|
height: visible ? 32 : 0
|
||||||
|
implicitHeight: height
|
||||||
color: Style.current.red
|
color: Style.current.red
|
||||||
|
|
||||||
property string text: ""
|
property string text: ""
|
||||||
property string btnText: ""
|
property string btnText: ""
|
||||||
property int btnWidth: 58
|
property int btnWidth: 58
|
||||||
|
property bool closing: false
|
||||||
|
|
||||||
property var onClick: function() {}
|
property var onClick: function() {}
|
||||||
|
|
||||||
|
signal closed()
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
closeBtn.clicked(null)
|
closeBtn.clicked(null)
|
||||||
|
closed();
|
||||||
}
|
}
|
||||||
|
|
||||||
signal closed
|
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Style.current.halfPadding
|
spacing: Style.current.halfPadding
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
@ -89,10 +92,21 @@ Rectangle {
|
||||||
id: closeBtn
|
id: closeBtn
|
||||||
anchors.fill: closeImg
|
anchors.fill: closeImg
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: ParallelAnimation {
|
onClicked: {
|
||||||
PropertyAnimation { target: root; property: "visible"; to: false; }
|
closing = true
|
||||||
PropertyAnimation { target: root; property: "y"; to: -1 * root.height }
|
}
|
||||||
onFinished: root.closed()
|
}
|
||||||
|
|
||||||
|
ParallelAnimation {
|
||||||
|
running: closing
|
||||||
|
PropertyAnimation { target: root; property: "visible"; to: false; }
|
||||||
|
PropertyAnimation { target: root; property: "y"; to: -1 * root.height }
|
||||||
|
onRunningChanged: {
|
||||||
|
if(!running){
|
||||||
|
closing = false;
|
||||||
|
root.y = 0;
|
||||||
|
root.closed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,9 @@ Item {
|
||||||
property alias tooltipUnder: copyToClipboardBtn.tooltipUnder
|
property alias tooltipUnder: copyToClipboardBtn.tooltipUnder
|
||||||
property var store
|
property var store
|
||||||
|
|
||||||
|
property alias textFont: name.font
|
||||||
|
property alias textColor: name.color
|
||||||
|
|
||||||
id: root
|
id: root
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: name.height
|
height: name.height
|
||||||
|
|
|
@ -19,7 +19,8 @@ QtObject {
|
||||||
signal openImagePopup(var image, var contextMenu)
|
signal openImagePopup(var image, var contextMenu)
|
||||||
signal openLinkInBrowser(string link)
|
signal openLinkInBrowser(string link)
|
||||||
signal openChooseBrowserPopup(string link)
|
signal openChooseBrowserPopup(string link)
|
||||||
signal openDownloadModalRequested()
|
signal openPopupRequested(var popupComponent, var params)
|
||||||
|
signal openDownloadModalRequested(bool available, string version, string url)
|
||||||
signal settingsLoaded()
|
signal settingsLoaded()
|
||||||
signal openBackUpSeedPopup()
|
signal openBackUpSeedPopup()
|
||||||
signal openCreateChatView()
|
signal openCreateChatView()
|
||||||
|
@ -40,8 +41,8 @@ QtObject {
|
||||||
return popup;
|
return popup;
|
||||||
}
|
}
|
||||||
|
|
||||||
function openDownloadModal(){
|
function openDownloadModal(available, version, url){
|
||||||
openDownloadModalRequested();
|
openDownloadModalRequested(available, version, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeAppSectionBySectionType(sectionType, subsection = 0) {
|
function changeAppSectionBySectionType(sectionType, subsection = 0) {
|
||||||
|
|
Loading…
Reference in New Issue