randomize cards
This commit is contained in:
parent
4c6c12ebe5
commit
0acba6ace3
69
gui/draw.go
69
gui/draw.go
|
@ -2,19 +2,17 @@ package gui
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
var hotPinkText = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF06B7"))
|
||||
var frontText = lipgloss.NewStyle().Foreground(lipgloss.Color("#268bd2"))
|
||||
var backText = lipgloss.NewStyle().Foreground(lipgloss.Color("#6c71c4"))
|
||||
|
||||
func (m *model) nextCard() {
|
||||
m.drawSeen = false
|
||||
}
|
||||
var hotPinkTextStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF06B7"))
|
||||
var frontTextStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#268bd2"))
|
||||
var backTextStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#6c71c4"))
|
||||
|
||||
func (m *model) updateDraw(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
|
@ -27,16 +25,18 @@ func (m *model) updateDraw(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
m.drawSeen = true
|
||||
case "2": // Correct
|
||||
if m.drawSeen {
|
||||
// TODO
|
||||
m.drawSeen = false
|
||||
m.drawRandomCard()
|
||||
}
|
||||
case "3": // Incorrect
|
||||
if m.drawSeen {
|
||||
// TODO:
|
||||
m.drawSeen = false
|
||||
m.drawRandomCard()
|
||||
}
|
||||
case "4": // Skip
|
||||
if !m.drawSeen {
|
||||
// CAN SKIP
|
||||
// TODO:
|
||||
m.drawSeen = false
|
||||
m.drawRandomCard()
|
||||
}
|
||||
|
||||
case "ctrl+c", "q":
|
||||
|
@ -45,10 +45,14 @@ func (m *model) updateDraw(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
m.switchMode(Select)
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
return m, tea.Tick(time.Second, func(_ time.Time) tea.Msg {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (m *model) viewDraw() string {
|
||||
card := m.selectedCard()
|
||||
|
||||
// Button Text
|
||||
viewText := "1: View"
|
||||
correctText := "2: Correct"
|
||||
|
@ -56,17 +60,21 @@ func (m *model) viewDraw() string {
|
|||
skipText := "4: Skip"
|
||||
|
||||
// Buttons default
|
||||
viewOption := fmt.Sprintf("[%s]", hotPinkText.Width(7).Render(viewText))
|
||||
viewOption := fmt.Sprintf("[%s]", hotPinkTextStyle.Width(7).Render(viewText))
|
||||
correctOption := fmt.Sprintf(strings.Repeat(" ", len(correctText)+2))
|
||||
incorrectOption := fmt.Sprintf(strings.Repeat(" ", len(incorrectText)+2))
|
||||
skipOption := fmt.Sprintf(strings.Repeat(" ", len(skipText)+2))
|
||||
|
||||
// Button text filling
|
||||
frontText := frontTextStyle.Width(len(card.Front)).Render(card.Front)
|
||||
backText := ""
|
||||
|
||||
if m.drawSeen {
|
||||
correctOption = fmt.Sprintf("[%s]", hotPinkText.Width(10).Render(correctText))
|
||||
incorrectOption = fmt.Sprintf("[%s]", hotPinkText.Width(12).Render(incorrectText))
|
||||
backText = backTextStyle.Width(len(card.Back)).Render(card.Back)
|
||||
correctOption = fmt.Sprintf("[%s]", hotPinkTextStyle.Width(10).Render(correctText))
|
||||
incorrectOption = fmt.Sprintf("[%s]", hotPinkTextStyle.Width(12).Render(incorrectText))
|
||||
} else {
|
||||
skipOption = fmt.Sprintf("[%s]", hotPinkText.Width(7).Render(skipText))
|
||||
skipOption = fmt.Sprintf("[%s]", hotPinkTextStyle.Width(7).Render(skipText))
|
||||
}
|
||||
|
||||
selectedMap := fmt.Sprintf("%v", m.selected)
|
||||
|
@ -74,8 +82,8 @@ func (m *model) viewDraw() string {
|
|||
// Return a template
|
||||
return template(`Draw Mode ({numSelected} cards, {selectedCardIndexes}):
|
||||
|
||||
{cardList}
|
||||
{selectedMap}
|
||||
{frontTextStyle}
|
||||
{backTextStyle}
|
||||
|
||||
{viewOption} {correctOption} {incorrectOption} {skipOption}
|
||||
|
||||
|
@ -85,11 +93,13 @@ Press [q] to quit.
|
|||
"{numSelected}", fmt.Sprintf("%d", len(m.selected)),
|
||||
"{selectedCardIndexes}", fmt.Sprintf("%v", m.selectedCardIndexes()),
|
||||
"{cardList}", m.cardListToString(),
|
||||
"{selectedMap}", fmt.Sprintf("%s", frontText.Width(len(selectedMap)).Render(selectedMap)),
|
||||
"{selectedMap}", fmt.Sprintf("%s", frontTextStyle.Width(len(selectedMap)).Render(selectedMap)),
|
||||
"{viewOption}", viewOption,
|
||||
"{correctOption}", correctOption,
|
||||
"{incorrectOption}", incorrectOption,
|
||||
"{skipOption}", skipOption,
|
||||
"{frontTextStyle}", frontText,
|
||||
"{backTextStyle}", backText,
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -103,3 +113,24 @@ func (m *model) cardListToString() string {
|
|||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (m *model) drawRandomCard() {
|
||||
if len(m.selectedCardIndexes()) == 1 {
|
||||
// Can't draw a next card, just return same card.
|
||||
return
|
||||
}
|
||||
rand.Seed(time.Now().Unix()) // initialize global pseudo random generator
|
||||
indexes := m.selectedCardIndexes()
|
||||
nextId := m.drawCardId
|
||||
|
||||
// Randomize until the next card is not the same card
|
||||
for {
|
||||
randomIndex := indexes[rand.Intn(len(indexes))]
|
||||
nextId = m.deck[randomIndex].Id
|
||||
if m.drawCardId != nextId {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
m.drawCardId = nextId
|
||||
}
|
||||
|
|
40
gui/model.go
40
gui/model.go
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/charmbracelet/bubbles/list"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type model struct {
|
||||
|
@ -17,21 +18,37 @@ type model struct {
|
|||
createInputs []textinput.Model // Inputs for front and back, is an array because we change position by an index
|
||||
createdInputIndex int // holds an index for which input is active editing in create mode
|
||||
|
||||
drawSeen bool
|
||||
drawCardIndex int
|
||||
drawSeen bool
|
||||
drawCardId string
|
||||
|
||||
mode Mode
|
||||
err error
|
||||
}
|
||||
|
||||
/// returns an int slice of the selected card indexes, sorted
|
||||
func (m *model) selectedCardIndexes() []int {
|
||||
var keys []int
|
||||
for _, key := range reflect.ValueOf(m.selected).MapKeys() {
|
||||
keys = append(keys, int(key.Int()))
|
||||
}
|
||||
sort.Ints(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
/// Returns a card with matching drawCardId
|
||||
func (m *model) selectedCard() models.Card {
|
||||
for _, card := range m.deck {
|
||||
if card.Id == m.drawCardId {
|
||||
return card
|
||||
}
|
||||
}
|
||||
return models.Card{
|
||||
Front: "ERROR",
|
||||
Back: "ERROR",
|
||||
Id: "-1",
|
||||
}
|
||||
}
|
||||
|
||||
func initialModel() model {
|
||||
front := textinput.New()
|
||||
front.Placeholder = "Front..."
|
||||
|
@ -45,9 +62,22 @@ func initialModel() model {
|
|||
back.Width = 80
|
||||
|
||||
deck := []models.Card{
|
||||
models.NewCard("Hello (JP)", "Konnichi wa"),
|
||||
models.NewCard("Hello (SP)", "Hola"),
|
||||
models.NewCard("Hello (DE)", "Guten Tag"),
|
||||
models.NewCard("Oui, je parle français.", "Yes, I speak French."),
|
||||
models.NewCard("Non, je ne parle pas français.", "No, I don’t speak French."),
|
||||
models.NewCard("Merci beaucoup.", "Thank you very much."),
|
||||
models.NewCard("Je mange le pain.", "I eat the bread."),
|
||||
models.NewCard("Tu manges la salade.", "You seat the salad."),
|
||||
models.NewCard("Vous mangez la pizza.", "You eat the pizza."),
|
||||
models.NewCard("Le garçon chante.", "The boy sings."),
|
||||
models.NewCard("La fille nage.", "The girl swims."),
|
||||
models.NewCard("Les enfants chantent.", "The children sing."),
|
||||
models.NewCard("Un garçon écrit.", "A boy writes."),
|
||||
models.NewCard("Une fille dort.", "A girl sleeps."),
|
||||
models.NewCard("Des enfant étudient.", "Some kids study."),
|
||||
models.NewCard("Je le/la mange.", "I eat it."),
|
||||
models.NewCard("Je les mange.", "I eat them."),
|
||||
models.NewCard("Marc et Sylvie.", "Marc and Sylvie."),
|
||||
models.NewCard("Il aime Sylvie mais il est trop timide.", "He likes Sylvie but he’s ),too shy."),
|
||||
}
|
||||
|
||||
var items []list.Item
|
||||
|
|
|
@ -52,7 +52,7 @@ func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list
|
|||
}
|
||||
}
|
||||
|
||||
fmt.Fprint(w, fn(str))
|
||||
_, _ = fmt.Fprint(w, fn(str)) // ignore error
|
||||
}
|
||||
|
||||
func (m *model) updateSelect(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
|
@ -81,7 +81,11 @@ func (m *model) updateSelect(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
|
||||
// MODES
|
||||
case "d":
|
||||
m.switchMode(Draw)
|
||||
// Only draw if at least one card
|
||||
if len(m.selected) > 0 {
|
||||
m.drawRandomCard()
|
||||
m.switchMode(Draw)
|
||||
}
|
||||
case "c":
|
||||
m.switchMode(Create)
|
||||
|
||||
|
@ -91,7 +95,6 @@ func (m *model) updateSelect(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
card, ok := m.selectList.SelectedItem().(models.Card)
|
||||
if ok {
|
||||
idx := SliceIndex(len(m.deck), func(i int) bool { return m.deck[i].Id == card.Id })
|
||||
fmt.Printf("%d IS THE CARD: %s", idx, card.Front)
|
||||
if _, ok := m.selected[idx]; ok {
|
||||
delete(m.selected, idx)
|
||||
m.deck[idx].Selected = false
|
||||
|
|
Loading…
Reference in New Issue
Block a user