summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Chausse <benjamin@chausse.xyz>2024-11-24 18:19:04 -0500
committerGitHub <noreply@github.com>2024-11-24 18:19:04 -0500
commit26e4f7f11a8c10c48af66ce4f2d4c50d5a2dc760 (patch)
treefd72a6c25b97333487aafcd8c86374d709050840
parent0a8ed6b216ab58bf0ae0695a89f602e477c9573c (diff)
feat: Notice messages when performing actions (#11)
* Update releaser CI/CD version * feat: Notice messages when performing actions * Showcase notices in demo.gif
-rw-r--r--assets/vhs.tape4
-rw-r--r--go.mod1
-rw-r--r--go.sum2
-rw-r--r--internal/notices/notices.go60
-rw-r--r--internal/quit/quit.go14
-rw-r--r--internal/switcher/switcher.go26
-rw-r--r--internal/util/clipboard.go5
7 files changed, 97 insertions, 15 deletions
diff --git a/assets/vhs.tape b/assets/vhs.tape
index 4ae61e4..c683cd8 100644
--- a/assets/vhs.tape
+++ b/assets/vhs.tape
@@ -14,6 +14,10 @@ Type "termpicker"
Enter
Sleep 250ms
Type "jlllljjhhhhh"
+Sleep 200ms
+Type "x"
+Sleep 200ms
+Type "s"
Sleep 1s
Tab
diff --git a/go.mod b/go.mod
index 807d116..8c5a23f 100644
--- a/go.mod
+++ b/go.mod
@@ -7,6 +7,7 @@ require (
github.com/charmbracelet/bubbles v0.20.0
github.com/charmbracelet/bubbletea v1.2.3
github.com/charmbracelet/lipgloss v1.0.0
+ github.com/hashicorp/go-uuid v1.0.3
github.com/urfave/cli/v2 v2.27.5
)
diff --git a/go.sum b/go.sum
index 8ea30a1..7237336 100644
--- a/go.sum
+++ b/go.sum
@@ -18,6 +18,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
+github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
+github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
diff --git a/internal/notices/notices.go b/internal/notices/notices.go
new file mode 100644
index 0000000..49fb179
--- /dev/null
+++ b/internal/notices/notices.go
@@ -0,0 +1,60 @@
+package notices
+
+import (
+ "log/slog"
+ "strings"
+ "time"
+
+ "github.com/ChausseBenjamin/termpicker/internal/util"
+ tea "github.com/charmbracelet/bubbletea"
+ "github.com/hashicorp/go-uuid"
+)
+
+const (
+ expiryDelay = 1 // seconds
+)
+
+type NoticeExpiryMsg string
+
+type Model struct {
+ // Notices is a map of UUIDs pointing to a messages
+ Notices map[string]string
+}
+
+func (m Model) Init() tea.Cmd { return nil }
+
+func (m Model) View() string {
+ noticeStr := ""
+ for _, v := range m.Notices {
+ noticeStr += v + "\n"
+ }
+ return strings.TrimRight(noticeStr, "\n")
+}
+
+func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ switch msg := msg.(type) {
+ case NoticeExpiryMsg:
+ delete(m.Notices, string(msg))
+ return m, nil
+ }
+ return m, nil
+}
+
+func New() Model {
+ return Model{
+ Notices: make(map[string]string),
+ }
+}
+
+func (m Model) New(msg string) tea.Cmd {
+ uuid, err := uuid.GenerateUUID()
+ if err != nil {
+ slog.Error("Failed to generate UUID", util.ErrKey, err)
+ }
+ m.Notices[uuid] = msg
+
+ return func() tea.Msg {
+ time.Sleep(expiryDelay * time.Second)
+ return NoticeExpiryMsg(uuid)
+ }
+}
diff --git a/internal/quit/quit.go b/internal/quit/quit.go
index de1e3b4..ac11abc 100644
--- a/internal/quit/quit.go
+++ b/internal/quit/quit.go
@@ -2,16 +2,12 @@ package quit
import tea "github.com/charmbracelet/bubbletea"
+const byeMsg = "Goodbye!\n"
+
type Model struct{}
-func (m Model) Init() tea.Cmd {
- return nil
-}
+func (m Model) Init() tea.Cmd { return nil }
-func (m Model) Update(tea.Msg) (tea.Model, tea.Cmd) {
- return m, nil
-}
+func (m Model) Update(tea.Msg) (tea.Model, tea.Cmd) { return m, nil }
-func (m Model) View() string {
- return "Goodbye!\n"
-}
+func (m Model) View() string { return byeMsg }
diff --git a/internal/switcher/switcher.go b/internal/switcher/switcher.go
index 589b029..fce242c 100644
--- a/internal/switcher/switcher.go
+++ b/internal/switcher/switcher.go
@@ -5,6 +5,7 @@ import (
"log/slog"
"github.com/ChausseBenjamin/termpicker/internal/colors"
+ "github.com/ChausseBenjamin/termpicker/internal/notices"
"github.com/ChausseBenjamin/termpicker/internal/picker"
"github.com/ChausseBenjamin/termpicker/internal/preview"
"github.com/ChausseBenjamin/termpicker/internal/quit"
@@ -21,6 +22,7 @@ type Model struct {
preview preview.Model
help help.Model
fullHelp bool // When false, only show help for the switcher (not children)
+ notices notices.Model
}
func New(pickers []picker.Model) Model {
@@ -30,6 +32,7 @@ func New(pickers []picker.Model) Model {
preview: *preview.New(colors.Hex(pickers[0].GetColor())),
help: help.New(),
fullHelp: false,
+ notices: notices.New(),
}
}
@@ -91,11 +94,12 @@ func (m Model) View() string {
helpstr = boxStyle.Render(helpstr)
- return fmt.Sprintf("%s\n%s\n%s\n%v",
+ return fmt.Sprintf("%s\n%s\n%s\n%v\n%v",
tabs,
pickerView,
previewStr,
helpstr,
+ m.notices.View(),
)
}
@@ -104,6 +108,10 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds := []tea.Cmd{}
slog.Info("Received tea.Msg", "tea_msg", msg, "type", fmt.Sprintf("%T", msg))
switch msg := msg.(type) {
+ case notices.NoticeExpiryMsg:
+ newNotices, cmd := m.notices.Update(msg)
+ m.notices = newNotices.(notices.Model)
+ cmds = append(cmds, cmd)
case tea.KeyMsg:
switch {
case key.Matches(msg, keys.next):
@@ -117,22 +125,26 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.pickers[m.active].SetColor(cs)
case key.Matches(msg, keys.cpHex):
- util.Copy(colors.Hex(m.pickers[m.active].GetColor()))
+ cmd := m.notices.New(util.Copy(colors.Hex(m.pickers[m.active].GetColor())))
+ cmds = append(cmds, cmd)
case key.Matches(msg, keys.cpRgb):
pc := m.pickers[m.active].GetColor().ToPrecise()
rgb := colors.RGB{}.FromPrecise(pc).(colors.RGB)
- util.Copy(rgb.String())
+ cmd := m.notices.New(util.Copy(rgb.String()))
+ cmds = append(cmds, cmd)
case key.Matches(msg, keys.cpHsl):
pc := m.pickers[m.active].GetColor().ToPrecise()
hsl := colors.HSL{}.FromPrecise(pc).(colors.HSL)
- util.Copy(hsl.String())
+ cmd := m.notices.New(util.Copy(hsl.String()))
+ cmds = append(cmds, cmd)
case key.Matches(msg, keys.cpCmyk):
pc := m.pickers[m.active].GetColor().ToPrecise()
cmyk := colors.CMYK{}.FromPrecise(pc).(colors.CMYK)
- util.Copy(cmyk.String())
+ cmd := m.notices.New(util.Copy(cmyk.String()))
+ cmds = append(cmds, cmd)
case key.Matches(msg, keys.help):
m.fullHelp = !m.fullHelp
@@ -149,6 +161,10 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
newPreview := preview.New(colors.Hex(m.pickers[m.active].GetColor()))
m.preview = *newPreview
+ newNotices, cmd := m.notices.Update(msg)
+ m.notices = newNotices.(notices.Model)
+ cmds = append(cmds, cmd)
+
return m, tea.Batch(cmds...)
}
default:
diff --git a/internal/util/clipboard.go b/internal/util/clipboard.go
index 64930fa..1425d97 100644
--- a/internal/util/clipboard.go
+++ b/internal/util/clipboard.go
@@ -1,14 +1,17 @@
package util
import (
+ "fmt"
"log/slog"
"github.com/atotto/clipboard"
)
// Copies any object that has the Stringer interface to the clipboard
-func Copy(str string) {
+func Copy(str string) string {
if err := clipboard.WriteAll(str); err != nil {
slog.Error("Unable to copy item", "item", str, ErrKey, err)
+ return fmt.Sprintf("Copy operation failed: %v", err)
}
+ return fmt.Sprintf("Copied %s to clipboard!", str)
}