v0.4.7 2ff82fa

chat_timestamps.go RawHistoryFolder

1package modes
2
3import (
4	"strconv"
5
6	"github.com/patriceckhart/zot/packages/tui"
7)
8
9// Optional to preserve compatibility with embedders implementing SettingsStore.
10type chatTimestampSettingsStore interface {
11	SetChatTimestamps(bool) error
12	SetChatTimestampInterval(int) error
13}
14
15type chatTimestampDateSettingsStore interface {
16	SetChatTimestampDate(string) error
17}
18
19func (i *Interactive) chatTimestampDateSetting() settingsItem {
20	choice := 0
21	if tui.ChatTimestampDateMode(i.cfg.ChatTimestampDate) == "every_message" {
22		choice = 1
23	}
24	return settingsItem{
25		key:    "chat_timestamp_date",
26		label:  "date display",
27		desc:   "choose when to include the date beside the time",
28		choice: choice,
29		options: []settingsOption{
30			{value: "day_start", label: "Start of each day", desc: "show the date on the first timestamp and when the day changes"},
31			{value: "every_message", label: "Every timestamp", desc: "include the date on every displayed timestamp"},
32		},
33	}
34}
35
36func (i *Interactive) applyChatTimestampDate(value string) {
37	mode := tui.ChatTimestampDateMode(value)
38	if store, ok := i.cfg.SettingsStore.(chatTimestampDateSettingsStore); ok {
39		if err := store.SetChatTimestampDate(mode); err != nil {
40			i.chatTimestampSettingError(err)
41			return
42		}
43	}
44	i.mu.Lock()
45	i.cfg.ChatTimestampDate = mode
46	i.view.ChatTimestampDate = mode
47	i.statusOK = "timestamp date display updated"
48	i.statusErr = ""
49	i.mu.Unlock()
50	i.repaintChatTimestamps()
51}
52
53func (i *Interactive) chatTimestampIntervalSetting() settingsItem {
54	minutes := tui.ChatTimestampInterval(i.cfg.ChatTimestampIntervalMinutes)
55	item := settingsItem{
56		key:   "chat_timestamp_interval_minutes",
57		label: "interval",
58		desc:  "minimum minutes since the last timestamp, zero shows every completed message",
59	}
60	values := []int{0, 1, 5, 10, 15, 30, 60}
61	found := false
62	for _, value := range values {
63		found = found || value == minutes
64	}
65	if !found {
66		values = append(values, minutes)
67	}
68	for idx, value := range values {
69		label := strconv.Itoa(value) + " min"
70		if value == 0 {
71			label = "every message"
72		}
73		item.options = append(item.options, settingsOption{value: strconv.Itoa(value), label: label})
74		if value == minutes {
75			item.choice = idx
76		}
77	}
78	return item
79}
80
81func (i *Interactive) applyChatTimestamps(enabled bool) {
82	if store, ok := i.cfg.SettingsStore.(chatTimestampSettingsStore); ok {
83		if err := store.SetChatTimestamps(enabled); err != nil {
84			i.chatTimestampSettingError(err)
85			return
86		}
87	}
88	i.mu.Lock()
89	i.cfg.ChatTimestamps = enabled
90	i.view.ChatTimestamps = enabled
91	i.statusOK = "chat timestamps " + onOff(enabled)
92	i.statusErr = ""
93	i.mu.Unlock()
94	i.repaintChatTimestamps()
95}
96
97func (i *Interactive) applyChatTimestampInterval(value string) {
98	minutes, err := strconv.Atoi(value)
99	if err != nil || minutes < 0 {
100		return
101	}
102	if store, ok := i.cfg.SettingsStore.(chatTimestampSettingsStore); ok {
103		if err := store.SetChatTimestampInterval(minutes); err != nil {
104			i.chatTimestampSettingError(err)
105			return
106		}
107	}
108	i.mu.Lock()
109	i.cfg.ChatTimestampIntervalMinutes = &minutes
110	i.view.ChatTimestampIntervalMinutes = &minutes
111	i.statusOK = "chat timestamp interval " + value + " min"
112	i.statusErr = ""
113	i.mu.Unlock()
114	i.repaintChatTimestamps()
115}
116
117func (i *Interactive) chatTimestampSettingError(err error) {
118	i.mu.Lock()
119	i.statusErr = "settings: " + err.Error()
120	i.statusOK = ""
121	i.mu.Unlock()
122	i.invalidate()
123}
124
125func (i *Interactive) repaintChatTimestamps() {
126	if i.rend != nil {
127		i.rend.Clear()
128	}
129	i.invalidate()
130}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 477

↑↓ moveenter openesc close