Implement Task 16: Murphy Grammar Engine & Handwritten Journaling
This commit is contained in:
@@ -9,6 +9,7 @@ import { initDictionary, loadInitialData } from './modules/dictionary.js';
|
||||
import { initSrs, startSrsTrainingSession, openStatsDashboard } from './modules/srs.js';
|
||||
import { initReader, loadBookshelf, openBook } from './modules/reader.js';
|
||||
import { initCefr, loadCefrOverview, startCefrQuiz } from './modules/cefr.js';
|
||||
import { initGrammar, loadGrammarUnits, openGrammarUnit } from './modules/grammar.js';
|
||||
|
||||
let currentUser = null;
|
||||
let isRouting = false;
|
||||
@@ -40,6 +41,8 @@ export function applyInitialViewPreflight() {
|
||||
hash = '#srs';
|
||||
} else if (lastView === 'cefr-view') {
|
||||
hash = '#cefr';
|
||||
} else if (lastView === 'grammar-view') {
|
||||
hash = '#grammar';
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
@@ -48,6 +51,7 @@ export function applyInitialViewPreflight() {
|
||||
const srsView = document.getElementById('srs-view');
|
||||
const readerView = document.getElementById('reader-view');
|
||||
const cefrView = document.getElementById('cefr-view');
|
||||
const grammarView = document.getElementById('grammar-view');
|
||||
const bookshelfContainer = document.getElementById('bookshelf-container');
|
||||
const readerInterface = document.getElementById('reader-interface');
|
||||
const readerBookTitle = document.getElementById('reader-book-title');
|
||||
@@ -56,6 +60,7 @@ export function applyInitialViewPreflight() {
|
||||
if (dictionaryView) dictionaryView.classList.add('hidden');
|
||||
if (srsView) srsView.classList.add('hidden');
|
||||
if (cefrView) cefrView.classList.add('hidden');
|
||||
if (grammarView) grammarView.classList.add('hidden');
|
||||
if (readerView) readerView.classList.remove('hidden');
|
||||
updateMobileActiveTab('reader');
|
||||
if (hash.includes('/book/')) {
|
||||
@@ -67,14 +72,23 @@ export function applyInitialViewPreflight() {
|
||||
if (dictionaryView) dictionaryView.classList.add('hidden');
|
||||
if (readerView) readerView.classList.add('hidden');
|
||||
if (cefrView) cefrView.classList.add('hidden');
|
||||
if (grammarView) grammarView.classList.add('hidden');
|
||||
if (srsView) srsView.classList.remove('hidden');
|
||||
updateMobileActiveTab('srs');
|
||||
} else if (hash.startsWith('#cefr')) {
|
||||
if (dictionaryView) dictionaryView.classList.add('hidden');
|
||||
if (readerView) readerView.classList.add('hidden');
|
||||
if (srsView) srsView.classList.add('hidden');
|
||||
if (grammarView) grammarView.classList.add('hidden');
|
||||
if (cefrView) cefrView.classList.remove('hidden');
|
||||
updateMobileActiveTab('');
|
||||
} else if (hash.startsWith('#grammar')) {
|
||||
if (dictionaryView) dictionaryView.classList.add('hidden');
|
||||
if (readerView) readerView.classList.add('hidden');
|
||||
if (srsView) srsView.classList.add('hidden');
|
||||
if (cefrView) cefrView.classList.add('hidden');
|
||||
if (grammarView) grammarView.classList.remove('hidden');
|
||||
updateMobileActiveTab('');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,10 +104,12 @@ export function openDictionaryView(updateHash = true) {
|
||||
const srsView = document.getElementById('srs-view');
|
||||
const readerView = document.getElementById('reader-view');
|
||||
const cefrView = document.getElementById('cefr-view');
|
||||
const grammarView = document.getElementById('grammar-view');
|
||||
|
||||
if (srsView) srsView.classList.add('hidden');
|
||||
if (readerView) readerView.classList.add('hidden');
|
||||
if (cefrView) cefrView.classList.add('hidden');
|
||||
if (grammarView) grammarView.classList.add('hidden');
|
||||
if (dictionaryView) dictionaryView.classList.remove('hidden');
|
||||
updateMobileActiveTab('dict');
|
||||
try { localStorage.setItem('notes_active_view', 'dictionary-view'); } catch (e) {}
|
||||
@@ -110,10 +126,12 @@ export function openSrsView(tagFilter = null, updateHash = true) {
|
||||
const srsView = document.getElementById('srs-view');
|
||||
const readerView = document.getElementById('reader-view');
|
||||
const cefrView = document.getElementById('cefr-view');
|
||||
const grammarView = document.getElementById('grammar-view');
|
||||
|
||||
if (dictionaryView) dictionaryView.classList.add('hidden');
|
||||
if (readerView) readerView.classList.add('hidden');
|
||||
if (cefrView) cefrView.classList.add('hidden');
|
||||
if (grammarView) grammarView.classList.add('hidden');
|
||||
if (srsView) srsView.classList.remove('hidden');
|
||||
updateMobileActiveTab('srs');
|
||||
try { localStorage.setItem('notes_active_view', 'srs-view'); } catch (e) {}
|
||||
@@ -133,12 +151,14 @@ export function openBookshelfView(updateHash = true) {
|
||||
const srsView = document.getElementById('srs-view');
|
||||
const readerView = document.getElementById('reader-view');
|
||||
const cefrView = document.getElementById('cefr-view');
|
||||
const grammarView = document.getElementById('grammar-view');
|
||||
const bookshelfContainer = document.getElementById('bookshelf-container');
|
||||
const readerInterface = document.getElementById('reader-interface');
|
||||
|
||||
if (dictionaryView) dictionaryView.classList.add('hidden');
|
||||
if (srsView) srsView.classList.add('hidden');
|
||||
if (cefrView) cefrView.classList.add('hidden');
|
||||
if (grammarView) grammarView.classList.add('hidden');
|
||||
if (readerView) readerView.classList.remove('hidden');
|
||||
if (bookshelfContainer) bookshelfContainer.classList.remove('hidden');
|
||||
if (readerInterface) readerInterface.classList.add('hidden');
|
||||
@@ -173,10 +193,12 @@ export function openCefrView(level = null, mode = 'all', updateHash = true) {
|
||||
const srsView = document.getElementById('srs-view');
|
||||
const readerView = document.getElementById('reader-view');
|
||||
const cefrView = document.getElementById('cefr-view');
|
||||
const grammarView = document.getElementById('grammar-view');
|
||||
|
||||
if (dictionaryView) dictionaryView.classList.add('hidden');
|
||||
if (srsView) srsView.classList.add('hidden');
|
||||
if (readerView) readerView.classList.add('hidden');
|
||||
if (grammarView) grammarView.classList.add('hidden');
|
||||
if (cefrView) cefrView.classList.remove('hidden');
|
||||
|
||||
updateMobileActiveTab('');
|
||||
@@ -189,6 +211,36 @@ export function openCefrView(level = null, mode = 'all', updateHash = true) {
|
||||
}
|
||||
}
|
||||
|
||||
export function openGrammarView(unitId = null, updateHash = true) {
|
||||
const targetHash = unitId ? `#grammar/unit/${unitId}` : '#grammar';
|
||||
|
||||
if (updateHash && window.location.hash !== targetHash) {
|
||||
window.location.hash = targetHash;
|
||||
return;
|
||||
}
|
||||
|
||||
const dictionaryView = document.getElementById('dictionary-view');
|
||||
const srsView = document.getElementById('srs-view');
|
||||
const readerView = document.getElementById('reader-view');
|
||||
const cefrView = document.getElementById('cefr-view');
|
||||
const grammarView = document.getElementById('grammar-view');
|
||||
|
||||
if (dictionaryView) dictionaryView.classList.add('hidden');
|
||||
if (srsView) srsView.classList.add('hidden');
|
||||
if (readerView) readerView.classList.add('hidden');
|
||||
if (cefrView) cefrView.classList.add('hidden');
|
||||
if (grammarView) grammarView.classList.remove('hidden');
|
||||
|
||||
updateMobileActiveTab('');
|
||||
try { localStorage.setItem('notes_active_view', 'grammar-view'); } catch (e) {}
|
||||
|
||||
if (unitId) {
|
||||
openGrammarUnit(unitId);
|
||||
} else {
|
||||
loadGrammarUnits();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Route Handler
|
||||
// -----------------------------------------------------------------------
|
||||
@@ -213,6 +265,10 @@ export async function handleRouting() {
|
||||
hash = '#cefr';
|
||||
window.location.hash = hash;
|
||||
return;
|
||||
} else if (lastView === 'grammar-view') {
|
||||
hash = '#grammar';
|
||||
window.location.hash = hash;
|
||||
return;
|
||||
} else {
|
||||
hash = '#dictionary';
|
||||
}
|
||||
@@ -234,6 +290,14 @@ export async function handleRouting() {
|
||||
const level = parts[1] || null;
|
||||
const mode = parts[2] === 'mistakes' ? 'mistakes' : 'all';
|
||||
openCefrView(level, mode, false);
|
||||
} else if (cleanHash.startsWith('grammar')) {
|
||||
const parts = cleanHash.split('/');
|
||||
if (parts[1] === 'unit' && parts[2]) {
|
||||
const unitId = parseInt(parts[2], 10);
|
||||
openGrammarView(unitId, false);
|
||||
} else {
|
||||
openGrammarView(null, false);
|
||||
}
|
||||
} else if (cleanHash.startsWith('reader') || cleanHash === 'bookshelf') {
|
||||
const parts = cleanHash.split('/');
|
||||
if (parts[1] === 'book' && parts[2]) {
|
||||
@@ -355,6 +419,14 @@ function initMobileNavigation() {
|
||||
});
|
||||
}
|
||||
|
||||
const mobileGrammarBtn = document.getElementById('mobile-grammar-btn');
|
||||
if (mobileGrammarBtn) {
|
||||
mobileGrammarBtn.addEventListener('click', () => {
|
||||
closeMobileMenu();
|
||||
openGrammarView(null, true);
|
||||
});
|
||||
}
|
||||
|
||||
const mobileCefrBtn = document.getElementById('mobile-cefr-btn');
|
||||
if (mobileCefrBtn) {
|
||||
mobileCefrBtn.addEventListener('click', () => {
|
||||
@@ -499,11 +571,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
initSrs();
|
||||
initReader();
|
||||
initCefr();
|
||||
initGrammar();
|
||||
|
||||
// 5. Global Navigation & Header Actions
|
||||
const navBrandHome = document.getElementById('nav-brand-home');
|
||||
const navReaderBtn = document.getElementById('nav-reader-btn');
|
||||
const navCefrBtn = document.getElementById('nav-cefr-btn');
|
||||
const navGrammarBtn = document.getElementById('nav-grammar-btn');
|
||||
const srsTrainerBtn = document.getElementById('srs-trainer-btn');
|
||||
const srsJumpCefrBtn = document.getElementById('srs-jump-cefr-btn');
|
||||
const loginForm = document.getElementById('login-form');
|
||||
@@ -521,6 +595,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
if (navCefrBtn) {
|
||||
navCefrBtn.addEventListener('click', () => { window.location.hash = '#cefr'; });
|
||||
}
|
||||
if (navGrammarBtn) {
|
||||
navGrammarBtn.addEventListener('click', () => { window.location.hash = '#grammar'; });
|
||||
}
|
||||
if (srsTrainerBtn) {
|
||||
srsTrainerBtn.addEventListener('click', () => { window.location.hash = '#srs'; });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user