lexivo/app/controllers/words_controller.rb
Fibe Agent e9f5d8ece2
Some checks failed
CI / Lint & Test (push) Has been cancelled
Deploy Status Page / Build & Deploy (push) Has been cancelled
Lexivo: vocabulary learning app with SM-2 spaced repetition
- Word import (multi-format: word, word-def, word:def, word|def)
- Flashcard filter UI (swipe + keyboard arrows + Space to flip)
- SM-2 spaced repetition review queue
- Stimulus flashcard controller with 3D flip animation
2026-04-22 15:02:45 +00:00

56 lines
1.4 KiB
Ruby

# frozen_string_literal: true
class WordsController < ApplicationController
def index
@stats = {
total: Word.count,
unseen: Review.where(status: "new").count,
known: Review.where(status: "known").count,
learning: Review.where(status: "learning").count,
skipped: Review.where(status: "skipped").count,
due: Review.due.count
}
@words = Word.includes(:review).by_text
end
def create
raw = params[:word_list].to_s.strip
lines = raw.split("\n").map(&:strip).reject { |l| l.blank? || l.start_with?("#") }
imported = 0
skipped = 0
lines.each do |line|
text, definition = parse_line(line)
next if text.blank?
w = Word.new(text: text.strip, definition: definition&.strip.presence)
if w.save
imported += 1
else
skipped += 1
end
end
flash[:notice] = "Imported #{imported} word#{"s" unless imported == 1}."
flash[:alert] = "Skipped #{skipped} (duplicates or invalid)." if skipped > 0
redirect_to words_path
end
def destroy
Word.find(params[:id]).destroy
redirect_to words_path, notice: "Removed."
end
private
def parse_line(line)
# "word - definition", "word: definition", "word | definition", "word\tdefinition"
if (m = line.match(/\A(.+?)\s*(?:\t|-{1,2}|:{1,2}|\|)\s*(.+)\z/))
[ m[1], m[2] ]
else
[ line, nil ]
end
end
end