/
CodeStacer
/
SimpleDictionaryEnglishApp
Обзор
Документация
Войти
/
CodeStacer
/
SimpleDictionaryEnglishApp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
MainPage.xaml.cs
411 строк
14 KB
Durashca
Обновление: новый дизайн и база данных 200 слов
26 июн 2026, 15:18
26 июн 2026, 15:18
a41c626
Код
Авторство
О чём код?
using System.Text.Json; namespace SimpleDictionaryEnglish; public partial class MainPage : ContentPage { // ===== ДАННЫЕ ===== private List<Word> _words = new(); private List<Word> _filteredWords = new(); private readonly string _filePath; private readonly string _remoteFileUrl = "https://gitverse.ru/api/repos/CodeStacer/EnglishDictionaryDB/raw/branch/master/words.json"; private bool _isLoading = false; private bool _isTestMode = false; // Режим тестирования private List<Word> _testWords = new(); // Слова для теста private int _currentTestIndex = 0; private int _correctAnswers = 0; private int _totalTestWords = 0; // ===== МОДЕЛЬ ===== public class Word { public int Id { get; set; } public string English { get; set; } = ""; public string Russian { get; set; } = ""; public string? Example { get; set; } } // ===== КОНСТРУКТОР ===== public MainPage() { InitializeComponent(); _filePath = Path.Combine(FileSystem.AppDataDirectory, "words.json"); LoadLocalData(); _ = LoadFromInternetAsync(silent: true); // Скрываем поиск при старте (покажем в режиме словаря) SearchBar.IsVisible = true; } // ===== ЗАГРУЗКА ЛОКАЛЬНЫХ ДАННЫХ ===== private void LoadLocalData() { try { if (File.Exists(_filePath)) { var json = File.ReadAllText(_filePath); var loaded = JsonSerializer.Deserialize<List<Word>>(json); if (loaded != null && loaded.Any()) { _words = loaded; UpdateList(); SetStatus($"✅ Загружено локально ({_words.Count} слов)", Colors.Green); CountLabel.Text = $"Слов: {_words.Count}"; return; } } } catch (Exception ex) { Console.WriteLine($"Ошибка загрузки локального файла: {ex.Message}"); } _words = new List<Word> { new() { Id = 1, English = "Hello", Russian = "Привет" }, new() { Id = 2, English = "World", Russian = "Мир" }, new() { Id = 3, English = "Apple", Russian = "Яблоко" }, new() { Id = 4, English = "Book", Russian = "Книга" }, new() { Id = 5, English = "Car", Russian = "Машина" } }; SaveLocalData(); UpdateList(); SetStatus("📚 Загружены стартовые слова", Colors.Orange); CountLabel.Text = $"Слов: {_words.Count}"; } private void SaveLocalData() { try { var json = JsonSerializer.Serialize(_words, new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(_filePath, json); } catch (Exception ex) { Console.WriteLine($"Ошибка сохранения: {ex.Message}"); } } private void UpdateList() { var source = _filteredWords.Any() ? _filteredWords : _words; WordsListView.ItemsSource = null; WordsListView.ItemsSource = source; WordsListView.InvalidateMeasure(); CountLabel.Text = _isTestMode ? $"Тест: {_currentTestIndex + 1}/{_totalTestWords}" : $"Слов: {_words.Count}"; } private void SetStatus(string text, Color color) { StatusLabel.Text = text; StatusLabel.TextColor = color; } // ===== ЗАГРУЗКА ИЗ ИНТЕРНЕТА ===== private async Task LoadFromInternetAsync(bool silent = false) { if (_isLoading) return; _isLoading = true; try { if (!silent) SetStatus("⏳ Загрузка...", Colors.Blue); using var client = new HttpClient(); client.Timeout = TimeSpan.FromSeconds(15); client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0"); client.DefaultRequestHeaders.Add("Cache-Control", "no-cache"); var response = await client.GetAsync(_remoteFileUrl); if (!response.IsSuccessStatusCode) { if (!silent) { await ShowMessage("Ошибка", $"Не удалось загрузить словарь (код {response.StatusCode})"); SetStatus($"❌ Ошибка {response.StatusCode}", Colors.Red); } return; } var json = await response.Content.ReadAsStringAsync(); if (string.IsNullOrWhiteSpace(json) || !json.TrimStart().StartsWith("[")) { if (!silent) { await ShowMessage("Ошибка", "Скачанный файл повреждён или не является JSON"); SetStatus("❌ Файл повреждён", Colors.Red); } return; } var loaded = JsonSerializer.Deserialize<List<Word>>(json); if (loaded == null || !loaded.Any()) { if (!silent) { await ShowMessage("Ошибка", "Словарь пуст"); SetStatus("❌ Словарь пуст", Colors.Red); } return; } _words = loaded; _filteredWords.Clear(); SaveLocalData(); UpdateList(); SetStatus($"✅ Загружено {_words.Count} слов", Colors.Green); CountLabel.Text = $"Слов: {_words.Count}"; if (!silent) { await ShowMessage("Успех", $"Словарь обновлён! Загружено {_words.Count} слов"); } } catch (Exception ex) { Console.WriteLine($"Ошибка: {ex.Message}"); if (!silent) { await ShowMessage("Ошибка", $"Что-то пошло не так: {ex.Message}"); SetStatus("❌ Ошибка", Colors.Red); } } finally { _isLoading = false; } } // ===== ТЕСТИРОВАНИЕ ===== private async Task StartTest() { if (_words.Count < 3) { await ShowMessage("Ошибка", "Недостаточно слов для теста. Нужно минимум 3 слова."); return; } // Перемешиваем слова и берём 10 случайных var random = new Random(); _testWords = _words.OrderBy(x => random.Next()).Take(Math.Min(10, _words.Count)).ToList(); _currentTestIndex = 0; _correctAnswers = 0; _totalTestWords = _testWords.Count; _isTestMode = true; SearchBar.IsVisible = false; await ShowTestQuestion(); } private async Task ShowTestQuestion() { if (_currentTestIndex >= _totalTestWords) { await EndTest(); return; } var currentWord = _testWords[_currentTestIndex]; // Показываем диалог с вопросом var answer = await DisplayPromptAsync( $"Тест {_currentTestIndex + 1}/{_totalTestWords}", $"Как переводится: {currentWord.Russian}?", placeholder: "Введите перевод на английский", maxLength: 50, keyboard: Keyboard.Text ); if (answer == null) { // Пользователь нажал "Отмена" — выходим из теста _isTestMode = false; SearchBar.IsVisible = true; UpdateList(); SetStatus("Тест прерван", Colors.Orange); return; } // Проверяем ответ (игнорируем регистр) var isCorrect = answer.Trim().Equals(currentWord.English, StringComparison.OrdinalIgnoreCase); if (isCorrect) { _correctAnswers++; await DisplayAlert("✅ Правильно!", $"'{currentWord.English}' — верно!", "OK"); } else { await DisplayAlert("❌ Неправильно", $"Правильный ответ: {currentWord.English}\n" + $"Твой ответ: {answer.Trim()}", "OK"); } _currentTestIndex++; await ShowTestQuestion(); } private async Task EndTest() { _isTestMode = false; SearchBar.IsVisible = true; var percent = (int)((double)_correctAnswers / _totalTestWords * 100); var emoji = percent >= 80 ? "🌟" : percent >= 60 ? "👍" : "📚"; await DisplayAlert( "Тест завершён! 🎉", $"Правильных ответов: {_correctAnswers} из {_totalTestWords}\n" + $"Результат: {percent}% {emoji}", "OK" ); SetStatus($"Тест завершён: {_correctAnswers}/{_totalTestWords}", Colors.Blue); UpdateList(); } // ===== ВСПОМОГАТЕЛЬНЫЕ МЕТОДЫ ===== private async Task ShowMessage(string title, string message) { await DisplayAlert(title, message, "OK"); } // ===== ОБРАБОТЧИКИ ===== private void OnSearchTextChanged(object sender, TextChangedEventArgs e) { var query = e.NewTextValue?.Trim() ?? ""; if (string.IsNullOrWhiteSpace(query)) { _filteredWords.Clear(); } else { _filteredWords = _words .Where(w => w.English.Contains(query, StringComparison.OrdinalIgnoreCase) || w.Russian.Contains(query, StringComparison.OrdinalIgnoreCase)) .ToList(); } UpdateList(); } private async void OnRefreshClicked(object sender, EventArgs e) { var confirm = await DisplayAlert( "Обновление словаря", "Загрузить свежую версию словаря из интернета?", "Да", "Нет" ); if (!confirm) return; await LoadFromInternetAsync(silent: false); } private async void OnDictionaryClicked(object sender, EventArgs e) { if (_isTestMode) { var confirm = await DisplayAlert( "Выйти из теста?", "Текущий тест будет прерван. Продолжить?", "Да", "Нет" ); if (!confirm) return; _isTestMode = false; } _isTestMode = false; SearchBar.IsVisible = true; _filteredWords.Clear(); UpdateList(); SetStatus("📚 Режим словаря", Colors.Green); } private async void OnTestClicked(object sender, EventArgs e) { if (_isTestMode) { var confirm = await DisplayAlert( "Выйти из теста?", "Текущий тест будет прерван. Начать новый?", "Да", "Нет" ); if (!confirm) return; } await StartTest(); } private async void OnQuizClicked(object sender, EventArgs e) { try { if (_words == null || _words.Count < 3) { await DisplayAlert("Внимание", "Добавьте больше слов для викторины!", "OK"); return; } Console.WriteLine($"Создаём QuizPage со {_words.Count} словами"); var quizPage = new QuizPage(_words); Console.WriteLine("QuizPage создан, переходим..."); await Navigation.PushAsync(quizPage); } catch (Exception ex) { Console.WriteLine($"Ошибка в OnQuizClicked: {ex}"); await DisplayAlert("Ошибка", $"Не удалось открыть викторину: {ex.Message}", "OK"); } } private async void OnResetClicked(object sender, EventArgs e) { var confirm = await DisplayAlert( "Сброс кэша", "Удалить локальную копию словаря и загрузить стартовые слова?", "Да", "Нет" ); if (!confirm) return; try { if (File.Exists(_filePath)) { File.Delete(_filePath); } _words = new List<Word> { new() { Id = 1, English = "Hello", Russian = "Привет" }, new() { Id = 2, English = "World", Russian = "Мир" }, new() { Id = 3, English = "Apple", Russian = "Яблоко" }, new() { Id = 4, English = "Book", Russian = "Книга" }, new() { Id = 5, English = "Car", Russian = "Машина" } }; SaveLocalData(); _filteredWords.Clear(); _isTestMode = false; SearchBar.IsVisible = true; UpdateList(); SetStatus("🗑 Кэш очищен", Colors.Orange); CountLabel.Text = $"Слов: {_words.Count}"; await DisplayAlert("Успех", "Кэш очищен.", "OK"); } catch (Exception ex) { await DisplayAlert("Ошибка", ex.Message, "OK"); } } }