summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2020-06-16 21:28:48 +0200
committerkali kaneko (leap communications) <kali@leap.se>2020-06-26 12:12:41 +0200
commitc17b5f6f7b6b28c890764688ff5e966ecebece63 (patch)
tree4c9931b10e7cddd9050f76aff95205dbf04d6d26 /pkg
parenta18e61aa1be37aa568552c69fbd743d25498b9bb (diff)
[feat] re-implement donation reminders
first pass on giving functionality to the donation reminder
Diffstat (limited to 'pkg')
-rw-r--r--pkg/backend/api.go29
-rw-r--r--pkg/backend/bitmask.go19
-rw-r--r--pkg/backend/donate.go35
-rw-r--r--pkg/backend/status.go103
-rw-r--r--pkg/config/gui.go14
5 files changed, 126 insertions, 74 deletions
diff --git a/pkg/backend/api.go b/pkg/backend/api.go
index f924cbd..5cb0304 100644
--- a/pkg/backend/api.go
+++ b/pkg/backend/api.go
@@ -6,6 +6,7 @@ import (
"C"
"fmt"
"log"
+ "time"
"unsafe"
"0xacab.org/leap/bitmask-vpn/pkg/bitmask"
@@ -23,18 +24,24 @@ func SwitchOff() {
}
func Unblock() {
+ //TODO
fmt.Println("unblock... [not implemented]")
}
func Quit() {
if ctx.Status != off {
go setStatus(stopping)
+ ctx.cfg.SetUserStoppedVPN(true)
stopVPN()
}
}
-func ToggleDonate() {
- toggleDonate()
+func DonateAccepted() {
+ donateAccepted()
+}
+
+func DonateRejected() {
+ donateRejected()
}
func SubscribeToEvent(event string, f unsafe.Pointer) {
@@ -42,21 +49,23 @@ func SubscribeToEvent(event string, f unsafe.Pointer) {
}
func InitializeBitmaskContext() {
- pi := bitmask.GetConfiguredProvider()
+ p := bitmask.GetConfiguredProvider()
initOnce.Do(func() {
- initializeContext(pi.Provider, pi.AppName)
+ initializeContext(
+ p.Provider, p.AppName)
})
go ctx.updateStatus()
- /* DEBUG
- timer := time.NewTimer(time.Second * 3)
go func() {
- <-timer.C
- fmt.Println("donate timer fired")
- toggleDonate()
+ if needsDonationReminder() {
+ // wait a bit before launching reminder
+ timer := time.NewTimer(time.Minute * 5)
+ <-timer.C
+ showDonate()
+ }
+
}()
- */
}
func RefreshContext() *C.char {
diff --git a/pkg/backend/bitmask.go b/pkg/backend/bitmask.go
index 07d27ea..8fd2367 100644
--- a/pkg/backend/bitmask.go
+++ b/pkg/backend/bitmask.go
@@ -5,6 +5,7 @@ import (
"os"
"0xacab.org/leap/bitmask-vpn/pkg/bitmask"
+ "0xacab.org/leap/bitmask-vpn/pkg/config"
)
func initializeBitmask() {
@@ -19,6 +20,7 @@ func initializeBitmask() {
log.Println("error: cannot initialize bitmask")
}
ctx.bm = b
+ ctx.cfg = config.ParseConfig()
}
func startVPN() {
@@ -36,16 +38,25 @@ func stopVPN() {
}
}
+func wantDonations() bool {
+ if config.AskForDonations == "true" {
+ return true
+ }
+ return false
+}
+
// initializeContext initializes an empty connStatus and assigns it to the
// global ctx holder. This is expected to be called only once, so the public
// api uses the sync.Once primitive to call this.
func initializeContext(provider, appName string) {
var st status = off
ctx = &connectionCtx{
- AppName: appName,
- Provider: provider,
- Donate: false,
- Status: st,
+ AppName: appName,
+ Provider: provider,
+ DonateURL: config.DonateURL,
+ AskForDonations: wantDonations(),
+ DonateDialog: false,
+ Status: st,
}
go trigger(OnStatusChanged)
initializeBitmask()
diff --git a/pkg/backend/donate.go b/pkg/backend/donate.go
new file mode 100644
index 0000000..d216687
--- /dev/null
+++ b/pkg/backend/donate.go
@@ -0,0 +1,35 @@
+package backend
+
+import (
+ "log"
+ "time"
+)
+
+func needsDonationReminder() bool {
+ return ctx.cfg.NeedsDonationReminder()
+}
+
+func donateAccepted() {
+ stmut.Lock()
+ defer stmut.Unlock()
+ ctx.DonateDialog = false
+ log.Println("marking as donated")
+ ctx.cfg.SetDonated()
+ go trigger(OnStatusChanged)
+}
+
+func donateRejected() {
+ timer := time.NewTimer(time.Hour)
+ go func() {
+ <-timer.C
+ showDonate()
+ }()
+}
+
+func showDonate() {
+ stmut.Lock()
+ defer stmut.Unlock()
+ ctx.DonateDialog = true
+ ctx.cfg.SetLastReminded()
+ go trigger(OnStatusChanged)
+}
diff --git a/pkg/backend/status.go b/pkg/backend/status.go
index e2d31db..7e9f211 100644
--- a/pkg/backend/status.go
+++ b/pkg/backend/status.go
@@ -6,6 +6,7 @@ import (
"log"
"0xacab.org/leap/bitmask-vpn/pkg/bitmask"
+ "0xacab.org/leap/bitmask-vpn/pkg/config"
)
const (
@@ -20,60 +21,20 @@ const (
// if we ever switch again to a provider-agnostic app, we should keep a map here.
var ctx *connectionCtx
-// the status type reflects the current VPN status. Go code is responsible for updating
-// it; the C gui just watches its changes and pulls its updates via the serialized
-// context object.
-
-type status int
-
-const (
- off status = iota
- starting
- on
- stopping
- failed
- unknown
-)
-
-func (s status) String() string {
- return [...]string{offStr, startingStr, onStr, stoppingStr, failedStr}[s]
-}
-
-func (s status) MarshalJSON() ([]byte, error) {
- b := bytes.NewBufferString(`"`)
- b.WriteString(s.String())
- b.WriteString(`"`)
- return b.Bytes(), nil
-}
-
-func (s status) fromString(st string) status {
- switch st {
- case offStr:
- return off
- case startingStr:
- return starting
- case onStr:
- return on
- case stoppingStr:
- return stopping
- case failedStr:
- return failed
- default:
- return unknown
- }
-}
-
// The connectionCtx keeps the global state that is passed around to C-land. It
// also serves as the primary way of passing requests from the frontend to the
// Go-core, by letting the UI write some of these variables and processing
// them.
type connectionCtx struct {
- AppName string `json:"appName"`
- Provider string `json:"provider"`
- Donate bool `json:"donate"`
- Status status `json:"status"`
- bm bitmask.Bitmask
+ AppName string `json:"appName"`
+ Provider string `json:"provider"`
+ AskForDonations bool `json:"askForDonations"`
+ DonateDialog bool `json:"donateDialog"`
+ DonateURL string `json:"donateURL"`
+ Status status `json:"status"`
+ bm bitmask.Bitmask
+ cfg *config.Config
}
func (c connectionCtx) toJson() ([]byte, error) {
@@ -110,11 +71,47 @@ func setStatus(st status) {
go trigger(OnStatusChanged)
}
-func toggleDonate() {
- stmut.Lock()
- defer stmut.Unlock()
- ctx.Donate = !ctx.Donate
- go trigger(OnStatusChanged)
+// the status type reflects the current VPN status. Go code is responsible for updating
+// it; the C gui just watches its changes and pulls its updates via the serialized
+// context object.
+
+type status int
+
+const (
+ off status = iota
+ starting
+ on
+ stopping
+ failed
+ unknown
+)
+
+func (s status) String() string {
+ return [...]string{offStr, startingStr, onStr, stoppingStr, failedStr}[s]
+}
+
+func (s status) MarshalJSON() ([]byte, error) {
+ b := bytes.NewBufferString(`"`)
+ b.WriteString(s.String())
+ b.WriteString(`"`)
+ return b.Bytes(), nil
+}
+
+func (s status) fromString(st string) status {
+ switch st {
+ case offStr:
+ return off
+ case startingStr:
+ return starting
+ case onStr:
+ return on
+ case stoppingStr:
+ return stopping
+ case failedStr:
+ return failed
+ default:
+ return unknown
+ }
}
func setStatusFromStr(stStr string) {
diff --git a/pkg/config/gui.go b/pkg/config/gui.go
index ce3f14d..5fa4886 100644
--- a/pkg/config/gui.go
+++ b/pkg/config/gui.go
@@ -37,7 +37,7 @@ var (
// Config holds the configuration of the systray
type Config struct {
file struct {
- LastNotification time.Time
+ LastReminded time.Time
Donated time.Time
SelectGateway bool
Obfs4 bool
@@ -77,16 +77,16 @@ func (c *Config) SetUserStoppedVPN(vpnStopped bool) error {
return c.save()
}
-func (c *Config) HasDonated() bool {
- return c.file.Donated.Add(oneMonth).After(time.Now())
+func (c *Config) NeedsDonationReminder() bool {
+ return !c.hasDonated() && c.file.LastReminded.Add(oneDay).Before(time.Now())
}
-func (c *Config) NeedsNotification() bool {
- return !c.HasDonated() && c.file.LastNotification.Add(oneDay).Before(time.Now())
+func (c *Config) hasDonated() bool {
+ return c.file.Donated.Add(oneMonth).After(time.Now())
}
-func (c *Config) SetNotification() error {
- c.file.LastNotification = time.Now()
+func (c *Config) SetLastReminded() error {
+ c.file.LastReminded = time.Now()
return c.save()
}