init
This commit is contained in:
		
							parent
							
								
									99907e5051
								
							
						
					
					
						commit
						dc71938bd8
					
				
					 7 changed files with 123 additions and 99 deletions
				
			
		|  | @ -34,3 +34,7 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next | |||
| The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. | ||||
| 
 | ||||
| Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. | ||||
| 
 | ||||
| 
 | ||||
| # Structure | ||||
| Store on local machine and use a middleware to process (compress) the file and facilitate storage. | ||||
							
								
								
									
										
											BIN
										
									
								
								bun.lockb
									
										
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								bun.lockb
									
										
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -9,9 +9,10 @@ | |||
|     "lint": "next lint" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "bun-types": "^1.2.9", | ||||
|     "next": "15.3.0", | ||||
|     "react": "^19.0.0", | ||||
|     "react-dom": "^19.0.0", | ||||
|     "next": "15.3.0" | ||||
|     "react-dom": "^19.0.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "typescript": "^5", | ||||
|  |  | |||
							
								
								
									
										15
									
								
								services/docker-compose.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								services/docker-compose.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| services: | ||||
|   postgres: | ||||
|     image: postgres:17.4-alpine3.21 | ||||
|     restart: always | ||||
|     shm_size: 128mb | ||||
|     environment: | ||||
|       - POSTGRES_PASSWORD=test | ||||
|       - POSTGRES_USER=test | ||||
|     ports: | ||||
|       - 5432:5432 | ||||
|   adminer: | ||||
|     image: adminer | ||||
|     restart: always | ||||
|     ports: | ||||
|       - 8080:8080 | ||||
							
								
								
									
										106
									
								
								src/app/page.tsx
									
										
									
									
									
								
							
							
						
						
									
										106
									
								
								src/app/page.tsx
									
										
									
									
									
								
							|  | @ -1,103 +1,15 @@ | |||
| import Image from "next/image"; | ||||
| import { retrieve_post } from "@/db"; | ||||
| 
 | ||||
| export default function Home() { | ||||
|   return ( | ||||
|     <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]"> | ||||
|       <main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start"> | ||||
|         <Image | ||||
|           className="dark:invert" | ||||
|           src="/next.svg" | ||||
|           alt="Next.js logo" | ||||
|           width={180} | ||||
|           height={38} | ||||
|           priority | ||||
|         /> | ||||
|         <ol className="list-inside list-decimal text-sm/6 text-center sm:text-left font-[family-name:var(--font-geist-mono)]"> | ||||
|           <li className="mb-2 tracking-[-.01em]"> | ||||
|             Get started by editing{" "} | ||||
|             <code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-[family-name:var(--font-geist-mono)] font-semibold"> | ||||
|               src/app/page.tsx | ||||
|             </code> | ||||
|             . | ||||
|           </li> | ||||
|           <li className="tracking-[-.01em]"> | ||||
|             Save and see your changes instantly. | ||||
|           </li> | ||||
|         </ol> | ||||
| 
 | ||||
|         <div className="flex gap-4 items-center flex-col sm:flex-row"> | ||||
|           <a | ||||
|             className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto" | ||||
|             href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" | ||||
|             target="_blank" | ||||
|             rel="noopener noreferrer" | ||||
|           > | ||||
|             <Image | ||||
|               className="dark:invert" | ||||
|               src="/vercel.svg" | ||||
|               alt="Vercel logomark" | ||||
|               width={20} | ||||
|               height={20} | ||||
|             /> | ||||
|             Deploy now | ||||
|           </a> | ||||
|           <a | ||||
|             className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]" | ||||
|             href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" | ||||
|             target="_blank" | ||||
|             rel="noopener noreferrer" | ||||
|           > | ||||
|             Read our docs | ||||
|           </a> | ||||
|         </div> | ||||
|       </main> | ||||
|       <footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center"> | ||||
|         <a | ||||
|           className="flex items-center gap-2 hover:underline hover:underline-offset-4" | ||||
|           href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" | ||||
|           target="_blank" | ||||
|           rel="noopener noreferrer" | ||||
|         > | ||||
|           <Image | ||||
|             aria-hidden | ||||
|             src="/file.svg" | ||||
|             alt="File icon" | ||||
|             width={16} | ||||
|             height={16} | ||||
|           /> | ||||
|           Learn | ||||
|         </a> | ||||
|         <a | ||||
|           className="flex items-center gap-2 hover:underline hover:underline-offset-4" | ||||
|           href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" | ||||
|           target="_blank" | ||||
|           rel="noopener noreferrer" | ||||
|         > | ||||
|           <Image | ||||
|             aria-hidden | ||||
|             src="/window.svg" | ||||
|             alt="Window icon" | ||||
|             width={16} | ||||
|             height={16} | ||||
|           /> | ||||
|           Examples | ||||
|         </a> | ||||
|         <a | ||||
|           className="flex items-center gap-2 hover:underline hover:underline-offset-4" | ||||
|           href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" | ||||
|           target="_blank" | ||||
|           rel="noopener noreferrer" | ||||
|         > | ||||
|           <Image | ||||
|             aria-hidden | ||||
|             src="/globe.svg" | ||||
|             alt="Globe icon" | ||||
|             width={16} | ||||
|             height={16} | ||||
|           /> | ||||
|           Go to nextjs.org → | ||||
|         </a> | ||||
|       </footer> | ||||
|   return ( | ||||
|     <div className="relative min-h-screen px-8 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]"> | ||||
|       <div className="w-full h-5dvh fixed top-0 left-0"> | ||||
|         <h1 className="text-4xl mt-4 ml-3">匿名中工</h1> | ||||
|       </div> | ||||
|       <div className="h-[90dvh] w-[85dvw] absolute left-1/2 top-1/2 mt-5 -translate-1/2"> | ||||
|          | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										35
									
								
								src/app/post.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/app/post.tsx
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| 
 | ||||
| import { Suspense } from "react"; | ||||
| import Image from "next/image"; | ||||
| import { Attachment } from "@/db"; | ||||
| 
 | ||||
| export default function Post(post_content: string, attachments: Attachment[]) { | ||||
|     let images = []; | ||||
|     let videos = []; | ||||
|     attachments.forEach(attachment => { | ||||
|         if (attachment.type.type == "video") { | ||||
|             attachment.urls.forEach(url => { | ||||
|                 videos.push( | ||||
|                     <Suspense fallback={<p>加載中</p>}> | ||||
|                         <video controls preload="none" aria-label="Video player"> | ||||
|                             <source src={url} type={attachment.type.toString()} /> | ||||
|                             Your browser does not support the video tag. | ||||
|                         </video> | ||||
|                     </Suspense> | ||||
|                 ) | ||||
|             }) | ||||
|         }else if (attachment.type.type="image"){ | ||||
|             attachment.urls.forEach(url => { | ||||
|                 images.push(<Image src={url} alt="Uploaded" width={300} height={200}></Image>) | ||||
|             }) | ||||
|         } | ||||
|     }) | ||||
|     return (<div className="w-full h-fit"> | ||||
|         <div> | ||||
|             {post_content} | ||||
|         </div> | ||||
|         <div> | ||||
|             <div></div> | ||||
|         </div> | ||||
|     </div>) | ||||
| } | ||||
							
								
								
									
										57
									
								
								src/db.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/db.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,57 @@ | |||
| import { main } from "bun"; | ||||
| import { sql } from "bun"; | ||||
| import { MIMEType } from "util" | ||||
| 
 | ||||
| export interface Attachment { | ||||
|   type: MIMEType; | ||||
|   urls: string[]; | ||||
| } | ||||
| export interface Post { | ||||
|   content: string, | ||||
|   hash: string, | ||||
| } | ||||
| 
 | ||||
| export async function setup_func() { | ||||
|   const rows = await sql` | ||||
|   CREATE OR REPLACE FUNCTION fetch_post( | ||||
|    OUT p_text VARCHAR(1000), | ||||
|    OUT p_hash CHAR(32), | ||||
|    OUT p_date TIMESTAMP, | ||||
|    OUT p_pics INT[] | ||||
|   ) | ||||
|   RETURNS SETOF RECORD AS | ||||
|   $$ | ||||
|   DECLARE | ||||
|       post_cursor CURSOR FOR | ||||
|           SELECT content, hash, date | ||||
|           FROM posts; | ||||
|       post_record RECORD; | ||||
|   BEGIN | ||||
|       -- Open cursor | ||||
|       OPEN post_cursor; | ||||
| 
 | ||||
|       -- Fetch rows and return | ||||
|       LOOP | ||||
|           FETCH NEXT FROM post_cursor INTO post_record; | ||||
|           EXIT WHEN NOT FOUND; | ||||
| 
 | ||||
|           p_text = post_record.content; | ||||
|           p_date = post_record.date; | ||||
|           p_hash = post_record.hash; | ||||
|           RETURN NEXT; | ||||
|       END LOOP; | ||||
| 
 | ||||
|       -- Close cursor | ||||
|       CLOSE post_cursor; | ||||
|   END; | ||||
|   $$ | ||||
|   LANGUAGE PLPGSQL;`;
 | ||||
| } | ||||
| 
 | ||||
| /* retrieve the latest post with posts table */ | ||||
| export async function retrieve_post(offset: Number) { | ||||
|   const res = await sql`SELECT * FROM fetch_post();` | ||||
|   console.log(res) | ||||
| } | ||||
| setup_func() | ||||
| retrieve_post(0) | ||||
		Loading…
	
	Add table
		
		Reference in a new issue