Add dialog that notifies you if an update is available. Fixes
MODIFY
app/app.go
app/app.go
@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/Bios-Marcel/cordless/readstate"
"github.com/Bios-Marcel/cordless/shortcuts"
+ "github.com/Bios-Marcel/cordless/version"
"log"
"os"
@@ -46,6 +47,15 @@ func Run() {
log.Fatalf("Error loading configuration file (%s).\n", configLoadError.Error())
}
+ updateAvailableChannel := make(chan bool, 1)
+ if configuration.ShowUpdateNotifications {
+ go func() {
+ updateAvailableChannel <- version.IsLocalOutdated(configuration.DontShowUpdateNotificationFor)
+ }()
+ } else {
+ updateAvailableChannel <- false
+ }
+
app.MouseEnabled = configuration.MouseEnabled
go func() {
@@ -64,7 +74,7 @@ func Run() {
log.Fatalf("Error persisting configuration (%s).\n", persistError.Error())
}
- readyChan := make(chan *discordgo.Ready)
+ readyChan := make(chan *discordgo.Ready, 1)
discord.AddHandlerOnce(func(s *discordgo.Session, event *discordgo.Ready) {
readyChan <- event
})
@@ -76,9 +86,41 @@ func Run() {
}
readyEvent := <-readyChan
+ close(readyChan)
readstate.Load(discord.State)
+ isUpdateAvailable := <-updateAvailableChannel
+ close(updateAvailableChannel)
+ if isUpdateAvailable {
+ waitForUpdateDialogChannel := make(chan bool, 1)
+
+ dialog := tview.NewModal()
+ dialog.SetText(fmt.Sprintf("Version %s of cordless is available!\nYou are currently running version %s.\n\nUpdates have to be installed manually or via your package manager.", version.GetLatestRemoteVersion(), version.Version))
+ buttonOk := "Thanks for the info"
+ buttonDontRemindAgainForThisVersion := fmt.Sprintf("Skip reminders for %s", version.GetLatestRemoteVersion())
+ buttonNeverRemindMeAgain := "Never remind me again"
+ dialog.AddButtons([]string{buttonOk, buttonDontRemindAgainForThisVersion, buttonNeverRemindMeAgain})
+ dialog.SetDoneFunc(func(index int, label string) {
+ if label == buttonDontRemindAgainForThisVersion {
+ configuration.DontShowUpdateNotificationFor = version.GetLatestRemoteVersion()
+ config.PersistConfig()
+ } else if label == buttonNeverRemindMeAgain {
+ configuration.ShowUpdateNotifications = false
+ config.PersistConfig()
+ }
+
+ waitForUpdateDialogChannel <- true
+ })
+
+ app.QueueUpdateDraw(func() {
+ app.SetRoot(dialog, true)
+ })
+
+ <-waitForUpdateDialogChannel
+ close(waitForUpdateDialogChannel)
+ }
+
app.QueueUpdateDraw(func() {
window, createError := ui.NewWindow(runNext, app, discord, readyEvent)

MODIFY
config/config.go
config/config.go
@@ -50,6 +50,8 @@ var (
ShortenerPort: 63212,
DesktopNotifications: true,
ShowPlaceholderForBlockedMessages: true,
+ DontShowUpdateNotificationFor: "",
+ ShowUpdateNotifications: true,
}
)
@@ -106,6 +108,14 @@ type Config struct {
// the timeline of messages.
ShowPlaceholderForBlockedMessages bool
+ // ShowUpdateNotifications decides whether update notifications are
+ // shown at all.
+ ShowUpdateNotifications bool
+ // DontShowUpdateNotificationFor decides what version to skip update
+ // notifications for. Since there's always only one latest version, this
+ // is a string and not an array of strings.
+ DontShowUpdateNotificationFor string
+
// Accounts contains all saved accounts, allowing the user to dynamicly
// switch between the accounts.
Accounts []*Account

MODIFY
go.mod
go.mod
@@ -13,6 +13,7 @@ require (
github.com/gdamore/tcell v1.3.0
github.com/gen2brain/beeep v0.0.0-20190317152856-aa3d7c1499fd
github.com/godbus/dbus v4.1.0+incompatible // indirect
+ github.com/google/go-github/v28 v28.1.1
github.com/gopherjs/gopherwasm v1.1.0 // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/pkg/errors v0.8.1

MODIFY
go.sum
go.sum
@@ -42,6 +42,12 @@ github.com/gen2brain/beeep v0.0.0-20190317152856-aa3d7c1499fd h1:sdFcN/xBncOaEHS
github.com/gen2brain/beeep v0.0.0-20190317152856-aa3d7c1499fd/go.mod h1:GprdPCZglWh5OMcIDpeKBxuUJI+fEDOTVUfxZeda4zo=
github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4=
github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
+github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo=
+github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
+github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
+github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c h1:16eHWuMGvCjSfgRJKqIzapE78onvvTbdi1rMkU00lZw=
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ=
@@ -90,7 +96,10 @@ golang.org/x/crypto v0.0.0-20190403202508-8e1b8d32e692 h1:GRhHqDOgeDr6QDTtq9gn2O
golang.org/x/crypto v0.0.0-20190403202508-8e1b8d32e692/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e h1:nFYrTHrdrAOpShe27kaFHjsqYSEQ0KWqdWLu3xuZJts=
@@ -104,6 +113,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 h1:MZF6J7CV6s/h0HBkfqebrYfKCVEo5iN+wzE4QhV3Evo=

ADD
version/check.go
+package version
+
+import (
+ "context"
+ "fmt"
+ "github.com/google/go-github/v28/github"
+)
+
+var latestRemoteVersion *string
+
+// IsLocalOutdated checks the latest release on github and compares the version
+// numbers. Version numbers representing a later date than the local version
+// will cause the call to return true. If an error occurs, we will return
+// false. If dontRemindFor is passed, false will be returned if it equals the
+// current remote version. This is used in order to avoid spamming the user
+// with an update notification on every startup.
+func IsLocalOutdated(dontRemindFor string) bool {
+ if GetLatestRemoteVersion() == "" || GetLatestRemoteVersion() == dontRemindFor {
+ return false
+ }
+
+ var yearRemote, monthRemote, dayRemote int
+ fmt.Sscanf(GetLatestRemoteVersion(), "%04d-%02d-%02d", &yearRemote, &monthRemote, &dayRemote)
+ var yearLocal, monthLocal, dayLocal int
+ fmt.Sscanf(Version, "%04d-%02d-%02d", &yearLocal, &monthLocal, &dayLocal)
+ return !(yearLocal >= yearRemote && monthLocal >= monthRemote && dayLocal >= dayRemote)
+}
+
+// GetLatestRemoteVersion queries GitHub for the latest Release-Tag and caches
+// it. This value will never be updated during runtime of cordless.
+func GetLatestRemoteVersion() string {
+ if latestRemoteVersion != nil {
+ return *latestRemoteVersion
+ }
+
+ repositoryRelease, _, lookupError := github.NewClient(nil).Repositories.GetLatestRelease(context.Background(), "Bios-Marcel", "cordless")
+ if lookupError == nil {
+ latestRemoteVersion = repositoryRelease.TagName
+ } else {
+ emptyVersion := ""
+ latestRemoteVersion = &emptyVersion
+ }
+
+ return *latestRemoteVersion
+}

Add dialog that notifies you if an update is available. Fixes #76