feat: add custom text via URL query parameter#574
Open
Dronakurl wants to merge 15 commits into
Open
Conversation
Allow users to practice custom text submitted via the `text` URL query parameter. Features: - Extract `text` parameter from URL on server-side - Pass custom text to client via PageData - Apply text to settings using React hook on mount - Show visual indicator when text is loaded from URL - Enforce 10,000 character limit Usage: http://localhost:3000/?text=Hello%20World Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add useRef to track if custom text has been applied, preventing the useEffect from running repeatedly and causing React error aradzie#185. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When custom text is provided via URL parameter, automatically switch the lesson type to CUSTOM so the text is immediately available for practice without manual mode switching. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add customText: null to all PageDataContext.Provider values in test files to satisfy the updated PageData type which now includes the customText field. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit fixes critical issues with the custom text via URL feature: ## Session-Only URL Text (Fixes Settings Persistence) - URL-loaded text is no longer persisted to user settings - Created UrlTextContext in @keybr/pages-shared to pass URL text - Modified CustomTextLesson to accept optional initialText parameter - useUrlCustomText now returns text instead of persisting it - Only switches lesson type, does not modify customText.content setting ## Server-Side Validation (Security Fix) - Added validation and truncation on server before sending to client - Prevents abuse with extremely long URLs - MAX_URL_TEXT_LENGTH = 10_000 characters enforced server-side ## Unit Tests - Added comprehensive unit tests for useUrlCustomText hook - Tests cover: null input, trimming, truncation, whitespace handling ## i18n Translations - Added translation keys for URL text message in: - English (en.json) - German (de.json) - French (fr.json) - Spanish (es.json) This ensures users don't get "stuck" with text from URLs they visited once, and provides proper security validation and test coverage. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes issues when custom text is loaded from URL: - URL text now displays correctly in the textarea (was showing placeholder/saved text) - URL text stats now display correctly (word count, etc.) - Users can now edit the text, which saves it to settings - Added useUrlText hook to CustomTextLessonSettings This resolves the confusing behavior where URL text was active but the UI showed the old saved text or placeholder. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The context provider was only in PracticeScreen, but SettingsScreen (which contains CustomTextLessonSettings) is a separate view. Moving the provider to PracticePage ensures both views have access to the URL text context. This fixes the issues where: - URL text was not showing in settings UI - Stats were not displaying correctly for URL text - "sHagCCk1" placeholder was showing instead of URL text Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add comprehensive test coverage for special characters, unicode, and edge cases: - Special characters from URL encoding (@#$%^&*()) - Unicode and emoji characters - Mixed quote types (double, single, backticks) - HTML-like characters (angle brackets, entities) - Newlines and tabs in text - Long text near browser URL limit (~925 chars) - Zero-width and invisible unicode characters - URL-encoded newlines and special characters Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents the text parameter from persisting in the URL after it has been applied to the practice session, allowing users to refresh or share the page without the text being re-applied. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Translate "lessonType.customText.fromUrl" and its description to all 43 supported languages using the new generic translation script. Languages translated: af, ar, bn, ca, cs, da, el, en, eo, et, fa, fo, ga, he, hr, hu, id, is, it, ja, ko, lt, mn, nb, ne, nl, pl, pt-br, pt-pt, ro, ru, sk, sl, sq, sv, th, tr, uk, vi, zh-hans, zh-hant, zh-tw, bg Already translated: de, es, fr Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auto-disable lowercase setting when URL text contains uppercase letters, so the original text casing is preserved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add ability to share custom typing practice text via URL query parameter. Users can now add
?text=YOUR_TEXTto any keybr.com URL to practice with specific text without manual pasting.What
textquery parameter (10,000 char limit)?text=from URL)Usage Examples
Changes
Core Files
packages/server/lib/app/page/controller.tsx- Server-side URL param extractionpackages/page-practice/lib/practice/useUrlCustomText.ts- Hook with URL cleanuppackages/keybr-pages-shared/lib/UrlTextContext.tsx- Session-only contextpackages/keybr-lesson/lib/customtext.ts- Accept initial text from URLpackages/keybr-lesson-loader/lib/LessonLoader.tsx- Use URL text from contextpackages/page-practice/lib/settings/lesson/CustomTextLessonSettings.tsx- Display URL textpackages/page-practice/lib/PracticePage.tsx- Context provider placementpackages/page-practice/lib/practice/useUrlCustomText.test.tsx- Comprehensive testsTests & Translations
Testing
All tests pass:
npm test -- --scope=@keybr/page-practice(21 tests)