forked from Silverfish/proton-bridge
[GODT-274] GUI changes for autoupdates
[GODT-275] Add enable/disable auto updates GUI option Refactor Updater module GODT-805 Changed manual update information bar layout GODT-806, GODT-875 Change update dialogs Refactor InformationBar
This commit is contained in:
committed by
James Houlahan
parent
b7b2297635
commit
98ab794f13
@ -193,7 +193,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
|
|||||||
* GODT-682 Persistent anonymous API cookies for Import-Export.
|
* GODT-682 Persistent anonymous API cookies for Import-Export.
|
||||||
* GODT-357 Use go-message to make a better message parser.
|
* GODT-357 Use go-message to make a better message parser.
|
||||||
* GODT-720 Time measurement of progress for Import-Export.
|
* GODT-720 Time measurement of progress for Import-Export.
|
||||||
* GODT-693 Launcher
|
* GODT-693 Launcher.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
* GODT-511 User agent format changed.
|
* GODT-511 User agent format changed.
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/ProtonMail/proton-bridge/internal/config/settings"
|
"github.com/ProtonMail/proton-bridge/internal/config/settings"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/constants"
|
"github.com/ProtonMail/proton-bridge/internal/constants"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/frontend"
|
"github.com/ProtonMail/proton-bridge/internal/frontend"
|
||||||
|
"github.com/ProtonMail/proton-bridge/internal/frontend/types"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/imap"
|
"github.com/ProtonMail/proton-bridge/internal/imap"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/smtp"
|
"github.com/ProtonMail/proton-bridge/internal/smtp"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/updater"
|
"github.com/ProtonMail/proton-bridge/internal/updater"
|
||||||
@ -119,19 +120,50 @@ func run(b *base.Base, c *cli.Context) error { // nolint[funlen]
|
|||||||
b,
|
b,
|
||||||
)
|
)
|
||||||
|
|
||||||
b.Updater.Watch(
|
// Watch for updates routine
|
||||||
time.Hour,
|
go func() {
|
||||||
func(update updater.VersionInfo) error {
|
ticker := time.NewTicker(time.Hour)
|
||||||
if !b.Settings.GetBool(settings.AutoUpdateKey) {
|
|
||||||
return f.NotifyManualUpdate(update)
|
|
||||||
}
|
|
||||||
|
|
||||||
return b.Updater.InstallUpdate(update)
|
for {
|
||||||
},
|
checkAndHandleUpdate(b.Updater, f, b.Settings.GetBool(settings.AutoUpdateKey))
|
||||||
func(err error) {
|
<-ticker.C
|
||||||
logrus.WithError(err).Error("An error occurred while watching for updates")
|
}
|
||||||
},
|
}()
|
||||||
)
|
|
||||||
|
|
||||||
return f.Loop()
|
return f.Loop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkAndHandleUpdate(u types.Updater, f frontend.Frontend, autoUpdate bool) {
|
||||||
|
version, err := u.Check()
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).Error("An error occurred while checking for updates")
|
||||||
|
f.NotifySilentUpdateError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !u.IsUpdateApplicable(version) {
|
||||||
|
logrus.Debug("No need to update")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.WithField("version", version.Version).Info("An update is available")
|
||||||
|
|
||||||
|
if !autoUpdate {
|
||||||
|
f.NotifyManualUpdate(version, u.CanInstall(version))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !u.CanInstall(version) {
|
||||||
|
logrus.Info("A manual update is required")
|
||||||
|
f.NotifySilentUpdateError(updater.ErrManualUpdateRequired)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := u.InstallUpdate(version); err != nil {
|
||||||
|
logrus.WithError(err).Error("An error occurred while silent installing updates")
|
||||||
|
f.NotifySilentUpdateError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.NotifySilentUpdateInstalled()
|
||||||
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/ProtonMail/proton-bridge/internal/config/settings"
|
"github.com/ProtonMail/proton-bridge/internal/config/settings"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/constants"
|
"github.com/ProtonMail/proton-bridge/internal/constants"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/frontend"
|
"github.com/ProtonMail/proton-bridge/internal/frontend"
|
||||||
|
"github.com/ProtonMail/proton-bridge/internal/frontend/types"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/importexport"
|
"github.com/ProtonMail/proton-bridge/internal/importexport"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/updater"
|
"github.com/ProtonMail/proton-bridge/internal/updater"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -59,25 +60,57 @@ func run(b *base.Base, c *cli.Context) error {
|
|||||||
frontendMode,
|
frontendMode,
|
||||||
b.CrashHandler,
|
b.CrashHandler,
|
||||||
b.Locations,
|
b.Locations,
|
||||||
|
b.Settings,
|
||||||
b.Listener,
|
b.Listener,
|
||||||
b.Updater,
|
b.Updater,
|
||||||
ie,
|
ie,
|
||||||
b,
|
b,
|
||||||
)
|
)
|
||||||
|
|
||||||
b.Updater.Watch(
|
// Watch for updates routine
|
||||||
time.Hour,
|
go func() {
|
||||||
func(update updater.VersionInfo) error {
|
ticker := time.NewTicker(time.Hour)
|
||||||
if !b.Settings.GetBool(settings.AutoUpdateKey) {
|
|
||||||
return f.NotifyManualUpdate(update)
|
|
||||||
}
|
|
||||||
|
|
||||||
return b.Updater.InstallUpdate(update)
|
for {
|
||||||
},
|
checkAndHandleUpdate(b.Updater, f, b.Settings.GetBool(settings.AutoUpdateKey))
|
||||||
func(err error) {
|
<-ticker.C
|
||||||
logrus.WithError(err).Error("An error occurred while watching for updates")
|
}
|
||||||
},
|
}()
|
||||||
)
|
|
||||||
|
|
||||||
return f.Loop()
|
return f.Loop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkAndHandleUpdate(u types.Updater, f frontend.Frontend, autoUpdate bool) {
|
||||||
|
version, err := u.Check()
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).Error("An error occurred while checking for updates")
|
||||||
|
f.NotifySilentUpdateError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !u.IsUpdateApplicable(version) {
|
||||||
|
logrus.Debug("No need to update")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.WithField("version", version.Version).Info("An update is available")
|
||||||
|
|
||||||
|
if !autoUpdate {
|
||||||
|
f.NotifyManualUpdate(version, u.CanInstall(version))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !u.CanInstall(version) {
|
||||||
|
logrus.Info("A manual update is required")
|
||||||
|
f.NotifySilentUpdateError(updater.ErrManualUpdateRequired)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := u.InstallUpdate(version); err != nil {
|
||||||
|
logrus.WithError(err).Error("An error occurred while silent installing updates")
|
||||||
|
f.NotifySilentUpdateError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.NotifySilentUpdateInstalled()
|
||||||
|
}
|
||||||
|
|||||||
@ -72,7 +72,7 @@ func (s *Settings) setDefaultValues() {
|
|||||||
s.setDefault(NextHeartbeatKey, fmt.Sprintf("%v", time.Now().Unix()))
|
s.setDefault(NextHeartbeatKey, fmt.Sprintf("%v", time.Now().Unix()))
|
||||||
s.setDefault(AllowProxyKey, "true")
|
s.setDefault(AllowProxyKey, "true")
|
||||||
s.setDefault(AutostartKey, "true")
|
s.setDefault(AutostartKey, "true")
|
||||||
s.setDefault(AutoUpdateKey, "false")
|
s.setDefault(AutoUpdateKey, "true")
|
||||||
s.setDefault(ReportOutgoingNoEncKey, "false")
|
s.setDefault(ReportOutgoingNoEncKey, "false")
|
||||||
s.setDefault(LastVersionKey, "")
|
s.setDefault(LastVersionKey, "")
|
||||||
s.setDefault(RolloutKey, fmt.Sprintf("%v", rand.Float64()))
|
s.setDefault(RolloutKey, fmt.Sprintf("%v", rand.Float64()))
|
||||||
|
|||||||
@ -226,7 +226,12 @@ WARNING: The CLI is an experimental feature and does not yet cover all functiona
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *frontendCLI) NotifyManualUpdate(update updater.VersionInfo) error {
|
func (f *frontendCLI) NotifyManualUpdate(update updater.VersionInfo, canInstall bool) {
|
||||||
// NOTE: Save the update somewhere so that it can be installed when user chooses "install now".
|
// NOTE: Save the update somewhere so that it can be installed when user chooses "install now".
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
func (f *frontendCLI) NotifySilentUpdateInstalled() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *frontendCLI) NotifySilentUpdateError(err error) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -253,7 +253,12 @@ func (f *frontendCLI) Loop() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *frontendCLI) NotifyManualUpdate(update updater.VersionInfo) error {
|
func (f *frontendCLI) NotifyManualUpdate(update updater.VersionInfo, canInstall bool) {
|
||||||
// NOTE: Save the update somewhere so that it can be installed when user chooses "install now".
|
// NOTE: Save the update somewhere so that it can be installed when user chooses "install now".
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
func (f *frontendCLI) NotifySilentUpdateInstalled() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *frontendCLI) NotifySilentUpdateError(err error) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,9 @@ var (
|
|||||||
// Frontend is an interface to be implemented by each frontend type (cli, gui, html).
|
// Frontend is an interface to be implemented by each frontend type (cli, gui, html).
|
||||||
type Frontend interface {
|
type Frontend interface {
|
||||||
Loop() error
|
Loop() error
|
||||||
NotifyManualUpdate(update updater.VersionInfo) error
|
NotifyManualUpdate(update updater.VersionInfo, canInstall bool)
|
||||||
|
NotifySilentUpdateInstalled()
|
||||||
|
NotifySilentUpdateError(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns initialized frontend based on `frontendType`, which can be `cli` or `qt`.
|
// New returns initialized frontend based on `frontendType`, which can be `cli` or `qt`.
|
||||||
@ -123,8 +125,8 @@ func NewImportExport(
|
|||||||
buildVersion,
|
buildVersion,
|
||||||
frontendType string,
|
frontendType string,
|
||||||
panicHandler types.PanicHandler,
|
panicHandler types.PanicHandler,
|
||||||
|
|
||||||
locations *locations.Locations,
|
locations *locations.Locations,
|
||||||
|
settings *settings.Settings,
|
||||||
eventListener listener.Listener,
|
eventListener listener.Listener,
|
||||||
updater types.Updater,
|
updater types.Updater,
|
||||||
ie *importexport.ImportExport,
|
ie *importexport.ImportExport,
|
||||||
@ -137,6 +139,7 @@ func NewImportExport(
|
|||||||
frontendType,
|
frontendType,
|
||||||
panicHandler,
|
panicHandler,
|
||||||
locations,
|
locations,
|
||||||
|
settings,
|
||||||
eventListener,
|
eventListener,
|
||||||
updater,
|
updater,
|
||||||
ieWrap,
|
ieWrap,
|
||||||
@ -149,8 +152,8 @@ func newIEFrontend(
|
|||||||
buildVersion,
|
buildVersion,
|
||||||
frontendType string,
|
frontendType string,
|
||||||
panicHandler types.PanicHandler,
|
panicHandler types.PanicHandler,
|
||||||
|
|
||||||
locations *locations.Locations,
|
locations *locations.Locations,
|
||||||
|
settings *settings.Settings,
|
||||||
eventListener listener.Listener,
|
eventListener listener.Listener,
|
||||||
updater types.Updater,
|
updater types.Updater,
|
||||||
ie types.ImportExporter,
|
ie types.ImportExporter,
|
||||||
@ -158,8 +161,25 @@ func newIEFrontend(
|
|||||||
) Frontend {
|
) Frontend {
|
||||||
switch frontendType {
|
switch frontendType {
|
||||||
case "cli":
|
case "cli":
|
||||||
return cliie.New(panicHandler, locations, eventListener, updater, ie, restarter)
|
return cliie.New(
|
||||||
|
panicHandler,
|
||||||
|
locations,
|
||||||
|
eventListener,
|
||||||
|
updater,
|
||||||
|
ie,
|
||||||
|
restarter,
|
||||||
|
)
|
||||||
default:
|
default:
|
||||||
return qtie.New(version, buildVersion, panicHandler, locations, eventListener, updater, ie, restarter)
|
return qtie.New(
|
||||||
|
version,
|
||||||
|
buildVersion,
|
||||||
|
panicHandler,
|
||||||
|
locations,
|
||||||
|
settings,
|
||||||
|
eventListener,
|
||||||
|
updater,
|
||||||
|
ie,
|
||||||
|
restarter,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -368,7 +368,7 @@ Dialog {
|
|||||||
if ( state == "quit" ) { Qt.quit () }
|
if ( state == "quit" ) { Qt.quit () }
|
||||||
if ( state == "instance exists" ) { Qt.quit () }
|
if ( state == "instance exists" ) { Qt.quit () }
|
||||||
if ( state == "noKeychain" ) { Qt.quit () }
|
if ( state == "noKeychain" ) { Qt.quit () }
|
||||||
if ( state == "checkUpdates" ) { go.runCheckVersion (true) }
|
if ( state == "checkUpdates" ) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -74,9 +74,7 @@ Item {
|
|||||||
rightIcon.text : Style.fa.chevron_circle_right
|
rightIcon.text : Style.fa.chevron_circle_right
|
||||||
rightIcon.font.pointSize : Style.settings.toggleSize * Style.pt
|
rightIcon.font.pointSize : Style.settings.toggleSize * Style.pt
|
||||||
onClicked: {
|
onClicked: {
|
||||||
dialogGlobal.state="checkUpdates"
|
go.checkForUpdates()
|
||||||
dialogGlobal.show()
|
|
||||||
dialogGlobal.confirmed()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +136,7 @@ Item {
|
|||||||
fontSize : Style.main.fontSize
|
fontSize : Style.main.fontSize
|
||||||
textUnderline : true
|
textUnderline : true
|
||||||
onClicked : {
|
onClicked : {
|
||||||
Qt.openUrlExternally(go.releaseNotesLink)
|
Qt.openUrlExternally(go.updateReleaseNotesLink)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -314,50 +314,7 @@ Window {
|
|||||||
|
|
||||||
DialogUpdate {
|
DialogUpdate {
|
||||||
id: dialogUpdate
|
id: dialogUpdate
|
||||||
|
forceUpdate: root.isOutdateVersion
|
||||||
property string manualLinks : {
|
|
||||||
var out = ""
|
|
||||||
var links = go.downloadLink.split("\n")
|
|
||||||
var l;
|
|
||||||
for (l in links) {
|
|
||||||
out += '<a href="%1">%1</a><br>'.arg(links[l])
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
title: root.isOutdateVersion ?
|
|
||||||
qsTr("%1 is outdated", "title of outdate dialog").arg(go.programTitle):
|
|
||||||
qsTr("%1 update to %2", "title of update dialog").arg(go.programTitle).arg(go.newversion)
|
|
||||||
introductionText: {
|
|
||||||
if (root.isOutdateVersion) {
|
|
||||||
if (go.goos=="linux") {
|
|
||||||
return qsTr('You are using an outdated version of our software.<br>
|
|
||||||
Please download and install the latest version to continue using %1.<br><br>
|
|
||||||
%2',
|
|
||||||
"Message for force-update in Linux").arg(go.programTitle).arg(dialogUpdate.manualLinks)
|
|
||||||
} else {
|
|
||||||
return qsTr('You are using an outdated version of our software.<br>
|
|
||||||
Please download and install the latest version to continue using %1.<br><br>
|
|
||||||
You can continue with the update or download and install the new version manually from<br><br>
|
|
||||||
<a href="%2">%2</a>',
|
|
||||||
"Message for force-update in Win/Mac").arg(go.programTitle).arg(go.landingPage)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (go.goos=="linux") {
|
|
||||||
return qsTr('A new version of Bridge is available.<br>
|
|
||||||
Check <a href="%1">release notes</a> to learn what is new in %2.<br>
|
|
||||||
Use your package manager to update or download and install the new version manually from<br><br>
|
|
||||||
%3',
|
|
||||||
"Message for update in Linux").arg(go.releaseNotesLink).arg(go.newversion).arg(dialogUpdate.manualLinks)
|
|
||||||
} else {
|
|
||||||
return qsTr('A new version of Bridge is available.<br>
|
|
||||||
Check <a href="%1">release notes</a> to learn what is new in %2.<br>
|
|
||||||
You can continue with the update or download and install the new version manually from<br><br>
|
|
||||||
<a href="%3">%3</a>',
|
|
||||||
"Message for update in Win/Mac").arg(go.releaseNotesLink).arg(go.newversion).arg(go.landingPage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -97,6 +97,25 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ButtonIconText {
|
||||||
|
id: autoUpdates
|
||||||
|
text: qsTr("Keep the application up to date", "label for toggle that activates and disables the automatic updates")
|
||||||
|
leftIcon.text : Style.fa.download
|
||||||
|
rightIcon {
|
||||||
|
font.pointSize : Style.settings.toggleSize * Style.pt
|
||||||
|
text : go.isAutoUpdate!=false ? Style.fa.toggle_on : Style.fa.toggle_off
|
||||||
|
color : go.isAutoUpdate!=false ? Style.main.textBlue : Style.main.textDisabled
|
||||||
|
}
|
||||||
|
Accessible.description: (
|
||||||
|
go.isAutoUpdate == false ?
|
||||||
|
qsTr("Enable" , "Click to enable the automatic update of Bridge") :
|
||||||
|
qsTr("Disable" , "Click to disable the automatic update of Bridge")
|
||||||
|
) + " " + text
|
||||||
|
onClicked: {
|
||||||
|
go.toggleAutoUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ButtonIconText {
|
ButtonIconText {
|
||||||
id: advancedSettings
|
id: advancedSettings
|
||||||
property bool isAdvanced : !go.isDefaultPort
|
property bool isAdvanced : !go.isDefaultPort
|
||||||
|
|||||||
@ -54,13 +54,15 @@ Item {
|
|||||||
onWarningFlagsChanged : {
|
onWarningFlagsChanged : {
|
||||||
if (gui.warningFlags==Style.okInfoBar) {
|
if (gui.warningFlags==Style.okInfoBar) {
|
||||||
go.normalSystray()
|
go.normalSystray()
|
||||||
} else {
|
return
|
||||||
if ((gui.warningFlags & Style.errorInfoBar) == Style.errorInfoBar) {
|
|
||||||
go.errorSystray()
|
|
||||||
} else {
|
|
||||||
go.highlightSystray()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((gui.warningFlags & Style.errorInfoBar) == Style.errorInfoBar) {
|
||||||
|
go.errorSystray()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go.highlightSystray()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signals from Go
|
// Signals from Go
|
||||||
@ -112,14 +114,6 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onRunCheckVersion : {
|
|
||||||
gui.openMainWindow(false)
|
|
||||||
go.setUpdateState("upToDate")
|
|
||||||
winMain.dialogGlobal.state="checkUpdates"
|
|
||||||
winMain.dialogGlobal.show()
|
|
||||||
go.isNewVersionAvailable(showMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
onSetUpdateState : {
|
onSetUpdateState : {
|
||||||
// once app is outdated prevent from state change
|
// once app is outdated prevent from state change
|
||||||
if (winMain.updateState != "forceUpdate") {
|
if (winMain.updateState != "forceUpdate") {
|
||||||
@ -134,15 +128,50 @@ Item {
|
|||||||
go.silentBubble(2,qsTr("You have the latest version!", "notification", -1))
|
go.silentBubble(2,qsTr("You have the latest version!", "notification", -1))
|
||||||
}
|
}
|
||||||
|
|
||||||
onNotifyUpdate : {
|
onNotifyManualUpdate: {
|
||||||
|
go.setUpdateState("oldVersion")
|
||||||
|
}
|
||||||
|
|
||||||
|
onNotifyManualUpdateRestartNeeded: {
|
||||||
|
if (!winMain.dialogUpdate.visible) {
|
||||||
|
gui.openMainWindow(true)
|
||||||
|
winMain.dialogUpdate.show()
|
||||||
|
}
|
||||||
|
go.setUpdateState("updateRestart")
|
||||||
|
winMain.dialogUpdate.finished(false)
|
||||||
|
|
||||||
|
// after manual update - just retart immidiatly
|
||||||
|
go.setToRestart()
|
||||||
|
Qt.quit()
|
||||||
|
}
|
||||||
|
|
||||||
|
onNotifyManualUpdateError: {
|
||||||
|
if (!winMain.dialogUpdate.visible) {
|
||||||
|
gui.openMainWindow(true)
|
||||||
|
winMain.dialogUpdate.show()
|
||||||
|
}
|
||||||
|
go.setUpdateState("updateError")
|
||||||
|
winMain.dialogUpdate.finished(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
onNotifyForceUpdate : {
|
||||||
go.setUpdateState("forceUpdate")
|
go.setUpdateState("forceUpdate")
|
||||||
if (!winMain.dialogUpdate.visible) {
|
if (!winMain.dialogUpdate.visible) {
|
||||||
gui.openMainWindow(true)
|
gui.openMainWindow(true)
|
||||||
go.runCheckVersion(false)
|
|
||||||
winMain.dialogUpdate.show()
|
winMain.dialogUpdate.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onNotifySilentUpdateRestartNeeded: {
|
||||||
|
go.setUpdateState("updateRestart")
|
||||||
|
gui.openMainWindow(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
onNotifySilentUpdateError: {
|
||||||
|
go.setUpdateState("updateError")
|
||||||
|
gui.openMainWindow(true)
|
||||||
|
}
|
||||||
|
|
||||||
onNotifyLogout : {
|
onNotifyLogout : {
|
||||||
go.notifyBubble(0, qsTr("Account %1 has been disconnected. Please log in to continue to use the Bridge with this account.").arg(accname) )
|
go.notifyBubble(0, qsTr("Account %1 has been disconnected. Please log in to continue to use the Bridge with this account.").arg(accname) )
|
||||||
}
|
}
|
||||||
@ -229,10 +258,6 @@ Item {
|
|||||||
outgoingNoEncPopup.y = y
|
outgoingNoEncPopup.y = y
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdateFinished : {
|
|
||||||
winMain.dialogUpdate.finished(hasError)
|
|
||||||
}
|
|
||||||
|
|
||||||
onShowCertIssue : {
|
onShowCertIssue : {
|
||||||
winMain.tlsBarState="notOK"
|
winMain.tlsBarState="notOK"
|
||||||
}
|
}
|
||||||
@ -240,14 +265,6 @@ Item {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: checkVersionTimer
|
|
||||||
repeat : true
|
|
||||||
triggeredOnStart: false
|
|
||||||
interval : Style.main.verCheckRepeatTime
|
|
||||||
onTriggered : go.runCheckVersion(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
function openMainWindow(showAndRise) {
|
function openMainWindow(showAndRise) {
|
||||||
// wait and check until font is loaded
|
// wait and check until font is loaded
|
||||||
while(true){
|
while(true){
|
||||||
@ -301,10 +318,8 @@ Item {
|
|||||||
|
|
||||||
// start window
|
// start window
|
||||||
gui.openMainWindow(false)
|
gui.openMainWindow(false)
|
||||||
checkVersionTimer.start()
|
|
||||||
if (go.isShownOnStart) {
|
if (go.isShownOnStart) {
|
||||||
gui.winMain.showAndRise()
|
gui.winMain.showAndRise()
|
||||||
}
|
}
|
||||||
go.runCheckVersion(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ Item {
|
|||||||
property var allMonths : getMonthList(1,12)
|
property var allMonths : getMonthList(1,12)
|
||||||
property var allDays : getDayList(1,31)
|
property var allDays : getDayList(1,31)
|
||||||
|
|
||||||
property var enums : JSON.parse('{"pathOK":1,"pathEmptyPath":2,"pathWrongPath":4,"pathNotADir":8,"pathWrongPermissions":16,"pathDirEmpty":32,"errUnknownError":0,"errEventAPILogout":1,"errUpdateAPI":2,"errUpdateJSON":3,"errUserAuth":4,"errQApplication":18,"errEmailExportFailed":6,"errEmailExportMissing":7,"errNothingToImport":8,"errEmailImportFailed":12,"errDraftImportFailed":13,"errDraftLabelFailed":14,"errEncryptMessageAttachment":15,"errEncryptMessage":16,"errNoInternetWhileImport":17,"errUnlockUser":5,"errSourceMessageNotSelected":19,"errCannotParseMail":5000,"errWrongLoginOrPassword":5001,"errWrongServerPathOrPort":5002,"errWrongAuthMethod":5003,"errIMAPFetchFailed":5004,"errLocalSourceLoadFailed":1000,"errPMLoadFailed":1001,"errRemoteSourceLoadFailed":1002,"errLoadAccountList":1005,"errExit":1006,"errRetry":1007,"errAsk":1008,"errImportFailed":1009,"errCreateLabelFailed":1010,"errCreateFolderFailed":1011,"errUpdateLabelFailed":1012,"errUpdateFolderFailed":1013,"errFillFolderName":1014,"errSelectFolderColor":1015,"errNoInternet":1016,"folderTypeSystem":"system","folderTypeLabel":"label","folderTypeFolder":"folder","folderTypeExternal":"external","progressInit":"init","progressLooping":"looping","statusNoInternet":"noInternet","statusCheckingInternet":"internetCheck","statusNewVersionAvailable":"oldVersion","statusUpToDate":"upToDate","statusForceUpdate":"forceupdate"}')
|
property var enums : JSON.parse('{"pathOK":1,"pathEmptyPath":2,"pathWrongPath":4,"pathNotADir":8,"pathWrongPermissions":16,"pathDirEmpty":32,"errUnknownError":0,"errEventAPILogout":1,"errUpdateAPI":2,"errUpdateJSON":3,"errUserAuth":4,"errQApplication":18,"errEmailExportFailed":6,"errEmailExportMissing":7,"errNothingToImport":8,"errEmailImportFailed":12,"errDraftImportFailed":13,"errDraftLabelFailed":14,"errEncryptMessageAttachment":15,"errEncryptMessage":16,"errNoInternetWhileImport":17,"errUnlockUser":5,"errSourceMessageNotSelected":19,"errCannotParseMail":5000,"errWrongLoginOrPassword":5001,"errWrongServerPathOrPort":5002,"errWrongAuthMethod":5003,"errIMAPFetchFailed":5004,"errLocalSourceLoadFailed":1000,"errPMLoadFailed":1001,"errRemoteSourceLoadFailed":1002,"errLoadAccountList":1005,"errExit":1006,"errRetry":1007,"errAsk":1008,"errImportFailed":1009,"errCreateLabelFailed":1010,"errCreateFolderFailed":1011,"errUpdateLabelFailed":1012,"errUpdateFolderFailed":1013,"errFillFolderName":1014,"errSelectFolderColor":1015,"errNoInternet":1016,"folderTypeSystem":"system","folderTypeLabel":"label","folderTypeFolder":"folder","folderTypeExternal":"external","progressInit":"init","progressLooping":"looping","statusNoInternet":"noInternet","statusCheckingInternet":"internetCheck","statusNewVersionAvailable":"oldVersion","statusUpToDate":"upToDate","statusForceUpdate":"forceUpdate"}')
|
||||||
|
|
||||||
IEStyle{}
|
IEStyle{}
|
||||||
|
|
||||||
@ -103,16 +103,9 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onRunCheckVersion : {
|
|
||||||
go.setUpdateState(gui.enums.statusUpToDate)
|
|
||||||
winMain.dialogGlobal.state=gui.enums.statusCheckingInternet
|
|
||||||
winMain.dialogGlobal.show()
|
|
||||||
go.isNewVersionAvailable(showMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
onSetUpdateState : {
|
onSetUpdateState : {
|
||||||
// once app is outdated prevent from state change
|
// once app is outdated prevent from state change
|
||||||
if (winMain.updateState != gui.enums.statusForceUpdate) {
|
if (winMain.updateState != "forceUpdate") {
|
||||||
winMain.updateState = updateState
|
winMain.updateState = updateState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,13 +206,43 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onNotifyUpdate : {
|
onNotifyManualUpdate: {
|
||||||
go.setUpdateState("forceUpdate")
|
go.setUpdateState("oldVersion")
|
||||||
|
}
|
||||||
|
|
||||||
|
onNotifyManualUpdateRestartNeeded: {
|
||||||
if (!winMain.dialogUpdate.visible) {
|
if (!winMain.dialogUpdate.visible) {
|
||||||
gui.openMainWindow(true)
|
|
||||||
go.runCheckVersion(false)
|
|
||||||
winMain.dialogUpdate.show()
|
winMain.dialogUpdate.show()
|
||||||
}
|
}
|
||||||
|
go.setUpdateState("updateRestart")
|
||||||
|
winMain.dialogUpdate.finished(false)
|
||||||
|
|
||||||
|
// after manual update - just retart immidiatly
|
||||||
|
go.setToRestart()
|
||||||
|
Qt.quit()
|
||||||
|
}
|
||||||
|
|
||||||
|
onNotifyManualUpdateError: {
|
||||||
|
if (!winMain.dialogUpdate.visible) {
|
||||||
|
winMain.dialogUpdate.show()
|
||||||
|
}
|
||||||
|
go.setUpdateState("updateError")
|
||||||
|
winMain.dialogUpdate.finished(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
onNotifyForceUpdate : {
|
||||||
|
go.setUpdateState("forceUpdate")
|
||||||
|
if (!winMain.dialogUpdate.visible) {
|
||||||
|
winMain.dialogUpdate.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onNotifySilentUpdateRestartNeeded: {
|
||||||
|
go.setUpdateState("updateRestart")
|
||||||
|
}
|
||||||
|
|
||||||
|
onNotifySilentUpdateError: {
|
||||||
|
go.setUpdateState("updateError")
|
||||||
}
|
}
|
||||||
|
|
||||||
onNotifyLogout : {
|
onNotifyLogout : {
|
||||||
@ -382,14 +405,6 @@ Item {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: checkVersionTimer
|
|
||||||
repeat : true
|
|
||||||
triggeredOnStart: false
|
|
||||||
interval : Style.main.verCheckRepeatTime
|
|
||||||
onTriggered : go.runCheckVersion(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
property string areYouSureYouWantToQuit : qsTr("There are incomplete processes - some items are not yet transferred. Do you really want to stop and quit?")
|
property string areYouSureYouWantToQuit : qsTr("There are incomplete processes - some items are not yet transferred. Do you really want to stop and quit?")
|
||||||
// On start
|
// On start
|
||||||
Component.onCompleted : {
|
Component.onCompleted : {
|
||||||
@ -402,9 +417,6 @@ Item {
|
|||||||
go.bugNotSent = qsTr("Unable to submit bug report." , "notification", -1)
|
go.bugNotSent = qsTr("Unable to submit bug report." , "notification", -1)
|
||||||
go.bugReportSent = qsTr("Bug report successfully sent." , "notification", -1)
|
go.bugReportSent = qsTr("Bug report successfully sent." , "notification", -1)
|
||||||
|
|
||||||
go.runCheckVersion(false)
|
|
||||||
checkVersionTimer.start()
|
|
||||||
|
|
||||||
gui.allMonths = getMonthList(1,12)
|
gui.allMonths = getMonthList(1,12)
|
||||||
gui.allMonthsChanged()
|
gui.allMonthsChanged()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -341,7 +341,7 @@ Dialog {
|
|||||||
if ( state == "toggleAutoStart" ) { go.toggleAutoStart () }
|
if ( state == "toggleAutoStart" ) { go.toggleAutoStart () }
|
||||||
if ( state == "quit" ) { Qt.quit () }
|
if ( state == "quit" ) { Qt.quit () }
|
||||||
if ( state == "instance exists" ) { Qt.quit () }
|
if ( state == "instance exists" ) { Qt.quit () }
|
||||||
if ( state == "checkUpdates" ) { go.runCheckVersion (true) }
|
if ( state == "checkUpdates" ) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -55,9 +55,7 @@ Item {
|
|||||||
rightIcon.text : Style.fa.chevron_circle_right
|
rightIcon.text : Style.fa.chevron_circle_right
|
||||||
rightIcon.font.pointSize : Style.settings.toggleSize * Style.pt
|
rightIcon.font.pointSize : Style.settings.toggleSize * Style.pt
|
||||||
onClicked: {
|
onClicked: {
|
||||||
dialogGlobal.state="checkUpdates"
|
go.checkForUpdates()
|
||||||
dialogGlobal.show()
|
|
||||||
dialogGlobal.confirmed()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +128,7 @@ Item {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked : {
|
onClicked : {
|
||||||
Qt.openUrlExternally(go.releaseNotesLink)
|
Qt.openUrlExternally(go.updateReleaseNotesLink)
|
||||||
}
|
}
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ Window {
|
|||||||
minimumWidth : Style.main.width
|
minimumWidth : Style.main.width
|
||||||
minimumHeight : Style.main.height
|
minimumHeight : Style.main.height
|
||||||
|
|
||||||
property bool isOutdateVersion : root.updateState == "forceUpgrade"
|
property bool isOutdateVersion : root.updateState == "forceUpdate"
|
||||||
|
|
||||||
property bool activeContent :
|
property bool activeContent :
|
||||||
!dialogAddUser .visible &&
|
!dialogAddUser .visible &&
|
||||||
@ -252,40 +252,7 @@ Window {
|
|||||||
|
|
||||||
DialogUpdate {
|
DialogUpdate {
|
||||||
id: dialogUpdate
|
id: dialogUpdate
|
||||||
|
forceUpdate: root.isOutdateVersion
|
||||||
title: root.isOutdateVersion ?
|
|
||||||
qsTr("%1 is outdated", "title of outdate dialog").arg(go.programTitle):
|
|
||||||
qsTr("%1 update to %2", "title of update dialog").arg(go.programTitle).arg(go.newversion)
|
|
||||||
introductionText: {
|
|
||||||
if (root.isOutdateVersion) {
|
|
||||||
if (go.goos=="linux") {
|
|
||||||
return qsTr('You are using an outdated version of our software.<br>
|
|
||||||
Please dowload and install the latest version to continue using %1.<br><br>
|
|
||||||
<a href="%2">%2</a>',
|
|
||||||
"Message for force-update in Linux").arg(go.programTitle).arg(go.landingPage)
|
|
||||||
} else {
|
|
||||||
return qsTr('You are using an outdated version of our software.<br>
|
|
||||||
Please dowload and install the latest version to continue using %1.<br><br>
|
|
||||||
You can continue with update or download and install the new version manually from<br><br>
|
|
||||||
<a href="%2">%2</a>',
|
|
||||||
"Message for force-update in Win/Mac").arg(go.programTitle).arg(go.landingPage)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (go.goos=="linux") {
|
|
||||||
return qsTr('A new version of %1 is available.<br>
|
|
||||||
Check <a href="%2">release notes</a> to learn what is new in %3.<br>
|
|
||||||
Use your package manager to update or download and install new the version manually from<br><br>
|
|
||||||
<a href="%4">%4</a>',
|
|
||||||
"Message for update in Linux").arg(go.programTitle).arg(go.releaseNotesLink).arg(go.newversion).arg(go.landingPage)
|
|
||||||
} else {
|
|
||||||
return qsTr('A new version of %1 is available.<br>
|
|
||||||
Check <a href="%2">release notes</a> to learn what is new in %3.<br>
|
|
||||||
You can continue with update or download and install new the version manually from<br><br>
|
|
||||||
<a href="%4">%4</a>',
|
|
||||||
"Message for update in Win/Mac").arg(go.programTitle).arg(go.releaseNotesLink).arg(go.newversion).arg(go.landingPage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -75,6 +75,25 @@ Item {
|
|||||||
onClicked: bugreportWin.show()
|
onClicked: bugreportWin.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ButtonIconText {
|
||||||
|
id: autoUpdates
|
||||||
|
text: qsTr("Keep the application up to date", "label for toggle that activates and disables the automatic updates")
|
||||||
|
leftIcon.text : Style.fa.download
|
||||||
|
rightIcon {
|
||||||
|
font.pointSize : Style.settings.toggleSize * Style.pt
|
||||||
|
text : go.isAutoUpdate!=false ? Style.fa.toggle_on : Style.fa.toggle_off
|
||||||
|
color : go.isAutoUpdate!=false ? Style.main.textBlue : Style.main.textDisabled
|
||||||
|
}
|
||||||
|
Accessible.description: (
|
||||||
|
go.isAutoUpdate == false ?
|
||||||
|
qsTr("Enable" , "Click to enable the automatic update of Bridge") :
|
||||||
|
qsTr("Disable" , "Click to disable the automatic update of Bridge")
|
||||||
|
) + " " + text
|
||||||
|
onClicked: {
|
||||||
|
go.toggleAutoUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
ButtonIconText {
|
ButtonIconText {
|
||||||
|
|||||||
@ -25,16 +25,17 @@ import ProtonUI 1.0
|
|||||||
Dialog {
|
Dialog {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
title: "Bridge update "+go.newversion
|
|
||||||
|
|
||||||
property alias introductionText : introduction.text
|
|
||||||
property bool hasError : false
|
property bool hasError : false
|
||||||
|
property bool forceUpdate : false
|
||||||
|
|
||||||
signal cancel()
|
signal cancel()
|
||||||
signal okay()
|
signal okay()
|
||||||
|
|
||||||
|
title: forceUpdate ?
|
||||||
|
qsTr("Update %1 now", "title of force update dialog").arg(go.programTitle):
|
||||||
|
qsTr("Update to %1 %2", "title of normal update dialog").arg(go.programTitle).arg(go.updateVersion)
|
||||||
|
|
||||||
isDialogBusy: currentIndex==1
|
isDialogBusy: currentIndex==1 || forceUpdate
|
||||||
|
|
||||||
Rectangle { // 0: Release notes and confirm
|
Rectangle { // 0: Release notes and confirm
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@ -51,18 +52,45 @@ Dialog {
|
|||||||
color: Style.dialog.text
|
color: Style.dialog.text
|
||||||
linkColor: Style.dialog.textBlue
|
linkColor: Style.dialog.textBlue
|
||||||
font {
|
font {
|
||||||
pointSize: 0.8 * Style.dialog.fontSize * Style.pt
|
pointSize: Style.dialog.fontSize * Style.pt
|
||||||
}
|
}
|
||||||
width: 2*root.width/3
|
width: 2*root.width/3
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
|
|
||||||
// customize message per application
|
text: {
|
||||||
text: ' <a href="%1">Release notes</a><br> New version %2<br> <br><br> <a href="%3">%3</a>'
|
if (forceUpdate) {
|
||||||
|
if (go.updateCanInstall) {
|
||||||
|
return qsTr('You need to update this app to continue using it.<br>
|
||||||
|
Update now or manually download the most recent version here:<br>
|
||||||
|
<a href="%1">%1</a><br>
|
||||||
|
<a href="https://protonmail.com/support/knowledge-base/update-required/">Learn why</a> you need to update',
|
||||||
|
"Message for force-update").arg(go.updateLandingPage)
|
||||||
|
} else {
|
||||||
|
return qsTr('You need to update this app to continue using it.<br>
|
||||||
|
Download the most recent version here:<br>
|
||||||
|
<a href="%1">%1</a><br>
|
||||||
|
<a href="https://protonmail.com/support/knowledge-base/update-required/">Learn why</a> you need to update',
|
||||||
|
"Message for force-update").arg(go.updateLandingPage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (go.updateCanInstall) {
|
||||||
|
return qsTr('Update to the newest version or download it from:<br>
|
||||||
|
<a href="%1">%1</a><br>
|
||||||
|
<a href="%2">View release notes</a>',
|
||||||
|
"Message for manual update").arg(go.updateLandingPage).arg(go.updateReleaseNotesLink)
|
||||||
|
} else {
|
||||||
|
return qsTr('Update to the newest version from:<br>
|
||||||
|
<a href="%1">%1</a><br>
|
||||||
|
<a href="%2">View release notes</a>',
|
||||||
|
"Message for manual update").arg(go.updateLandingPage).arg(go.updateReleaseNotesLink)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
onLinkActivated : {
|
onLinkActivated : {
|
||||||
console.log("clicked link:", link)
|
console.log("clicked link:", link)
|
||||||
root.hide()
|
|
||||||
Qt.openUrlExternally(link)
|
Qt.openUrlExternally(link)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,21 +101,30 @@ Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckBoxLabel {
|
||||||
|
id: autoUpdate
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: qsTr("Automatically update in the future", "Checkbox label for using autoupdates later on")
|
||||||
|
checked: go.isAutoUpdate
|
||||||
|
onToggled: go.toggleAutoUpdate()
|
||||||
|
visible: !root.forceUpdate
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
spacing: Style.dialog.spacing
|
spacing: Style.dialog.spacing
|
||||||
|
|
||||||
ButtonRounded {
|
ButtonRounded {
|
||||||
fa_icon: Style.fa.times
|
fa_icon: Style.fa.times
|
||||||
text: (go.goos=="linux" ? qsTr("Okay") : qsTr("Cancel"))
|
text: root.forceUpdate ? qsTr("Quit") : qsTr("Cancel")
|
||||||
color_main: Style.dialog.text
|
color_main: Style.dialog.text
|
||||||
onClicked: root.cancel()
|
onClicked: root.forceUpdate ? Qt.quit() : root.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonRounded {
|
ButtonRounded {
|
||||||
fa_icon: Style.fa.check
|
fa_icon: Style.fa.check
|
||||||
text: qsTr("Update")
|
text: qsTr("Update")
|
||||||
visible: go.goos!="linux"
|
visible: go.updateCanInstall
|
||||||
color_main: Style.dialog.text
|
color_main: Style.dialog.text
|
||||||
color_minor: Style.main.textBlue
|
color_minor: Style.main.textBlue
|
||||||
isOpaque: true
|
isOpaque: true
|
||||||
@ -97,7 +134,7 @@ Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle { // 0: Check / download / unpack / prepare
|
Rectangle { // 1: Installing update
|
||||||
id: updateStatus
|
id: updateStatus
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
@ -116,35 +153,29 @@ Dialog {
|
|||||||
width: 2*root.width/3
|
width: 2*root.width/3
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
text: {
|
text: qsTr("Updating...")
|
||||||
switch (go.progressDescription) {
|
|
||||||
case "1": return qsTr("Checking the current version.")
|
|
||||||
case "2": return qsTr("Downloading the update files.")
|
|
||||||
case "3": return qsTr("Verifying the update files.")
|
|
||||||
case "4": return qsTr("Unpacking the update files.")
|
|
||||||
case "5": return qsTr("Starting the update.")
|
|
||||||
case "6": return qsTr("Quitting the application.")
|
|
||||||
default: return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressBar {
|
ProgressBar {
|
||||||
id: progressbar
|
id: updateProgressBar
|
||||||
implicitWidth : 2*updateStatus.width/3
|
width: 2*updateStatus.width/3
|
||||||
implicitHeight : Style.exporting.rowHeight
|
height: Style.exporting.rowHeight
|
||||||
visible: go.progress!=0 // hack hide animation when clearing out progress bar
|
//implicitWidth : 2*updateStatus.width/3
|
||||||
value: go.progress
|
//implicitHeight : Style.exporting.rowHeight
|
||||||
property int current: go.total * go.progress
|
indeterminate: true
|
||||||
property bool isFinished: finishedPartBar.width == progressbar.width
|
//value: 0.5
|
||||||
|
//property int current: go.total * go.progress
|
||||||
|
//property bool isFinished: finishedPartBar.width == progressbar.width
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
radius : Style.exporting.boxRadius
|
radius : Style.exporting.boxRadius
|
||||||
color : Style.exporting.progressBackground
|
color : Style.exporting.progressBackground
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: Item {
|
||||||
|
clip: true
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: finishedPartBar
|
id: progressIndicator
|
||||||
width : parent.width * progressbar.visualPosition
|
width : updateProgressBar.indeterminate ? 50 : parent.width * updateProgressBar.visualPosition
|
||||||
height : parent.height
|
height : parent.height
|
||||||
radius : Style.exporting.boxRadius
|
radius : Style.exporting.boxRadius
|
||||||
gradient : Gradient {
|
gradient : Gradient {
|
||||||
@ -156,6 +187,27 @@ Dialog {
|
|||||||
Behavior on width {
|
Behavior on width {
|
||||||
NumberAnimation { duration:300; easing.type: Easing.InOutQuad }
|
NumberAnimation { duration:300; easing.type: Easing.InOutQuad }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
running: updateProgressBar.visible && updateProgressBar.indeterminate
|
||||||
|
loops: Animation.Infinite
|
||||||
|
|
||||||
|
SmoothedAnimation {
|
||||||
|
target: progressIndicator
|
||||||
|
property: "x"
|
||||||
|
from: 0
|
||||||
|
to: updateProgressBar.width - progressIndicator.width
|
||||||
|
duration: 2000
|
||||||
|
}
|
||||||
|
|
||||||
|
SmoothedAnimation {
|
||||||
|
target: progressIndicator
|
||||||
|
property: "x"
|
||||||
|
from: updateProgressBar.width - progressIndicator.width
|
||||||
|
to: 0
|
||||||
|
duration: 2000
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@ -170,7 +222,7 @@ Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle { // 1: Something went wrong / All ok, closing bridge
|
Rectangle { // 2: Something went wrong / All ok, closing bridge
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
color: Style.transparent
|
color: Style.transparent
|
||||||
@ -188,8 +240,8 @@ Dialog {
|
|||||||
width: 2*root.width/3
|
width: 2*root.width/3
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
text: !root.hasError ? qsTr('Application will quit now to finish the update.', "message after successful update") :
|
text: !root.hasError ? qsTr('%1 will restart now to finish the update.', "message after successful update").arg(go.programTitle) :
|
||||||
qsTr('<b>The update procedure was not successful!</b><br>Please follow the download link and update manually. <br><br><a href="%1">%1</a>').arg(go.downloadLink)
|
qsTr('<b>The update procedure was not successful!</b><br>Please follow the download link and update manually. <br><br><a href="%1">%1</a>').arg(go.updateLandingPage)
|
||||||
|
|
||||||
onLinkActivated : {
|
onLinkActivated : {
|
||||||
console.log("clicked link:", link)
|
console.log("clicked link:", link)
|
||||||
@ -220,7 +272,7 @@ Dialog {
|
|||||||
|
|
||||||
function finished(hasError) {
|
function finished(hasError) {
|
||||||
root.hasError = hasError
|
root.hasError = hasError
|
||||||
root.incrementCurrentIndex()
|
root.currentIndex = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
onShow: {
|
onShow: {
|
||||||
@ -234,9 +286,10 @@ Dialog {
|
|||||||
onOkay: {
|
onOkay: {
|
||||||
switch (root.currentIndex) {
|
switch (root.currentIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
go.startUpdate()
|
go.startManualUpdate()
|
||||||
|
root.currentIndex = 1
|
||||||
|
break
|
||||||
}
|
}
|
||||||
root.incrementCurrentIndex()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onCancel: {
|
onCancel: {
|
||||||
|
|||||||
@ -53,6 +53,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
id: messageRow
|
||||||
anchors.centerIn: root
|
anchors.centerIn: root
|
||||||
visible: root.isVisible
|
visible: root.isVisible
|
||||||
spacing: Style.main.leftMarginButton
|
spacing: Style.main.leftMarginButton
|
||||||
@ -63,80 +64,74 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClickIconText {
|
ClickIconText {
|
||||||
|
id: linkText
|
||||||
anchors.verticalCenter : message.verticalCenter
|
anchors.verticalCenter : message.verticalCenter
|
||||||
text : "("+go.newversion+" " + qsTr("release notes", "display the release notes from the new version")+")"
|
|
||||||
visible : root.state=="oldVersion"
|
|
||||||
iconText : ""
|
iconText : ""
|
||||||
onClicked : {
|
|
||||||
Qt.openUrlExternally(go.releaseNotesLink)
|
|
||||||
}
|
|
||||||
fontSize : root.fontSize
|
fontSize : root.fontSize
|
||||||
}
|
}
|
||||||
|
|
||||||
ClickIconText {
|
ClickIconText {
|
||||||
|
id: actionText
|
||||||
anchors.verticalCenter : message.verticalCenter
|
anchors.verticalCenter : message.verticalCenter
|
||||||
text : root.state=="oldVersion" || root.state == "forceUpdate" ?
|
|
||||||
qsTr("Update", "click to update to a new version when one is available") :
|
|
||||||
qsTr("Retry now", "click to try to connect to the internet when the app is disconnected from the internet")
|
|
||||||
visible : root.state!="internetCheck"
|
|
||||||
iconText : ""
|
iconText : ""
|
||||||
onClicked : {
|
|
||||||
if (root.state=="oldVersion" || root.state=="forceUpdate" ) {
|
|
||||||
winMain.dialogUpdate.show()
|
|
||||||
} else {
|
|
||||||
go.checkInternet()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fontSize : root.fontSize
|
fontSize : root.fontSize
|
||||||
textUnderline: true
|
textUnderline: true
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
|
id: separatorText
|
||||||
anchors.baseline : message.baseline
|
anchors.baseline : message.baseline
|
||||||
color: Style.main.text
|
color: Style.main.text
|
||||||
font {
|
font {
|
||||||
pointSize : root.fontSize * Style.pt
|
pointSize : root.fontSize * Style.pt
|
||||||
bold : true
|
bold : true
|
||||||
}
|
}
|
||||||
visible: root.state=="oldVersion" || root.state=="noInternet"
|
|
||||||
text : "|"
|
|
||||||
}
|
}
|
||||||
ClickIconText {
|
ClickIconText {
|
||||||
|
id: action2Text
|
||||||
anchors.verticalCenter : message.verticalCenter
|
anchors.verticalCenter : message.verticalCenter
|
||||||
iconText : ""
|
iconText : ""
|
||||||
text : root.state == "noInternet" ?
|
|
||||||
qsTr("Troubleshoot", "Show modal screen with additional tips for troubleshooting connection issues") :
|
|
||||||
qsTr("Remind me later", "Do not install new version and dismiss a notification")
|
|
||||||
visible : root.state=="oldVersion" || root.state=="noInternet"
|
|
||||||
onClicked : {
|
|
||||||
if (root.state == "oldVersion") {
|
|
||||||
root.state = "upToDate"
|
|
||||||
}
|
|
||||||
if (root.state == "noInternet") {
|
|
||||||
dialogConnectionTroubleshoot.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fontSize : root.fontSize
|
fontSize : root.fontSize
|
||||||
textUnderline: true
|
textUnderline: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClickIconText {
|
||||||
|
id: closeSign
|
||||||
|
anchors.verticalCenter : messageRow.verticalCenter
|
||||||
|
anchors.right: root.right
|
||||||
|
iconText : Style.fa.close
|
||||||
|
fontSize : root.fontSize
|
||||||
|
textUnderline: true
|
||||||
|
}
|
||||||
|
|
||||||
onStateChanged : {
|
onStateChanged : {
|
||||||
switch (root.state) {
|
switch (root.state) {
|
||||||
case "forceUpdate" :
|
case "internetCheck":
|
||||||
gui.warningFlags |= Style.errorInfoBar
|
break;
|
||||||
break;
|
|
||||||
case "upToDate" :
|
|
||||||
gui.warningFlags &= ~Style.warnInfoBar
|
|
||||||
iTry = 0
|
|
||||||
secLeft=checkInterval[iTry]
|
|
||||||
break;
|
|
||||||
case "noInternet" :
|
case "noInternet" :
|
||||||
gui.warningFlags |= Style.warnInfoBar
|
gui.warningFlags |= Style.warnInfoBar
|
||||||
retryInternet.start()
|
retryInternet.start()
|
||||||
secLeft=checkInterval[iTry]
|
secLeft=checkInterval[iTry]
|
||||||
break;
|
break;
|
||||||
|
case "oldVersion":
|
||||||
|
gui.warningFlags |= Style.warnInfoBar
|
||||||
|
break;
|
||||||
|
case "forceUpdate":
|
||||||
|
gui.warningFlags |= Style.errorInfoBar
|
||||||
|
break;
|
||||||
|
case "upToDate":
|
||||||
|
gui.warningFlags &= ~Style.warnInfoBar
|
||||||
|
iTry = 0
|
||||||
|
secLeft=checkInterval[iTry]
|
||||||
|
break;
|
||||||
|
case "updateRestart":
|
||||||
|
gui.warningFlags |= Style.warnInfoBar
|
||||||
|
break;
|
||||||
|
case "updateError":
|
||||||
|
gui.warningFlags |= Style.errorInfoBar
|
||||||
|
break;
|
||||||
default :
|
default :
|
||||||
gui.warningFlags |= Style.warnInfoBar
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root.state!="noInternet") {
|
if (root.state!="noInternet") {
|
||||||
@ -172,6 +167,26 @@ Rectangle {
|
|||||||
color: Style.main.background
|
color: Style.main.background
|
||||||
text: qsTr("Checking connection. Please wait...", "displayed after user retries internet connection")
|
text: qsTr("Checking connection. Please wait...", "displayed after user retries internet connection")
|
||||||
}
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: linkText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: actionText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: separatorText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: action2Text
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: closeSign
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "noInternet"
|
name: "noInternet"
|
||||||
@ -186,6 +201,35 @@ Rectangle {
|
|||||||
color: Style.main.line
|
color: Style.main.line
|
||||||
text: qsTr("Cannot contact server. Retrying in ", "displayed when the app is disconnected from the internet or server has problems")+timeToRetry()+"."
|
text: qsTr("Cannot contact server. Retrying in ", "displayed when the app is disconnected from the internet or server has problems")+timeToRetry()+"."
|
||||||
}
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: linkText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: actionText
|
||||||
|
visible: true
|
||||||
|
text: qsTr("Retry now", "click to try to connect to the internet when the app is disconnected from the internet")
|
||||||
|
onClicked: {
|
||||||
|
go.checkInternet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: separatorText
|
||||||
|
visible: true
|
||||||
|
text: "|"
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: action2Text
|
||||||
|
visible: true
|
||||||
|
text: qsTr("Troubleshoot", "Show modal screen with additional tips for troubleshooting connection issues")
|
||||||
|
onClicked: {
|
||||||
|
dialogConnectionTroubleshoot.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: closeSign
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "oldVersion"
|
name: "oldVersion"
|
||||||
@ -198,7 +242,38 @@ Rectangle {
|
|||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: message
|
target: message
|
||||||
color: Style.main.background
|
color: Style.main.background
|
||||||
text: qsTr("An update is available.", "displayed in a notification when an app update is available")
|
text: qsTr("Update available", "displayed in a notification when an app update is available")
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: linkText
|
||||||
|
visible: true
|
||||||
|
text: "(" + qsTr("view release notes", "display the release notes from the new version") + ")"
|
||||||
|
onClicked: {
|
||||||
|
Qt.openUrlExternally(go.updateReleaseNotesLink)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: actionText
|
||||||
|
visible: true
|
||||||
|
text: qsTr("Update", "click to update to a new version when one is available")
|
||||||
|
onClicked: {
|
||||||
|
winMain.dialogUpdate.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: separatorText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: action2Text
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: closeSign
|
||||||
|
visible: true
|
||||||
|
onClicked: {
|
||||||
|
root.state = "upToDate"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
@ -214,6 +289,30 @@ Rectangle {
|
|||||||
color: Style.main.line
|
color: Style.main.line
|
||||||
text: qsTr("%1 is outdated.", "displayed in a notification when app is outdated").arg(go.programTitle)
|
text: qsTr("%1 is outdated.", "displayed in a notification when app is outdated").arg(go.programTitle)
|
||||||
}
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: linkText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: actionText
|
||||||
|
visible: true
|
||||||
|
text: qsTr("Update", "click to update to a new version when one is available")
|
||||||
|
onClicked: {
|
||||||
|
winMain.dialogUpdate.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: separatorText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: action2Text
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: closeSign
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "upToDate"
|
name: "upToDate"
|
||||||
@ -228,6 +327,103 @@ Rectangle {
|
|||||||
color: Style.main.background
|
color: Style.main.background
|
||||||
text: ""
|
text: ""
|
||||||
}
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: linkText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: actionText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: separatorText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: action2Text
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: closeSign
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "updateRestart"
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
height: 2* Style.main.fontSize
|
||||||
|
isVisible: true
|
||||||
|
color: Style.main.textBlue
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: message
|
||||||
|
color: Style.main.background
|
||||||
|
text: qsTr("%1 update is ready", "displayed in a notification when an app update is installed and restart is needed").arg(go.programTitle)
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: linkText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: actionText
|
||||||
|
visible: true
|
||||||
|
text: qsTr("Restart now", "click to restart application as new version was installed")
|
||||||
|
onClicked: {
|
||||||
|
go.setToRestart()
|
||||||
|
Qt.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: separatorText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: action2Text
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: closeSign
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "updateError"
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
height: 2* Style.main.fontSize
|
||||||
|
isVisible: true
|
||||||
|
color: Style.main.textRed
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: message
|
||||||
|
color: Style.main.line
|
||||||
|
text: qsTr("Sorry, %1 couldn't update.", "displayed in a notification when app failed to autoupdate").arg(go.programTitle)
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: linkText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: actionText
|
||||||
|
visible: true
|
||||||
|
text: qsTr("Please update manually", "click to open download page to update manally")
|
||||||
|
onClicked: {
|
||||||
|
Qt.openUrlExternally(go.updateLandingPage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: separatorText
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: action2Text
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: closeSign
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,7 +59,6 @@ QtObject {
|
|||||||
property real fontSize : 12 * px
|
property real fontSize : 12 * px
|
||||||
property real iconSize : 15 * px
|
property real iconSize : 15 * px
|
||||||
property real leftMarginButton : 9 * px
|
property real leftMarginButton : 9 * px
|
||||||
property real verCheckRepeatTime : 15*60*60*1000 // milliseconds
|
|
||||||
property real topMargin : fontSize
|
property real topMargin : fontSize
|
||||||
property real bottomMargin : fontSize
|
property real bottomMargin : fontSize
|
||||||
property real border : 1 * px
|
property real border : 1 * px
|
||||||
|
|||||||
@ -108,9 +108,14 @@ Window {
|
|||||||
ListElement { title: "Logout bridge" }
|
ListElement { title: "Logout bridge" }
|
||||||
ListElement { title: "Internet on" }
|
ListElement { title: "Internet on" }
|
||||||
ListElement { title: "Internet off" }
|
ListElement { title: "Internet off" }
|
||||||
ListElement { title: "NeedUpdate" }
|
|
||||||
ListElement { title: "UpToDate" }
|
ListElement { title: "UpToDate" }
|
||||||
ListElement { title: "ForceUpdate" }
|
ListElement { title: "NotifyManualUpdate(CanInstall)" }
|
||||||
|
ListElement { title: "NotifyManualUpdate(CantInstall)" }
|
||||||
|
ListElement { title: "NotifyManualUpdateRestart" }
|
||||||
|
ListElement { title: "NotifyManualUpdateError" }
|
||||||
|
ListElement { title: "ForceUpdate" }
|
||||||
|
ListElement { title: "NotifySilentUpdateRestartNeeded" }
|
||||||
|
ListElement { title: "NotifySilentUpdateError" }
|
||||||
ListElement { title: "Linux" }
|
ListElement { title: "Linux" }
|
||||||
ListElement { title: "Windows" }
|
ListElement { title: "Windows" }
|
||||||
ListElement { title: "Macos" }
|
ListElement { title: "Macos" }
|
||||||
@ -196,12 +201,29 @@ Window {
|
|||||||
case "UpToDate" :
|
case "UpToDate" :
|
||||||
testroot.newVersion = false
|
testroot.newVersion = false
|
||||||
break;
|
break;
|
||||||
case "NeedUpdate" :
|
case "NotifyManualUpdate(CanInstall)" :
|
||||||
testroot.newVersion = true
|
go.notifyManualUpdate()
|
||||||
break;
|
go.updateCanInstall = true
|
||||||
|
break;
|
||||||
|
case "NotifyManualUpdate(CantInstall)" :
|
||||||
|
go.notifyManualUpdate()
|
||||||
|
go.updateCanInstall = false
|
||||||
|
break;
|
||||||
|
case "NotifyManualUpdateRestart":
|
||||||
|
go.notifyManualUpdateRestartNeeded()
|
||||||
|
break;
|
||||||
|
case "NotifyManualUpdateError":
|
||||||
|
go.notifyManualUpdateError()
|
||||||
|
break;
|
||||||
case "ForceUpdate" :
|
case "ForceUpdate" :
|
||||||
go.notifyUpdate()
|
go.notifyForceUpdate()
|
||||||
break;
|
break;
|
||||||
|
case "NotifySilentUpdateRestartNeeded" :
|
||||||
|
go.notifySilentUpdateRestartNeeded()
|
||||||
|
break;
|
||||||
|
case "NotifySilentUpdateError" :
|
||||||
|
go.notifySilentUpdateError()
|
||||||
|
break;
|
||||||
case "SendAlertPopup" :
|
case "SendAlertPopup" :
|
||||||
go.showOutgoingNoEncPopup("Alert sending unencrypted!")
|
go.showOutgoingNoEncPopup("Alert sending unencrypted!")
|
||||||
break;
|
break;
|
||||||
@ -244,6 +266,7 @@ Window {
|
|||||||
id: go
|
id: go
|
||||||
|
|
||||||
property bool isAutoStart : true
|
property bool isAutoStart : true
|
||||||
|
property bool isAutoUpdate : false
|
||||||
property bool isProxyAllowed : false
|
property bool isProxyAllowed : false
|
||||||
property bool isFirstStart : false
|
property bool isFirstStart : false
|
||||||
property bool isFreshVersion : false
|
property bool isFreshVersion : false
|
||||||
@ -269,17 +292,35 @@ Window {
|
|||||||
property string genericErrSeeLogs
|
property string genericErrSeeLogs
|
||||||
|
|
||||||
property string programTitle : "ProtonMail Bridge"
|
property string programTitle : "ProtonMail Bridge"
|
||||||
property string newversion : "QA.1.0"
|
|
||||||
property string fullversion : "QA.1.0 (d9f8sdf9) 2020-02-19T10:57:23+01:00"
|
property string fullversion : "QA.1.0 (d9f8sdf9) 2020-02-19T10:57:23+01:00"
|
||||||
property string landingPage : "https://landing.page"
|
|
||||||
//property string downloadLink: "https://landing.page/download/link"
|
|
||||||
property string downloadLink: "https://protonmail.com/download/beta/protonmail-bridge-1.1.5-1.x86_64.rpm;https://www.protonmail.com/downloads/beta/Desktop-Bridge-link1.exe;https://www.protonmail.com/downloads/beta/Desktop-Bridge-link1.exe;https://www.protonmail.com/downloads/beta/Desktop-Bridge-link1.exe;"
|
property string downloadLink: "https://protonmail.com/download/beta/protonmail-bridge-1.1.5-1.x86_64.rpm;https://www.protonmail.com/downloads/beta/Desktop-Bridge-link1.exe;https://www.protonmail.com/downloads/beta/Desktop-Bridge-link1.exe;https://www.protonmail.com/downloads/beta/Desktop-Bridge-link1.exe;"
|
||||||
property string releaseNotesLink : "https://protonmail.com/download/bridge/release_notes.html"
|
|
||||||
|
property string updateVersion : "QA.1.0"
|
||||||
|
property bool updateCanInstall: true
|
||||||
|
property string updateLandingPage : "https://protonmail.com/bridge/download/"
|
||||||
|
property string updateReleaseNotesLink : "https://protonmail.com/download/bridge/release_notes.html"
|
||||||
|
signal notifyManualUpdate()
|
||||||
|
signal notifyManualUpdateRestartNeeded()
|
||||||
|
signal notifyManualUpdateError()
|
||||||
|
signal notifyForceUpdate()
|
||||||
|
signal notifySilentUpdateRestartNeeded()
|
||||||
|
signal notifySilentUpdateError()
|
||||||
|
function checkForUpdates() {
|
||||||
|
console.log("checkForUpdates")
|
||||||
|
}
|
||||||
|
function startManualUpdate() {
|
||||||
|
console.log("startManualUpdate")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
property string credits : "here;goes;list;;of;;used;packages;"
|
property string credits : "here;goes;list;;of;;used;packages;"
|
||||||
|
|
||||||
property real progress: 0.3
|
property real progress: 0.3
|
||||||
property int progressDescription: 2
|
property int progressDescription: 2
|
||||||
|
|
||||||
|
function setToRestart() {
|
||||||
|
console.log("setting to restart")
|
||||||
|
}
|
||||||
|
|
||||||
signal toggleMainWin(int systX, int systY, int systW, int systH)
|
signal toggleMainWin(int systX, int systY, int systW, int systH)
|
||||||
|
|
||||||
@ -295,12 +336,11 @@ Window {
|
|||||||
|
|
||||||
signal processFinished()
|
signal processFinished()
|
||||||
signal toggleAutoStart()
|
signal toggleAutoStart()
|
||||||
|
signal toggleAutoUpdate()
|
||||||
signal notifyBubble(int tabIndex, string message)
|
signal notifyBubble(int tabIndex, string message)
|
||||||
signal silentBubble(int tabIndex, string message)
|
signal silentBubble(int tabIndex, string message)
|
||||||
signal runCheckVersion(bool showMessage)
|
|
||||||
signal setAddAccountWarning(string message)
|
signal setAddAccountWarning(string message)
|
||||||
|
|
||||||
signal notifyUpdate()
|
|
||||||
signal notifyFirewall()
|
signal notifyFirewall()
|
||||||
signal notifyLogout(string accname)
|
signal notifyLogout(string accname)
|
||||||
signal notifyAddressChanged(string accname)
|
signal notifyAddressChanged(string accname)
|
||||||
@ -463,9 +503,6 @@ Window {
|
|||||||
switch (timer.work) {
|
switch (timer.work) {
|
||||||
case "wait":
|
case "wait":
|
||||||
break
|
break
|
||||||
case "startUpdate":
|
|
||||||
go.animateProgressBar.start()
|
|
||||||
go.updateFinished(true)
|
|
||||||
default:
|
default:
|
||||||
go.processFinished()
|
go.processFinished()
|
||||||
}
|
}
|
||||||
@ -476,11 +513,6 @@ Window {
|
|||||||
timer.start()
|
timer.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
function startUpdate() {
|
|
||||||
timer.work="startUpdate"
|
|
||||||
timer.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadAccounts() {
|
function loadAccounts() {
|
||||||
console.log("Test: Account loaded")
|
console.log("Test: Account loaded")
|
||||||
}
|
}
|
||||||
@ -500,21 +532,7 @@ Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getLocalVersionInfo(){
|
function getLocalVersionInfo(){
|
||||||
go.newversion = "QA.1.0"
|
go.updateVersion = "QA.1.0"
|
||||||
}
|
|
||||||
|
|
||||||
function isNewVersionAvailable(showMessage){
|
|
||||||
if (testroot.newVersion) {
|
|
||||||
go.newversion = "QA.2.0"
|
|
||||||
setUpdateState("oldVersion")
|
|
||||||
} else {
|
|
||||||
go.newversion = "QA.1.0"
|
|
||||||
setUpdateState("upToDate")
|
|
||||||
if(showMessage) {
|
|
||||||
notifyVersionIsTheLatest()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
workAndClose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBackendVersion() {
|
function getBackendVersion() {
|
||||||
@ -603,6 +621,12 @@ Window {
|
|||||||
isAutoStart = (isAutoStart!=false) ? false : true
|
isAutoStart = (isAutoStart!=false) ? false : true
|
||||||
console.log (" Test: toggleAutoStart "+isAutoStart)
|
console.log (" Test: toggleAutoStart "+isAutoStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onToggleAutoUpdate: {
|
||||||
|
workAndClose()
|
||||||
|
isAutoUpdate = (isAutoUpdate!=false) ? false : true
|
||||||
|
console.log (" Test: onToggleAutoUpdate "+isAutoUpdate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -98,24 +98,29 @@ Window {
|
|||||||
ListModel {
|
ListModel {
|
||||||
id: buttons
|
id: buttons
|
||||||
|
|
||||||
ListElement { title : "Show window" }
|
ListElement { title : "Show window" }
|
||||||
ListElement { title : "Logout" }
|
ListElement { title : "Logout" }
|
||||||
ListElement { title : "Internet on" }
|
ListElement { title : "Internet on" }
|
||||||
ListElement { title : "Internet off" }
|
ListElement { title : "Internet off" }
|
||||||
ListElement { title : "Macos" }
|
ListElement { title : "Macos" }
|
||||||
ListElement { title : "Windows" }
|
ListElement { title : "Windows" }
|
||||||
ListElement { title : "Linux" }
|
ListElement { title : "Linux" }
|
||||||
ListElement { title : "New Version" }
|
ListElement { title: "NotifyManualUpdate(CanInstall)" }
|
||||||
ListElement { title : "ForceUpgrade" }
|
ListElement { title: "NotifyManualUpdate(CantInstall)" }
|
||||||
ListElement { title : "ImportStructure" }
|
ListElement { title: "NotifyManualUpdateRestart" }
|
||||||
ListElement { title : "DraftImpFailed" }
|
ListElement { title: "NotifyManualUpdateError" }
|
||||||
ListElement { title : "NoInterImp" }
|
ListElement { title: "ForceUpdate" }
|
||||||
ListElement { title : "ReportImp" }
|
ListElement { title: "NotifySilentUpdateRestartNeeded" }
|
||||||
ListElement { title : "NewFolder" }
|
ListElement { title: "NotifySilentUpdateError" }
|
||||||
ListElement { title : "EditFolder" }
|
ListElement { title : "ImportStructure" }
|
||||||
ListElement { title : "EditLabel" }
|
ListElement { title : "DraftImpFailed" }
|
||||||
ListElement { title : "ExpProgErr" }
|
ListElement { title : "NoInterImp" }
|
||||||
ListElement { title : "ImpProgErr" }
|
ListElement { title : "ReportImp" }
|
||||||
|
ListElement { title : "NewFolder" }
|
||||||
|
ListElement { title : "EditFolder" }
|
||||||
|
ListElement { title : "EditLabel" }
|
||||||
|
ListElement { title : "ExpProgErr" }
|
||||||
|
ListElement { title : "ImpProgErr" }
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
@ -161,13 +166,29 @@ Window {
|
|||||||
case "Linux" :
|
case "Linux" :
|
||||||
go.goos = "linux";
|
go.goos = "linux";
|
||||||
break;
|
break;
|
||||||
case "New Version" :
|
case "NotifyManualUpdate(CanInstall)" :
|
||||||
testroot.newVersion = !testroot.newVersion
|
go.notifyManualUpdate()
|
||||||
systrText.text = testroot.newVersion ? "new version" : "uptodate"
|
go.updateCanInstall = true
|
||||||
break
|
break;
|
||||||
case "ForceUpgrade" :
|
case "NotifyManualUpdate(CantInstall)" :
|
||||||
go.notifyUpgrade()
|
go.notifyManualUpdate()
|
||||||
break;
|
go.updateCanInstall = false
|
||||||
|
break;
|
||||||
|
case "NotifyManualUpdateRestart":
|
||||||
|
go.notifyManualUpdateRestartNeeded()
|
||||||
|
break;
|
||||||
|
case "NotifyManualUpdateError":
|
||||||
|
go.notifyManualUpdateError()
|
||||||
|
break;
|
||||||
|
case "ForceUpdate" :
|
||||||
|
go.notifyForceUpdate()
|
||||||
|
break;
|
||||||
|
case "NotifySilentUpdateRestartNeeded" :
|
||||||
|
go.notifySilentUpdateRestartNeeded()
|
||||||
|
break;
|
||||||
|
case "NotifySilentUpdateError" :
|
||||||
|
go.notifySilentUpdateError()
|
||||||
|
break;
|
||||||
case "ImportStructure" :
|
case "ImportStructure" :
|
||||||
testgui.winMain.dialogImport.address = "cuto@pm.com"
|
testgui.winMain.dialogImport.address = "cuto@pm.com"
|
||||||
testgui.winMain.dialogImport.show()
|
testgui.winMain.dialogImport.show()
|
||||||
@ -815,6 +836,7 @@ Window {
|
|||||||
id: go
|
id: go
|
||||||
|
|
||||||
property int isAutoStart : 1
|
property int isAutoStart : 1
|
||||||
|
property bool isAutoUpdate : false
|
||||||
property bool isFirstStart : false
|
property bool isFirstStart : false
|
||||||
property string currentAddress : "none"
|
property string currentAddress : "none"
|
||||||
//property string goos : "windows"
|
//property string goos : "windows"
|
||||||
@ -831,9 +853,25 @@ Window {
|
|||||||
property string bugReportSent
|
property string bugReportSent
|
||||||
|
|
||||||
property string programTitle : "ProtonMail Import-Export app"
|
property string programTitle : "ProtonMail Import-Export app"
|
||||||
property string newversion : "q0.1.0"
|
property string fullversion : "QA.1.0 (d9f8sdf9) 2020-02-19T10:57:23+01:00"
|
||||||
property string landingPage : "https://landing.page"
|
property string downloadLink: "https://protonmail.com/download/beta/protonmail-bridge-1.1.5-1.x86_64.rpm;https://www.protonmail.com/downloads/beta/Desktop-Bridge-link1.exe;https://www.protonmail.com/downloads/beta/Desktop-Bridge-link1.exe;https://www.protonmail.com/downloads/beta/Desktop-Bridge-link1.exe;"
|
||||||
property string releaseNotesLink : "https://protonmail.com/download/ie/release_notes.html"
|
|
||||||
|
property string updateVersion : "q0.1.0"
|
||||||
|
property bool updateCanInstall: true
|
||||||
|
property string updateLandingPage : "https://protonmail.com/import-export/download/"
|
||||||
|
property string updateReleaseNotesLink : "https://protonmail.com/download/ie/release_notes.html"
|
||||||
|
signal notifyManualUpdate()
|
||||||
|
signal notifyManualUpdateRestartNeeded()
|
||||||
|
signal notifyManualUpdateError()
|
||||||
|
signal notifyForceUpdate()
|
||||||
|
signal notifySilentUpdateRestartNeeded()
|
||||||
|
signal notifySilentUpdateError()
|
||||||
|
function checkForUpdates() {
|
||||||
|
console.log("checkForUpdates")
|
||||||
|
}
|
||||||
|
function startManualUpdate() {
|
||||||
|
console.log("startManualUpdate")
|
||||||
|
}
|
||||||
|
|
||||||
property real progress: 0.0
|
property real progress: 0.0
|
||||||
property int progressFails: 0
|
property int progressFails: 0
|
||||||
@ -846,13 +884,10 @@ Window {
|
|||||||
|
|
||||||
signal toggleMainWin(int systX, int systY, int systW, int systH)
|
signal toggleMainWin(int systX, int systY, int systW, int systH)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
signal notifyHasNoKeychain()
|
signal notifyHasNoKeychain()
|
||||||
signal notifyKeychainRebuild()
|
signal notifyKeychainRebuild()
|
||||||
signal notifyAddressChangedLogout()
|
signal notifyAddressChangedLogout()
|
||||||
signal notifyAddressChanged()
|
signal notifyAddressChanged()
|
||||||
signal notifyUpdate()
|
|
||||||
|
|
||||||
signal showWindow()
|
signal showWindow()
|
||||||
signal showHelp()
|
signal showHelp()
|
||||||
@ -871,10 +906,10 @@ Window {
|
|||||||
|
|
||||||
signal processFinished()
|
signal processFinished()
|
||||||
signal toggleAutoStart()
|
signal toggleAutoStart()
|
||||||
|
signal toggleAutoUpdate()
|
||||||
signal notifyBubble(int tabIndex, string message)
|
signal notifyBubble(int tabIndex, string message)
|
||||||
signal runCheckVersion(bool showMessage)
|
|
||||||
signal setAddAccountWarning(string message)
|
signal setAddAccountWarning(string message)
|
||||||
signal notifyUpgrade()
|
signal notifyUpdate()
|
||||||
signal updateFinished(bool hasError)
|
signal updateFinished(bool hasError)
|
||||||
|
|
||||||
signal notifyLogout(string accname)
|
signal notifyLogout(string accname)
|
||||||
@ -882,6 +917,10 @@ Window {
|
|||||||
signal notifyError(int errCode)
|
signal notifyError(int errCode)
|
||||||
property string errorDescription : ""
|
property string errorDescription : ""
|
||||||
|
|
||||||
|
function setToRestart() {
|
||||||
|
console.log("setting to restart")
|
||||||
|
}
|
||||||
|
|
||||||
function delay(duration) {
|
function delay(duration) {
|
||||||
var timeStart = new Date().getTime();
|
var timeStart = new Date().getTime();
|
||||||
|
|
||||||
@ -955,7 +994,7 @@ Window {
|
|||||||
workAndClose("addAccount")
|
workAndClose("addAccount")
|
||||||
}
|
}
|
||||||
|
|
||||||
property SequentialAnimation animateProgressBarUpgrade : SequentialAnimation {
|
property SequentialAnimation animateProgressBarUpdate : SequentialAnimation {
|
||||||
// version
|
// version
|
||||||
PropertyAnimation{ target: go; properties: "progressDescription"; to: 1; duration: 1; }
|
PropertyAnimation{ target: go; properties: "progressDescription"; to: 1; duration: 1; }
|
||||||
PropertyAnimation{ duration: 2000; }
|
PropertyAnimation{ duration: 2000; }
|
||||||
@ -1066,7 +1105,6 @@ Window {
|
|||||||
onTriggered : {
|
onTriggered : {
|
||||||
console.log("triggered "+timer.work)
|
console.log("triggered "+timer.work)
|
||||||
switch (timer.work) {
|
switch (timer.work) {
|
||||||
case "isNewVersionAvailable" :
|
|
||||||
case "clearCache" :
|
case "clearCache" :
|
||||||
case "clearKeychain" :
|
case "clearKeychain" :
|
||||||
case "logout" :
|
case "logout" :
|
||||||
@ -1093,8 +1131,8 @@ Window {
|
|||||||
go.animateProgressBar.start()
|
go.animateProgressBar.start()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "startUpgrade":
|
case "startManualUpdate":
|
||||||
go.animateProgressBarUpgrade.start()
|
go.animateProgressBarUpdate.start()
|
||||||
go.updateFinished(true)
|
go.updateFinished(true)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1105,18 +1143,10 @@ Window {
|
|||||||
|
|
||||||
function workAndClose(workDescription) {
|
function workAndClose(workDescription) {
|
||||||
go.progress=0.0
|
go.progress=0.0
|
||||||
timer.work = workDescription
|
timer.work = workDescription === undefined ? "" : workDescription
|
||||||
timer.start()
|
timer.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
function startUpgrade() {
|
|
||||||
timer.work="startUpgrade"
|
|
||||||
timer.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function checkPathStatus(path) {
|
function checkPathStatus(path) {
|
||||||
if ( path == "" ) return testgui.enums.pathEmptyPath
|
if ( path == "" ) return testgui.enums.pathEmptyPath
|
||||||
if ( path == "wrong" ) return testgui.enums.pathWrongPath
|
if ( path == "wrong" ) return testgui.enums.pathWrongPath
|
||||||
@ -1218,20 +1248,6 @@ Window {
|
|||||||
workAndClose("switchAddressMode")
|
workAndClose("switchAddressMode")
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNewVersionAvailable(showMessage){
|
|
||||||
if (testroot.newVersion) {
|
|
||||||
setUpdateState("oldVersion")
|
|
||||||
} else {
|
|
||||||
setUpdateState("upToDate")
|
|
||||||
if(showMessage) {
|
|
||||||
notifyVersionIsTheLatest()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
workAndClose("isNewVersionAvailable")
|
|
||||||
//notifyBubble(2,go.versionCheckFailed)
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLocalVersionInfo(){}
|
function getLocalVersionInfo(){}
|
||||||
|
|
||||||
function getBackendVersion() {
|
function getBackendVersion() {
|
||||||
@ -1328,5 +1344,11 @@ Window {
|
|||||||
console.log("sending import report from ", address, " file ", fname)
|
console.log("sending import report from ", address, " file ", fname)
|
||||||
return !fname.includes("fail")
|
return !fname.includes("fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onToggleAutoUpdate: {
|
||||||
|
workAndClose()
|
||||||
|
isAutoUpdate = (isAutoUpdate!=false) ? false : true
|
||||||
|
console.log (" Test: onToggleAutoUpdate "+isAutoUpdate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/ProtonMail/proton-bridge/internal/config/settings"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/events"
|
"github.com/ProtonMail/proton-bridge/internal/events"
|
||||||
qtcommon "github.com/ProtonMail/proton-bridge/internal/frontend/qt-common"
|
qtcommon "github.com/ProtonMail/proton-bridge/internal/frontend/qt-common"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/frontend/types"
|
"github.com/ProtonMail/proton-bridge/internal/frontend/types"
|
||||||
@ -50,6 +51,7 @@ var log = logrus.WithField("pkg", "frontend-qt-ie")
|
|||||||
type FrontendQt struct {
|
type FrontendQt struct {
|
||||||
panicHandler types.PanicHandler
|
panicHandler types.PanicHandler
|
||||||
locations *locations.Locations
|
locations *locations.Locations
|
||||||
|
settings *settings.Settings
|
||||||
eventListener listener.Listener
|
eventListener listener.Listener
|
||||||
updater types.Updater
|
updater types.Updater
|
||||||
ie types.ImportExporter
|
ie types.ImportExporter
|
||||||
@ -71,14 +73,17 @@ type FrontendQt struct {
|
|||||||
progress *transfer.Progress
|
progress *transfer.Progress
|
||||||
|
|
||||||
restarter types.Restarter
|
restarter types.Restarter
|
||||||
|
|
||||||
|
// saving most up-to-date update info to install it manually
|
||||||
|
updateInfo updater.VersionInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// New is constructor for Import-Export Qt-Go interface
|
// New is constructor for Import-Export Qt-Go interface
|
||||||
func New(
|
func New(
|
||||||
version, buildVersion string,
|
version, buildVersion string,
|
||||||
panicHandler types.PanicHandler,
|
panicHandler types.PanicHandler,
|
||||||
|
|
||||||
locations *locations.Locations,
|
locations *locations.Locations,
|
||||||
|
settings *settings.Settings,
|
||||||
eventListener listener.Listener,
|
eventListener listener.Listener,
|
||||||
updater types.Updater,
|
updater types.Updater,
|
||||||
ie types.ImportExporter,
|
ie types.ImportExporter,
|
||||||
@ -87,6 +92,7 @@ func New(
|
|||||||
f := &FrontendQt{
|
f := &FrontendQt{
|
||||||
panicHandler: panicHandler,
|
panicHandler: panicHandler,
|
||||||
locations: locations,
|
locations: locations,
|
||||||
|
settings: settings,
|
||||||
programName: "ProtonMail Import-Export",
|
programName: "ProtonMail Import-Export",
|
||||||
programVersion: "v" + version,
|
programVersion: "v" + version,
|
||||||
eventListener: eventListener,
|
eventListener: eventListener,
|
||||||
@ -111,9 +117,21 @@ func (f *FrontendQt) Loop() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FrontendQt) NotifyManualUpdate(update updater.VersionInfo) error {
|
func (f *FrontendQt) NotifyManualUpdate(update updater.VersionInfo, canInstall bool) {
|
||||||
// NOTE: Save the update somewhere so that it can be installed when user chooses "install now".
|
f.Qml.SetUpdateVersion(update.Version.String())
|
||||||
return nil
|
f.Qml.SetUpdateLandingPage(update.Landing)
|
||||||
|
f.Qml.SetUpdateReleaseNotesLink("https://protonmail.com/download/ie/release_notes.html")
|
||||||
|
f.Qml.SetUpdateCanInstall(canInstall)
|
||||||
|
f.updateInfo = update
|
||||||
|
f.Qml.NotifyManualUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FrontendQt) NotifySilentUpdateInstalled() {
|
||||||
|
f.Qml.NotifySilentUpdateRestartNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FrontendQt) NotifySilentUpdateError(err error) {
|
||||||
|
f.Qml.NotifySilentUpdateError()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FrontendQt) watchEvents() {
|
func (f *FrontendQt) watchEvents() {
|
||||||
@ -152,7 +170,7 @@ func (f *FrontendQt) watchEvents() {
|
|||||||
f.Qml.NotifyLogout(user.Username())
|
f.Qml.NotifyLogout(user.Username())
|
||||||
case <-updateApplicationCh:
|
case <-updateApplicationCh:
|
||||||
f.Qml.ProcessFinished()
|
f.Qml.ProcessFinished()
|
||||||
f.Qml.NotifyUpdate()
|
f.Qml.NotifyForceUpdate()
|
||||||
case <-newUserCh:
|
case <-newUserCh:
|
||||||
f.Qml.LoadAccounts()
|
f.Qml.LoadAccounts()
|
||||||
}
|
}
|
||||||
@ -219,6 +237,12 @@ func (f *FrontendQt) QtExecute(Procedure func(*FrontendQt) error) error {
|
|||||||
f.Qml.SetCredits(importexport.Credits)
|
f.Qml.SetCredits(importexport.Credits)
|
||||||
f.Qml.SetFullversion(f.buildVersion)
|
f.Qml.SetFullversion(f.buildVersion)
|
||||||
|
|
||||||
|
if f.settings.GetBool(settings.AutoUpdateKey) {
|
||||||
|
f.Qml.SetIsAutoUpdate(true)
|
||||||
|
} else {
|
||||||
|
f.Qml.SetIsAutoUpdate(false)
|
||||||
|
}
|
||||||
|
|
||||||
// Loop
|
// Loop
|
||||||
if ret := gui.QGuiApplication_Exec(); ret != 0 {
|
if ret := gui.QGuiApplication_Exec(); ret != 0 {
|
||||||
//err := errors.New(errors.ErrQApplication, "Event loop ended with return value: %v", string(ret))
|
//err := errors.New(errors.ErrQApplication, "Event loop ended with return value: %v", string(ret))
|
||||||
@ -299,6 +323,18 @@ func (f *FrontendQt) sendBug(description, emailClient, address string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FrontendQt) toggleAutoUpdate() {
|
||||||
|
defer f.Qml.ProcessFinished()
|
||||||
|
|
||||||
|
if f.settings.GetBool(settings.AutoUpdateKey) {
|
||||||
|
f.settings.SetBool(settings.AutoUpdateKey, false)
|
||||||
|
f.Qml.SetIsAutoUpdate(false)
|
||||||
|
} else {
|
||||||
|
f.settings.SetBool(settings.AutoUpdateKey, true)
|
||||||
|
f.Qml.SetIsAutoUpdate(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// checkInternet is almost idetical to bridge
|
// checkInternet is almost idetical to bridge
|
||||||
func (f *FrontendQt) checkInternet() {
|
func (f *FrontendQt) checkInternet() {
|
||||||
f.Qml.SetConnectionStatus(f.ie.CheckConnection() == nil)
|
f.Qml.SetConnectionStatus(f.ie.CheckConnection() == nil)
|
||||||
@ -369,21 +405,43 @@ func (f *FrontendQt) setProgressManager(progress *transfer.Progress) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FrontendQt) StartUpdate() {
|
func (f *FrontendQt) startManualUpdate() {
|
||||||
// NOTE: Fix this.
|
go func() {
|
||||||
|
err := f.updater.InstallUpdate(f.updateInfo)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).Error("An error occurred while installing updates manually")
|
||||||
|
f.Qml.NotifyManualUpdateError()
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Qml.NotifyManualUpdateRestartNeeded()
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// isNewVersionAvailable is identical to bridge
|
func (f *FrontendQt) checkForUpdates() {
|
||||||
// return 0 when local version is fine
|
|
||||||
// return 1 when new version is available
|
|
||||||
func (f *FrontendQt) isNewVersionAvailable(showMessage bool) {
|
|
||||||
go func() {
|
go func() {
|
||||||
defer f.Qml.ProcessFinished()
|
version, err := f.updater.Check()
|
||||||
f.Qml.SetConnectionStatus(true) // if we are here connection is ok
|
|
||||||
f.Qml.SetUpdateState(StatusUpToDate)
|
if err != nil {
|
||||||
if showMessage {
|
logrus.WithError(err).Error("An error occurred while checking updates manually")
|
||||||
f.Qml.NotifyVersionIsTheLatest()
|
f.Qml.NotifyManualUpdateError()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !f.updater.IsUpdateApplicable(version) {
|
||||||
|
logrus.Debug("No need to update")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.WithField("version", version.Version).Info("An update is available")
|
||||||
|
|
||||||
|
if !f.updater.CanInstall(version) {
|
||||||
|
logrus.Debug("A manual update is required")
|
||||||
|
f.NotifyManualUpdate(version, false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.NotifyManualUpdate(version, true)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/ProtonMail/proton-bridge/internal/config/settings"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/frontend/types"
|
"github.com/ProtonMail/proton-bridge/internal/frontend/types"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/locations"
|
"github.com/ProtonMail/proton-bridge/internal/locations"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/updater"
|
"github.com/ProtonMail/proton-bridge/internal/updater"
|
||||||
@ -42,15 +43,21 @@ func (s *FrontendHeadless) Loop() error {
|
|||||||
return http.ListenAndServe(":8082", nil)
|
return http.ListenAndServe(":8082", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FrontendHeadless) NotifyManualUpdate(update updater.VersionInfo) error {
|
func (s *FrontendHeadless) NotifyManualUpdate(update updater.VersionInfo, canInstall bool) {
|
||||||
// NOTE: Save the update somewhere so that it can be installed when user chooses "install now".
|
// NOTE: Save the update somewhere so that it can be installed when user chooses "install now".
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
func (s *FrontendHeadless) NotifySilentUpdateInstalled() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FrontendHeadless) NotifySilentUpdateError(err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(
|
func New(
|
||||||
version, buildVersion string,
|
version, buildVersion string,
|
||||||
panicHandler types.PanicHandler,
|
panicHandler types.PanicHandler,
|
||||||
locations *locations.Locations,
|
locations *locations.Locations,
|
||||||
|
settings *settings.Settings,
|
||||||
eventListener listener.Listener,
|
eventListener listener.Listener,
|
||||||
updater types.Updater,
|
updater types.Updater,
|
||||||
ie types.ImportExporter,
|
ie types.ImportExporter,
|
||||||
|
|||||||
@ -33,6 +33,7 @@ type GoQMLInterface struct {
|
|||||||
|
|
||||||
_ func() `constructor:"init"`
|
_ func() `constructor:"init"`
|
||||||
|
|
||||||
|
_ bool `property:"isAutoUpdate"`
|
||||||
_ string `property:"currentAddress"`
|
_ string `property:"currentAddress"`
|
||||||
_ string `property:"goos"`
|
_ string `property:"goos"`
|
||||||
_ string `property:"credits"`
|
_ string `property:"credits"`
|
||||||
@ -49,11 +50,21 @@ type GoQMLInterface struct {
|
|||||||
_ string `property:importLogFileName`
|
_ string `property:importLogFileName`
|
||||||
|
|
||||||
_ string `property:"programTitle"`
|
_ string `property:"programTitle"`
|
||||||
_ string `property:"newversion"`
|
|
||||||
_ string `property:"fullversion"`
|
_ string `property:"fullversion"`
|
||||||
_ string `property:"downloadLink"`
|
_ string `property:"downloadLink"`
|
||||||
_ string `property:"landingPage"`
|
|
||||||
_ string `property:"releaseNotesLink"`
|
_ string `property:"updateVersion"`
|
||||||
|
_ bool `property:"updateCanInstall"`
|
||||||
|
_ string `property:"updateLandingPage"`
|
||||||
|
_ string `property:"updateReleaseNotesLink"`
|
||||||
|
_ func() `signal:"notifyManualUpdate"`
|
||||||
|
_ func() `signal:"notifyManualUpdateRestartNeeded"`
|
||||||
|
_ func() `signal:"notifyManualUpdateError"`
|
||||||
|
_ func() `signal:"notifyForceUpdate"`
|
||||||
|
_ func() `signal:"notifySilentUpdateRestartNeeded"`
|
||||||
|
_ func() `signal:"notifySilentUpdateError"`
|
||||||
|
_ func() `slot:"checkForUpdates"`
|
||||||
|
_ func() `slot:"startManualUpdate"`
|
||||||
|
|
||||||
// translations
|
// translations
|
||||||
_ string `property:"wrongCredentials"`
|
_ string `property:"wrongCredentials"`
|
||||||
@ -79,6 +90,7 @@ type GoQMLInterface struct {
|
|||||||
|
|
||||||
_ func() `signal:"showWindow"`
|
_ func() `signal:"showWindow"`
|
||||||
|
|
||||||
|
_ func() `slot:"toggleAutoUpdate"`
|
||||||
_ func() `slot:"quit"`
|
_ func() `slot:"quit"`
|
||||||
_ func() `slot:"loadAccounts"`
|
_ func() `slot:"loadAccounts"`
|
||||||
_ func() `slot:"openLogs"`
|
_ func() `slot:"openLogs"`
|
||||||
@ -89,8 +101,7 @@ type GoQMLInterface struct {
|
|||||||
_ func() `signal:"highlightSystray"`
|
_ func() `signal:"highlightSystray"`
|
||||||
_ func() `signal:"normalSystray"`
|
_ func() `signal:"normalSystray"`
|
||||||
|
|
||||||
_ func(showMessage bool) `slot:"isNewVersionAvailable"`
|
_ func() string `slot:"getBackendVersion"`
|
||||||
_ func() string `slot:"getBackendVersion"`
|
|
||||||
|
|
||||||
_ func(description, client, address string) bool `slot:"sendBug"`
|
_ func(description, client, address string) bool `slot:"sendBug"`
|
||||||
_ func(address string) bool `slot:"sendImportReport"`
|
_ func(address string) bool `slot:"sendImportReport"`
|
||||||
@ -128,12 +139,10 @@ type GoQMLInterface struct {
|
|||||||
_ func() `signal:"notifyVersionIsTheLatest"`
|
_ func() `signal:"notifyVersionIsTheLatest"`
|
||||||
_ func() `signal:"notifyKeychainRebuild"`
|
_ func() `signal:"notifyKeychainRebuild"`
|
||||||
_ func() `signal:"notifyHasNoKeychain"`
|
_ func() `signal:"notifyHasNoKeychain"`
|
||||||
_ func() `signal:"notifyUpdate"`
|
|
||||||
_ func(accname string) `signal:"notifyLogout"`
|
_ func(accname string) `signal:"notifyLogout"`
|
||||||
_ func(accname string) `signal:"notifyAddressChanged"`
|
_ func(accname string) `signal:"notifyAddressChanged"`
|
||||||
_ func(accname string) `signal:"notifyAddressChangedLogout"`
|
_ func(accname string) `signal:"notifyAddressChangedLogout"`
|
||||||
|
|
||||||
_ func() `slot:"startUpdate"`
|
|
||||||
_ func(hasError bool) `signal:"updateFinished"`
|
_ func(hasError bool) `signal:"updateFinished"`
|
||||||
|
|
||||||
// errors
|
// errors
|
||||||
@ -150,6 +159,7 @@ func (s *GoQMLInterface) init() {}
|
|||||||
func (s *GoQMLInterface) SetFrontend(f *FrontendQt) {
|
func (s *GoQMLInterface) SetFrontend(f *FrontendQt) {
|
||||||
s.ConnectQuit(f.App.Quit)
|
s.ConnectQuit(f.App.Quit)
|
||||||
|
|
||||||
|
s.ConnectToggleAutoUpdate(f.toggleAutoUpdate)
|
||||||
s.ConnectLoadAccounts(f.Accounts.LoadAccounts)
|
s.ConnectLoadAccounts(f.Accounts.LoadAccounts)
|
||||||
s.ConnectOpenLogs(f.openLogs)
|
s.ConnectOpenLogs(f.openLogs)
|
||||||
s.ConnectOpenDownloadLink(f.openDownloadLink)
|
s.ConnectOpenDownloadLink(f.openDownloadLink)
|
||||||
@ -170,10 +180,10 @@ func (s *GoQMLInterface) SetFrontend(f *FrontendQt) {
|
|||||||
s.SetProgramTitle(f.programName)
|
s.SetProgramTitle(f.programName)
|
||||||
|
|
||||||
s.ConnectOpenLicenseFile(f.openLicenseFile)
|
s.ConnectOpenLicenseFile(f.openLicenseFile)
|
||||||
s.SetReleaseNotesLink("https://protonmail.com/download/ie/release_notes.html")
|
s.SetUpdateReleaseNotesLink("https://protonmail.com/download/ie/release_notes.html")
|
||||||
|
|
||||||
s.ConnectGetLocalVersionInfo(f.getLocalVersionInfo)
|
s.ConnectGetLocalVersionInfo(f.getLocalVersionInfo)
|
||||||
s.ConnectIsNewVersionAvailable(f.isNewVersionAvailable)
|
s.ConnectCheckForUpdates(f.checkForUpdates)
|
||||||
s.ConnectGetBackendVersion(func() string {
|
s.ConnectGetBackendVersion(func() string {
|
||||||
return f.programVersion
|
return f.programVersion
|
||||||
})
|
})
|
||||||
@ -193,7 +203,5 @@ func (s *GoQMLInterface) SetFrontend(f *FrontendQt) {
|
|||||||
|
|
||||||
s.ConnectCheckPathStatus(CheckPathStatus)
|
s.ConnectCheckPathStatus(CheckPathStatus)
|
||||||
|
|
||||||
s.ConnectStartUpdate(f.StartUpdate)
|
|
||||||
|
|
||||||
s.ConnectEmitEvent(f.emitEvent)
|
s.ConnectEmitEvent(f.emitEvent)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,6 +95,9 @@ type FrontendQt struct {
|
|||||||
userIDAdded string
|
userIDAdded string
|
||||||
|
|
||||||
restarter types.Restarter
|
restarter types.Restarter
|
||||||
|
|
||||||
|
// saving most up-to-date update info to install it manually
|
||||||
|
updateInfo updater.VersionInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new Qt frontend for the bridge.
|
// New returns a new Qt frontend for the bridge.
|
||||||
@ -173,9 +176,21 @@ func (s *FrontendQt) Loop() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FrontendQt) NotifyManualUpdate(update updater.VersionInfo) error {
|
func (s *FrontendQt) NotifyManualUpdate(update updater.VersionInfo, canInstall bool) {
|
||||||
// NOTE: Save the update somewhere so that it can be installed when user chooses "install now".
|
s.Qml.SetUpdateVersion(update.Version.String())
|
||||||
return nil
|
s.Qml.SetUpdateLandingPage(update.Landing)
|
||||||
|
s.Qml.SetUpdateReleaseNotesLink("https://protonmail.com/download/bridge/release_notes.html")
|
||||||
|
s.Qml.SetUpdateCanInstall(canInstall)
|
||||||
|
s.updateInfo = update
|
||||||
|
s.Qml.NotifyManualUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FrontendQt) NotifySilentUpdateInstalled() {
|
||||||
|
s.Qml.NotifySilentUpdateRestartNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FrontendQt) NotifySilentUpdateError(err error) {
|
||||||
|
s.Qml.NotifySilentUpdateError()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FrontendQt) watchEvents() {
|
func (s *FrontendQt) watchEvents() {
|
||||||
@ -233,7 +248,7 @@ func (s *FrontendQt) watchEvents() {
|
|||||||
s.Qml.NotifyLogout(user.Username())
|
s.Qml.NotifyLogout(user.Username())
|
||||||
case <-updateApplicationCh:
|
case <-updateApplicationCh:
|
||||||
s.Qml.ProcessFinished()
|
s.Qml.ProcessFinished()
|
||||||
s.Qml.NotifyUpdate()
|
s.Qml.NotifyForceUpdate()
|
||||||
case <-newUserCh:
|
case <-newUserCh:
|
||||||
s.Qml.LoadAccounts()
|
s.Qml.LoadAccounts()
|
||||||
case <-certIssue:
|
case <-certIssue:
|
||||||
@ -343,6 +358,12 @@ func (s *FrontendQt) qtExecute(Procedure func(*FrontendQt) error) error {
|
|||||||
s.Qml.SetIsAutoStart(false)
|
s.Qml.SetIsAutoStart(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.settings.GetBool(settings.AutoUpdateKey) {
|
||||||
|
s.Qml.SetIsAutoUpdate(true)
|
||||||
|
} else {
|
||||||
|
s.Qml.SetIsAutoUpdate(false)
|
||||||
|
}
|
||||||
|
|
||||||
if s.settings.GetBool(settings.AllowProxyKey) {
|
if s.settings.GetBool(settings.AllowProxyKey) {
|
||||||
s.Qml.SetIsProxyAllowed(true)
|
s.Qml.SetIsProxyAllowed(true)
|
||||||
} else {
|
} else {
|
||||||
@ -397,16 +418,30 @@ func (s *FrontendQt) openLogs() {
|
|||||||
go open.Run(logsPath)
|
go open.Run(logsPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check version in separate goroutine to not block the GUI (avoid program not responding message).
|
func (s *FrontendQt) checkForUpdates() {
|
||||||
func (s *FrontendQt) isNewVersionAvailable(showMessage bool) {
|
|
||||||
go func() {
|
go func() {
|
||||||
defer s.panicHandler.HandlePanic()
|
version, err := s.updater.Check()
|
||||||
defer s.Qml.ProcessFinished()
|
|
||||||
s.Qml.SetConnectionStatus(true) // If we are here connection is ok.
|
if err != nil {
|
||||||
s.Qml.SetUpdateState("upToDate")
|
logrus.WithError(err).Error("An error occurred while checking updates manually")
|
||||||
if showMessage {
|
s.Qml.NotifyManualUpdateError()
|
||||||
s.Qml.NotifyVersionIsTheLatest()
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !s.updater.IsUpdateApplicable(version) {
|
||||||
|
logrus.Debug("No need to update")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.WithField("version", version.Version).Info("An update is available")
|
||||||
|
|
||||||
|
if !s.updater.CanInstall(version) {
|
||||||
|
logrus.Debug("A manual update is required")
|
||||||
|
s.NotifyManualUpdate(version, false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.NotifyManualUpdate(version, true)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,6 +536,18 @@ func (s *FrontendQt) toggleAutoStart() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FrontendQt) toggleAutoUpdate() {
|
||||||
|
defer s.Qml.ProcessFinished()
|
||||||
|
|
||||||
|
if s.settings.GetBool(settings.AutoUpdateKey) {
|
||||||
|
s.settings.SetBool(settings.AutoUpdateKey, false)
|
||||||
|
s.Qml.SetIsAutoUpdate(false)
|
||||||
|
} else {
|
||||||
|
s.settings.SetBool(settings.AutoUpdateKey, true)
|
||||||
|
s.Qml.SetIsAutoUpdate(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *FrontendQt) toggleAllowProxy() {
|
func (s *FrontendQt) toggleAllowProxy() {
|
||||||
defer s.Qml.ProcessFinished()
|
defer s.Qml.ProcessFinished()
|
||||||
|
|
||||||
@ -594,6 +641,15 @@ func (s *FrontendQt) saveOutgoingNoEncPopupCoord(x, y float32) {
|
|||||||
//prefs.SetFloat(prefs.OutgoingNoEncPopupCoordY, y)
|
//prefs.SetFloat(prefs.OutgoingNoEncPopupCoordY, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FrontendQt) StartUpdate() {
|
func (s *FrontendQt) startManualUpdate() {
|
||||||
// NOTE: Fix this.
|
go func() {
|
||||||
|
err := s.updater.InstallUpdate(s.updateInfo)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).Error("An error occurred while installing updates manually")
|
||||||
|
s.Qml.NotifyManualUpdateError()
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Qml.NotifyManualUpdateRestartNeeded()
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,9 +43,14 @@ func (s *FrontendHeadless) Loop() error {
|
|||||||
return http.ListenAndServe(":8081", nil)
|
return http.ListenAndServe(":8081", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FrontendHeadless) NotifyManualUpdate(update updater.VersionInfo) error {
|
func (s *FrontendHeadless) NotifyManualUpdate(update updater.VersionInfo, canInstall bool) {
|
||||||
// NOTE: Save the update somewhere so that it can be installed when user chooses "install now".
|
// NOTE: Save the update somewhere so that it can be installed when user chooses "install now".
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
func (s *FrontendHeadless) NotifySilentUpdateInstalled() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FrontendHeadless) NotifySilentUpdateError(err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FrontendHeadless) InstanceExistAlert() {}
|
func (s *FrontendHeadless) InstanceExistAlert() {}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ type GoQMLInterface struct {
|
|||||||
_ func() `constructor:"init"`
|
_ func() `constructor:"init"`
|
||||||
|
|
||||||
_ bool `property:"isAutoStart"`
|
_ bool `property:"isAutoStart"`
|
||||||
|
_ bool `property:"isAutoUpdate"`
|
||||||
_ bool `property:"isProxyAllowed"`
|
_ bool `property:"isProxyAllowed"`
|
||||||
_ string `property:"currentAddress"`
|
_ string `property:"currentAddress"`
|
||||||
_ string `property:"goos"`
|
_ string `property:"goos"`
|
||||||
@ -45,11 +46,21 @@ type GoQMLInterface struct {
|
|||||||
_ bool `property:"isDefaultPort"`
|
_ bool `property:"isDefaultPort"`
|
||||||
|
|
||||||
_ string `property:"programTitle"`
|
_ string `property:"programTitle"`
|
||||||
_ string `property:"newversion"`
|
|
||||||
_ string `property:"fullversion"`
|
_ string `property:"fullversion"`
|
||||||
_ string `property:"downloadLink"`
|
_ string `property:"downloadLink"`
|
||||||
_ string `property:"landingPage"`
|
|
||||||
_ string `property:"releaseNotesLink"`
|
_ string `property:"updateVersion"`
|
||||||
|
_ bool `property:"updateCanInstall"`
|
||||||
|
_ string `property:"updateLandingPage"`
|
||||||
|
_ string `property:"updateReleaseNotesLink"`
|
||||||
|
_ func() `signal:"notifyManualUpdate"`
|
||||||
|
_ func() `signal:"notifyManualUpdateRestartNeeded"`
|
||||||
|
_ func() `signal:"notifyManualUpdateError"`
|
||||||
|
_ func() `signal:"notifyForceUpdate"`
|
||||||
|
_ func() `signal:"notifySilentUpdateRestartNeeded"`
|
||||||
|
_ func() `signal:"notifySilentUpdateError"`
|
||||||
|
_ func() `slot:"checkForUpdates"`
|
||||||
|
_ func() `slot:"startManualUpdate"`
|
||||||
|
|
||||||
// Translations.
|
// Translations.
|
||||||
_ string `property:"wrongCredentials"`
|
_ string `property:"wrongCredentials"`
|
||||||
@ -82,6 +93,7 @@ type GoQMLInterface struct {
|
|||||||
_ func() `signal:"showQuit"`
|
_ func() `signal:"showQuit"`
|
||||||
|
|
||||||
_ func() `slot:"toggleAutoStart"`
|
_ func() `slot:"toggleAutoStart"`
|
||||||
|
_ func() `slot:"toggleAutoUpdate"`
|
||||||
_ func() `slot:"toggleAllowProxy"`
|
_ func() `slot:"toggleAllowProxy"`
|
||||||
_ func() `slot:"loadAccounts"`
|
_ func() `slot:"loadAccounts"`
|
||||||
_ func() `slot:"openLogs"`
|
_ func() `slot:"openLogs"`
|
||||||
@ -121,7 +133,6 @@ type GoQMLInterface struct {
|
|||||||
_ func() `signal:"notifyVersionIsTheLatest"`
|
_ func() `signal:"notifyVersionIsTheLatest"`
|
||||||
_ func() `signal:"notifyKeychainRebuild"`
|
_ func() `signal:"notifyKeychainRebuild"`
|
||||||
_ func() `signal:"notifyHasNoKeychain"`
|
_ func() `signal:"notifyHasNoKeychain"`
|
||||||
_ func() `signal:"notifyUpdate"`
|
|
||||||
_ func(accname string) `signal:"notifyLogout"`
|
_ func(accname string) `signal:"notifyLogout"`
|
||||||
_ func(accname string) `signal:"notifyAddressChanged"`
|
_ func(accname string) `signal:"notifyAddressChanged"`
|
||||||
_ func(accname string) `signal:"notifyAddressChangedLogout"`
|
_ func(accname string) `signal:"notifyAddressChangedLogout"`
|
||||||
@ -137,7 +148,6 @@ type GoQMLInterface struct {
|
|||||||
_ func(recipient string) `signal:"showNoActiveKeyForRecipient"`
|
_ func(recipient string) `signal:"showNoActiveKeyForRecipient"`
|
||||||
_ func() `signal:"showCertIssue"`
|
_ func() `signal:"showCertIssue"`
|
||||||
|
|
||||||
_ func() `slot:"startUpdate"`
|
|
||||||
_ func(hasError bool) `signal:"updateFinished"`
|
_ func(hasError bool) `signal:"updateFinished"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,15 +157,16 @@ func (s *GoQMLInterface) init() {}
|
|||||||
// SetFrontend connects all slots and signals from Go to QML.
|
// SetFrontend connects all slots and signals from Go to QML.
|
||||||
func (s *GoQMLInterface) SetFrontend(f *FrontendQt) {
|
func (s *GoQMLInterface) SetFrontend(f *FrontendQt) {
|
||||||
s.ConnectToggleAutoStart(f.toggleAutoStart)
|
s.ConnectToggleAutoStart(f.toggleAutoStart)
|
||||||
|
s.ConnectToggleAutoUpdate(f.toggleAutoUpdate)
|
||||||
s.ConnectToggleAllowProxy(f.toggleAllowProxy)
|
s.ConnectToggleAllowProxy(f.toggleAllowProxy)
|
||||||
s.ConnectLoadAccounts(f.loadAccounts)
|
s.ConnectLoadAccounts(f.loadAccounts)
|
||||||
s.ConnectOpenLogs(f.openLogs)
|
s.ConnectOpenLogs(f.openLogs)
|
||||||
s.ConnectClearCache(f.clearCache)
|
s.ConnectClearCache(f.clearCache)
|
||||||
s.ConnectClearKeychain(f.clearKeychain)
|
s.ConnectClearKeychain(f.clearKeychain)
|
||||||
|
|
||||||
s.ConnectOpenLicenseFile(f.openLicenseFile)
|
s.ConnectOpenLicenseFile(f.openLicenseFile)
|
||||||
|
s.ConnectStartManualUpdate(f.startManualUpdate)
|
||||||
s.ConnectGetLocalVersionInfo(f.getLocalVersionInfo)
|
s.ConnectGetLocalVersionInfo(f.getLocalVersionInfo)
|
||||||
s.ConnectIsNewVersionAvailable(f.isNewVersionAvailable)
|
s.ConnectCheckForUpdates(f.checkForUpdates)
|
||||||
s.ConnectGetIMAPPort(f.getIMAPPort)
|
s.ConnectGetIMAPPort(f.getIMAPPort)
|
||||||
s.ConnectGetSMTPPort(f.getSMTPPort)
|
s.ConnectGetSMTPPort(f.getSMTPPort)
|
||||||
s.ConnectGetLastMailClient(f.getLastMailClient)
|
s.ConnectGetLastMailClient(f.getLastMailClient)
|
||||||
@ -180,8 +191,6 @@ func (s *GoQMLInterface) SetFrontend(f *FrontendQt) {
|
|||||||
s.SetGoos(runtime.GOOS)
|
s.SetGoos(runtime.GOOS)
|
||||||
s.SetProgramTitle(f.programName)
|
s.SetProgramTitle(f.programName)
|
||||||
|
|
||||||
s.SetReleaseNotesLink("https://protonmail.com/download/bridge/release_notes.html")
|
|
||||||
|
|
||||||
s.ConnectGetBackendVersion(func() string {
|
s.ConnectGetBackendVersion(func() string {
|
||||||
return f.programVer
|
return f.programVer
|
||||||
})
|
})
|
||||||
@ -193,5 +202,4 @@ func (s *GoQMLInterface) SetFrontend(f *FrontendQt) {
|
|||||||
s.ConnectToggleIsReportingOutgoingNoEnc(f.toggleIsReportingOutgoingNoEnc)
|
s.ConnectToggleIsReportingOutgoingNoEnc(f.toggleIsReportingOutgoingNoEnc)
|
||||||
s.ConnectShouldSendAnswer(f.shouldSendAnswer)
|
s.ConnectShouldSendAnswer(f.shouldSendAnswer)
|
||||||
s.ConnectSaveOutgoingNoEncPopupCoord(f.saveOutgoingNoEncPopupCoord)
|
s.ConnectSaveOutgoingNoEncPopupCoord(f.saveOutgoingNoEncPopupCoord)
|
||||||
s.ConnectStartUpdate(f.StartUpdate)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,10 @@ type NoEncConfirmator interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Updater interface {
|
type Updater interface {
|
||||||
|
Check() (updater.VersionInfo, error)
|
||||||
InstallUpdate(updater.VersionInfo) error
|
InstallUpdate(updater.VersionInfo) error
|
||||||
|
IsUpdateApplicable(updater.VersionInfo) bool
|
||||||
|
CanInstall(updater.VersionInfo) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserManager is an interface of users needed by frontend.
|
// UserManager is an interface of users needed by frontend.
|
||||||
|
|||||||
@ -30,13 +30,13 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Installer struct{}
|
type InstallerDarwin struct{}
|
||||||
|
|
||||||
func NewInstaller(*versioner.Versioner) *Installer {
|
func NewInstaller(*versioner.Versioner) *InstallerDarwin {
|
||||||
return &Installer{}
|
return &InstallerDarwin{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Installer) InstallUpdate(_ *semver.Version, r io.Reader) error {
|
func (i *InstallerDarwin) InstallUpdate(_ *semver.Version, r io.Reader) error {
|
||||||
gr, err := gzip.NewReader(r)
|
gr, err := gzip.NewReader(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -26,16 +26,16 @@ import (
|
|||||||
"github.com/ProtonMail/proton-bridge/internal/versioner"
|
"github.com/ProtonMail/proton-bridge/internal/versioner"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Installer struct {
|
type InstallerDefault struct {
|
||||||
versioner *versioner.Versioner
|
versioner *versioner.Versioner
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInstaller(versioner *versioner.Versioner) *Installer {
|
func NewInstaller(versioner *versioner.Versioner) *InstallerDefault {
|
||||||
return &Installer{
|
return &InstallerDefault{
|
||||||
versioner: versioner,
|
versioner: versioner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Installer) InstallUpdate(version *semver.Version, r io.Reader) error {
|
func (i *InstallerDefault) InstallUpdate(version *semver.Version, r io.Reader) error {
|
||||||
return i.versioner.InstallNewVersion(version, r)
|
return i.versioner.InstallNewVersion(version, r)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,6 @@ package updater
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Masterminds/semver/v3"
|
"github.com/Masterminds/semver/v3"
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
@ -29,17 +28,19 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type clientProvider interface {
|
var ErrManualUpdateRequired = errors.New("manual update is required")
|
||||||
|
|
||||||
|
type ClientProvider interface {
|
||||||
GetAnonymousClient() pmapi.Client
|
GetAnonymousClient() pmapi.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
type installer interface {
|
type Installer interface {
|
||||||
InstallUpdate(*semver.Version, io.Reader) error
|
InstallUpdate(*semver.Version, io.Reader) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
cm clientProvider
|
cm ClientProvider
|
||||||
installer installer
|
installer Installer
|
||||||
kr *crypto.KeyRing
|
kr *crypto.KeyRing
|
||||||
|
|
||||||
curVer *semver.Version
|
curVer *semver.Version
|
||||||
@ -51,8 +52,8 @@ type Updater struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(
|
func New(
|
||||||
cm clientProvider,
|
cm ClientProvider,
|
||||||
installer installer,
|
installer Installer,
|
||||||
kr *crypto.KeyRing,
|
kr *crypto.KeyRing,
|
||||||
curVer *semver.Version,
|
curVer *semver.Version,
|
||||||
updateURLName, platform string,
|
updateURLName, platform string,
|
||||||
@ -70,56 +71,44 @@ func New(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Updater) Watch(
|
func (u *Updater) Check() (VersionInfo, error) {
|
||||||
period time.Duration,
|
|
||||||
handleUpdate func(VersionInfo) error,
|
|
||||||
handleError func(error),
|
|
||||||
) func() {
|
|
||||||
logrus.WithField("period", period).Info("Watching for updates")
|
|
||||||
|
|
||||||
ticker := time.NewTicker(period)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
u.watch(handleUpdate, handleError)
|
|
||||||
<-ticker.C
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return ticker.Stop
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Updater) watch(
|
|
||||||
handleUpdate func(VersionInfo) error,
|
|
||||||
handleError func(error),
|
|
||||||
) {
|
|
||||||
logrus.Info("Checking for updates")
|
logrus.Info("Checking for updates")
|
||||||
|
|
||||||
latest, err := u.fetchVersionInfo()
|
client := u.cm.GetAnonymousClient()
|
||||||
|
defer client.Logout()
|
||||||
|
|
||||||
|
r, err := client.DownloadAndVerify(
|
||||||
|
u.getVersionFileURL(),
|
||||||
|
u.getVersionFileURL()+".sig",
|
||||||
|
u.kr,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleError(errors.Wrap(err, "failed to fetch version info"))
|
return VersionInfo{}, err
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !latest.Version.GreaterThan(u.curVer) || u.rollout > latest.Rollout {
|
var versionMap VersionMap
|
||||||
logrus.WithError(err).Debug("No need to update")
|
|
||||||
return
|
if err := json.NewDecoder(r).Decode(&versionMap); err != nil {
|
||||||
|
return VersionInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.curVer.LessThan(latest.MinAuto) {
|
return versionMap[Channel], nil
|
||||||
logrus.Debug("A manual update is required")
|
}
|
||||||
// NOTE: Need to notify user that they must update manually.
|
|
||||||
return
|
func (u *Updater) IsUpdateApplicable(version VersionInfo) bool {
|
||||||
|
if !version.Version.GreaterThan(u.curVer) {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.
|
if u.rollout > version.Rollout {
|
||||||
WithField("latest", latest.Version).
|
return false
|
||||||
WithField("current", u.curVer).
|
|
||||||
Info("An update is available")
|
|
||||||
|
|
||||||
if err := handleUpdate(latest); err != nil {
|
|
||||||
handleError(errors.Wrap(err, "failed to handle update"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Updater) CanInstall(version VersionInfo) bool {
|
||||||
|
return !u.curVer.LessThan(version.MinAuto)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Updater) InstallUpdate(update VersionInfo) error {
|
func (u *Updater) InstallUpdate(update VersionInfo) error {
|
||||||
@ -143,25 +132,3 @@ func (u *Updater) InstallUpdate(update VersionInfo) error {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Updater) fetchVersionInfo() (VersionInfo, error) {
|
|
||||||
client := u.cm.GetAnonymousClient()
|
|
||||||
defer client.Logout()
|
|
||||||
|
|
||||||
r, err := client.DownloadAndVerify(
|
|
||||||
u.getVersionFileURL(),
|
|
||||||
u.getVersionFileURL()+".sig",
|
|
||||||
u.kr,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return VersionInfo{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var versionMap VersionMap
|
|
||||||
|
|
||||||
if err := json.NewDecoder(r).Decode(&versionMap); err != nil {
|
|
||||||
return VersionInfo{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return versionMap[Channel], nil
|
|
||||||
}
|
|
||||||
|
|||||||
@ -34,13 +34,13 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWatch(t *testing.T) {
|
func TestCheck(t *testing.T) {
|
||||||
c := gomock.NewController(t)
|
c := gomock.NewController(t)
|
||||||
defer c.Finish()
|
defer c.Finish()
|
||||||
|
|
||||||
client := mocks.NewMockClient(c)
|
client := mocks.NewMockClient(c)
|
||||||
|
|
||||||
updater := newTestUpdater(client, "1.4.0")
|
updater := newTestUpdater(client, "1.1.0")
|
||||||
|
|
||||||
versionMap := VersionMap{
|
versionMap := VersionMap{
|
||||||
"live": VersionInfo{
|
"live": VersionInfo{
|
||||||
@ -59,119 +59,19 @@ func TestWatch(t *testing.T) {
|
|||||||
|
|
||||||
client.EXPECT().Logout()
|
client.EXPECT().Logout()
|
||||||
|
|
||||||
updateCh := make(chan VersionInfo)
|
version, err := updater.Check()
|
||||||
|
|
||||||
defer updater.Watch(
|
assert.Equal(t, semver.MustParse("1.5.0"), version.Version)
|
||||||
time.Minute,
|
assert.NoError(t, err)
|
||||||
func(update VersionInfo) error {
|
|
||||||
updateCh <- update
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
func(err error) {
|
|
||||||
t.Fatal(err)
|
|
||||||
},
|
|
||||||
)()
|
|
||||||
|
|
||||||
assert.Equal(t, semver.MustParse("1.5.0"), (<-updateCh).Version)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWatchIgnoresCurrentVersion(t *testing.T) {
|
func TestCheckBadSignature(t *testing.T) {
|
||||||
c := gomock.NewController(t)
|
c := gomock.NewController(t)
|
||||||
defer c.Finish()
|
defer c.Finish()
|
||||||
|
|
||||||
client := mocks.NewMockClient(c)
|
client := mocks.NewMockClient(c)
|
||||||
|
|
||||||
updater := newTestUpdater(client, "1.5.0")
|
updater := newTestUpdater(client, "1.2.0")
|
||||||
|
|
||||||
versionMap := VersionMap{
|
|
||||||
"live": VersionInfo{
|
|
||||||
Version: semver.MustParse("1.5.0"),
|
|
||||||
MinAuto: semver.MustParse("1.4.0"),
|
|
||||||
Package: "https://protonmail.com/download/bridge/update_1.5.0_linux.tgz",
|
|
||||||
Rollout: 1.0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
client.EXPECT().DownloadAndVerify(
|
|
||||||
updater.getVersionFileURL(),
|
|
||||||
updater.getVersionFileURL()+".sig",
|
|
||||||
gomock.Any(),
|
|
||||||
).Return(bytes.NewReader(mustMarshal(t, versionMap)), nil)
|
|
||||||
|
|
||||||
client.EXPECT().Logout()
|
|
||||||
|
|
||||||
updateCh := make(chan VersionInfo)
|
|
||||||
|
|
||||||
defer updater.Watch(
|
|
||||||
time.Minute,
|
|
||||||
func(update VersionInfo) error {
|
|
||||||
updateCh <- update
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
func(err error) {
|
|
||||||
t.Fatal(err)
|
|
||||||
},
|
|
||||||
)()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-updateCh:
|
|
||||||
t.Fatal("We shouldn't update because we are already up to date")
|
|
||||||
case <-time.After(1500 * time.Millisecond):
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWatchIgnoresVerionsThatRequireManualUpdate(t *testing.T) {
|
|
||||||
c := gomock.NewController(t)
|
|
||||||
defer c.Finish()
|
|
||||||
|
|
||||||
client := mocks.NewMockClient(c)
|
|
||||||
|
|
||||||
updater := newTestUpdater(client, "1.4.0")
|
|
||||||
|
|
||||||
versionMap := VersionMap{
|
|
||||||
"live": VersionInfo{
|
|
||||||
Version: semver.MustParse("1.5.0"),
|
|
||||||
MinAuto: semver.MustParse("1.5.0"),
|
|
||||||
Package: "https://protonmail.com/download/bridge/update_1.5.0_linux.tgz",
|
|
||||||
Rollout: 1.0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
client.EXPECT().DownloadAndVerify(
|
|
||||||
updater.getVersionFileURL(),
|
|
||||||
updater.getVersionFileURL()+".sig",
|
|
||||||
gomock.Any(),
|
|
||||||
).Return(bytes.NewReader(mustMarshal(t, versionMap)), nil)
|
|
||||||
|
|
||||||
client.EXPECT().Logout()
|
|
||||||
|
|
||||||
updateCh := make(chan VersionInfo)
|
|
||||||
|
|
||||||
defer updater.Watch(
|
|
||||||
time.Minute,
|
|
||||||
func(update VersionInfo) error {
|
|
||||||
updateCh <- update
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
func(err error) {
|
|
||||||
t.Fatal(err)
|
|
||||||
},
|
|
||||||
)()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-updateCh:
|
|
||||||
t.Fatal("We shouldn't update because this version requires a manual update")
|
|
||||||
case <-time.After(1500 * time.Millisecond):
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWatchBadSignature(t *testing.T) {
|
|
||||||
c := gomock.NewController(t)
|
|
||||||
defer c.Finish()
|
|
||||||
|
|
||||||
client := mocks.NewMockClient(c)
|
|
||||||
|
|
||||||
updater := newTestUpdater(client, "1.4.0")
|
|
||||||
|
|
||||||
client.EXPECT().DownloadAndVerify(
|
client.EXPECT().DownloadAndVerify(
|
||||||
updater.getVersionFileURL(),
|
updater.getVersionFileURL(),
|
||||||
@ -181,21 +81,72 @@ func TestWatchBadSignature(t *testing.T) {
|
|||||||
|
|
||||||
client.EXPECT().Logout()
|
client.EXPECT().Logout()
|
||||||
|
|
||||||
updateCh := make(chan VersionInfo)
|
_, err := updater.Check()
|
||||||
errorsCh := make(chan error)
|
|
||||||
|
|
||||||
defer updater.Watch(
|
assert.Error(t, err)
|
||||||
time.Minute,
|
}
|
||||||
func(update VersionInfo) error {
|
|
||||||
updateCh <- update
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
func(err error) {
|
|
||||||
errorsCh <- err
|
|
||||||
},
|
|
||||||
)()
|
|
||||||
|
|
||||||
assert.Error(t, <-errorsCh)
|
func TestIsUpdateApplicable(t *testing.T) {
|
||||||
|
c := gomock.NewController(t)
|
||||||
|
defer c.Finish()
|
||||||
|
|
||||||
|
client := mocks.NewMockClient(c)
|
||||||
|
|
||||||
|
updater := newTestUpdater(client, "1.4.0")
|
||||||
|
|
||||||
|
versionOld := VersionInfo{
|
||||||
|
Version: semver.MustParse("1.3.0"),
|
||||||
|
MinAuto: semver.MustParse("1.3.0"),
|
||||||
|
Package: "https://protonmail.com/download/bridge/update_1.3.0_linux.tgz",
|
||||||
|
Rollout: 1.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, false, updater.IsUpdateApplicable(versionOld))
|
||||||
|
|
||||||
|
versionEqual := VersionInfo{
|
||||||
|
Version: semver.MustParse("1.4.0"),
|
||||||
|
MinAuto: semver.MustParse("1.3.0"),
|
||||||
|
Package: "https://protonmail.com/download/bridge/update_1.4.0_linux.tgz",
|
||||||
|
Rollout: 1.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, false, updater.IsUpdateApplicable(versionEqual))
|
||||||
|
|
||||||
|
versionNew := VersionInfo{
|
||||||
|
Version: semver.MustParse("1.5.0"),
|
||||||
|
MinAuto: semver.MustParse("1.3.0"),
|
||||||
|
Package: "https://protonmail.com/download/bridge/update_1.5.0_linux.tgz",
|
||||||
|
Rollout: 1.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, true, updater.IsUpdateApplicable(versionNew))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCanInstall(t *testing.T) {
|
||||||
|
c := gomock.NewController(t)
|
||||||
|
defer c.Finish()
|
||||||
|
|
||||||
|
client := mocks.NewMockClient(c)
|
||||||
|
|
||||||
|
updater := newTestUpdater(client, "1.4.0")
|
||||||
|
|
||||||
|
versionManual := VersionInfo{
|
||||||
|
Version: semver.MustParse("1.5.0"),
|
||||||
|
MinAuto: semver.MustParse("1.5.0"),
|
||||||
|
Package: "https://protonmail.com/download/bridge/update_1.5.0_linux.tgz",
|
||||||
|
Rollout: 1.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, false, updater.CanInstall(versionManual))
|
||||||
|
|
||||||
|
versionAuto := VersionInfo{
|
||||||
|
Version: semver.MustParse("1.5.0"),
|
||||||
|
MinAuto: semver.MustParse("1.3.0"),
|
||||||
|
Package: "https://protonmail.com/download/bridge/update_1.5.0_linux.tgz",
|
||||||
|
Rollout: 1.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, true, updater.CanInstall(versionAuto))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInstallUpdate(t *testing.T) {
|
func TestInstallUpdate(t *testing.T) {
|
||||||
@ -221,7 +172,9 @@ func TestInstallUpdate(t *testing.T) {
|
|||||||
|
|
||||||
client.EXPECT().Logout()
|
client.EXPECT().Logout()
|
||||||
|
|
||||||
assert.NoError(t, updater.InstallUpdate(latestVersion))
|
err := updater.InstallUpdate(latestVersion)
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInstallUpdateBadSignature(t *testing.T) {
|
func TestInstallUpdateBadSignature(t *testing.T) {
|
||||||
@ -247,7 +200,9 @@ func TestInstallUpdateBadSignature(t *testing.T) {
|
|||||||
|
|
||||||
client.EXPECT().Logout()
|
client.EXPECT().Logout()
|
||||||
|
|
||||||
assert.Error(t, updater.InstallUpdate(latestVersion))
|
err := updater.InstallUpdate(latestVersion)
|
||||||
|
|
||||||
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInstallUpdateAlreadyOngoing(t *testing.T) {
|
func TestInstallUpdateAlreadyOngoing(t *testing.T) {
|
||||||
|
|||||||
@ -5,6 +5,22 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
|
|||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
* GODT-906 Handle RFC2047-encoded content transfer encoding values.
|
||||||
|
|
||||||
|
* GODT-875 Added GUI dialog on force update.
|
||||||
|
* GODT-820 Added GUI notification on impossibility of update installation (both silent and manual).
|
||||||
|
* GODT-870 Added GUI notification on error during silent update.
|
||||||
|
* GODT-805 Added GUI notification on update available.
|
||||||
|
* GODT-804 Added GUI notification on silent update installed (promt to restart).
|
||||||
|
* GODT-275 Added option to disable autoupdates in settings (default autoupdate is enabled).
|
||||||
|
* GODT-874 Added manual triggers to Updater module.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* GODT-893 Bump go-rfc5322 dependency to v0.2.1 to properly detect syntax errors during parsing.
|
||||||
|
* GODT-892 Swap type and value from sentry exception and cut panic handlers from the traceback.
|
||||||
|
* GODT-854 EXPUNGE and FETCH unilateral responses are returned before OK EXPUNGE or OK STORE, respectively.
|
||||||
|
|
||||||
|
* GODT-806 Changed GUI dialog on manual update. Added autoupdates checkbox. Simplifyed installation process GUI.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user