summaryrefslogtreecommitdiff
path: root/internal
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 /internal
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
Diffstat (limited to 'internal')
-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
4 files changed, 90 insertions, 15 deletions
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)
}