Skip to content

Commit

Permalink
chore(song): enhance view
Browse files Browse the repository at this point in the history
  • Loading branch information
Topvennie committed Dec 7, 2024
1 parent 7245f2e commit fd6715a
Show file tree
Hide file tree
Showing 18 changed files with 395 additions and 121 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/sqlc-diff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jobs:
diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: sqlc-dev/setup-sqlc@v3
with:
sqlc-version: '1.27.0'
Expand Down
2 changes: 1 addition & 1 deletion db/queries/song.sql
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ ORDER BY a.name, g.genre;
-- name: GetSongHistory :many
SELECT s.title
FROM song_history sh
JOIN song s ON sh.song_id = s.id
JOIN song s ON sh.song_id = s.id
ORDER BY created_at DESC
LIMIT 5;

Expand Down
9 changes: 6 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.23.1

require (
github.com/NimbleMarkets/ntcharts v0.1.2
github.com/charmbracelet/bubbletea v0.25.0
github.com/charmbracelet/bubbletea v1.1.0
github.com/charmbracelet/lipgloss v1.0.0
github.com/disintegration/imaging v1.6.2
github.com/go-playground/validator/v10 v10.22.1
Expand All @@ -27,9 +27,12 @@ require (
github.com/antchfx/xmlquery v1.4.2 // indirect
github.com/antchfx/xpath v1.3.2 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/bubbles v0.18.0 // indirect
github.com/charmbracelet/bubbles v0.20.0 // indirect
github.com/charmbracelet/harmonica v0.2.0 // indirect
github.com/charmbracelet/x/ansi v0.4.2 // indirect
github.com/charmbracelet/x/term v0.2.0 // indirect
github.com/containerd/console v1.0.4 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-playground/locales v0.14.1 // indirect
Expand All @@ -47,7 +50,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
Expand Down
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,23 @@ github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWp
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
github.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c=
github.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
github.com/charmbracelet/x/ansi v0.4.2 h1:0JM6Aj/g/KC154/gOP4vfxun0ff6itogDYk41kof+qk=
github.com/charmbracelet/x/ansi v0.4.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30=
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q=
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -34,6 +43,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
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/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
Expand Down Expand Up @@ -97,6 +108,8 @@ github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+Ei
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
Expand Down Expand Up @@ -189,6 +202,7 @@ golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import (
tui "github.com/zeusWPI/scc/ui"
"github.com/zeusWPI/scc/ui/screen"
"github.com/zeusWPI/scc/ui/screen/cammie"
songScreen "github.com/zeusWPI/scc/ui/screen/song"
"github.com/zeusWPI/scc/ui/view"
"go.uber.org/zap"
)

var screens = map[string]func(*db.DB) screen.Screen{
"cammie": cammie.New,
"song": screen.NewSong,
"test": screen.NewTest,
"song": songScreen.New,
}

// TUI starts the terminal user interface
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/db/sqlc/song.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 17 additions & 15 deletions internal/pkg/lyrics/lrc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/zeusWPI/scc/internal/pkg/db/dto"
)

var re = regexp.MustCompile(`^\[(\d{2}):(\d{2})\.(\d{2})\]`)

// LRC represents synced lyrics
type LRC struct {
song dto.Song
Expand Down Expand Up @@ -76,40 +78,40 @@ func (l *LRC) Upcoming(amount int) []Lyric {
return lyrics
}

// Progress shows the fraction of lyrics that have been used.
func (l *LRC) Progress() float64 {
return float64(l.i) / float64(len(l.lyrics))
}

func parseLRC(text string, totalDuration time.Duration) []Lyric {
lines := strings.Split(text, "\n")

lyrics := make([]Lyric, 0, len(lines)+1)
var previousTimestamp time.Duration

re, err := regexp.Compile(`^\[(\d{2}):(\d{2})\.(\d{2})\] (.+)$`)
if err != nil {
return lyrics
}

// Add first lyric (no text)
lyrics = append(lyrics, Lyric{Text: ""})
previousTimestamp = time.Duration(0)

for i, line := range lines {
match := re.FindStringSubmatch(line)
if match == nil {
parts := strings.SplitN(line, " ", 2)
if len(parts) != 2 {
continue
}

// Construct timestamp
minutes, _ := strconv.Atoi(match[1])
seconds, _ := strconv.Atoi(match[2])
hundredths, _ := strconv.Atoi(match[3])
// Duration part
timeParts := re.FindStringSubmatch(parts[0])
minutes, _ := strconv.Atoi(timeParts[1])
seconds, _ := strconv.Atoi(timeParts[2])
hundredths, _ := strconv.Atoi(timeParts[3])
timestamp := time.Duration(minutes)*time.Minute +
time.Duration(seconds)*time.Second +
time.Duration(hundredths)*10*time.Millisecond

t := match[4]

lyrics = append(lyrics, Lyric{Text: t})
// Actual lyric
lyric := parts[1]

// Set duration of previous lyric
lyrics = append(lyrics, Lyric{Text: lyric})
lyrics[i].Duration = timestamp - previousTimestamp
previousTimestamp = timestamp
}
Expand Down
1 change: 1 addition & 0 deletions internal/pkg/lyrics/lyrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Lyrics interface {
Current() (Lyric, bool)
Next() (Lyric, bool)
Upcoming(int) []Lyric
Progress() float64
}

// Lyric represents a single lyric line.
Expand Down
9 changes: 9 additions & 0 deletions internal/pkg/lyrics/plain.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,12 @@ func (p *Plain) Next() (Lyric, bool) {
func (p *Plain) Upcoming(_ int) []Lyric {
return []Lyric{}
}

// Progress shows the fraction of lyrics that have been used.
func (p *Plain) Progress() float64 {
if p.given {
return 1
}

return 0
}
128 changes: 128 additions & 0 deletions ui/components/stopwatch/stopwatch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Package stopwatch provides a simple stopwatch component
package stopwatch

import (
"fmt"
"sync/atomic"
"time"

tea "github.com/charmbracelet/bubbletea"
)

// Slightly adjusted version of https://github.com/charmbracelet/bubbles/blob/master/stopwatch/stopwatch.go

var lastID int64

func nextID() int {
return int(atomic.AddInt64(&lastID, 1))
}

// TickMsg is a message that is sent on every stopwatch tick
type TickMsg struct {
id int
}

// StartStopMsg is a message that controls if the stopwatch is running or not
type StartStopMsg struct {
running bool
startDuration time.Duration
}

// ResetMsg is a message that resets the stopwatch
type ResetMsg struct {
}

// Model for the stopwatch component
type Model struct {
id int
duration time.Duration
running bool
}

// New created a new stopwatch with a given interval
func New() Model {
return Model{
id: nextID(),
duration: 0,
running: false,
}
}

// Init initiates the stopwatch component
func (m Model) Init() tea.Cmd {
return nil
}

// Start starts the stopwatch
func (m Model) Start(startDuration time.Duration) tea.Cmd {
return func() tea.Msg {
return StartStopMsg{running: true, startDuration: startDuration}
}
}

// Stop stops the stopwatch
func (m Model) Stop() tea.Cmd {
return func() tea.Msg {
return StartStopMsg{running: false}
}
}

// Reset resets the stopwatch
func (m Model) Reset() tea.Cmd {
return func() tea.Msg {
return ResetMsg{}
}
}

// Update handles the stopwatch tick
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
switch msg := msg.(type) {
case TickMsg:
if msg.id != m.id || !m.running {
return m, nil
}

m.duration += time.Second
return m, tick(m.id)

case ResetMsg:
m.duration = 0
m.running = false

case StartStopMsg:
if msg.running {
// Start
if m.running {
// Already running
return m, nil
}

m.id = nextID()
m.duration = msg.startDuration
m.running = true

return m, tick(m.id)
}

// Stop
m.running = false
return m, nil
}
return m, nil
}

// View of the stopwatch component
func (m Model) View() string {
duration := m.duration.Round(time.Second)

min := int(duration / time.Minute)
sec := int((duration % time.Minute) / time.Second)

return fmt.Sprintf("%02d:%02d", min, sec)
}

func tick(id int) tea.Cmd {
return tea.Tick(time.Second, func(_ time.Time) tea.Msg {
return TickMsg{id: id}
})
}
Loading

0 comments on commit fd6715a

Please sign in to comment.