package gui import ( "fmt" "math/rand" "strings" "time" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" ) 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) { case tea.KeyMsg: // string value of keypresses switch msg.String() { case "1": // View m.drawSeen = true case "2": // Correct if m.drawSeen { m.drawSeen = false m.drawRandomCard() } case "3": // Incorrect if m.drawSeen { m.drawSeen = false m.drawRandomCard() } case "4": // Skip if !m.drawSeen { m.drawSeen = false m.drawRandomCard() } case "ctrl+c", "q": return m, tea.Quit case "s": m.switchMode(Select) } } 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" incorrectText := "3: Incorrect" skipText := "4: Skip" // Buttons default 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 { 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]", hotPinkTextStyle.Width(7).Render(skipText)) } selectedMap := fmt.Sprintf("%v", m.selected) // Return a template return template(`Draw Mode ({numSelected} cards, {selectedCardIndexes}): {frontTextStyle} {backTextStyle} {viewOption} {correctOption} {incorrectOption} {skipOption} Press [s] to go back to select Press [q] to quit. `, "{numSelected}", fmt.Sprintf("%d", len(m.selected)), "{selectedCardIndexes}", fmt.Sprintf("%v", m.selectedCardIndexes()), "{cardList}", m.cardListToString(), "{selectedMap}", fmt.Sprintf("%s", frontTextStyle.Width(len(selectedMap)).Render(selectedMap)), "{viewOption}", viewOption, "{correctOption}", correctOption, "{incorrectOption}", incorrectOption, "{skipOption}", skipOption, "{frontTextStyle}", frontText, "{backTextStyle}", backText, ) } func (m *model) cardListToString() string { s := "" for i, card := range m.deck { if _, ok := m.selected[i]; ok { s += fmt.Sprintf("%d %s [%s]\n", i, card.Front, card.Back) } } 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 }