summaryrefslogtreecommitdiff
path: root/pim/cmd/cal9/menu.go
blob: f210ed02f2d012b5b6b31f83a5628cb17aa1c062 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package main

import (
	"os"
	"os/exec"
	"regexp"
	"strings"

	"9front/gui/ui"
)

func (s *state) menuItems() []ui.Item {
	items := []ui.Item{}
	// one toggle per calendar, so a crowded work calendar can be put
	// aside without unmounting anything
	for _, c := range s.cals {
		c := c
		mark := "[ ] "
		if s.on[c] {
			mark = "[x] "
		}
		items = append(items, ui.Item{Label: mark + c, Do: func() {
			s.on[c] = !s.on[c]
			s.load()
			s.redraw()
		}})
	}
	if len(writable()) > 0 {
		items = append(items, ui.Item{Label: "New event", Do: func() {
			s.New(520, 300, "cal9", "-v", "invite")
		}})
	}

	// A second view of the calendar is a second cal, in its own window.
	items = append(items, ui.Item{Label: "Open " + strings.ToLower(viewName[s.view]), Do: func() { s.openCal(s.view, s.at) }})
	items = append(items,
		ui.Item{Label: "Today", Do: func() {
			s.at = now()
			s.top = 8 * 60
			s.load()
			s.redraw()
		}},
		// rio has no iconify, so "compact" is a resize request: shrink
		// the window and the small-window view takes over by itself.
		// One item, not two: the window is either compact or it is not,
		// and offering the state you are already in is noise.
		s.compactItem(),
		// No move or resize here. rio owns the border -- it puts corner
		// cursors there and takes the clicks before we see them -- so
		// dragging it already moves and resizes the window, and doing
		// it worse from in here helps nobody.
		ui.Item{Label: "Hide", Do: func() { s.Wctl("hide") }},
		ui.Item{Label: "Exit", Do: func() { s.quit = true }},
	)
	return items
}

var urlRe = regexp.MustCompile(`https?://[^\s<>"]+`)

// plumb sends the event's join link to the plumber, falling back to the
// event file itself, which lands in acme.
func (s *state) plumb(e *event) error {
	data := e.file
	if body, err := os.ReadFile(e.file); err == nil {
		if m := urlRe.Find(body); m != nil {
			data = strings.TrimRight(string(m), ".,)")
		}
	}
	return exec.Command("/bin/plumb", data).Run()
}

// compactItem offers whichever of compact and restore you are not
// already in. compactH is the height below which the small view takes
// over, so it is also how we tell which state we are in.
func (s *state) compactItem() ui.Item {
	if s.Win.Rect().Dy() < compactH {
		return ui.Item{Label: "Restore", Do: func() { s.Resize(820, 620) }}
	}
	return ui.Item{Label: "Compact", Do: func() { s.Resize(320, 72) }}
}