diff --git a/internal/app/app.go b/internal/app/app.go index 189c648..b7f69c8 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -30,38 +30,34 @@ type AppModel struct { const NUM_WORDS = 20 func NewAppModel(init_state AppState) tea.Model { - chars := make([]character.CharacterModel, 0) text := "" - - // A bunch of gross stuff to track which words are at the - // end of each line. We need to know this because we let - // bubbletea do the text wrapping, but the last space on - // each line needs to be handled differently to show the - // '_' character. - space_pos := -1 - start_of_cur_line := 0 + line_len := 0 + lines := 0 for i := 0; i < NUM_WORDS; i++ { // Pull random word from data word := data.GetWord() + " " - text += word - for _, ch := range word { - chars = append(chars, character.NewCharacter(ch)) - } - - // Deal with last word of each line - space_line := (space_pos - start_of_cur_line) / (styles.APP_WIDTH - 2) - cur_line := (len(text) - start_of_cur_line) / (styles.APP_WIDTH - 2) - if space_pos > 0 && (space_line != cur_line) { - chars[space_pos].EndSpace = true - start_of_cur_line = len(text) - (len(word) - 1) + // Manually insert newlines + if line_len+len(word) >= styles.APP_WIDTH-4 { + text += "\n" + line_len = len(word) + lines++ + + if lines == styles.MAX_LINES { + break + } + } else { + line_len += len(word) } + text += word + } + text = strings.TrimSpace(text) - space_pos = len(text) - 1 + // Fill models array + chars := make([]character.CharacterModel, len(text)) + for i, ch := range text { + chars[i] = character.NewCharacter(ch) } - // Remove space from last word - chars = chars[:len(chars)-1] - text = text[:len(text)-1] // First character is active chars[0].State = character.ActiveState diff --git a/internal/app/typing.go b/internal/app/typing.go index 1fb5b0c..aa3cedc 100644 --- a/internal/app/typing.go +++ b/internal/app/typing.go @@ -26,6 +26,9 @@ func typingHandler(m AppModel, msg tea.Msg) (tea.Model, tea.Cmd) { m.chars[m.pos].State = character.CorrectState m.pos++ if m.pos < len(m.text) { + if m.text[m.pos] == '\n' { + m.pos++ + } m.chars[m.pos].State = character.ActiveState } } else { diff --git a/internal/character/character.go b/internal/character/character.go index 7c46f89..c7851b5 100644 --- a/internal/character/character.go +++ b/internal/character/character.go @@ -20,16 +20,14 @@ const ( ) type CharacterModel struct { - Val string - State CharState - EndSpace bool + Val string + State CharState } func NewCharacter(val rune) CharacterModel { return CharacterModel{ string(val), RemainingState, - false, } } @@ -43,24 +41,12 @@ func (m CharacterModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m CharacterModel) View() string { ch := m.Val - // For the last word of each line, we need to make sure - // the space character is double width. This is because - // when its in its active state it will display the '_' - // character instead. + + // Display underscore instead of space in some states if ch == CH_SPACE { switch m.State { - case HiddenState, RemainingState, CorrectState: - if m.EndSpace { - ch = " " - } else { - ch = " " - } - case ActiveState, WrongState: - if m.EndSpace { - ch = "_ " - } else { - ch = "_" - } + case WrongState, ActiveState: + ch = "_" } } diff --git a/internal/styles/styles.go b/internal/styles/styles.go index d871a65..6abab66 100644 --- a/internal/styles/styles.go +++ b/internal/styles/styles.go @@ -4,6 +4,7 @@ import "github.com/charmbracelet/lipgloss" const ( APP_WIDTH = 60 + MAX_LINES = 3 ) var (