release: v1.0.2
Publish Docker image / build-and-push (push) Canceled after 0s
GitHub Release / release (push) Canceled after 0s
ci / ci (22, ubuntu-latest) (push) Canceled after 0s

Add i18n (zh-CN/en), mobile navigation menus, stats and upload UI
improvements, and Docker reset-password CLI for emergency recovery.
This commit is contained in:
O96u committed 2026-08-23 17:43:42 +08:00
1 parent 074e4502c2
commit 22cb2ca8bc
46 files changed
+3724 -587

No files matched your search

+304
View File
@@ -0,0 +1,304 @@
{
"app": {
"title": "PicHost - Image Hosting",
"description": "A lightweight self-hosted image hosting system",
"tagline": "Personal lightweight image host"
},
"common": {
"loadingSession": "Verifying session…",
"save": "Save",
"cancel": "Cancel",
"copy": "Copy",
"delete": "Delete",
"search": "Search",
"refresh": "Refresh",
"back": "Back",
"all": "All",
"notConfigured": "(not configured)",
"countImages": "{count} images",
"itemsUnit": "items",
"imagesUnit": "images"
},
"nav": {
"api": "API",
"stats": "Stats",
"settings": "Settings",
"menu": "Menu",
"language": "Language",
"appearance": "Appearance",
"account": "Account",
"backToUpload": "Back to upload",
"changePassword": "Change password",
"systemSettings": "System settings",
"logout": "Log out"
},
"theme": {
"switch": "Switch theme",
"light": "Light",
"dark": "Dark",
"system": "System"
},
"locale": {
"switch": "Switch language",
"zh-CN": "简体中文",
"en": "English"
},
"auth": {
"username": "Username",
"password": "Password",
"confirmPassword": "Confirm password",
"login": "Log in",
"register": "Register",
"adminSecret": "Admin secret",
"adminSecretPlaceholder": "Enter ADMIN_SECRET",
"legacyHint": "Legacy deployment: sign in with the secret to migrate to username/password",
"noAccount": "No account?",
"hasAccount": "Already have an account?",
"backToLogin": "Back to login",
"loginFooter": "Upload and management require sign-in",
"loginSuccess": "Signed in",
"loginFailedSecret": "Sign-in failed. Check your secret",
"loginFailedCredentials": "Invalid username or password",
"loginFailed": "Sign-in failed. Check username and password",
"registerFailed": "Registration failed. Check your input",
"setupFailed": "Setup failed. Check your input",
"migrateFailed": "Migration failed. Check your input",
"passwordMismatch": "Passwords do not match",
"registerSuccess": "Registered successfully",
"errors": {
"invalidUsername": "Username must be 3–32 letters, numbers, or underscores",
"invalidPassword": "Password must be at least 8 characters"
}
},
"setup": {
"migrateTitle": "Migrate to username/password",
"initTitle": "First run — create admin account",
"usernamePlaceholder": "3–32 letters, numbers, or underscores",
"passwordPlaceholder": "Set login password",
"confirmPlaceholder": "Enter password again",
"allowRegistration": "Allow user registration",
"migrateSubmit": "Complete migration",
"initSubmit": "Create and continue",
"migrateSuccess": "Migration complete",
"initSuccess": "Setup complete"
},
"register": {
"title": "Register",
"subtitle": "Create a PicHost user account"
},
"password": {
"title": "Change password",
"subtitle": "Update your login password",
"current": "Current password",
"new": "New password",
"confirmNew": "Confirm new password",
"newPlaceholder": "Set new password",
"mismatch": "New passwords do not match",
"changed": "Password updated",
"tooShort": "New password must be at least 8 characters",
"changeFailed": "Failed to change password",
"strength": "Password strength",
"weak": "Weak",
"medium": "Medium",
"strong": "Strong",
"ruleMinLength": "At least {n} characters",
"ruleMixedCase": "Upper and lower case letters",
"ruleNumber": "Contains a number",
"ruleSpecial": "Contains a special character"
},
"upload": {
"title": "Drop images here to upload",
"hint": "Or click to select files, press {ctrl} + {v} to paste",
"formats": "JPEG / PNG / WebP / GIF / SVG / ICO, max 10 MB each, up to 10 files per batch",
"selectFiles": "Select images",
"settings": "Upload settings",
"progress": "Upload progress",
"statusPending": "Pending",
"statusUploading": "Uploading",
"statusSuccess": "Done",
"statusError": "Failed",
"selectImages": "Select images to upload",
"maxFiles": "Up to {n} images per upload",
"uploadSuccess": "Uploaded {n} image(s)",
"uploadPartialFail": "{n} image(s) failed to upload",
"uploadFailed": "Upload failed",
"loginRequired": "Please sign in first",
"sessionTitle": "This session",
"sessionEmpty": "No uploads in this session"
},
"copy": {
"url": "URL",
"markdown": "Markdown",
"html": "HTML",
"copied": "Copied to clipboard",
"copiedLabel": "Copied {label}",
"copiedUrl": "URL copied",
"copiedMarkdown": "Markdown copied",
"copiedHtml": "HTML copied",
"copiedFormat": "Copied {format}",
"failed": "Copy failed",
"failedManual": "Copy failed — select the link manually",
"curl": "cURL example copied"
},
"preferences": {
"title": "Upload preferences",
"subtitle": "Browser-local and account settings for your uploads only",
"back": "Back to upload",
"processing": "Image processing",
"clientCompress": "Client-side compression",
"clientCompressHint": "Compress in the browser before upload (server still converts to WebP)",
"autoDeletePrefix": "Auto-delete after",
"autoDeleteSuffix": "days",
"autoDeleteHint": "Only affects images uploaded after enabling; existing images are kept",
"webpQuality": "WebP quality",
"webpQualityHint": "Client compression quality (1–100); requires client-side compression",
"current": "Current: {n}",
"qualityHigh": "High quality",
"qualityMedium": "Medium quality",
"qualityLow": "Lossy",
"convenience": "Convenience",
"autoCopy": "Copy link after upload",
"autoCopyHint": "Copy to clipboard in the selected format"
},
"settings": {
"title": "System settings",
"subtitle": "Saved to database; environment variables take precedence",
"uploadAccount": "Upload & accounts",
"defaultFolder": "Default upload folder",
"defaultFolderHint": "Stored in this browser only; affects your upload target",
"allowRegistration": "Open registration",
"allowRegistrationHint": "Allow new users to register (regular users see only their images)",
"accessControl": "Access control",
"refererHint": "Referer hotlink protection; comma-separated hostnames, empty = no restriction",
"refererPlaceholder": "example.com, www.example.com",
"linkGeneration": "Link generation",
"imageBaseUrlHint": "Public URL prefix for generated links; use your public domain behind a reverse proxy",
"imageBaseUrlPlaceholder": "https://pic.example.com",
"imageBaseUrlActive": "Active: {url}",
"badgeEnv": ".env",
"badgeSaved": "Saved",
"badgeDefault": "Default",
"badgeUnset": "Not set",
"tokenEnv": "Environment",
"tokenDb": "Generated in app",
"tokenNone": "Not configured",
"apiTokenLine": "API Token · {source} · v{version}",
"unsavedChanges": "Unsaved changes",
"manageToken": "Manage token",
"envOverride": "Overridden by environment variable; cannot edit in UI",
"saved": "Settings saved",
"saveFailed": "Failed to save settings",
"loadFailed": "Failed to load settings"
},
"stats": {
"title": "Statistics",
"subtitle": "Overview and gallery",
"uploadToday": "Uploaded today",
"uploadMonth": "Uploaded this month",
"uploadTotal": "Total uploads",
"storedCount": "Stored images",
"deleteToday": "Deleted today",
"deleteMonth": "Deleted this month",
"deleteTotal": "Total deleted",
"userCount": "Registered users",
"uploadBytes": "Total upload size",
"folderDistribution": "Uploads by folder",
"folderUsage": "Storage by folder",
"noData": "No data",
"folderCount": "{count} · {size}",
"gallery": "Gallery",
"folder": "Folder",
"searchPlaceholder": "Search filename",
"clear": "Clear",
"selected": "{n} selected",
"batchDelete": "Delete selected",
"scrollTop": "Back to top",
"loadFailed": "Failed to load statistics",
"selectFirst": "Select images first",
"deleted": "Deleted {n} image(s)",
"deletePartialFail": "{n} image(s) failed to delete",
"deleteFailed": "Delete failed",
"deletedSingle": "Deleted",
"allFolders": "All",
"counting": "Counting…",
"summarySearch": "{folder} · Search “{q}” · {total} images",
"summaryTotal": "{folder} · {total} images"
},
"image": {
"empty": "No images",
"previewFailed": "Preview failed",
"uploader": "Uploader: {name}"
},
"delete": {
"confirmTitle": "Confirm delete",
"confirmDesc": "Delete {count} selected image(s)? This cannot be undone.",
"confirm": "Delete"
},
"pagination": {
"pageOf": "Page {page} / {totalPages} · {total} {unit}",
"totalOnly": "{total} {unit}",
"first": "First page",
"prev": "Previous page",
"next": "Next page",
"last": "Last page"
},
"api": {
"tokenTitle": "API Token",
"envOverrideTitle": "Token overridden by environment",
"envOverrideDesc": "Restart after changing API_UPLOAD_TOKEN; cannot regenerate in UI.",
"personalTitle": "Personal API token",
"personalDesc": "For your scripts only; uploads belong to your account.",
"notConfiguredTitle": "No token configured",
"notConfiguredDesc": "Click Regenerate to create a token for Auth-Token on all endpoints below.",
"regenerate": "Regenerate",
"tokenSourceEnv": "Source: API_UPLOAD_TOKEN environment variable",
"tokenSourceDb": "Source: generated in app (can regenerate)",
"tokenSourceNone": "Source: not configured",
"tokenHeader": "Header:",
"tokenInvalidate": "Old token is invalidated immediately after regenerate",
"docsTitle": "API reference",
"curlExample": "cURL example",
"loadFailed": "Failed to load API settings",
"regenerateEnvBlocked": "Token is set via environment; cannot regenerate in UI",
"regenerateFailed": "Failed to regenerate token",
"confirmRegenerateTitle": "Regenerate token?",
"confirmRegenerateDesc": "The old token stops working immediately. Update scripts and automation before continuing.",
"confirmRegenerate": "Regenerate",
"newTokenTitle": "New token generated",
"newTokenDesc": "Copy and save it now. You can copy again from the field above after closing.",
"copyToken": "Copy token",
"saved": "Saved",
"docs": {
"upload": {
"title": "Upload images",
"descAdmin": "Upload one or more images. Use image field; folder creates directory if missing. Also accepts file, files, type.",
"descUser": "Upload one or more images via image field. Also accepts file, files. Stored under images/."
},
"list": {
"title": "List images",
"descAdmin": "Paginated gallery; optional folder filter. limit default 20, max 100.",
"descUser": "Paginated list of your images. limit default 20, max 100."
},
"search": {
"title": "Search images",
"desc": "Search by filename or path; q is required."
},
"delete": {
"title": "Delete image",
"desc": "Delete by key (storage path, e.g. images/2026/08/xxx.webp)."
},
"batchDelete": {
"title": "Batch delete",
"desc": "Delete multiple images; request body is a keys array."
},
"twikoo": {
"title": "Twikoo-compatible upload",
"desc": "Twikoo / EasyImage 2.0 protocol; stored under twikoo/. Fields: image + token."
}
}
},
"userSettings": {
"loadFailed": "Failed to load settings",
"saveFailed": "Failed to save settings"
}
}