diff --git a/LearnEnglish/LearnEnglish/Models/Word.swift b/LearnEnglish/LearnEnglish/Models/Word.swift index 16398ce..bd02bef 100644 --- a/LearnEnglish/LearnEnglish/Models/Word.swift +++ b/LearnEnglish/LearnEnglish/Models/Word.swift @@ -15,7 +15,7 @@ struct WordCategory: Codable, Identifiable, Hashable { struct Subcategory: Codable, Hashable { let name: String - let words: [Word] + var words: [Word] } struct Word: Codable, Identifiable, Hashable { diff --git a/LearnEnglish/LearnEnglish/Views/WordListViewController.swift b/LearnEnglish/LearnEnglish/Views/WordListViewController.swift index 20d064e..4fdc68e 100644 --- a/LearnEnglish/LearnEnglish/Views/WordListViewController.swift +++ b/LearnEnglish/LearnEnglish/Views/WordListViewController.swift @@ -3,14 +3,22 @@ import UIKit final class WordListViewController: UIViewController { private let category: WordCategory private let colorIndex: Int + private var words: [Word] + private var subcategories: [Subcategory]? private let tableView = UITableView(frame: .zero, style: .plain) private let ctaBackground = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) private let quizButton = UIButton(type: .system) private var speechObserver: NSObjectProtocol? + private var displaySubcategories: [Subcategory]? { + subcategories.flatMap { $0.isEmpty ? nil : $0 } + } + init(category: WordCategory, colorIndex: Int) { self.category = category self.colorIndex = colorIndex + self.words = category.words + self.subcategories = category.subcategories super.init(nibName: nil, bundle: nil) } @@ -27,6 +35,12 @@ final class WordListViewController: UIViewController { super.viewDidLoad() title = category.name navigationItem.largeTitleDisplayMode = .never + navigationItem.rightBarButtonItem = UIBarButtonItem( + image: UIImage(systemName: "arrow.triangle.2.circlepath"), + style: .plain, + target: self, + action: #selector(shuffleWords) + ) view.backgroundColor = .systemBackground tableView.dataSource = self @@ -119,16 +133,31 @@ final class WordListViewController: UIViewController { private func startQuiz() { Haptics.selection() - let words: [Word] + let quizWords: [Word] if category.id == "numbers" { - words = NumberWords.randomWords(count: 50) + quizWords = NumberWords.randomWords(count: 50) } else { - words = category.words + quizWords = words } - let request = QuizSetupRequest(words: words) + let request = QuizSetupRequest(words: quizWords) navigationController?.pushViewController(QuizSetupViewController(request: request), animated: true) } + @objc private func shuffleWords() { + Haptics.selection() + if var subs = subcategories { + subs = subs.map { sub in + var s = sub + s.words = sub.words.shuffled() + return s + } + subcategories = subs + } else { + words.shuffle() + } + tableView.reloadData() + } + private func updateVisibleSpeakers() { for cell in tableView.visibleCells.compactMap({ $0 as? WordCardCell }) { cell.updateSpeakerState() @@ -137,32 +166,28 @@ final class WordListViewController: UIViewController { } extension WordListViewController: UITableViewDataSource, UITableViewDelegate { - private var sections: [Subcategory]? { - category.subcategories.flatMap { $0.isEmpty ? nil : $0 } - } - func numberOfSections(in tableView: UITableView) -> Int { - sections?.count ?? 1 + displaySubcategories?.count ?? 1 } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - sections?[section].name + displaySubcategories?[section].name } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - if let sections { - return sections[section].words.count + if let subs = displaySubcategories { + return subs[section].words.count } - return category.words.count + return words.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! WordCardCell let word: Word - if let sections { - word = sections[indexPath.section].words[indexPath.row] + if let subs = displaySubcategories { + word = subs[indexPath.section].words[indexPath.row] } else { - word = category.words[indexPath.row] + word = words[indexPath.row] } cell.configure(with: word) cell.onSpeak = { word in @@ -179,10 +204,10 @@ extension WordListViewController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { Haptics.selection() let word: Word - if let sections { - word = sections[indexPath.section].words[indexPath.row] + if let subs = displaySubcategories { + word = subs[indexPath.section].words[indexPath.row] } else { - word = category.words[indexPath.row] + word = words[indexPath.row] } let detail = WordDetailViewController(word: word, categoryName: category.name) navigationController?.pushViewController(detail, animated: true)