ππ» myapp61μμλ μλ¦Όνμ΄μ§μμ λ°μ΄ν°κ° μ€λ³΅ νμλλ λ¬Έμ λ₯Ό μμ ν©λλ€.
In myapp61, the issue where data was displayed redundantly on the notification page is being fixed.
ππ» νμλΌμΈμμ λ°μ΄ν°κ° μμΌλ©΄ Home,Local,Federated νμ΄ μ¬λΌμ§λ λ¬Έμ λ₯Ό μμ ν©λλ€.
Fixes an issue where the Home, Local, and Federated tabs disappear when there is no data in the timeline.
ππ» λ΄κ° μμ±νμ§ μμ κΈλ DELETEνμλλ λ¬Έμ λ₯Ό μμ ν©λλ€.
Fixes an issue where posts I did not write were marked for deletion.
ππ» μ 체 μ½λλ κΉνλΈμμ νμΈ ν μ μμ΅λλ€.
You can find the full code on GitHub.
https://github.com/gideonslife01/flm-nextjs
π μ 체 νλ‘μ νΈ κ΅¬μ‘° / Overall Project Structure
myapp project/
βββ app/ (Next.js App Router)
β βββ .well-known/webfinger/route.ts -> webfinger
β βββ hooks/useCursorPagination.ts -> Pagination Hook
β βββ 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(deprecated)
β βββ api/timeline/route.ts -> Timeline API
β βββ api/followinglist/route.ts -> followinglist API
β βββ api/followerslist/route.ts -> followerslist API
β βββ api/v1/instance/route.ts -> auth
β βββ api/v1/apps/route.ts. -> auth
β βββ api/v1/accounts/verify_credentials/route.ts -> auth
β βββ api/v1/statuses/route.ts -> Write Post
β βββ api/v1/timelines/_home_back/route.ts -> timeline(Depreacted)
β βββ api/v1/media/route.ts -> Image upload
β βββ api/v1/media/[id]/route.ts -> Image Delete
β βββ api/v1/instance/rules/route.ts -> Feature not implemented.
β βββ api/v1/instance/domain_blocks/route.ts -> Feature not implemented.
β βββ api/v1/filters/route.ts -> Feature not implemented.
β βββ api/v1/lists/route.ts -> Feature not implemented.
β βββ api/v1/announcements/route.ts -> Feature not implemented.
β βββ api/v1/timelines/_public_back/route.ts -> Feature not implemented.(Deprecated)
β βββ api/v1/timelines/[type]/route.ts -> Timeline API
β βββ api/v1/statuses/[id]/context/route.ts -> Post Check,Delete
β βββ oauth/authorize/route.ts -> auth
β βββ oauth/token/route.ts -> auth
β βββ oauth/login-and-authorize/route.ts -> Tursky,Pinafore login processing
β βββ oauth/revoke/route.ts -> Feature not implemented.
β βββ api/v1/search/home/route.ts -> search
β βββ api/v2/search/home/route.ts -> search
β βββ api/v2/notifications/policy/route.ts-> Feature not implemented.
β βββ api/v1/accounts/[id]/followers/route.ts -> followers
β βββ api/v1/accounts/[id]/following/route.ts -> following
β βββ api/v1/statuses/[id]/route.ts -> Post delete(pinafore)
β βββ api/v1/statuses/[id]/favourite/route.ts -> favourite(for pinafore)
β βββ api/v1/statuses/[id]/unfavourite/route.ts -> unfavourite(for pinafore)
β βββ api/v1/statuses/[id]/reblog/route.ts -> reblog[boost](for pinafore)
β βββ api/v1/statuses/[id]/unreblog/route.ts -> unreblog[unboost](for pinafore)
β βββ api/auth/signup/route.ts -> Website Signup
β βββ api/auth/login/route.ts -> Website Login
β βββ api/auth/logout/route.ts -> Website Logout
β βββ api/auth/refresh/route.ts -> Refresh Token
β βββ api/cleanup-orphan/route.ts -> post,outbox clean up
β βββ api/auth/me/route.tsx -> Login Check
β βββ auth/signup/page.tsx -> Signup UI
β βββ auth/signup/page.tsx -> Login UI
β βββ 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(Server, 404)
β β βββ ClientPage.tsx. -> Timeline UI(Client,Call Active Themes)
β β βββ _components/themes/
β β βββ themeex/ThemeexTheme.tsx -> Example Theme
β β βββ themeex/FollowersList.tsx -> Theme Example, FollowersList
β β βββ themeex/FollowingList.tsx -> Theme Example, FollowingList
β β βββ themeex/NotificationsList.tsx -> Theme Example, NotificationsList
β β βββ themeex/TimelineList.tsx -> Theme Example, TimelineList
β β βββ pinafore/PinaforeTheme.tsx -> Theme 1
β β βββ pinafore/FollowersList.tsx -> Theme 1, FollowersList
β β βββ pinafore/FollowingList.tsx -> Theme 1, FollowingList
β β βββ pinafore/NotificationsList.tsx -> Theme 1, NotificationsList
β β βββ pinafore/TimelineList.tsx -> Theme 1, TimelineList
β β βββ 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
β βββ auth.ts -> Authentication, User Management
β βββ ap.ts -> Follow,Undo,Create,Likes,Announce
β βββ visibility.ts -> Visibility(Public,Unlisted,Private,Direct)
β βββ db.ts -> DB connection
βββ data/
β βββ keys/userIDs/ -> private.pem, public.pem(New)
β βββ keys/ -> private.pem, public.pem(legacy)
βββ data.sqlite -> Database(1/3)
βββ data.sqlite-wal -> Database(2/3)
βββ data.sqlite-shm -> Database(3/3)
βββ Caddyfile -> https
βββ instrumentation.ts -> Background Server
βββ proxy.ts -> middleware.ts - >proxy.ts(for Nextjs16)
βββ postcss.config.mjs -> for Nextjs16
βββ package.json
π νλ‘μ νΈ μμ / Project Start
π μ½λ μμ / Code Modification
βοΈ νμλΌμΈμμ λ°μ΄ν°κ° μμΌλ©΄ νμ¬λΌμ§λ μ€λ₯ μμ
Fixed an error where the tab would disappear when there was no data in the timeline.
βοΈ λ‘κ·ΈμΈνμ§ μμΌλ©΄ ννμ λ‘컬APIλ₯Ό νΈμΆ
If not logged in, the Home tab calls the local API
— app/usersui/[username]/_components/themes/Themeex/TimelineList.tsx
const {
flatData,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useCursorPagination({
... ...
// β
myapp61 - API μ£Όμ μμ / modify API Address
// - fetcher μμμ μ§μ λ‘κ·ΈμΈ μ¬λΆ μ²΄ν¬ νκΈ° / Check login status directly within the fetcher.
let me: string | null = null;
try {
const meRes = await fetch(`/api/auth/me`, { credentials: 'include', cache: 'no-store' });
if (meRes.ok) {
const j = await meRes.json();
me = j.username || null;
}
} catch {}
const effectiveUser = me || currentUser;
let url = '';
if (tab === 'home') {
if (effectiveUser) {
url = `/api/v1/timelines/home?${params.toString()}`;
} else {
params.set('local', 'true');
url = `/api/v1/timelines/public?${params.toString()}`;
}
} else if (tab === 'local') {
params.set('local', 'true');
url = `/api/v1/timelines/public?${params.toString()}`;
} else {
url = `/api/v1/timelines/public?${params.toString()}`;
}
... ...
});
// if (data.length === 0) {
// return <div className="p-5 text-[#999]">νμλΌμΈμ΄ λΉμ΄μμ΅λλ€ / No posts</div>;
// }
return ( ... ...
{/* β
myapp61 - No postsλ selector μλμ νμ / "No posts" is displayed below the selector. */}
{data.length === 0 && (
<div className="p-10 text-center text-[#999]">νμλΌμΈμ΄ λΉμ΄μμ΅λλ€ / No posts in {tab}</div>
)}
... ...
);
1)λ‘κ·ΈμΈ λΆλΆμ μλ²κ° μλ ν΄λΌμ΄μΈνΈ λΆλΆμμλ getUserν¨μλ‘ μΈμ¦ 체ν¬ν μ μμ
Regarding the login functionality, authentication cannot be verified using the getUser function on the client side; this must be handled on the server side.
2)ν΄λΌμ΄μΈνΈλ μΈμ¦ νμΈμ μν΄ /api/auth/me λΌμ°νΈ μ¬μ©ν¨
The client uses the /api/auth/me route to verify authentication.
3)λ‘κ·ΈμΈ ν κ²½μ° homeλΌμ°νΈ λ‘κ·ΈμΈνμ§ μμΌλ©΄ publicλΌμ°νΈλ‘ μ΄λ
If logged in, navigate to the home route; if not logged in, navigate to the public route.
βοΈ νμλΌμΈ Unknown λ° μ€λ₯ / Timeline Unknown and Errors
— app/api/v1/timelines/[type]/route.ts
1)νμλΌμΈ APIμμ acctκ°μ μλͺ» μ€μ λ°μνλ μ€λ₯
An error caused by providing an incorrect ‘acct’ value in the Timeline API.
return {
id: String(row.id),
uri: longId, url: longId,
account: {
// id: isMy ? accountId : `remote_${row.username}`, β
myapp61
id: isMy ? accountId : `remote_${row.username}@${acctDomain}`,
username: row.username,
// acct: `${row.username}@${DOMAIN}`, β
myapp61
acct: displayAcct,
//display_name: row.username,
display_name: accountUsername,
avatar: `https://${DOMAIN}/icon.png`, avatar_static: `https://${DOMAIN}/icon.png`,
header: `https://${DOMAIN}/header.png`, header_static: `https://${DOMAIN}/header.png`,
},
... ...
}
βοΈ FollowingList,FollowerList UI μ€λ₯/error
— app/usersui/[username]/_components/theme/pinafore/FollowingList.tsx
— app/usersui/[username]/_components/theme/pinafore/FollowersList.tsx
<div className="w-9 h-9 rounded-full bg-[#6364ff] text-white flex items-center justify-center font-extrabold shrink-0">
... ...
{/* <button className="ml-auto px-3 py-1 bg-[#6364ff] text-white rounded-full text-xs font-bold hover:bg-[#5556ee]">
Following
</button> */} --> or Delete
# v1 API
https://aloy-horizon.duckdns.org/api/v1/timelines/public
https://aloy-horizon.duckdns.org/api/v1/timelines/public?local=true
# pinafore ν
λ§μμ μ¬μ©νλ μ΄μ API
https://aloy-horizon.duckdns.org/api/timeline?username=user1&type=home
βοΈ λ¦¬λͺ¨νΈ κΈμλ DELETEλ²νΌ 보μ΄λκ² μμ
Fixed the issue where the DELETE button was visible on remote posts.
— λ‘κ·ΈμΈ ν λ΄κ° μμ±ν κΈμλ§ DELETEλ²νΌ 보μ
The DELETE button appears only on posts I have written after logging in.
// β
myapp61
const withMine = arr.map((p:any) => {
const acct = p.account?.acct || '';
const username = p.account?.username || p.username || '';
const acctDomain = acct.includes('@')? acct.split('@')[1] : DOMAIN;
const isLocalAccount = acctDomain === DOMAIN;
return {
...p,
isMine:!!(currentUser && isLocalAccount && username === currentUser)
};
});
... ...
{/* {currentUser && isMine && (
<button onClick={() => onDelete(p.id)} className="text-[#e0245e] ml-auto text-xs hover:underline">
π Delete
</button>
)} */}
{/* β
myapp61 */}
{isMine && (
<button onClick={() => onDelete(p.id)} className="text-[#e0245e] ml-auto text-xs">
π Delete
</button>
)}
βοΈ SNSνμ΄μ§κ° μ²μ μ€νλ λ νμλΌμΈμ΄ λΉμ΄μλ κ±Έλ‘ νμλλ μ€λ₯
An error where the timeline appears empty when the social media page is first launched.
— app/usersui/[username]/ClientPage.tsx
// β
myapp60 + myapp61
// - νμ΄μ§λ€μ΄μ
μ TimelineListκ° λ΄λΉ, μ¬κΈ°μ λΉ λ°°μ΄λ‘ μμ
// - Pagination is handled by TimelineList; start with an empty array here.
useEffect(() => {
if (!username) return;
//setTimeline([]);
setLoading(false);
}, [username]);
π ν μ€νΈ / Test
βοΈ Unknown error

βοΈ νλ‘μ,νλ‘μ리μ€νΈ UI μ€λ₯,μλ¦Όλ°μ΄ν° μ€λ³΅ μ²λ¦¬
UI errors in following/follower lists; handling of duplicate notification data.

βοΈ λ¦¬λͺ¨νΈ μλ² μμ κΈμ§,μ‘ν° μ νν νμ,리λͺ¨νΈ μλ²μμ΄μ½νμ
Prevent remote server deletion, display actors accurately, show remote server icons.

λ§ν볡μ 21μ₯ 22μ / Matthew 21: 22
“λν¬κ° κΈ°λν λμ 무μμ΄λ μ§ λ―Ώκ³ κ΅¬νλ κ²μ λ€ λ°μΌλ¦¬λΌ νμλλΌ”
“And everything you ask in prayer, believing, you will receive.”