Skip to content
Snippets Groups Projects
systray.go 3.84 KiB
Newer Older
  • Learn to ignore specific revisions
  • package main
    
    import (
    
    meskio's avatar
    meskio committed
    	"os"
    
    meskio's avatar
    meskio committed
    	"time"
    
    	"0xacab.org/meskio/bitmask-systray/bitmask"
    
    	"0xacab.org/meskio/bitmask-systray/icon"
    	"github.com/getlantern/systray"
    	"github.com/skratchdot/open-golang/open"
    )
    
    type bmTray struct {
    
    	bm        *bitmask.Bitmask
    
    meskio's avatar
    meskio committed
    	waitCh    chan bool
    
    	mStatus   *systray.MenuItem
    	mTurnOn   *systray.MenuItem
    	mTurnOff  *systray.MenuItem
    	mCancel   *systray.MenuItem
    	mGateways []*systray.MenuItem
    }
    
    
    func run(bm *bitmask.Bitmask) {
    	bt := bmTray{bm: bm}
    
    	systray.Run(bt.onReady, bt.onExit)
    }
    
    func (bt bmTray) onExit() {
    	// TODO: this doesn't get executed :(
    
    	log.Println("Finished onExit")
    
    }
    
    func (bt *bmTray) onReady() {
    	bt.mStatus = systray.AddMenuItem("Checking status...", "")
    	bt.mStatus.Disable()
    	bt.mTurnOn = systray.AddMenuItem("Turn on", "Turn RiseupVPN on")
    	go bt.mTurnOn.Hide()
    	bt.mTurnOff = systray.AddMenuItem("Turn off", "Turn RiseupVPN off")
    	go bt.mTurnOff.Hide()
    	bt.mCancel = systray.AddMenuItem("Cancel", "Cancel connection to RiseupVPN")
    	go bt.mCancel.Hide()
    	systray.AddSeparator()
    
    	mGateway := systray.AddMenuItem("Route traffic through", "")
    	mGateway.Disable()
    	bt.mGateways = append(bt.mGateways, systray.AddMenuItem("Seattle", "Use RiseupVPN Seattle gateway"))
    	bt.mGateways = append(bt.mGateways, systray.AddMenuItem("Montreal", "Use RiseupVPN Montreal gateway"))
    	bt.mGateways = append(bt.mGateways, systray.AddMenuItem("Amsterdam", "Use RiseupVPN Amsterdam gateway"))
    	bt.mGateways[0].Check()
    	bt.mGateways[1].Uncheck()
    	bt.mGateways[2].Uncheck()
    	systray.AddSeparator()
    
    
    	mHelp := systray.AddMenuItem("Help ...", "")
    	mDonate := systray.AddMenuItem("Donate ...)", "")
    	mAbout := systray.AddMenuItem("About ...", "")
    
    	systray.AddSeparator()
    
    	mQuit := systray.AddMenuItem("Quit", "Quit BitmaskVPN")
    
    	go func() {
    
    		ch := bt.bm.GetStatusCh()
    		status, err := bt.bm.GetStatus()
    		if err != nil {
    			log.Printf("Error getting status: %v", err)
    		} else {
    			bt.changeStatus(status)
    		}
    
    
    		for {
    			select {
    			case status := <-ch:
    
    				log.Println("status: " + status)
    
    				bt.changeStatus(status)
    
    			case <-bt.mTurnOn.ClickedCh:
    
    				log.Println("on")
    				bt.bm.StartVPN(provider)
    
    			case <-bt.mTurnOff.ClickedCh:
    
    				log.Println("off")
    				bt.bm.StopVPN()
    
    			case <-bt.mCancel.ClickedCh:
    
    				log.Println("cancel")
    				bt.bm.StopVPN()
    
    
    			case <-mHelp.ClickedCh:
    				open.Run("https://riseup.net/en/vpn/vpn-black")
    			case <-mDonate.ClickedCh:
    				open.Run("https://riseup.net/en/donate")
    			case <-mAbout.ClickedCh:
    				open.Run("https://bitmask.net")
    
    			case <-mQuit.ClickedCh:
    				systray.Quit()
    
    				bt.bm.Close()
    				log.Println("Quit now...")
    
    meskio's avatar
    meskio committed
    				os.Exit(0)
    
    			}
    		}
    	}()
    }
    
    func (bt *bmTray) changeStatus(status string) {
    	statusStr := status
    
    	bt.mTurnOn.SetTitle("Turn on")
    
    meskio's avatar
    meskio committed
    	if bt.waitCh != nil {
    		bt.waitCh <- true
    		bt.waitCh = nil
    	}
    
    
    	switch status {
    	case "on":
    		systray.SetIcon(icon.On)
    		go bt.mTurnOn.Hide()
    		go bt.mTurnOff.Show()
    		go bt.mCancel.Hide()
    
    	case "off":
    		systray.SetIcon(icon.Off)
    		go bt.mTurnOn.Show()
    		go bt.mTurnOff.Hide()
    		go bt.mCancel.Hide()
    
    	case "starting":
    
    meskio's avatar
    meskio committed
    		bt.waitCh = make(chan bool)
    		go bt.waitIcon()
    
    		go bt.mTurnOn.Hide()
    		go bt.mTurnOff.Hide()
    		go bt.mCancel.Show()
    
    	case "stopping":
    
    meskio's avatar
    meskio committed
    		bt.waitCh = make(chan bool)
    		go bt.waitIcon()
    
    		go bt.mTurnOn.Hide()
    		go bt.mTurnOff.Hide()
    		go bt.mCancel.Hide()
    
    	case "failed":
    		systray.SetIcon(icon.Error)
    
    		bt.mTurnOn.SetTitle("Retry")
    
    		go bt.mTurnOn.Show()
    
    		go bt.mTurnOff.Show()
    		go bt.mCancel.Hide()
    
    		statusStr = "blocking internet"
    	}
    
    	systray.SetTooltip("RiseupVPN is " + statusStr)
    	bt.mStatus.SetTitle("VPN is " + statusStr)
    	bt.mStatus.SetTooltip("RiseupVPN is " + statusStr)
    }
    
    meskio's avatar
    meskio committed
    
    func (bt *bmTray) waitIcon() {
    	icons := [][]byte{icon.Wait0, icon.Wait1, icon.Wait2, icon.Wait3}
    
    meskio's avatar
    meskio committed
    	for i := 0; true; i = (i + 1) % 4 {
    
    meskio's avatar
    meskio committed
    		systray.SetIcon(icons[i])
    
    meskio's avatar
    meskio committed
    		select {
    		case <-bt.waitCh:
    			return
    		case <-time.After(time.Millisecond * 500):
    
    meskio's avatar
    meskio committed
    			continue
    
    meskio's avatar
    meskio committed
    		}
    	}
    }