Spaces:
Running
Running
First commit
Browse filesThis view is limited to 50 files because it contains too many changes. ย
See raw diff
- .env +20 -0
- .eslintrc.json +3 -0
- .gitignore +37 -0
- .nvmrc +1 -0
- Dockerfile +65 -0
- README.md +9 -6
- components.json +16 -0
- next.config.js +11 -0
- package-lock.json +0 -0
- package.json +75 -0
- postcss.config.js +6 -0
- public/bubble.jpg +0 -0
- public/favicon.ico +0 -0
- public/favicon/favicon-114-precomposed.png +0 -0
- public/favicon/favicon-120-precomposed.png +0 -0
- public/favicon/favicon-144-precomposed.png +0 -0
- public/favicon/favicon-152-precomposed.png +0 -0
- public/favicon/favicon-180-precomposed.png +0 -0
- public/favicon/favicon-192.png +0 -0
- public/favicon/favicon-32.png +0 -0
- public/favicon/favicon-36.png +0 -0
- public/favicon/favicon-48.png +0 -0
- public/favicon/favicon-57.png +0 -0
- public/favicon/favicon-60.png +0 -0
- public/favicon/favicon-72-precomposed.png +0 -0
- public/favicon/favicon-72.png +0 -0
- public/favicon/favicon-76.png +0 -0
- public/favicon/favicon-96.png +0 -0
- public/favicon/favicon.ico +0 -0
- public/favicon/manifest.json +41 -0
- public/icon.png +0 -0
- public/images/hf.png +0 -0
- public/images/models/sdxl-akira.jpg +0 -0
- public/images/models/sdxl-cinematic-2.jpg +0 -0
- public/images/models/sdxl-cyberpunk-2077.jpg +0 -0
- public/images/models/sdxl-foundation-2.jpg +0 -0
- public/images/models/sdxl-modern-pixar.jpg +0 -0
- public/images/models/sdxl-moebius-lean.jpg +0 -0
- public/images/models/sdxl-starfield.jpg +0 -0
- public/images/sign-in-with-huggingface-xl.svg +43 -0
- public/images/sprite.png +0 -0
- public/mask.png +0 -0
- public/next.svg +1 -0
- public/vercel.svg +1 -0
- src/app/favicon.ico +0 -0
- src/app/globals.css +39 -0
- src/app/icon.png +0 -0
- src/app/interface/about/index.tsx +33 -0
- src/app/interface/background/index.tsx +60 -0
- src/app/interface/bottom-bar/index.tsx +28 -0
.env
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
AI_STORY_API_GRADIO_URL="https://ruslanmv-ai-story-server.hf.space"
|
3 |
+
AI_STORY_API_SECRET_TOKEN=
|
4 |
+
|
5 |
+
AI_FAST_IMAGE_SERVER_API_GRADIO_URL="https://ruslanmv-ai-fast-image-server.hf.space"
|
6 |
+
AI_FAST_IMAGE_SERVER_API_SECRET_TOKEN=
|
7 |
+
|
8 |
+
# ----------- CENSORSHIP -------
|
9 |
+
ENABLE_CENSORSHIP=
|
10 |
+
FINGERPRINT_KEY=
|
11 |
+
MODERATION_KEY=
|
12 |
+
|
13 |
+
# ----------- COMMUNITY (OPTIONAL, YOU DON'T NEED THIS IN LOCAL) -----------
|
14 |
+
NEXT_PUBLIC_ENABLE_COMMUNITY_SHARING="false"
|
15 |
+
|
16 |
+
COMMUNITY_API_URL="https://ruslanmv-community-api.hf.space"
|
17 |
+
COMMUNITY_API_TOKEN=""
|
18 |
+
|
19 |
+
# must be unique per app
|
20 |
+
COMMUNITY_API_ID=""
|
.eslintrc.json
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"extends": "next/core-web-vitals"
|
3 |
+
}
|
.gitignore
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
2 |
+
|
3 |
+
# dependencies
|
4 |
+
/node_modules
|
5 |
+
/.pnp
|
6 |
+
.pnp.js
|
7 |
+
|
8 |
+
# testing
|
9 |
+
/coverage
|
10 |
+
|
11 |
+
# next.js
|
12 |
+
/.next/
|
13 |
+
/out/
|
14 |
+
|
15 |
+
# production
|
16 |
+
/build
|
17 |
+
|
18 |
+
# misc
|
19 |
+
.DS_Store
|
20 |
+
*.pem
|
21 |
+
|
22 |
+
# debug
|
23 |
+
npm-debug.log*
|
24 |
+
yarn-debug.log*
|
25 |
+
yarn-error.log*
|
26 |
+
|
27 |
+
# local env files
|
28 |
+
.env*.local
|
29 |
+
|
30 |
+
# vercel
|
31 |
+
.vercel
|
32 |
+
|
33 |
+
# typescript
|
34 |
+
*.tsbuildinfo
|
35 |
+
next-env.d.ts
|
36 |
+
|
37 |
+
/sandbox/
|
.nvmrc
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
v20.9.0
|
Dockerfile
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM node:20-alpine AS base
|
2 |
+
|
3 |
+
# Install dependencies only when needed
|
4 |
+
FROM base AS deps
|
5 |
+
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
6 |
+
RUN apk add --no-cache libc6-compat
|
7 |
+
WORKDIR /app
|
8 |
+
|
9 |
+
# Install dependencies based on the preferred package manager
|
10 |
+
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
|
11 |
+
RUN \
|
12 |
+
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
|
13 |
+
elif [ -f package-lock.json ]; then npm ci; \
|
14 |
+
elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
|
15 |
+
else echo "Lockfile not found." && exit 1; \
|
16 |
+
fi
|
17 |
+
|
18 |
+
# Uncomment the following lines if you want to use a secret at buildtime,
|
19 |
+
# for example to access your private npm packages
|
20 |
+
# RUN --mount=type=secret,id=HF_EXAMPLE_SECRET,mode=0444,required=true \
|
21 |
+
# $(cat /run/secrets/HF_EXAMPLE_SECRET)
|
22 |
+
|
23 |
+
# Rebuild the source code only when needed
|
24 |
+
FROM base AS builder
|
25 |
+
WORKDIR /app
|
26 |
+
COPY --from=deps /app/node_modules ./node_modules
|
27 |
+
COPY . .
|
28 |
+
|
29 |
+
# Next.js collects completely anonymous telemetry data about general usage.
|
30 |
+
# Learn more here: https://nextjs.org/telemetry
|
31 |
+
# Uncomment the following line in case you want to disable telemetry during the build.
|
32 |
+
# ENV NEXT_TELEMETRY_DISABLED 1
|
33 |
+
|
34 |
+
# RUN yarn build
|
35 |
+
|
36 |
+
# If you use yarn, comment out this line and use the line above
|
37 |
+
RUN npm run build
|
38 |
+
|
39 |
+
# Production image, copy all the files and run next
|
40 |
+
FROM base AS runner
|
41 |
+
WORKDIR /app
|
42 |
+
|
43 |
+
ENV NODE_ENV production
|
44 |
+
# Uncomment the following line in case you want to disable telemetry during runtime.
|
45 |
+
# ENV NEXT_TELEMETRY_DISABLED 1
|
46 |
+
|
47 |
+
RUN addgroup --system --gid 1001 nodejs
|
48 |
+
RUN adduser --system --uid 1001 nextjs
|
49 |
+
|
50 |
+
COPY --from=builder /app/public ./public
|
51 |
+
|
52 |
+
# Automatically leverage output traces to reduce image size
|
53 |
+
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
54 |
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
55 |
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
56 |
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/cache ./.next/cache
|
57 |
+
# COPY --from=builder --chown=nextjs:nodejs /app/.next/cache/fetch-cache ./.next/cache/fetch-cache
|
58 |
+
|
59 |
+
USER nextjs
|
60 |
+
|
61 |
+
EXPOSE 3000
|
62 |
+
|
63 |
+
ENV PORT 3000
|
64 |
+
|
65 |
+
CMD ["node", "server.js"]
|
README.md
CHANGED
@@ -1,10 +1,13 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: docker
|
7 |
-
pinned:
|
|
|
8 |
---
|
9 |
|
10 |
-
|
|
|
|
|
|
1 |
---
|
2 |
+
title: AI Story Teller ๐๏ธ
|
3 |
+
emoji: ๐
|
4 |
+
colorFrom: yellow
|
5 |
+
colorTo: gray
|
6 |
sdk: docker
|
7 |
+
pinned: true
|
8 |
+
app_port: 3000
|
9 |
---
|
10 |
|
11 |
+
# ๐ AI Story Teller ๐๏ธ
|
12 |
+
|
13 |
+
(To be continued)
|
components.json
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"$schema": "https://ui.shadcn.com/schema.json",
|
3 |
+
"style": "default",
|
4 |
+
"rsc": true,
|
5 |
+
"tsx": true,
|
6 |
+
"tailwind": {
|
7 |
+
"config": "tailwind.config.js",
|
8 |
+
"css": "app/globals.css",
|
9 |
+
"baseColor": "stone",
|
10 |
+
"cssVariables": false
|
11 |
+
},
|
12 |
+
"aliases": {
|
13 |
+
"components": "@/components",
|
14 |
+
"utils": "@/lib/utils"
|
15 |
+
}
|
16 |
+
}
|
next.config.js
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @type {import('next').NextConfig} */
|
2 |
+
const nextConfig = {
|
3 |
+
output: 'standalone',
|
4 |
+
|
5 |
+
experimental: {
|
6 |
+
serverActions: true,
|
7 |
+
serverActionsBodySizeLimit: '8mb',
|
8 |
+
},
|
9 |
+
}
|
10 |
+
|
11 |
+
module.exports = nextConfig
|
package-lock.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
package.json
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "ai-bedtime-story",
|
3 |
+
"version": "0.0.0",
|
4 |
+
"private": true,
|
5 |
+
"scripts": {
|
6 |
+
"dev": "next dev",
|
7 |
+
"build": "next build",
|
8 |
+
"start": "next start",
|
9 |
+
"lint": "next lint"
|
10 |
+
},
|
11 |
+
"dependencies": {
|
12 |
+
"@huggingface/inference": "^2.6.4",
|
13 |
+
"@radix-ui/react-accordion": "^1.1.2",
|
14 |
+
"@radix-ui/react-avatar": "^1.0.3",
|
15 |
+
"@radix-ui/react-checkbox": "^1.0.4",
|
16 |
+
"@radix-ui/react-collapsible": "^1.0.3",
|
17 |
+
"@radix-ui/react-dialog": "^1.0.4",
|
18 |
+
"@radix-ui/react-dropdown-menu": "^2.0.5",
|
19 |
+
"@radix-ui/react-icons": "^1.3.0",
|
20 |
+
"@radix-ui/react-label": "^2.0.2",
|
21 |
+
"@radix-ui/react-menubar": "^1.0.3",
|
22 |
+
"@radix-ui/react-popover": "^1.0.6",
|
23 |
+
"@radix-ui/react-select": "^1.2.2",
|
24 |
+
"@radix-ui/react-separator": "^1.0.3",
|
25 |
+
"@radix-ui/react-slider": "^1.1.2",
|
26 |
+
"@radix-ui/react-slot": "^1.0.2",
|
27 |
+
"@radix-ui/react-switch": "^1.0.3",
|
28 |
+
"@radix-ui/react-toast": "^1.1.4",
|
29 |
+
"@radix-ui/react-tooltip": "^1.0.6",
|
30 |
+
"@react-spring/web": "^9.7.3",
|
31 |
+
"@types/node": "20.4.2",
|
32 |
+
"@types/react": "18.2.15",
|
33 |
+
"@types/react-dom": "18.2.7",
|
34 |
+
"@types/uuid": "^9.0.2",
|
35 |
+
"autoprefixer": "10.4.14",
|
36 |
+
"class-variance-authority": "^0.6.1",
|
37 |
+
"clsx": "^2.0.0",
|
38 |
+
"cmdk": "^0.2.0",
|
39 |
+
"cookies-next": "^2.1.2",
|
40 |
+
"eslint": "8.45.0",
|
41 |
+
"eslint-config-next": "13.4.10",
|
42 |
+
"lucide-react": "^0.260.0",
|
43 |
+
"next": "13.4.10",
|
44 |
+
"pick": "^0.0.1",
|
45 |
+
"postcss": "8.4.26",
|
46 |
+
"qs": "^6.11.2",
|
47 |
+
"react": "18.2.0",
|
48 |
+
"react-circular-progressbar": "^2.1.0",
|
49 |
+
"react-dom": "18.2.0",
|
50 |
+
"react-smooth-scroll-hook": "^1.3.4",
|
51 |
+
"react-snowfall": "^1.2.1",
|
52 |
+
"react-virtualized-auto-sizer": "^1.0.20",
|
53 |
+
"replicate": "^0.17.0",
|
54 |
+
"sbd": "^1.0.19",
|
55 |
+
"sentence-splitter": "^4.3.0",
|
56 |
+
"sharp": "^0.32.5",
|
57 |
+
"styled-components": "^6.0.7",
|
58 |
+
"tailwind-merge": "^1.13.2",
|
59 |
+
"tailwindcss": "3.3.3",
|
60 |
+
"tailwindcss-animate": "^1.0.6",
|
61 |
+
"temp-dir": "^3.0.0",
|
62 |
+
"ts-node": "^10.9.1",
|
63 |
+
"typescript": "5.1.6",
|
64 |
+
"usehooks-ts": "^2.9.1",
|
65 |
+
"uuid": "^9.0.0",
|
66 |
+
"zustand": "^4.4.1"
|
67 |
+
},
|
68 |
+
"devDependencies": {
|
69 |
+
"@types/proper-lockfile": "^4.1.2",
|
70 |
+
"@types/qs": "^6.9.7",
|
71 |
+
"@types/react-virtualized": "^9.21.22",
|
72 |
+
"@types/sbd": "^1.0.3",
|
73 |
+
"daisyui": "^3.7.4"
|
74 |
+
}
|
75 |
+
}
|
postcss.config.js
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module.exports = {
|
2 |
+
plugins: {
|
3 |
+
tailwindcss: {},
|
4 |
+
autoprefixer: {},
|
5 |
+
},
|
6 |
+
}
|
public/bubble.jpg
ADDED
public/favicon.ico
ADDED
public/favicon/favicon-114-precomposed.png
ADDED
public/favicon/favicon-120-precomposed.png
ADDED
public/favicon/favicon-144-precomposed.png
ADDED
public/favicon/favicon-152-precomposed.png
ADDED
public/favicon/favicon-180-precomposed.png
ADDED
public/favicon/favicon-192.png
ADDED
public/favicon/favicon-32.png
ADDED
public/favicon/favicon-36.png
ADDED
public/favicon/favicon-48.png
ADDED
public/favicon/favicon-57.png
ADDED
public/favicon/favicon-60.png
ADDED
public/favicon/favicon-72-precomposed.png
ADDED
public/favicon/favicon-72.png
ADDED
public/favicon/favicon-76.png
ADDED
public/favicon/favicon-96.png
ADDED
public/favicon/favicon.ico
ADDED
public/favicon/manifest.json
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "pollo",
|
3 |
+
"icons": [
|
4 |
+
{
|
5 |
+
"src": "\/favicon-36.png",
|
6 |
+
"sizes": "36x36",
|
7 |
+
"type": "image\/png",
|
8 |
+
"density": 0.75
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"src": "\/favicon-48.png",
|
12 |
+
"sizes": "48x48",
|
13 |
+
"type": "image\/png",
|
14 |
+
"density": 1
|
15 |
+
},
|
16 |
+
{
|
17 |
+
"src": "\/favicon-72.png",
|
18 |
+
"sizes": "72x72",
|
19 |
+
"type": "image\/png",
|
20 |
+
"density": 1.5
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"src": "\/favicon-96.png",
|
24 |
+
"sizes": "96x96",
|
25 |
+
"type": "image\/png",
|
26 |
+
"density": 2
|
27 |
+
},
|
28 |
+
{
|
29 |
+
"src": "\/favicon-144.png",
|
30 |
+
"sizes": "144x144",
|
31 |
+
"type": "image\/png",
|
32 |
+
"density": 3
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"src": "\/favicon-192.png",
|
36 |
+
"sizes": "192x192",
|
37 |
+
"type": "image\/png",
|
38 |
+
"density": 4
|
39 |
+
}
|
40 |
+
]
|
41 |
+
}
|
public/icon.png
ADDED
public/images/hf.png
ADDED
public/images/models/sdxl-akira.jpg
ADDED
public/images/models/sdxl-cinematic-2.jpg
ADDED
public/images/models/sdxl-cyberpunk-2077.jpg
ADDED
public/images/models/sdxl-foundation-2.jpg
ADDED
public/images/models/sdxl-modern-pixar.jpg
ADDED
public/images/models/sdxl-moebius-lean.jpg
ADDED
public/images/models/sdxl-starfield.jpg
ADDED
public/images/sign-in-with-huggingface-xl.svg
ADDED
public/images/sprite.png
ADDED
public/mask.png
ADDED
public/next.svg
ADDED
public/vercel.svg
ADDED
src/app/favicon.ico
ADDED
src/app/globals.css
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@tailwind base;
|
2 |
+
@tailwind components;
|
3 |
+
@tailwind utilities;
|
4 |
+
|
5 |
+
:root {
|
6 |
+
--foreground-rgb: 0, 0, 0;
|
7 |
+
--background-start-rgb: 214, 219, 220;
|
8 |
+
--background-end-rgb: 255, 255, 255;
|
9 |
+
}
|
10 |
+
|
11 |
+
@media (prefers-color-scheme: dark) {
|
12 |
+
:root {
|
13 |
+
--foreground-rgb: 255, 255, 255;
|
14 |
+
--background-start-rgb: 0, 0, 0;
|
15 |
+
--background-end-rgb: 0, 0, 0;
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
body {
|
20 |
+
color: rgb(var(--foreground-rgb));
|
21 |
+
background: linear-gradient(
|
22 |
+
to bottom,
|
23 |
+
transparent,
|
24 |
+
rgb(var(--background-end-rgb))
|
25 |
+
)
|
26 |
+
rgb(var(--background-start-rgb));
|
27 |
+
}
|
28 |
+
|
29 |
+
|
30 |
+
/* this is the trick to bypass the style={{}} attribute when printing */
|
31 |
+
@media print {
|
32 |
+
.comic-page[style] { width: 100vw !important; }
|
33 |
+
}
|
34 |
+
|
35 |
+
|
36 |
+
.render-to-image .comic-panel {
|
37 |
+
height: auto !important;
|
38 |
+
/* max-width: fit-content !important; */
|
39 |
+
}
|
src/app/icon.png
ADDED
src/app/interface/about/index.tsx
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Button } from "@/components/ui/button"
|
2 |
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
|
3 |
+
import { useState } from "react"
|
4 |
+
|
5 |
+
export function About() {
|
6 |
+
const [isOpen, setOpen] = useState(false)
|
7 |
+
|
8 |
+
return (
|
9 |
+
<Dialog open={isOpen} onOpenChange={setOpen}>
|
10 |
+
<DialogTrigger asChild>
|
11 |
+
<Button variant="outline">
|
12 |
+
<span className="hidden md:inline">About SleepGPT</span>
|
13 |
+
<span className="inline md:hidden">About SleepGPT</span>
|
14 |
+
</Button>
|
15 |
+
</DialogTrigger>
|
16 |
+
<DialogContent className="sm:max-w-[425px]">
|
17 |
+
<DialogHeader>
|
18 |
+
<DialogDescription className="w-full text-center text-lg font-bold text-stone-800">
|
19 |
+
SleepGPT
|
20 |
+
</DialogDescription>
|
21 |
+
</DialogHeader>
|
22 |
+
<div className="grid gap-4 py-4 text-stone-800">
|
23 |
+
<p>
|
24 |
+
๐ This space generates bedtime stories.
|
25 |
+
</p>
|
26 |
+
</div>
|
27 |
+
<DialogFooter>
|
28 |
+
<Button type="submit" onClick={() => setOpen(false)}>Got it</Button>
|
29 |
+
</DialogFooter>
|
30 |
+
</DialogContent>
|
31 |
+
</Dialog>
|
32 |
+
)
|
33 |
+
}
|
src/app/interface/background/index.tsx
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"use client"
|
2 |
+
|
3 |
+
import { useEffect, useRef, useState } from "react"
|
4 |
+
import Snowfall from "react-snowfall"
|
5 |
+
|
6 |
+
export function Background() {
|
7 |
+
const [itsRainingFaces, makeItRain] = useState(false)
|
8 |
+
const [nbFaces, setNbFaces] = useState(0)
|
9 |
+
const nbFacesRef = useRef(0)
|
10 |
+
|
11 |
+
const [sprite, setSprite] = useState<HTMLImageElement>()
|
12 |
+
|
13 |
+
useEffect(() => {
|
14 |
+
const newSprite = document.createElement('img')
|
15 |
+
newSprite.src = "/images/sprite.png" // '/images/hf.png'
|
16 |
+
setSprite(newSprite)
|
17 |
+
}, [])
|
18 |
+
|
19 |
+
// just to delay things a bit
|
20 |
+
useEffect(() => {
|
21 |
+
setTimeout(() => { makeItRain(true) }, 1000)
|
22 |
+
}, [])
|
23 |
+
|
24 |
+
// effect is more interesting if progressive
|
25 |
+
useEffect(() => {
|
26 |
+
let interval = setInterval(() => {
|
27 |
+
// if (!itsRainingFaces) { return }
|
28 |
+
if (nbFacesRef.current > 25) {
|
29 |
+
clearInterval(interval)
|
30 |
+
} else {
|
31 |
+
setNbFaces(nbFacesRef.current += 1)
|
32 |
+
}
|
33 |
+
}, 1000)
|
34 |
+
}, [])
|
35 |
+
|
36 |
+
return (
|
37 |
+
<>{itsRainingFaces && sprite
|
38 |
+
? <Snowfall
|
39 |
+
// Applied to the canvas element.
|
40 |
+
|
41 |
+
style={{
|
42 |
+
background: 'transparent',
|
43 |
+
position: 'fixed',
|
44 |
+
width: '100vw',
|
45 |
+
height: '100vh',
|
46 |
+
transitionProperty: "color",
|
47 |
+
transitionDuration: "3000ms",
|
48 |
+
opacity: 1,
|
49 |
+
}}
|
50 |
+
radius={[10, 40]}
|
51 |
+
speed={[1, 2]}
|
52 |
+
wind={[1, 3.0]}
|
53 |
+
// Controls the number of snowflakes that are created (defaults to 150).
|
54 |
+
snowflakeCount={nbFaces}
|
55 |
+
images={[sprite]}
|
56 |
+
/>
|
57 |
+
: null}
|
58 |
+
</>
|
59 |
+
)
|
60 |
+
}
|
src/app/interface/bottom-bar/index.tsx
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { cn } from "@/lib/utils"
|
2 |
+
|
3 |
+
import { About } from "../about"
|
4 |
+
|
5 |
+
export function BottomBar() {
|
6 |
+
return (
|
7 |
+
<div className={cn(
|
8 |
+
`print:hidden`,
|
9 |
+
`fixed bottom-2 md:bottom-4 left-2 right-0 md:left-3 md:right-1`,
|
10 |
+
`flex flex-row`,
|
11 |
+
`justify-between`,
|
12 |
+
`pointer-events-none`
|
13 |
+
)}>
|
14 |
+
<div className={cn(
|
15 |
+
`flex flex-row`,
|
16 |
+
`items-end`,
|
17 |
+
`pointer-events-auto`,
|
18 |
+
`animation-all duration-300 ease-in-out`,
|
19 |
+
`space-x-3`,
|
20 |
+
`scale-[0.9]`
|
21 |
+
)}>
|
22 |
+
{/*
|
23 |
+
<About />
|
24 |
+
*/}
|
25 |
+
</div>
|
26 |
+
</div>
|
27 |
+
)
|
28 |
+
}
|