Task 12 batch around the existing crop/preview flow: - Success Notice (auto-dismiss ~2.5s) after an avatar upload. - "Reposition" re-crops the current avatar without re-picking a file. - Drag & drop an image straight onto the profile avatar circle. - Real upload progress via a new XHR-backed api.upload (fetch has none); refreshOnce now also stores the renewed token (reload-restore fix). - Local avatar history (last 5, IndexedDB, this-device-only) strip that re-uploads a stored crop. Stored as ArrayBuffer (Blob is not cloneable under structuredClone); label makes the per-device scope explicit. - Added a "success" tone to Notice. Infra (same session): registered @shared/@features/@pages/@app/@test path aliases in vite.config + tsconfigs and rewrote deep ../../../ imports; moved avatar components into components/avatar/ to keep folders at <=4 files. Tests: avatarHistory cap/order, recrop visibility, drop-opens-cropper, client upload/progress/401-retry. bun test 103 pass, lint 0 errors, build ok.
35 lines
986 B
JSON
35 lines
986 B
JSON
{
|
|
"compilerOptions": {
|
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
"target": "es2023",
|
|
"lib": ["ES2023", "DOM"],
|
|
"module": "esnext",
|
|
"types": ["vite/client"],
|
|
"allowArbitraryExtensions": true,
|
|
"skipLibCheck": true,
|
|
|
|
/* Bundler mode */
|
|
"moduleResolution": "bundler",
|
|
"paths": {
|
|
"@shared/*": ["./src/shared/*"],
|
|
"@features/*": ["./src/features/*"],
|
|
"@pages/*": ["./src/pages/*"],
|
|
"@app/*": ["./src/app/*"],
|
|
"@test/*": ["./src/test/*"]
|
|
},
|
|
"allowImportingTsExtensions": true,
|
|
"verbatimModuleSyntax": true,
|
|
"moduleDetection": "force",
|
|
"noEmit": true,
|
|
"jsx": "react-jsx",
|
|
|
|
/* Linting */
|
|
"noUnusedLocals": true,
|
|
"noUnusedParameters": true,
|
|
"erasableSyntaxOnly": true,
|
|
"noFallthroughCasesInSwitch": true
|
|
},
|
|
"include": ["src"],
|
|
// Tests are a separate project (tsconfig.test.json): they need Node types.
|
|
"exclude": ["src/**/tests/*", "src/test"]
|
|
}
|