6bbf77860b
- an account can carry a picture: POST /api/auth/avatar (raw bytes, sniffed, replaces and unlinks the old file) and the public GET /api/users/:id/avatar. It rides wherever the account is named — the landing chip, the studio TopBar, the profile form. - new /profile page for members, sharing one Profile form (picture, email, password) with the admin drawer. - /admin is now one bordered frame whose left column is Profile / User account / Pictures / Close. Pictures lists every photo in the system with the slot that shows it; User account lists each account's name, email, picture and contribution count. - account control opens a menu: Admin page + Log out for an admin, Profile + Log out for a member.
174 lines
5.5 KiB
TypeScript
174 lines
5.5 KiB
TypeScript
import type { Dict } from './vi';
|
||
|
||
export const en: Dict = {
|
||
'lang.name': 'English',
|
||
|
||
'nav.demo': 'TRY DEMO',
|
||
'nav.login': 'LOG IN',
|
||
'nav.signup': 'SIGN UP',
|
||
'nav.logout': 'Log out',
|
||
'nav.account': 'Account',
|
||
'nav.theme': 'Theme',
|
||
'nav.language': 'Language',
|
||
'nav.back': 'Back to home',
|
||
'nav.guest': 'Guest',
|
||
|
||
'act.undo': 'UNDO',
|
||
'act.reset': 'RESET',
|
||
'act.export': 'EXPORT',
|
||
'act.exporting': 'Exporting…',
|
||
'act.cancel': 'Cancel',
|
||
|
||
'drop.title': 'Drag & drop a photo here',
|
||
'drop.hint': 'or click to pick one · paste from the clipboard with Ctrl+V',
|
||
'drop.replace': 'Choose another photo',
|
||
'drop.peeking': 'SHOWING THE ORIGINAL',
|
||
'drop.peekHint': 'Hold right-click or the \\ key to compare with the original',
|
||
'drop.compare': 'Compare with original picture',
|
||
'drop.demoLimit': 'Demo build: exports are capped at {px}px and carry a watermark.',
|
||
|
||
'tab.presets': 'PRESETS',
|
||
'tab.favorited': 'FAVORITED',
|
||
'tab.light': 'LIGHT',
|
||
'tab.wb': 'WB',
|
||
'tab.fx': 'FX',
|
||
'tab.frame': 'FRAME',
|
||
'tab.create': 'CREATE RECIPES',
|
||
|
||
'create.title': 'CREATE RECIPES',
|
||
'create.save': 'SAVE RECIPE',
|
||
'create.export': 'EXPORT .RECIPE FILE',
|
||
'create.guestHint':
|
||
'Guest: the recipe stays in RECIPES until you close the page. Log in to save it to your account and export it.',
|
||
'create.userHint':
|
||
'Saved to your account. Export the .recipe file to share it — encrypted exactly like the app’s.',
|
||
|
||
'sec.filmSims': 'PHOTO STYLE',
|
||
'sec.recipes': 'RECIPES',
|
||
'sec.saved': 'SAVED',
|
||
'sec.savedEmpty': 'No saved recipes yet. Log in and hit SAVE to sync them.',
|
||
'sec.frame': 'FRAME',
|
||
'sec.crop': 'CROP',
|
||
'sec.rotate': 'ROTATE',
|
||
'sec.watermark': 'WATERMARK',
|
||
'sec.gps': 'GPS',
|
||
|
||
'wb.temp': 'COLOR TEMP',
|
||
|
||
'frame.none': 'NO FRAME',
|
||
'frame.polaroid': 'RETRO INSTANT',
|
||
'frame.classic': 'CLASSIC BORDER',
|
||
'frame.cinematic': 'CINEMATIC',
|
||
'frame.wall': 'WALL FRAME PORTRAIT',
|
||
'frame.wallLand': 'WALL FRAME LANDSCAPE',
|
||
|
||
'crop.none': 'NO CROP',
|
||
'crop.1:1': '1:1',
|
||
'crop.2:3': '2:3',
|
||
'crop.3:2': '3:2',
|
||
'crop.3:4': '3:4',
|
||
'crop.4:3': '4:3',
|
||
'crop.16:9': '16:9',
|
||
'crop.free': 'FREE',
|
||
'crop.apply': 'APPLY',
|
||
'crop.cancel': 'CANCEL',
|
||
|
||
'rot.0': '0°',
|
||
'rot.90': '90°',
|
||
'rot.180': '180°',
|
||
'rot.270': '270°',
|
||
|
||
'wm.text': 'TEXT',
|
||
'wm.color': 'COLOR',
|
||
'wm.size': 'SIZE',
|
||
'wm.gps': 'GPS STAMP',
|
||
'wm.place': 'PLACE NAME',
|
||
'wm.placePh': 'e.g. HANOI',
|
||
'wm.manual': 'ENTER COORDINATES',
|
||
'wm.lat': 'Latitude',
|
||
'wm.lng': 'Longitude',
|
||
'wm.hasExif': 'GPS read from the photo.',
|
||
'wm.noExif': 'This photo has no GPS — type it in if you want the stamp.',
|
||
|
||
'auth.loginTitle': 'Log in',
|
||
'auth.signupTitle': 'Create an account',
|
||
'auth.email': 'Email',
|
||
'auth.password': 'Password',
|
||
'auth.passwordHint': 'At least 8 characters',
|
||
'auth.noAccount': 'No account yet? Sign up',
|
||
'auth.haveAccount': 'Already have an account? Log in',
|
||
'auth.continueDemo': 'Keep using the demo',
|
||
'auth.busy': 'Working…',
|
||
'auth.loggedInAs': 'Signed in as {email}',
|
||
|
||
'save.title': 'Save recipe',
|
||
'save.name': 'Recipe name',
|
||
'save.save': 'SAVE',
|
||
'save.saved': 'Saved "{name}"',
|
||
'save.needLogin': 'Log in to save a recipe.',
|
||
|
||
'photo.contribute': 'CONTRIBUTE A PHOTO',
|
||
'photo.uploading': 'UPLOADING…',
|
||
'photo.thanks': 'Your frame is in the strip.',
|
||
'photo.failed': 'Upload failed: {msg}',
|
||
|
||
'nav.admin': 'Admin',
|
||
'nav.profile': 'Profile',
|
||
'adm.title': 'Strip moderation',
|
||
'adm.subtitle': 'Photos contributed by users. Delete one to pull it off the landing page.',
|
||
'adm.upload': 'ADD A PHOTO',
|
||
'adm.slot': 'Shows up in',
|
||
'adm.slotStrip': 'Community film strip',
|
||
'adm.slotTester': 'Live tester (lp-tester)',
|
||
'adm.slotCreator': 'Live recipe section (lp-sec)',
|
||
'adm.slotQr': 'QR card (lp-qr)',
|
||
'adm.slotHint': 'The three live slots each draw one photo out of their set at random, so several photos in the same slot rotate between visits.',
|
||
'adm.signIn': 'Sign in with an admin account',
|
||
'adm.notAdmin': 'This account has no admin rights.',
|
||
'adm.empty': 'No contributions yet.',
|
||
'adm.total': '{n} photos',
|
||
'adm.owner': 'Uploaded by',
|
||
'adm.size': 'Size',
|
||
'adm.uploaded': 'Uploaded',
|
||
'adm.delete': 'DELETE',
|
||
'adm.clearAll': 'DELETE ALL',
|
||
'adm.clearConfirm': 'Delete all {n} contributions? This cannot be undone.',
|
||
'adm.removed': 'Deleted {n} photos.',
|
||
'adm.back': 'Back to home',
|
||
'adm.settings': 'SETTINGS',
|
||
'adm.tabPictures': 'Pictures',
|
||
'adm.tabUsers': 'User account',
|
||
'adm.tabProfile': 'Profile',
|
||
'adm.close': 'Close',
|
||
'adm.userPicture': 'Picture',
|
||
'adm.userName': 'Name',
|
||
'adm.userEmail': 'Email',
|
||
'adm.userRole': 'Role',
|
||
'adm.userPhotos': 'Photos',
|
||
'adm.userJoined': 'Joined',
|
||
'adm.roleAdmin': 'Admin',
|
||
'adm.roleMember': 'Member',
|
||
'adm.viewPhotos': 'VIEW PHOTOS',
|
||
'adm.noUsers': 'No accounts yet.',
|
||
'adm.showAll': 'ALL',
|
||
'adm.profileHint': 'Picture, email and password of the signed-in account. Changing the email or password needs the current password.',
|
||
'adm.changeAvatar': 'CHANGE PICTURE',
|
||
'adm.currentPassword': 'Current password',
|
||
'adm.newEmail': 'New email',
|
||
'adm.newPassword': 'New password',
|
||
'adm.save': 'SAVE',
|
||
'adm.saved': 'Profile saved.',
|
||
|
||
'profile.title': 'My profile',
|
||
|
||
'err.noWebgl':
|
||
'The browser refused a WebGL context — this build needs WebGL to process photos (the CPU path is thousands of times slower).',
|
||
'err.decode': 'Could not read this image. Try another JPG or PNG.',
|
||
'err.generic': 'Something went wrong: {msg}',
|
||
'err.offline': 'Could not reach the server.',
|
||
|
||
'meta.exported': 'Downloaded {name} ({kb}KB, 300 ppi)',
|
||
};
|
||
|
||
export default en;
|