feature/quiz-mode #4
4 changed files with 28 additions and 3 deletions
|
|
@ -12,6 +12,8 @@
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@dicebear/core": "^10",
|
||||||
|
"@dicebear/styles": "^10",
|
||||||
"@nerdware/shared": "workspace:*",
|
"@nerdware/shared": "workspace:*",
|
||||||
"@workspace/ui": "workspace:*",
|
"@workspace/ui": "workspace:*",
|
||||||
"framer-motion": "^11",
|
"framer-motion": "^11",
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,27 @@
|
||||||
|
import { Avatar as DicebearAvatar, Style } from "@dicebear/core"
|
||||||
|
import loreleiDefinition from "@dicebear/styles/lorelei.json"
|
||||||
|
|
||||||
|
// Génération locale (pas d'appel à l'API DiceBear) : self-hosted, offline,
|
||||||
|
// aucun pseudo envoyé à un tiers. Lorelei par Lisa Wischofsky — licence CC0 1.0.
|
||||||
|
const style = new Style(loreleiDefinition)
|
||||||
|
const cache = new Map<string, string>()
|
||||||
|
|
||||||
|
/** Data URI de l'avatar pour un seed donné, mémoïsé. */
|
||||||
|
function avatarUri(seed: string): string {
|
||||||
|
let uri = cache.get(seed)
|
||||||
|
if (!uri) {
|
||||||
|
uri = new DicebearAvatar(style, { seed }).toDataUri()
|
||||||
|
cache.set(seed, uri)
|
||||||
|
}
|
||||||
|
return uri
|
||||||
|
}
|
||||||
|
|
||||||
/** Avatar DiceBear (style lorelei), seedé par le pseudo → stable et reconnaissable. */
|
/** Avatar DiceBear (style lorelei), seedé par le pseudo → stable et reconnaissable. */
|
||||||
export function Avatar({ seed, className }: { seed: string; className?: string }) {
|
export function Avatar({ seed, className }: { seed: string; className?: string }) {
|
||||||
const url = `https://api.dicebear.com/9.x/lorelei/svg?seed=${encodeURIComponent(seed)}`
|
|
||||||
return (
|
return (
|
||||||
<img
|
<img
|
||||||
src={url}
|
src={avatarUri(seed)}
|
||||||
alt={`Avatar de ${seed}`}
|
alt={`Avatar de ${seed}`}
|
||||||
loading="lazy"
|
|
||||||
className={`bg-muted shrink-0 rounded-full ${className ?? ""}`}
|
className={`bg-muted shrink-0 rounded-full ${className ?? ""}`}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
/* Bundler mode */
|
/* Bundler mode */
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
"verbatimModuleSyntax": true,
|
"verbatimModuleSyntax": true,
|
||||||
"moduleDetection": "force",
|
"moduleDetection": "force",
|
||||||
|
|
|
||||||
6
bun.lock
6
bun.lock
|
|
@ -35,6 +35,8 @@
|
||||||
"name": "web",
|
"name": "web",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@dicebear/core": "^10",
|
||||||
|
"@dicebear/styles": "^10",
|
||||||
"@nerdware/shared": "workspace:*",
|
"@nerdware/shared": "workspace:*",
|
||||||
"@workspace/ui": "workspace:*",
|
"@workspace/ui": "workspace:*",
|
||||||
"framer-motion": "^11",
|
"framer-motion": "^11",
|
||||||
|
|
@ -163,6 +165,10 @@
|
||||||
|
|
||||||
"@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="],
|
"@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="],
|
||||||
|
|
||||||
|
"@dicebear/core": ["@dicebear/core@10.1.0", "", {}, "sha512-OzwokGKfSJCTHNATS87Rl3Fbf00FvqKamitVaBsgm535paz09Vdgwv4QxwHR6CZUsrCdMJn+j/RfZX4o2iNk5g=="],
|
||||||
|
|
||||||
|
"@dicebear/styles": ["@dicebear/styles@10.2.0", "", {}, "sha512-o4rw0+7Q7sSAyr9YxYrUe3jCxlOAzEcBvbQvl4hQKQ+9WNmBK4p7wGYvsmGeJbxFh8y/Ux6ltrCPyXBIDV6qYA=="],
|
||||||
|
|
||||||
"@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.71.0", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^17.2.1", "eciesjs": "^0.4.10", "enquirer": "^2.4.1", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.4", "which": "^4.0.0", "yocto-spinner": "^1.1.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-KEUw/mGu+EDRhYWRTNGHIimVCs9NvMFaIXOGrHSXoCteKLE5EsJnmPjOPpYorjXVg/0xG0fbdVw720azw1z4ag=="],
|
"@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.71.0", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^17.2.1", "eciesjs": "^0.4.10", "enquirer": "^2.4.1", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.4", "which": "^4.0.0", "yocto-spinner": "^1.1.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-KEUw/mGu+EDRhYWRTNGHIimVCs9NvMFaIXOGrHSXoCteKLE5EsJnmPjOPpYorjXVg/0xG0fbdVw720azw1z4ag=="],
|
||||||
|
|
||||||
"@ecies/ciphers": ["@ecies/ciphers@0.2.6", "", { "peerDependencies": { "@noble/ciphers": "^1.0.0" } }, "sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g=="],
|
"@ecies/ciphers": ["@ecies/ciphers@0.2.6", "", { "peerDependencies": { "@noble/ciphers": "^1.0.0" } }, "sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g=="],
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue