mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-06 15:47:39 +03:00
Compare commits
3 Commits
ed439b9c01
...
7aee7ad06c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7aee7ad06c | ||
|
|
f67c544e16 | ||
|
|
38ee755033 |
@ -153,7 +153,7 @@ Click **File Manager** to access file management features.
|
||||
|
||||
1. Click the **+ Add** button in the top-right corner
|
||||
2. Select **New Folder** from the dropdown menu
|
||||
3. Enter a folder name (letters, numbers, underscores, and hyphens only)
|
||||
3. Enter a folder name (must not contain characters \" * : < > ? / \\ | and must not be . or ..)
|
||||
4. Click **Create Folder**
|
||||
|
||||
This is useful for organizing your ebooks by genre, author, or series.
|
||||
|
||||
@ -92,8 +92,26 @@ void KeyboardEntryActivity::handleKeyPress() {
|
||||
// Handle special row (bottom row with shift, space, backspace, done)
|
||||
if (selectedRow == SPECIAL_ROW) {
|
||||
if (selectedCol >= SHIFT_COL && selectedCol < SPACE_COL) {
|
||||
// Shift toggle
|
||||
// Shift toggle (double-tap enables caps lock)
|
||||
const unsigned long now = millis();
|
||||
const bool isDoubleTap = (lastShiftTapMs != 0) && ((now - lastShiftTapMs) <= SHIFT_DOUBLE_TAP_MS);
|
||||
|
||||
if (capsLockActive) {
|
||||
capsLockActive = false;
|
||||
shiftActive = false;
|
||||
lastShiftTapMs = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDoubleTap) {
|
||||
capsLockActive = true;
|
||||
shiftActive = true;
|
||||
lastShiftTapMs = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
shiftActive = !shiftActive;
|
||||
lastShiftTapMs = now;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -131,8 +149,9 @@ void KeyboardEntryActivity::handleKeyPress() {
|
||||
if (maxLength == 0 || text.length() < maxLength) {
|
||||
text += c;
|
||||
// Auto-disable shift after typing a letter
|
||||
if (shiftActive && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) {
|
||||
if (shiftActive && !capsLockActive && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) {
|
||||
shiftActive = false;
|
||||
lastShiftTapMs = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -318,7 +337,8 @@ void KeyboardEntryActivity::render() const {
|
||||
|
||||
// SHIFT key (logical col 0, spans 2 key widths)
|
||||
const bool shiftSelected = (selectedRow == 4 && selectedCol >= SHIFT_COL && selectedCol < SPACE_COL);
|
||||
renderItemWithSelector(currentX + 2, rowY, shiftActive ? "SHIFT" : "shift", shiftSelected);
|
||||
const char* shiftLabel = capsLockActive ? "CAPS" : (shiftActive ? "SHIFT" : "shift");
|
||||
renderItemWithSelector(currentX + 2, rowY, shiftLabel, shiftSelected);
|
||||
currentX += 2 * (keyWidth + keySpacing);
|
||||
|
||||
// Space bar (logical cols 2-6, spans 5 key widths)
|
||||
|
||||
@ -71,6 +71,10 @@ class KeyboardEntryActivity : public Activity {
|
||||
int selectedRow = 0;
|
||||
int selectedCol = 0;
|
||||
bool shiftActive = false;
|
||||
bool capsLockActive = false;
|
||||
unsigned long lastShiftTapMs = 0;
|
||||
|
||||
static constexpr unsigned long SHIFT_DOUBLE_TAP_MS = 500;
|
||||
|
||||
// Callbacks
|
||||
OnCompleteCallback onComplete;
|
||||
|
||||
@ -1146,10 +1146,10 @@ function retryAllFailedUploads() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate folder name (no special characters except underscore and hyphen)
|
||||
const validName = /^[a-zA-Z0-9_\-]+$/.test(folderName);
|
||||
// Validate folder name
|
||||
const validName = /^(?!\.{1,2}$)[^"*:<>?\/\\|]+$/.test(folderName);
|
||||
if (!validName) {
|
||||
alert('Folder name can only contain letters, numbers, underscores, and hyphens.');
|
||||
alert('Folder name cannot contain \" * : < > ? / \\ | and must not be . or ..');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user