ππ» myapp27μλ μ€ν¨ λλ ν 리 μ€μκ° μλμΈμμ ꡬνν©λλ€.
Real-time automatic detection of the skin directory is implemented in myapp27.
ππ» λλ ν 리λ₯Ό mv λͺ
λ Ήμ΄λ‘ μ΄λν κ²½μ° μ€λ₯ λ‘κ·Έκ° μΆλ ₯λ μ μμ΅λλ€.
An error log may be displayed when moving a directory using the mv command.
ππ» νμ§λ§ 1μ΄λ΄ λ°λ‘ 볡ꡬ μλ£ λ©λλ€.
However, recovery is completed within one second.
ππ» μ 체 μ½λλ κΉνλΈμμ νμΈ ν μ μμ΅λλ€.
You can find the full code on GitHub.
https://github.com/gideonslife01/flm-nextjs
π μ 체 νλ‘μ νΈ κ΅¬μ‘° / Overall Project Structure
myapp26/
βββ app/ (Next.js App Router)
β βββ .well-known/webfinger/route.ts -> webfinger
β βββ api/follow/route.ts -> Follow API(temporary)
β βββ api/announce/route.ts -> Boost(Announcement)
β βββ api/like/route.ts. -> Like API
β βββ api/posts/route.ts -> Writing API
β βββ api/timeline/route.ts -> Timeline API
β βββ users/[username]/
β β βββ statuses/[id]/route.ts -> Indivisual Post
β β βββ route.ts -> Acotr Information
β β βββ followers/route.ts -> Followers List
β β βββ following/route.ts -> Following List
β β βββ inbox/route.ts -> Inbox
β β βββ outbox/route.ts -> outbox
β βββ usersui/[username]/
β β βββ page.tsx -> Timeline UI
β β βββ _components/themes/
β β βββ themeex/ThemeexTheme.tsx -> Example Theme
β β βββ pinafore/PinaforeTheme.tsx -> Theme 1
β β βββ mastodon/MastodonTheme.tsx -> Theme 2
β β βββ minimal/MinimaltTheme.tsx -> Theme 3
β βββ layout.tsx, page.tsx, globals.css
β βββ favicon.ico
βββ lib/
β βββ theme.tsx -> Theme Provider
β βββ watchThemes.ts -> Check real-time theme changes
β βββ ap.ts -> Follow Accept
β βββ db.ts -> DB connection
βββ data/
β βββ keys/ -> private.pem, public.pem
βββ data.sqlite -> Database
βββ Caddyfile -> https
βββ instrumentation.ts -> Background Server
βββ package.json
π νλ‘μ νΈ μμ(myapp27)
Project Start (myapp27)
npx create-next-app@latest
π SQLiteμ€μΉ / Installing SQLite
cd ~/myapp27
npm install better-sqlite3
npm install -D @types/better-sqlite3
π DDNS,httpsμ€μ / DDNS,https settings
π λλ©μΈνμ©, @userid μ¬μ©νκΈ°
Allowing domains, using @userid
— next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* allow domain*/
allowedDevOrigins: ['aloy-horizon.duckdns.org', '*.duckdns.org'],
/* host.domain.org/@userid */
async rewrites() {
return [
{
source: '/@:username',
destination: '/usersui/:username',
},
]
}
};
export default nextConfig;
π ν
λ§ λλ ν 리 μ€μκ° μλμΈμ
Real-time automatic detection of theme directories
βοΈ λͺ¨λμ€μΉ / module installation
— μ€μκ° νμΌ λ° ν΄λλ³κ²½ κ°μκΈ°λ₯
Real-time file and folder change monitoring function
npm install -D chokidar
π μ½λ μμ λ° νμΌ μμ±
Code modification and file creation
βοΈ myapp27/lib/watchTheme.ts -> νμΌ μμ± / Create file
— μ€μκ° ν΄λ λ° νμΌλ³κ²½μ κ°μ§ν©λλ€.
It detects real-time changes to folders and files.
— _componentsλλ ν 리λ΄μ index.ts,themeNames.tsνμΌμ μμ±νκ³ μμ ν©λλ€.
Create and modify the index.ts and themeNames.ts files within the _components directory.
import fs from 'fs';
import path from 'path';
import chokidar from 'chokidar';
let started = false;
export function watchThemes() {
... ...
}
1)μ΄ νμΌμμ ν΄λΉ λλ ν 리λ΄μ νμΌμ΄λ λλ ν 리 λ³κ²½μ΄ μμΌλ©΄ ν
λ§νμΌ(index.ts,themeNames.ts)μ μ
λ°μ΄νΈ ν©λλ€.
This file updates the theme files (index.ts, themeNames.ts) whenever there are changes to files or directories within the specified directory.
2)index.ts,themeNames.tsνμΌμ΄ μμΌλ©΄ μλμμ±ν©λλ€.
If the index.ts and themeNames.ts files do not exist, they are automatically generated.
3)νμΌμ λ΄μ©μ΄λ λλ ν λ¦¬κ° λ³κ²½λλ©΄ κ°μ§νκ³ index.ts,themeNames.tsνμΌμ λ΄μ©μ μ
λ°μ΄νΈν©λλ€.
It detects changes to file contents or directories and updates the contents of index.ts and themeNames.ts.
βοΈ myapp27/instrumentation.ts -> νμΌ μμ± / Create file
— Nextjsμ κΈ°λ₯μΌλ‘ watchTheme.tsλ₯Ό λ°±κ·ΈλΌμ΄λμμ μ€ννλλ‘ν©λλ€.
Use Next.js features to run watchTheme.ts in the background.
// β
myapp27/instrumentation.ts - Next.js μμ μ μλ μ€ν / Automatic execution upon Next.js startup
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
const { watchThemes } = await import('./lib/watchThemes');
// λ°±κ·ΈλΌμ΄λμμ μ‘°μ©ν κ°μ μμ / Start monitoring quietly in the background.
watchThemes();
console.log('π Theme watcher started in background');
}
}
βοΈapp/usersui/[username]/_components/themes/page.tsx -> μμ / modify
— μ΄ νμΌμμ κ° ν
λ§λλ ν 리μ νμΌμ λΆλ¬ μ΅λλ€.
This file loads the files from each theme directory.
— themeλλ ν 리μ ν
λ§λ₯Ό μλμΌλ‘ λΆλ¬μ€λλ‘ μ½λ λ³κ²½νμ΅λλ€.
I modified the code to automatically load the theme from the theme directory.
//β
myappp27
import { themeRegistry, getThemeComponent } from './_components/themes'; // β
registryλ§ μ¬κΈ°μ κ°μ Έμ€κΈ° / Import only the registry from here.
import { themeNames } from './_components/themes/themeNames'; // β
namesλ λΆλ¦¬λ νμΌμμ κ°μ Έμ€κΈ° / names are imported from a separate file
... ...
if (loading) return <div style={{ padding: 20 }}>Loading...</div>;
const props = { timeline, username, onBoost: handleBoost, onLike: handleLike };
// ν
λ§ μλλΆκΈ°λ‘ λ³κ²½ / Changed to automatic theme switching.
const ActiveTheme = getThemeComponent(theme as any) || themeRegistry.pinafore?.component || themeRegistry[themeNames[0]]?.component;
if (!ActiveTheme) return <div>No themes found</div>;
return <ActiveTheme {...props} />;
βοΈ app/usersui/[username]/_components/themes/index.js
— μ΄ νμΌμ λ§λ€μ§ μμλ λ©λλ€. μλμμ±λ©λλ€.
You do not need to create this file; it is generated automatically.
import { MastodonTheme } from './mastodon/MastodonTheme';
import { MinimalTheme } from './minimal/MinimalTheme';
import { PinaforeTheme } from './pinafore/PinaforeTheme';
import { ThemeexTheme } from './themeex/ThemeexTheme';
export const themeRegistry = {
mastodon: { component: MastodonTheme, label: 'mastodon' },
minimal: { component: MinimalTheme, label: 'minimal' },
pinafore: { component: PinaforeTheme, label: 'pinafore' },
themeex: { component: ThemeexTheme, label: 'themeex' },
} as const;
export type ThemeName = keyof typeof themeRegistry;
export function getThemeComponent(name: ThemeName) {
return themeRegistry[name]?.component;
}
βοΈ app/usersui/[username]/_components/themes/themeNames.ts
— μ΄ νμΌμ λ§λ€μ§ μμλ λ©λλ€. μλμμ±λ©λλ€.
You do not need to create this file; it is generated automatically.
export const themeNames = ["mastodon","minimal","pinafore","themeex"] as const;
export type ThemeName = typeof themeNames[number];
βοΈ app/usersui/[username]/_components/themes/pinafore/PinaforeTheme.tsx -> νμΌ μμ / Modify file
— λ€λ₯Έ ν
λ§νμΌμ μμ νμ§ μμμ΅λλ€. myapp26μ λ΄μ©κ³Ό κ°μ΅λλ€.
I did not modify any other theme files. They are identical to the contents of myapp26.
— themeexλ ν
μ€νΈμ© ν
λ§λ‘ PinaforeTheme.tsxμ κ±°μ κ°μ΅λλ€.
themeex is a test theme that is almost identical to PinaforeTheme.tsx.
— PinaforeTheme.tsxμλ selectλ©λ΄λΆλΆμ themeNamesμμ μ½μ΄ μ΅λλ€.
In PinaforeTheme.tsx, the select menu section reads from themeNames.
'use client';
import { useTheme } from '@/lib/theme';
import { themeNames } from '../themeNames'; // β
myapp27
import { ThemeName } from '..';
... ...
{/* β
myapp27 - ../themeNames.ts*/}
<select value={theme || themeNames[0]} onChange={handleChange}>
{themeNames.map(name => (
<option key={name} value={name}>{name}</option>
))}
</select>
π ν μ€νΈ / Test
— μ κ· ν λ§ νμΌ μ λ‘λ / Upload New Theme File
etc % mv themeex /Users/gimdaegyeong/Desktop/app/NextJS/myapp27/app/usersui/[username]/_components/themes/
/Users/gimdaegyeong/Desktop/app/NextJS/myapp27/app/usersui/[username]/_components/themes/
etc % mv themeex /Users/gimdaegyeong/Desktop/app/NextJS/myapp27/app/usersui/'[username]'/_components/themes/
— μλ² μ΄μμ€ ν λ§ μ λ‘λμ ν λ§μ μλλ°μλ©λλ€.


π κ³Όμ μ 리 / Process Summary
- μ€μκ° νμΌ λ° λλ ν 리 λ³κ²½ κ°κΈ° νμΈ λͺ¨λμ€μΉ(chokidar)
Install the module for real-time file and directory change monitoring (chokidar). - ./lib/watchTheme.ts νμΌμμ±(μ€μκ° νμΌ λ³κ²½ κ°μ μλ²)
Create the ./lib/watchTheme.ts file (a server for monitoring real-time file changes). - watchTheme.tsλ₯Ό λ°±κ·ΈλΌμ΄λμμ μ€ννκΈ° μν΄μ instrument.ts νμΌμμ±
Create the instrument.ts file to run watchTheme.ts in the background. - watchThems.tsμ€νμ _components/themesλλ ν 리λ΄μ index.tsμ themeNames.tsνμΌμ μμ±νκ³ μμ ν©λλ€.
When watchTheme.ts runs, it generates and updates the index.ts and themeNames.ts files within the _components/themes directory. - theme/page.tsxνμΌμμ μμ±λ νμΌ(index.ts,themeNames.ts)μ λΆλ¬μ΅λλ€.
Import the generated files (index.ts, themeNames.ts) into theme/page.tsx. - λΆλ¬μ¨ νμΌμ λ΄μ©κ³Ό μΌμΉνλ ν
λ§λ₯Ό λΆλ¬μ€κ³ ν
λ§ selectλ©λ΄μλ λ°μν©λλ€.
Load the theme corresponding to the content of the imported files and reflect it in the theme selection menu.
μν볡μ 8μ₯ 32μ / John 8:32
“κ·Έλ¦¬κ³ λν¬λ μ§λ¦¬λ₯Ό μκ² λ κ²μ΄λ©°, μ§λ¦¬κ° λν¬λ₯Ό μμ λ‘κ² ν κ²μ΄λ€.”
“Then you will know the truth ,and the truth will set you free”