Merge pull request #205 from gamosoft/features/auto-continue
Features/auto continue
This commit is contained in:
commit
ae7141a18f
|
|
@ -526,7 +526,11 @@ def create_note_metadata(notes_dir: str, note_path: str) -> Dict:
|
||||||
"""Get metadata for a note"""
|
"""Get metadata for a note"""
|
||||||
full_path = Path(notes_dir) / note_path
|
full_path = Path(notes_dir) / note_path
|
||||||
|
|
||||||
if not full_path.exists():
|
if not full_path.exists() or not full_path.is_file():
|
||||||
|
return {}
|
||||||
|
|
||||||
|
# Security check: ensure the path is within notes_dir (same as get_note_content)
|
||||||
|
if not validate_path_security(notes_dir, full_path):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
stat = full_path.stat()
|
stat = full_path.stat()
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
- **Documents** - PDF (default max 20MB, configurable)
|
- **Documents** - PDF (default max 20MB, configurable)
|
||||||
- **In-app viewing** - View all media types directly in the sidebar
|
- **In-app viewing** - View all media types directly in the sidebar
|
||||||
- **Inline preview** - Audio/video players and PDF viewer embedded in notes
|
- **Inline preview** - Audio/video players and PDF viewer embedded in notes
|
||||||
|
- **Relative media paths** - For ``, paths resolve from the note’s folder
|
||||||
|
|
||||||
### Organization
|
### Organization
|
||||||
- **Folder hierarchy** - Organize notes in nested folders
|
- **Folder hierarchy** - Organize notes in nested folders
|
||||||
|
|
@ -32,6 +33,7 @@
|
||||||
- **Visual tree view** - Expandable/collapsible navigation
|
- **Visual tree view** - Expandable/collapsible navigation
|
||||||
- **Hide system folders** - Toggle to hide `_attachments`, `_templates` and other underscore-prefixed folders from sidebar
|
- **Hide system folders** - Toggle to hide `_attachments`, `_templates` and other underscore-prefixed folders from sidebar
|
||||||
- **Tab inserts tab** - Toggle to make Tab key insert a tab character in the editor instead of changing focus
|
- **Tab inserts tab** - Toggle to make Tab key insert a tab character in the editor instead of changing focus
|
||||||
|
- **List & quote continuation (Enter)** - At the end of a line, Enter continues blockquotes (`>`), bullets (`-` / `*` / `+`), and task lists (`- [ ]` / `- [x]`); pressing Enter again on an empty continued line exits the list or quote. Disabled inside fenced code blocks and when using Shift+Enter (plain newline)
|
||||||
|
|
||||||
### Export & Print
|
### Export & Print
|
||||||
- **HTML Export** - Download notes as standalone HTML files with all styling, images, diagrams, and math embedded
|
- **HTML Export** - Download notes as standalone HTML files with all styling, images, diagrams, and math embedded
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,7 @@ function noteApp() {
|
||||||
// Preview rendering debounce
|
// Preview rendering debounce
|
||||||
_previewDebounceTimeout: null,
|
_previewDebounceTimeout: null,
|
||||||
_lastRenderedContent: '',
|
_lastRenderedContent: '',
|
||||||
|
_lastRenderedNote: '',
|
||||||
_cachedRenderedHTML: '',
|
_cachedRenderedHTML: '',
|
||||||
_mathDebounceTimeout: null,
|
_mathDebounceTimeout: null,
|
||||||
_mermaidDebounceTimeout: null,
|
_mermaidDebounceTimeout: null,
|
||||||
|
|
@ -857,6 +858,31 @@ function noteApp() {
|
||||||
this.autoSave();
|
this.autoSave();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enter: continue blockquote / bullet / task list; second Enter on empty item exits (see editor-markdown-continue.js).
|
||||||
|
*/
|
||||||
|
handleEditorEnterKey(event) {
|
||||||
|
if (typeof EditorMarkdownContinue === 'undefined') return;
|
||||||
|
const textarea = event.target;
|
||||||
|
if (!textarea || textarea.id !== 'note-editor') return;
|
||||||
|
|
||||||
|
const result = EditorMarkdownContinue.tryEnter(
|
||||||
|
this.noteContent,
|
||||||
|
textarea.selectionStart,
|
||||||
|
textarea.selectionEnd,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
if (!result.handled) return;
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
this.noteContent = result.text;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
textarea.selectionStart = textarea.selectionEnd = result.cursor;
|
||||||
|
});
|
||||||
|
this.autoSave();
|
||||||
|
this.updateSyntaxHighlight();
|
||||||
|
},
|
||||||
|
|
||||||
// Sort mode configuration
|
// Sort mode configuration
|
||||||
sortModes: ['a-z', 'z-a', 'newest', 'oldest', 'largest', 'smallest'],
|
sortModes: ['a-z', 'z-a', 'newest', 'oldest', 'largest', 'smallest'],
|
||||||
sortModeIcons: {
|
sortModeIcons: {
|
||||||
|
|
@ -1262,6 +1288,49 @@ function noteApp() {
|
||||||
return this._mediaLookup.get(nameLower) || null;
|
return this._mediaLookup.get(nameLower) || null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Resolve a Markdown image path to a vault-relative path (forward slashes).
|
||||||
|
// Relative paths use the note file's directory as base (same rules as CommonMark / browsers).
|
||||||
|
// A leading "/" (not "//") means vault-root-relative.
|
||||||
|
resolveMarkdownMediaPathForNote(noteVaultPath, rawSrc) {
|
||||||
|
const pathPart = rawSrc.split('#')[0].split('?')[0];
|
||||||
|
if (!pathPart) return '';
|
||||||
|
if (pathPart.startsWith('/') && !pathPart.startsWith('//')) {
|
||||||
|
return pathPart.replace(/^\/+/, '');
|
||||||
|
}
|
||||||
|
if (!noteVaultPath) {
|
||||||
|
return pathPart;
|
||||||
|
}
|
||||||
|
const dir = noteVaultPath.includes('/')
|
||||||
|
? noteVaultPath.slice(0, noteVaultPath.lastIndexOf('/'))
|
||||||
|
: '';
|
||||||
|
const base = `https://vn.invalid/${dir ? `${dir}/` : ''}`;
|
||||||
|
try {
|
||||||
|
const u = new URL(pathPart, base);
|
||||||
|
let p = u.pathname;
|
||||||
|
if (p.startsWith('/')) p = p.slice(1);
|
||||||
|
return p.split('/').filter(seg => seg !== '').map(seg => {
|
||||||
|
try {
|
||||||
|
return decodeURIComponent(seg);
|
||||||
|
} catch (e) {
|
||||||
|
return seg;
|
||||||
|
}
|
||||||
|
}).join('/');
|
||||||
|
} catch (e) {
|
||||||
|
return pathPart;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
encodeVaultRelativePathForMediaApi(vaultRelativePath) {
|
||||||
|
if (!vaultRelativePath) return '';
|
||||||
|
return vaultRelativePath.split('/').map(segment => {
|
||||||
|
try {
|
||||||
|
return encodeURIComponent(decodeURIComponent(segment));
|
||||||
|
} catch (e) {
|
||||||
|
return encodeURIComponent(segment);
|
||||||
|
}
|
||||||
|
}).join('/');
|
||||||
|
},
|
||||||
|
|
||||||
// Load all tags
|
// Load all tags
|
||||||
async loadTags() {
|
async loadTags() {
|
||||||
try {
|
try {
|
||||||
|
|
@ -2833,6 +2902,7 @@ function noteApp() {
|
||||||
|
|
||||||
this.currentNote = notePath;
|
this.currentNote = notePath;
|
||||||
this._lastRenderedContent = ''; // Clear render cache for new note
|
this._lastRenderedContent = ''; // Clear render cache for new note
|
||||||
|
this._lastRenderedNote = '';
|
||||||
this._cachedRenderedHTML = '';
|
this._cachedRenderedHTML = '';
|
||||||
this._initializedVideoSources = new Set(); // Clear video cache for new note
|
this._initializedVideoSources = new Set(); // Clear video cache for new note
|
||||||
this.noteContent = data.content;
|
this.noteContent = data.content;
|
||||||
|
|
@ -3937,6 +4007,7 @@ function noteApp() {
|
||||||
this.noteContent = '';
|
this.noteContent = '';
|
||||||
this.currentNoteName = '';
|
this.currentNoteName = '';
|
||||||
this._lastRenderedContent = ''; // Clear render cache
|
this._lastRenderedContent = ''; // Clear render cache
|
||||||
|
this._lastRenderedNote = '';
|
||||||
this._cachedRenderedHTML = '';
|
this._cachedRenderedHTML = '';
|
||||||
document.title = this.appName;
|
document.title = this.appName;
|
||||||
// Redirect to root
|
// Redirect to root
|
||||||
|
|
@ -4108,7 +4179,9 @@ function noteApp() {
|
||||||
if (!this.noteContent) return '<p style="color: var(--text-tertiary);">Nothing to preview yet...</p>';
|
if (!this.noteContent) return '<p style="color: var(--text-tertiary);">Nothing to preview yet...</p>';
|
||||||
|
|
||||||
// Performance: Return cached HTML if content hasn't changed
|
// Performance: Return cached HTML if content hasn't changed
|
||||||
if (this.noteContent === this._lastRenderedContent && this._cachedRenderedHTML) {
|
if (this.noteContent === this._lastRenderedContent &&
|
||||||
|
this.currentNote === this._lastRenderedNote &&
|
||||||
|
this._cachedRenderedHTML) {
|
||||||
return this._cachedRenderedHTML;
|
return this._cachedRenderedHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4302,14 +4375,10 @@ function noteApp() {
|
||||||
|
|
||||||
// Transform relative paths to /api/media/ for serving
|
// Transform relative paths to /api/media/ for serving
|
||||||
if (isLocal && !src.startsWith('/api/media/')) {
|
if (isLocal && !src.startsWith('/api/media/')) {
|
||||||
// URL-encode path segments to handle spaces and special characters
|
const vaultRelative = self.currentNote
|
||||||
const encodedPath = src.split('/').map(segment => {
|
? self.resolveMarkdownMediaPathForNote(self.currentNote, src)
|
||||||
try {
|
: src.split('#')[0].split('?')[0];
|
||||||
return encodeURIComponent(decodeURIComponent(segment));
|
const encodedPath = self.encodeVaultRelativePathForMediaApi(vaultRelative);
|
||||||
} catch (e) {
|
|
||||||
return encodeURIComponent(segment);
|
|
||||||
}
|
|
||||||
}).join('/');
|
|
||||||
src = `/api/media/${encodedPath}`;
|
src = `/api/media/${encodedPath}`;
|
||||||
img.setAttribute('src', src);
|
img.setAttribute('src', src);
|
||||||
}
|
}
|
||||||
|
|
@ -4409,6 +4478,7 @@ function noteApp() {
|
||||||
|
|
||||||
// Cache the result for performance
|
// Cache the result for performance
|
||||||
this._lastRenderedContent = this.noteContent;
|
this._lastRenderedContent = this.noteContent;
|
||||||
|
this._lastRenderedNote = this.currentNote;
|
||||||
this._cachedRenderedHTML = html;
|
this._cachedRenderedHTML = html;
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
/**
|
||||||
|
* Markdown editor helpers: Enter continues blockquotes, bullets, and task lists.
|
||||||
|
* Plain functions only; no DOM. Used by app.js handleEditorEnterKey.
|
||||||
|
*/
|
||||||
|
(function (global) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if cursor position lies inside a ``` fenced code block (toggle per line).
|
||||||
|
*/
|
||||||
|
function cursorInMarkdownCodeFence(text, pos) {
|
||||||
|
const before = text.slice(0, pos);
|
||||||
|
let lineStart = 0;
|
||||||
|
let inFence = false;
|
||||||
|
for (;;) {
|
||||||
|
const nl = before.indexOf('\n', lineStart);
|
||||||
|
const end = nl === -1 ? before.length : nl;
|
||||||
|
const line = before.slice(lineStart, end);
|
||||||
|
const trimmed = line.trimStart();
|
||||||
|
if (trimmed.startsWith('```')) {
|
||||||
|
inFence = !inFence;
|
||||||
|
}
|
||||||
|
if (nl === -1) break;
|
||||||
|
lineStart = nl + 1;
|
||||||
|
}
|
||||||
|
return inFence;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLineBounds(text, pos) {
|
||||||
|
const lineStart = text.lastIndexOf('\n', Math.max(0, pos - 1)) + 1;
|
||||||
|
let lineEnd = text.indexOf('\n', pos);
|
||||||
|
if (lineEnd === -1) lineEnd = text.length;
|
||||||
|
return {
|
||||||
|
lineStart,
|
||||||
|
lineEnd,
|
||||||
|
line: text.slice(lineStart, lineEnd),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {{ continuePrefix: string, isEmpty: boolean } | null}
|
||||||
|
*/
|
||||||
|
function parseContinuationContext(line) {
|
||||||
|
const quoteMatch = line.match(/^(\s*)((?:>\s*)+)/);
|
||||||
|
let quoteFull = '';
|
||||||
|
let rest = line;
|
||||||
|
if (quoteMatch) {
|
||||||
|
quoteFull = quoteMatch[1] + quoteMatch[2];
|
||||||
|
rest = line.slice(quoteMatch[0].length);
|
||||||
|
}
|
||||||
|
|
||||||
|
const taskMatch = rest.match(/^(\s*)([-*+])\s+\[([xX ])\]\s*(.*)$/);
|
||||||
|
if (taskMatch) {
|
||||||
|
const inner = taskMatch[1];
|
||||||
|
const ch = taskMatch[2];
|
||||||
|
const mark = taskMatch[3];
|
||||||
|
const cont = taskMatch[4];
|
||||||
|
const marker = ch + ' [' + mark + '] ';
|
||||||
|
const isEmpty = cont.trim() === '';
|
||||||
|
return { continuePrefix: quoteFull + inner + marker, isEmpty };
|
||||||
|
}
|
||||||
|
|
||||||
|
const bulletMatch = rest.match(/^(\s*)([-*+])\s+(.*)$/);
|
||||||
|
if (bulletMatch) {
|
||||||
|
const inner = bulletMatch[1];
|
||||||
|
const ch = bulletMatch[2];
|
||||||
|
const cont = bulletMatch[3];
|
||||||
|
const marker = ch + ' ';
|
||||||
|
const isEmpty = cont.trim() === '';
|
||||||
|
return { continuePrefix: quoteFull + inner + marker, isEmpty };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quoteFull) {
|
||||||
|
const isEmpty = rest.trim() === '';
|
||||||
|
return { continuePrefix: quoteFull, isEmpty };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} text
|
||||||
|
* @param {number} selStart
|
||||||
|
* @param {number} selEnd
|
||||||
|
* @param {KeyboardEvent} event
|
||||||
|
* @returns {{ handled: false } | { handled: true, text: string, cursor: number }}
|
||||||
|
*/
|
||||||
|
function tryEnter(text, selStart, selEnd, event) {
|
||||||
|
if (event.key !== 'Enter') return { handled: false };
|
||||||
|
if (event.defaultPrevented) return { handled: false };
|
||||||
|
if (event.isComposing) return { handled: false };
|
||||||
|
if (event.shiftKey) return { handled: false };
|
||||||
|
if (event.ctrlKey || event.metaKey || event.altKey) return { handled: false };
|
||||||
|
if (selStart !== selEnd) return { handled: false };
|
||||||
|
if (cursorInMarkdownCodeFence(text, selStart)) return { handled: false };
|
||||||
|
|
||||||
|
const { lineStart, lineEnd, line } = getLineBounds(text, selStart);
|
||||||
|
if (selStart !== lineEnd) return { handled: false };
|
||||||
|
|
||||||
|
const lineForParse = line.replace(/\r/g, '');
|
||||||
|
const ctx = parseContinuationContext(lineForParse);
|
||||||
|
if (!ctx) return { handled: false };
|
||||||
|
|
||||||
|
if (ctx.isEmpty) {
|
||||||
|
let delEnd = lineEnd;
|
||||||
|
if (delEnd < text.length && text.charAt(delEnd) === '\n') {
|
||||||
|
delEnd += 1;
|
||||||
|
}
|
||||||
|
const newText = text.slice(0, lineStart) + text.slice(delEnd);
|
||||||
|
return { handled: true, text: newText, cursor: lineStart };
|
||||||
|
}
|
||||||
|
|
||||||
|
const insert = '\n' + ctx.continuePrefix;
|
||||||
|
const newText = text.slice(0, lineEnd) + insert + text.slice(lineEnd);
|
||||||
|
return { handled: true, text: newText, cursor: lineEnd + insert.length };
|
||||||
|
}
|
||||||
|
|
||||||
|
global.EditorMarkdownContinue = {
|
||||||
|
tryEnter,
|
||||||
|
parseContinuationContext,
|
||||||
|
getLineBounds,
|
||||||
|
cursorInMarkdownCodeFence,
|
||||||
|
};
|
||||||
|
})(typeof window !== 'undefined' ? window : globalThis);
|
||||||
|
|
@ -2682,6 +2682,7 @@
|
||||||
x-model="noteContent"
|
x-model="noteContent"
|
||||||
@input="autoSave(); updateSyntaxHighlight()"
|
@input="autoSave(); updateSyntaxHighlight()"
|
||||||
@scroll="syncOverlayScroll()"
|
@scroll="syncOverlayScroll()"
|
||||||
|
@keydown.enter="handleEditorEnterKey($event)"
|
||||||
@keydown.tab="handleTabKey($event)"
|
@keydown.tab="handleTabKey($event)"
|
||||||
@drop="onEditorDrop($event)"
|
@drop="onEditorDrop($event)"
|
||||||
@dragover.prevent="onEditorDragOver($event)"
|
@dragover.prevent="onEditorDragOver($event)"
|
||||||
|
|
@ -3433,6 +3434,7 @@
|
||||||
</button>
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
<script src="/static/editor-markdown-continue.js"></script>
|
||||||
<script src="/static/app.js"></script>
|
<script src="/static/app.js"></script>
|
||||||
|
|
||||||
<!-- PWA Service Worker Registration -->
|
<!-- PWA Service Worker Registration -->
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,10 @@
|
||||||
"collapse_all": "Alle Ordner zuklappen",
|
"collapse_all": "Alle Ordner zuklappen",
|
||||||
"sort_a-z": "Sortieren A-Z",
|
"sort_a-z": "Sortieren A-Z",
|
||||||
"sort_z-a": "Sortieren Z-A",
|
"sort_z-a": "Sortieren Z-A",
|
||||||
"sort_newest": "Nach neuesten sortieren",
|
"sort_newest": "Nach neuesten sortieren (nur Dateien)",
|
||||||
"sort_oldest": "Nach ältesten sortieren",
|
"sort_oldest": "Nach ältesten sortieren (nur Dateien)",
|
||||||
"sort_largest": "Nach größten sortieren",
|
"sort_largest": "Nach größten sortieren (nur Dateien)",
|
||||||
"sort_smallest": "Nach kleinsten sortieren",
|
"sort_smallest": "Nach kleinsten sortieren (nur Dateien)",
|
||||||
"toggle_sidebar": "Seitenleiste umschalten",
|
"toggle_sidebar": "Seitenleiste umschalten",
|
||||||
"go_to_homepage": "Zur Startseite",
|
"go_to_homepage": "Zur Startseite",
|
||||||
"files": "Dateien",
|
"files": "Dateien",
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,10 @@
|
||||||
"collapse_all": "Collapse all folders",
|
"collapse_all": "Collapse all folders",
|
||||||
"sort_a-z": "Sort A to Z",
|
"sort_a-z": "Sort A to Z",
|
||||||
"sort_z-a": "Sort Z to A",
|
"sort_z-a": "Sort Z to A",
|
||||||
"sort_newest": "Sort by newest",
|
"sort_newest": "Sort by newest (files only)",
|
||||||
"sort_oldest": "Sort by oldest",
|
"sort_oldest": "Sort by oldest (files only)",
|
||||||
"sort_largest": "Sort by largest",
|
"sort_largest": "Sort by largest (files only)",
|
||||||
"sort_smallest": "Sort by smallest",
|
"sort_smallest": "Sort by smallest (files only)",
|
||||||
"toggle_sidebar": "Toggle sidebar",
|
"toggle_sidebar": "Toggle sidebar",
|
||||||
"go_to_homepage": "Go to homepage",
|
"go_to_homepage": "Go to homepage",
|
||||||
"files": "Files",
|
"files": "Files",
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,10 @@
|
||||||
"collapse_all": "Collapse all folders",
|
"collapse_all": "Collapse all folders",
|
||||||
"sort_a-z": "Sort A to Z",
|
"sort_a-z": "Sort A to Z",
|
||||||
"sort_z-a": "Sort Z to A",
|
"sort_z-a": "Sort Z to A",
|
||||||
"sort_newest": "Sort by newest",
|
"sort_newest": "Sort by newest (files only)",
|
||||||
"sort_oldest": "Sort by oldest",
|
"sort_oldest": "Sort by oldest (files only)",
|
||||||
"sort_largest": "Sort by largest",
|
"sort_largest": "Sort by largest (files only)",
|
||||||
"sort_smallest": "Sort by smallest",
|
"sort_smallest": "Sort by smallest (files only)",
|
||||||
"toggle_sidebar": "Toggle sidebar",
|
"toggle_sidebar": "Toggle sidebar",
|
||||||
"go_to_homepage": "Go to homepage",
|
"go_to_homepage": "Go to homepage",
|
||||||
"files": "Files",
|
"files": "Files",
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,10 @@
|
||||||
"collapse_all": "Contraer todas las carpetas",
|
"collapse_all": "Contraer todas las carpetas",
|
||||||
"sort_a-z": "Ordenar A-Z",
|
"sort_a-z": "Ordenar A-Z",
|
||||||
"sort_z-a": "Ordenar Z-A",
|
"sort_z-a": "Ordenar Z-A",
|
||||||
"sort_newest": "Ordenar por más reciente",
|
"sort_newest": "Ordenar por más reciente (solo archivos)",
|
||||||
"sort_oldest": "Ordenar por más antiguo",
|
"sort_oldest": "Ordenar por más antiguo (solo archivos)",
|
||||||
"sort_largest": "Ordenar por más grande",
|
"sort_largest": "Ordenar por más grande (solo archivos)",
|
||||||
"sort_smallest": "Ordenar por más pequeño",
|
"sort_smallest": "Ordenar por más pequeño (solo archivos)",
|
||||||
"toggle_sidebar": "Alternar barra lateral",
|
"toggle_sidebar": "Alternar barra lateral",
|
||||||
"go_to_homepage": "Ir al inicio",
|
"go_to_homepage": "Ir al inicio",
|
||||||
"files": "Archivos",
|
"files": "Archivos",
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,10 @@
|
||||||
"collapse_all": "Réduire tous les dossiers",
|
"collapse_all": "Réduire tous les dossiers",
|
||||||
"sort_a-z": "Trier A-Z",
|
"sort_a-z": "Trier A-Z",
|
||||||
"sort_z-a": "Trier Z-A",
|
"sort_z-a": "Trier Z-A",
|
||||||
"sort_newest": "Trier par plus récent",
|
"sort_newest": "Trier par plus récent (fichiers uniquement)",
|
||||||
"sort_oldest": "Trier par plus ancien",
|
"sort_oldest": "Trier par plus ancien (fichiers uniquement)",
|
||||||
"sort_largest": "Trier par plus grand",
|
"sort_largest": "Trier par plus grand (fichiers uniquement)",
|
||||||
"sort_smallest": "Trier par plus petit",
|
"sort_smallest": "Trier par plus petit (fichiers uniquement)",
|
||||||
"toggle_sidebar": "Afficher/Masquer la barre latérale",
|
"toggle_sidebar": "Afficher/Masquer la barre latérale",
|
||||||
"go_to_homepage": "Aller à l'accueil",
|
"go_to_homepage": "Aller à l'accueil",
|
||||||
"files": "Fichiers",
|
"files": "Fichiers",
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,10 @@
|
||||||
"collapse_all": "Mappák összecsukása",
|
"collapse_all": "Mappák összecsukása",
|
||||||
"sort_a-z": "Rendezés A-Z",
|
"sort_a-z": "Rendezés A-Z",
|
||||||
"sort_z-a": "Rendezés Z-A",
|
"sort_z-a": "Rendezés Z-A",
|
||||||
"sort_newest": "Legújabb elöl",
|
"sort_newest": "Legújabb elöl (csak fájlok)",
|
||||||
"sort_oldest": "Legrégebbi elöl",
|
"sort_oldest": "Legrégebbi elöl (csak fájlok)",
|
||||||
"sort_largest": "Legnagyobb elöl",
|
"sort_largest": "Legnagyobb elöl (csak fájlok)",
|
||||||
"sort_smallest": "Legkisebb elöl",
|
"sort_smallest": "Legkisebb elöl (csak fájlok)",
|
||||||
"toggle_sidebar": "Oldalsáv megjelenítése",
|
"toggle_sidebar": "Oldalsáv megjelenítése",
|
||||||
"go_to_homepage": "Ugrás a kezdőlapra",
|
"go_to_homepage": "Ugrás a kezdőlapra",
|
||||||
"files": "Fájlok",
|
"files": "Fájlok",
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,10 @@
|
||||||
"collapse_all": "Comprimi tutte le cartelle",
|
"collapse_all": "Comprimi tutte le cartelle",
|
||||||
"sort_a-z": "Ordina A-Z",
|
"sort_a-z": "Ordina A-Z",
|
||||||
"sort_z-a": "Ordina Z-A",
|
"sort_z-a": "Ordina Z-A",
|
||||||
"sort_newest": "Ordina per più recente",
|
"sort_newest": "Ordina per più recente (solo file)",
|
||||||
"sort_oldest": "Ordina per più vecchio",
|
"sort_oldest": "Ordina per più vecchio (solo file)",
|
||||||
"sort_largest": "Ordina per più grande",
|
"sort_largest": "Ordina per più grande (solo file)",
|
||||||
"sort_smallest": "Ordina per più piccolo",
|
"sort_smallest": "Ordina per più piccolo (solo file)",
|
||||||
"toggle_sidebar": "Mostra/nascondi barra laterale",
|
"toggle_sidebar": "Mostra/nascondi barra laterale",
|
||||||
"go_to_homepage": "Vai alla home",
|
"go_to_homepage": "Vai alla home",
|
||||||
"files": "File",
|
"files": "File",
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,10 @@
|
||||||
"collapse_all": "すべて折りたたむ",
|
"collapse_all": "すべて折りたたむ",
|
||||||
"sort_a-z": "A-Z順",
|
"sort_a-z": "A-Z順",
|
||||||
"sort_z-a": "Z-A順",
|
"sort_z-a": "Z-A順",
|
||||||
"sort_newest": "新しい順",
|
"sort_newest": "新しい順(ファイルのみ)",
|
||||||
"sort_oldest": "古い順",
|
"sort_oldest": "古い順(ファイルのみ)",
|
||||||
"sort_largest": "大きい順",
|
"sort_largest": "大きい順(ファイルのみ)",
|
||||||
"sort_smallest": "小さい順",
|
"sort_smallest": "小さい順(ファイルのみ)",
|
||||||
"toggle_sidebar": "サイドバー切替",
|
"toggle_sidebar": "サイドバー切替",
|
||||||
"go_to_homepage": "ホームへ",
|
"go_to_homepage": "ホームへ",
|
||||||
"files": "ファイル",
|
"files": "ファイル",
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,10 @@
|
||||||
"collapse_all": "Свернуть все папки",
|
"collapse_all": "Свернуть все папки",
|
||||||
"sort_a-z": "Сортировка А-Я",
|
"sort_a-z": "Сортировка А-Я",
|
||||||
"sort_z-a": "Сортировка Я-А",
|
"sort_z-a": "Сортировка Я-А",
|
||||||
"sort_newest": "Сначала новые",
|
"sort_newest": "Сначала новые (только файлы)",
|
||||||
"sort_oldest": "Сначала старые",
|
"sort_oldest": "Сначала старые (только файлы)",
|
||||||
"sort_largest": "Сначала большие",
|
"sort_largest": "Сначала большие (только файлы)",
|
||||||
"sort_smallest": "Сначала маленькие",
|
"sort_smallest": "Сначала маленькие (только файлы)",
|
||||||
"toggle_sidebar": "Показать/скрыть боковую панель",
|
"toggle_sidebar": "Показать/скрыть боковую панель",
|
||||||
"go_to_homepage": "На главную",
|
"go_to_homepage": "На главную",
|
||||||
"files": "Файлы",
|
"files": "Файлы",
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,10 @@
|
||||||
"collapse_all": "Strni vse mape",
|
"collapse_all": "Strni vse mape",
|
||||||
"sort_a-z": "Razvrsti A-Ž",
|
"sort_a-z": "Razvrsti A-Ž",
|
||||||
"sort_z-a": "Razvrsti Ž-A",
|
"sort_z-a": "Razvrsti Ž-A",
|
||||||
"sort_newest": "Razvrsti po najnovejših",
|
"sort_newest": "Razvrsti po najnovejših (samo datoteke)",
|
||||||
"sort_oldest": "Razvrsti po najstarejših",
|
"sort_oldest": "Razvrsti po najstarejših (samo datoteke)",
|
||||||
"sort_largest": "Razvrsti po največjih",
|
"sort_largest": "Razvrsti po največjih (samo datoteke)",
|
||||||
"sort_smallest": "Razvrsti po najmanjših",
|
"sort_smallest": "Razvrsti po najmanjših (samo datoteke)",
|
||||||
"toggle_sidebar": "Preklopi stransko vrstico",
|
"toggle_sidebar": "Preklopi stransko vrstico",
|
||||||
"go_to_homepage": "Pojdi na začetno stran",
|
"go_to_homepage": "Pojdi na začetno stran",
|
||||||
"files": "Datoteke",
|
"files": "Datoteke",
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,10 @@
|
||||||
"collapse_all": "折叠所有文件夹",
|
"collapse_all": "折叠所有文件夹",
|
||||||
"sort_a-z": "按A-Z排序",
|
"sort_a-z": "按A-Z排序",
|
||||||
"sort_z-a": "按Z-A排序",
|
"sort_z-a": "按Z-A排序",
|
||||||
"sort_newest": "按最新排序",
|
"sort_newest": "按最新排序(仅文件)",
|
||||||
"sort_oldest": "按最旧排序",
|
"sort_oldest": "按最旧排序(仅文件)",
|
||||||
"sort_largest": "按最大排序",
|
"sort_largest": "按最大排序(仅文件)",
|
||||||
"sort_smallest": "按最小排序",
|
"sort_smallest": "按最小排序(仅文件)",
|
||||||
"toggle_sidebar": "切换侧边栏",
|
"toggle_sidebar": "切换侧边栏",
|
||||||
"go_to_homepage": "前往主页",
|
"go_to_homepage": "前往主页",
|
||||||
"files": "文件",
|
"files": "文件",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue