Skip to content

Commit

Permalink
feat: break out Update() in replay
Browse files Browse the repository at this point in the history
  • Loading branch information
cfoust committed Oct 27, 2023
1 parent c47f00d commit 7c98d01
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 138 deletions.
138 changes: 0 additions & 138 deletions pkg/mux/screen/replay/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ type Replay struct {

var _ taro.Model = (*Replay)(nil)

func (r *Replay) quit() (taro.Model, tea.Cmd) {
return r, tea.Quit
}

func (r *Replay) getTerminalCursor() geom.Vec2 {
cursor := r.terminal.Cursor()
return geom.Vec2{
Expand Down Expand Up @@ -122,140 +118,6 @@ func (r *Replay) Init() tea.Cmd {
return textinput.Blink
}

func reverse[S ~[]E, E any](s S) {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
}

func (r *Replay) Update(msg tea.Msg) (taro.Model, tea.Cmd) {
viewport := r.viewport

switch msg := msg.(type) {
case PlaybackRateEvent:
r.playbackRate = geom.Clamp(msg.Rate, -10, 10)
if r.playbackRate == 0 {
r.playbackRate = 1
}
return r, nil
case PlaybackEvent:
if !r.isPlaying {
return r, nil
}

r.setTimeDelta(time.Duration(int64(time.Now().Sub(msg.Since)) * int64(r.playbackRate)))

return r.scheduleUpdate()
case tea.WindowSizeMsg:
return r.setViewport(
r.viewport,
geom.Size{
R: msg.Height,
C: msg.Width,
},
)
case SearchResultEvent:
return r.handleSearchResult(msg)
}

if r.isSearching {
return r.handleSearchInput(msg)
}

// These events do not stop playback
switch msg := msg.(type) {
case ActionEvent:
switch msg.Type {
case ActionTimePlay:
r.isPlaying = !r.isPlaying

if r.isPlaying {
r.exitSelectionMode()
return r.scheduleUpdate()
}

return r, nil
}
case taro.KeyMsg:
// Pass unmatched keys into the binding engine; because of how
// text input works, :replay bindings have to be activated
// selectively
return r, func() tea.Msg {
r.binds.InputMessage(msg)
return nil
}
}

// Every other event causes us to pause
r.isPlaying = false

switch msg := msg.(type) {
case taro.MouseMsg:
switch msg.Type {
case taro.MouseWheelUp:
r.setScroll(r.offset.R - 1)
case taro.MouseWheelDown:
r.setScroll(r.offset.R + 1)
}
case ActionEvent:
switch msg.Type {
case ActionQuit:
if r.isSelectionMode {
r.exitSelectionMode()
return r, nil
}

return r.quit()
case ActionBeginning:
if r.isSelectionMode {
r.moveCursorDelta(
-r.viewportToTerm(r.cursor).R+r.minOffset.R,
0,
)
} else {
r.gotoIndex(0, -1)
}
case ActionEnd:
if r.isSelectionMode {
r.moveCursorDelta(
(r.getTerminalSize().R-1)-r.viewportToTerm(r.cursor).R,
0,
)
} else {
r.gotoIndex(-1, -1)
}
case ActionSearchAgain, ActionSearchReverse:
r.searchAgain(msg.Type != ActionSearchReverse)
case ActionSearchForward, ActionSearchBackward:
r.isSearching = true
r.isForward = msg.Type == ActionSearchForward
r.searchInput.Reset()
case ActionTimeStepBack:
r.gotoIndex(r.location.Index-1, -1)
case ActionTimeStepForward:
r.gotoIndex(r.location.Index+1, -1)
case ActionScrollUpHalf:
r.moveCursorDelta(-(viewport.R / 2), 0)
case ActionScrollDownHalf:
r.moveCursorDelta((viewport.R / 2), 0)
case ActionScrollUp:
r.setScroll(r.offset.R - 1)
case ActionScrollDown:
r.setScroll(r.offset.R + 1)
case ActionCursorDown:
r.moveCursorDelta(1, 0)
case ActionCursorUp:
r.moveCursorDelta(-1, 0)
case ActionCursorLeft:
r.moveCursorDelta(0, -1)
case ActionCursorRight:
r.moveCursorDelta(0, 1)
}
}

return r, nil
}

func newReplay(
events []sessions.Event,
binds *bind.Engine[bind.Action],
Expand Down
6 changes: 6 additions & 0 deletions pkg/mux/screen/replay/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ import (
tea "github.com/charmbracelet/bubbletea"
)

func reverse[S ~[]E, E any](s S) {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
}

func (r *Replay) gotoMatch(index int) {
if len(r.matches) == 0 {
return
Expand Down
142 changes: 142 additions & 0 deletions pkg/mux/screen/replay/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package replay

import (
"time"

"github.com/cfoust/cy/pkg/geom"
"github.com/cfoust/cy/pkg/taro"

tea "github.com/charmbracelet/bubbletea"
)

func (r *Replay) quit() (taro.Model, tea.Cmd) {
return r, tea.Quit
}

func (r *Replay) Update(msg tea.Msg) (taro.Model, tea.Cmd) {
viewport := r.viewport

switch msg := msg.(type) {
case PlaybackRateEvent:
r.playbackRate = geom.Clamp(msg.Rate, -10, 10)
if r.playbackRate == 0 {
r.playbackRate = 1
}
return r, nil
case PlaybackEvent:
if !r.isPlaying {
return r, nil
}

r.setTimeDelta(time.Duration(int64(time.Now().Sub(msg.Since)) * int64(r.playbackRate)))

return r.scheduleUpdate()
case tea.WindowSizeMsg:
return r.setViewport(
r.viewport,
geom.Size{
R: msg.Height,
C: msg.Width,
},
)
case SearchResultEvent:
return r.handleSearchResult(msg)
}

if r.isSearching {
return r.handleSearchInput(msg)
}

// These events do not stop playback
switch msg := msg.(type) {
case ActionEvent:
switch msg.Type {
case ActionTimePlay:
r.isPlaying = !r.isPlaying

if r.isPlaying {
r.exitSelectionMode()
return r.scheduleUpdate()
}

return r, nil
}
case taro.KeyMsg:
// Pass unmatched keys into the binding engine; because of how
// text input works, :replay bindings have to be activated
// selectively
return r, func() tea.Msg {
r.binds.InputMessage(msg)
return nil
}
}

// Every other event causes us to pause
r.isPlaying = false

switch msg := msg.(type) {
case taro.MouseMsg:
switch msg.Type {
case taro.MouseWheelUp:
r.setScroll(r.offset.R - 1)
case taro.MouseWheelDown:
r.setScroll(r.offset.R + 1)
}
case ActionEvent:
switch msg.Type {
case ActionQuit:
if r.isSelectionMode {
r.exitSelectionMode()
return r, nil
}

return r.quit()
case ActionBeginning:
if r.isSelectionMode {
r.moveCursorDelta(
-r.viewportToTerm(r.cursor).R+r.minOffset.R,
0,
)
} else {
r.gotoIndex(0, -1)
}
case ActionEnd:
if r.isSelectionMode {
r.moveCursorDelta(
(r.getTerminalSize().R-1)-r.viewportToTerm(r.cursor).R,
0,
)
} else {
r.gotoIndex(-1, -1)
}
case ActionSearchAgain, ActionSearchReverse:
r.searchAgain(msg.Type != ActionSearchReverse)
case ActionSearchForward, ActionSearchBackward:
r.isSearching = true
r.isForward = msg.Type == ActionSearchForward
r.searchInput.Reset()
case ActionTimeStepBack:
r.gotoIndex(r.location.Index-1, -1)
case ActionTimeStepForward:
r.gotoIndex(r.location.Index+1, -1)
case ActionScrollUpHalf:
r.moveCursorDelta(-(viewport.R / 2), 0)
case ActionScrollDownHalf:
r.moveCursorDelta((viewport.R / 2), 0)
case ActionScrollUp:
r.setScroll(r.offset.R - 1)
case ActionScrollDown:
r.setScroll(r.offset.R + 1)
case ActionCursorDown:
r.moveCursorDelta(1, 0)
case ActionCursorUp:
r.moveCursorDelta(-1, 0)
case ActionCursorLeft:
r.moveCursorDelta(0, -1)
case ActionCursorRight:
r.moveCursorDelta(0, 1)
}
}

return r, nil
}

0 comments on commit 7c98d01

Please sign in to comment.