···2233import { EmptyState } from "components/EmptyState";
44import { PostListing } from "components/PostListing";
55-import type { Post } from "app/(home-pages)/reader/getReaderFeed";
55+import type { Post } from "app/(app)/(home-pages)/reader/getReaderFeed";
66import type { Cursor } from "./getProfilePosts";
77import { getProfilePosts } from "./getProfilePosts";
88import useSWRInfinite from "swr/infinite";
···11"use server";
2233import { supabaseServerClient } from "supabase/serverClient";
44-import { getPublicationURL } from "app/lish/createPub/getPublicationURL";
55-import type { Post } from "app/(home-pages)/reader/getReaderFeed";
44+import { getPublicationURL } from "app/(app)/lish/createPub/getPublicationURL";
55+import type { Post } from "app/(app)/(home-pages)/reader/getReaderFeed";
66import {
77 normalizeDocumentRecord,
88 normalizePublicationRecord,
···11"use server";
2233-import { getPublicationURL } from "app/lish/createPub/getPublicationURL";
33+import { getPublicationURL } from "app/(app)/lish/createPub/getPublicationURL";
44import { supabaseServerClient } from "supabase/serverClient";
55import { AtUri } from "@atproto/api";
66-import { idResolver } from "app/(home-pages)/reader/idResolver";
77-import type { Post } from "app/(home-pages)/reader/getReaderFeed";
66+import { idResolver } from "app/(app)/(home-pages)/reader/idResolver";
77+import type { Post } from "app/(app)/(home-pages)/reader/getReaderFeed";
88import {
99 normalizeDocumentRecord,
1010 normalizePublicationRecord,
···11import { ImageResponse } from "next/og";
22import type { Fact } from "src/replicache";
33import type { Attribute } from "src/replicache/attributes";
44-import { Database } from "../../supabase/database.types";
44+import { Database } from "supabase/database.types";
55import { createServerClient } from "@supabase/ssr";
66import { parseHSBToRGB } from "src/utils/parseHSB";
77
···11import { z } from "zod";
22import { makeRoute } from "../lib";
33import type { Env } from "./route";
44-import { getConstellationBacklinks } from "app/lish/[did]/[publication]/[rkey]/getPostPageData";
55-import { getDocumentURL } from "app/lish/createPub/getPublicationURL";
44+import { getConstellationBacklinks } from "app/(app)/lish/[did]/[publication]/[rkey]/getPostPageData";
55+import { getDocumentURL } from "app/(app)/lish/createPub/getPublicationURL";
66import {
77 normalizeDocumentRecord,
88 normalizePublicationRecord,
+2-2
app/api/rpc/[command]/get_hot_feed.ts
···11import { z } from "zod";
22import { makeRoute } from "../lib";
33import type { Env } from "./route";
44-import { getHotFeed } from "app/(home-pages)/reader/getHotFeed";
55-import type { Post } from "app/(home-pages)/reader/getReaderFeed";
44+import { getHotFeed } from "app/(app)/(home-pages)/reader/getHotFeed";
55+import type { Post } from "app/(app)/(home-pages)/reader/getReaderFeed";
6677export type GetHotFeedReturnType = Awaited<
88 ReturnType<(typeof get_hot_feed)["handler"]>
+1-1
app/api/rpc/[command]/get_profile_data.ts
···11import { z } from "zod";
22import { makeRoute } from "../lib";
33import type { Env } from "./route";
44-import { idResolver } from "app/(home-pages)/reader/idResolver";
44+import { idResolver } from "app/(app)/(home-pages)/reader/idResolver";
55import { supabaseServerClient } from "supabase/serverClient";
66import { Agent } from "@atproto/api";
77import { getIdentityData } from "actions/getIdentityData";
···22import { z } from "zod";
33import { makeRoute } from "../lib";
44import type { Env } from "./route";
55-import { getDocumentURL } from "app/lish/createPub/getPublicationURL";
55+import { getDocumentURL } from "app/(app)/lish/createPub/getPublicationURL";
66import { normalizeDocumentRecord } from "src/utils/normalizeRecords";
7788export type SearchPublicationDocumentsReturnType = Awaited<
+1-1
app/api/rpc/[command]/search_publication_names.ts
···11import { z } from "zod";
22import { makeRoute } from "../lib";
33import type { Env } from "./route";
44-import { getPublicationURL } from "app/lish/createPub/getPublicationURL";
44+import { getPublicationURL } from "app/(app)/lish/createPub/getPublicationURL";
55import { deduplicateByUri } from "src/utils/deduplicateRecords";
6677export type SearchPublicationNamesReturnType = Awaited<
···11"use client";
2233-import { LinearDocumentPage } from "app/lish/[did]/[publication]/[rkey]/LinearDocumentPage";
33+import { LinearDocumentPage } from "app/(app)/lish/[did]/[publication]/[rkey]/LinearDocumentPage";
44import { LeafletContentProvider } from "contexts/LeafletContentContext";
55import {
66 DocumentProvider,
···99import { useIdentityData } from "components/IdentityProvider";
1010import type { ProfileViewDetailed } from "@atproto/api/dist/client/types/app/bsky/actor/defs";
1111import type { PubLeafletPagesLinearDocument } from "lexicons/api";
1212-import type { PostPageData } from "app/lish/[did]/[publication]/[rkey]/getPostPageData";
1212+import type { PostPageData } from "app/(app)/lish/[did]/[publication]/[rkey]/getPostPageData";
1313import type { DocumentContextValue } from "contexts/DocumentContext";
1414import {
1515 usePublicationData,
···11import { supabaseServerClient } from "supabase/serverClient";
22import { Metadata } from "next";
33-import { idResolver } from "app/(home-pages)/reader/idResolver";
44-import { DocumentPageRenderer } from "app/lish/[did]/[publication]/[rkey]/DocumentPageRenderer";
33+import { idResolver } from "app/(app)/(home-pages)/reader/idResolver";
44+import { DocumentPageRenderer } from "app/(app)/lish/[did]/[publication]/[rkey]/DocumentPageRenderer";
55import { NotFoundLayout } from "components/PageLayouts/NotFoundLayout";
66import { normalizeDocumentRecord } from "src/utils/normalizeRecords";
77import { documentUriFilter } from "src/utils/uriHelpers";
+14
app/page.tsx
···11+import type { Metadata } from "next";
22+import { AboutPage } from "./about/AboutPage";
33+44+export const metadata: Metadata = {
55+ title: "Leaflet — social publishing on the Atmosphere",
66+ description:
77+ "A simple and powerful platform for social publishing — blogs, newsletters, and more!",
88+};
99+1010+export const revalidate = 3600;
1111+1212+export default function RootPage() {
1313+ return <AboutPage />;
1414+}
+2-2
components/ActionBar/ProfileButton.tsx
···1010import { SpeedyLink } from "components/SpeedyLink";
1111import { Popover } from "components/Popover";
1212import { Modal } from "components/Modal";
1313-import { InlineUpgradeToPro } from "app/lish/[did]/[publication]/UpgradeModal";
1414-import { ManageProSubscription } from "app/lish/[did]/[publication]/dashboard/settings/ProSettings";
1313+import { InlineUpgradeToPro } from "app/(app)/lish/[did]/[publication]/UpgradeModal";
1414+import { ManageProSubscription } from "app/(app)/lish/[did]/[publication]/dashboard/settings/ProSettings";
1515import { ManageDomains } from "components/Domains/ManageDomains";
1616import { WebSmall } from "components/Icons/WebSmall";
1717import { useIsPro, useCanSeePro } from "src/hooks/useEntitlement";
+2-2
components/ActionBar/Publications.tsx
···3344import { useIdentityData } from "components/IdentityProvider";
55import { theme } from "tailwind.config";
66-import { getBasePublicationURL } from "app/lish/createPub/getPublicationURL";
66+import { getBasePublicationURL } from "app/(app)/lish/createPub/getPublicationURL";
77import { Json } from "supabase/database.types";
88import { AtUri } from "@atproto/syntax";
99import { ActionButton } from "./ActionButton";
···1616import { LooseLeafSmall } from "components/Icons/LooseleafSmall";
1717import { LoginModal } from "components/LoginButton";
1818import useSWR from "swr";
1919-import { getHomeDocs } from "app/(home-pages)/(writer)/home/storage";
1919+import { getHomeDocs } from "app/(app)/(home-pages)/(writer)/home/storage";
20202121export const PublicationButtons = (props: { className?: string }) => {
2222 let { identity } = useIdentityData();
···55 PublicationPostItemSmall,
66 PublicationPostItemMedium,
77 PublicationPostItemLarge,
88-} from "app/lish/[did]/[publication]/PublicationPostItem";
99-import { LocalizedDate } from "app/lish/[did]/[publication]/LocalizedDate";
88+} from "app/(app)/lish/[did]/[publication]/PublicationPostItem";
99+import { LocalizedDate } from "app/(app)/lish/[did]/[publication]/LocalizedDate";
1010import {
1111 getDocumentURL,
1212 getPublicationURL,
1313-} from "app/lish/createPub/getPublicationURL";
1313+} from "app/(app)/lish/createPub/getPublicationURL";
1414import { getFirstParagraph } from "src/utils/getFirstParagraph";
1515import { blobRefToSrc } from "src/utils/blobRefToSrc";
1616import { useStandardSitePost } from "components/StandardSitePostDataProvider";
+1-1
components/Blocks/TextBlock/index.tsx
···3030import { getAspectRatio } from "src/utils/aspectRatio";
31313232import { Mention, MentionAutocomplete } from "components/Mention";
3333-import { addMentionToEditor } from "app/[leaflet_id]/publish/BskyPostEditorProsemirror";
3333+import { addMentionToEditor } from "app/(app)/[leaflet_id]/publish/BskyPostEditorProsemirror";
3434import { v7 } from "uuid";
3535import { generateKeyBetween } from "fractional-indexing";
3636
+1-1
components/DesktopFooter.tsx
···55import { FootnoteToolbar } from "./Toolbar/FootnoteToolbarWrapper";
66import { useEntitySetContext } from "./EntitySetProvider";
77import { focusBlock } from "src/utils/focusBlock";
88-import { hasBlockToolbar } from "app/[leaflet_id]/Footer";
88+import { hasBlockToolbar } from "app/(app)/[leaflet_id]/Footer";
99import { useEntity } from "src/replicache";
10101111export function DesktopPageFooter(props: { pageID: string }) {
+2-2
components/Domains/PublicationDomains.tsx
···1111import {
1212 usePublicationData,
1313 useNormalizedPublicationRecord,
1414-} from "app/lish/[did]/[publication]/dashboard/PublicationSWRProvider";
1515-import { updatePublicationBasePath } from "app/lish/createPub/updatePublication";
1414+} from "app/(app)/lish/[did]/[publication]/dashboard/PublicationSWRProvider";
1515+import { updatePublicationBasePath } from "app/(app)/lish/createPub/updatePublication";
1616import {
1717 assignDomainToPublication,
1818 removeDomainAssignment,
+1-1
components/LoginButton.tsx
···1919 confirmEmailAuthToken,
2020} from "actions/emailAuth";
2121import { loginWithEmailToken } from "actions/login";
2222-import { getHomeDocs } from "app/(home-pages)/(writer)/home/storage";
2222+import { getHomeDocs } from "app/(app)/(home-pages)/(writer)/home/storage";
2323import { mutate } from "swr";
24242525export const LoginModal = (props: {
+2-2
components/PageLayouts/NotificationContent.tsx
···11"use client";
22import { useEffect, useState } from "react";
33import { DashboardPageLayout } from "./DashboardPageLayout";
44-import { NotificationList } from "app/(home-pages)/(writer)/notifications/NotificationList";
55-import { getNotifications } from "app/(home-pages)/(writer)/notifications/getNotifications";
44+import { NotificationList } from "app/(app)/(home-pages)/(writer)/notifications/NotificationList";
55+import { getNotifications } from "app/(app)/(home-pages)/(writer)/notifications/getNotifications";
66import { HydratedNotification } from "src/notifications";
7788export function NotificationContent() {
+1-1
components/PageSWRDataProvider.tsx
···1010import {
1111 getPublicationURL,
1212 getDocumentURL,
1313-} from "app/lish/createPub/getPublicationURL";
1313+} from "app/(app)/lish/createPub/getPublicationURL";
1414import { AtUri } from "@atproto/syntax";
1515import {
1616 normalizeDocumentRecord,
+1-1
components/Pages/Page.tsx
···1616import { focusPage } from "src/utils/focusPage";
1717import { PageOptions } from "./PageOptions";
1818import { CardThemeProvider } from "components/ThemeManager/ThemeProvider";
1919-import { useDrawerOpen } from "app/lish/[did]/[publication]/[rkey]/Interactions/InteractionDrawer";
1919+import { useDrawerOpen } from "app/(app)/lish/[did]/[publication]/[rkey]/Interactions/InteractionDrawer";
2020import { usePreserveScroll } from "src/hooks/usePreserveScroll";
2121import { usePageFootnotes } from "components/Footnotes/usePageFootnotes";
2222import { FootnoteContext } from "components/Footnotes/FootnoteContext";
+1-1
components/Pages/PageShareMenu.tsx
···22import {
33 ShareButton,
44 useReadOnlyShareLink,
55-} from "app/[leaflet_id]/actions/ShareOptions";
55+} from "app/(app)/[leaflet_id]/actions/ShareOptions";
66import { useEffect, useState } from "react";
7788export const PageShareMenu = (props: { entityID: string }) => {
+2-2
components/Pages/PublicationMetadata.tsx
···88import {
99 getBasePublicationURL,
1010 getPublicationURL,
1111-} from "app/lish/createPub/getPublicationURL";
1111+} from "app/(app)/lish/createPub/getPublicationURL";
1212import { useSubscribe } from "src/replicache/useSubscribe";
1313import { useEntitySetContext } from "components/EntitySetProvider";
1414import { timeAgo } from "src/utils/timeAgo";
···1818import { Popover } from "components/Popover";
1919import { TagSelector } from "components/Tags";
2020import { useIdentityData } from "components/IdentityProvider";
2121-import { PostHeaderLayout } from "app/lish/[did]/[publication]/[rkey]/PostHeader/PostHeader";
2121+import { PostHeaderLayout } from "app/(app)/lish/[did]/[publication]/[rkey]/PostHeader/PostHeader";
2222import { Backdater } from "./Backdater";
2323import { RecommendTinyEmpty } from "components/Icons/RecommendTiny";
2424import { mergePreferences } from "src/utils/mergePreferences";
+1-1
components/Pages/index.tsx
···8899import { useCardBorderHidden } from "./useCardBorderHidden";
1010import { BookendSpacer, SandwichSpacer } from "components/LeafletLayout";
1111-import { LeafletSidebar } from "app/[leaflet_id]/Sidebar";
1111+import { LeafletSidebar } from "app/(app)/[leaflet_id]/Sidebar";
1212import { Page } from "./Page";
1313import { IframePageView } from "./IframePageView";
1414import { PageOptionButton } from "./PageOptions";
+2-2
components/PostListing.tsx
···99 NormalizedPublication,
1010} from "src/utils/normalizeRecords";
1111import { hasLeafletContent } from "lexicons/src/normalize";
1212-import type { Post } from "app/(home-pages)/reader/getReaderFeed";
1212+import type { Post } from "app/(app)/(home-pages)/reader/getReaderFeed";
13131414import Link from "next/link";
1515import { useEffect, useRef, useState } from "react";
···2222import { useSelectedPostListing } from "src/useSelectedPostState";
2323import { mergePreferences } from "src/utils/mergePreferences";
2424import { ExternalLinkTiny } from "./Icons/ExternalLinkTiny";
2525-import { getDocumentURL } from "app/lish/createPub/getPublicationURL";
2525+import { getDocumentURL } from "app/(app)/lish/createPub/getPublicationURL";
2626import { RecommendButton } from "./RecommendButton";
2727import { getFirstParagraph } from "src/utils/getFirstParagraph";
2828
+1-1
components/ProfilePopover.tsx
···33import useSWR from "swr";
44import { callRPC } from "app/api/rpc/client";
55import { useRef, useState } from "react";
66-import { ProfileHeader } from "app/(home-pages)/p/[didOrHandle]/ProfileHeader";
66+import { ProfileHeader } from "app/(app)/(home-pages)/p/[didOrHandle]/ProfileHeader";
77import { SpeedyLink } from "./SpeedyLink";
88import { Tooltip } from "./Tooltip";
99import { ProfileViewDetailed } from "@atproto/api/dist/client/types/app/bsky/actor/defs";
+1-1
components/RecommendButton.tsx
···77import {
88 recommendAction,
99 unrecommendAction,
1010-} from "app/lish/[did]/[publication]/[rkey]/Interactions/recommendAction";
1010+} from "app/(app)/lish/[did]/[publication]/[rkey]/Interactions/recommendAction";
1111import { callRPC } from "app/api/rpc/client";
1212import { useSmoker, useToaster } from "./Toast";
1313import { OAuthErrorMessage, isOAuthSessionError } from "./OAuthError";
+1-1
components/Subscribe/HandleSubscribe.tsx
···44import Link from "next/link";
55import { useState } from "react";
66import { encodeActionToSearchParam } from "app/api/oauth/[route]/afterSignInActions";
77-import { subscribeToPublication } from "app/lish/subscribeToPublication";
77+import { subscribeToPublication } from "app/(app)/lish/subscribeToPublication";
88import { isOAuthSessionError, OAuthErrorMessage } from "components/OAuthError";
99import { useToaster } from "components/Toast";
1010import { DotLoader } from "components/utils/DotLoader";
+2-2
components/ThemeManager/PubThemeSetter.tsx
···11import {
22 usePublicationData,
33 useNormalizedPublicationRecord,
44-} from "app/lish/[did]/[publication]/dashboard/PublicationSWRProvider";
44+} from "app/(app)/lish/[did]/[publication]/dashboard/PublicationSWRProvider";
55import { useState } from "react";
66import { pickers, SectionArrow } from "./ThemeSetter";
77import { PubLeafletThemeBackgroundImage } from "lexicons/api";
···99import { useLocalPubTheme } from "./PublicationThemeProvider";
1010import { BaseThemeProvider, CardBorderHiddenContext } from "./ThemeProvider";
1111import { blobRefToSrc } from "src/utils/blobRefToSrc";
1212-import { updatePublicationTheme } from "app/lish/createPub/updatePublication";
1212+import { updatePublicationTheme } from "app/(app)/lish/createPub/updatePublication";
1313import { PagePickers } from "./PubPickers/PubTextPickers";
1414import { BackgroundPicker } from "./PubPickers/PubBackgroundPickers";
1515import { PubAccentPickers } from "./PubPickers/PubAcccentPickers";
···88import {
99 usePublicationData,
1010 useNormalizedPublicationRecord,
1111-} from "app/lish/[did]/[publication]/dashboard/PublicationSWRProvider";
1111+} from "app/(app)/lish/[did]/[publication]/dashboard/PublicationSWRProvider";
1212import { blobRefToSrc } from "src/utils/blobRefToSrc";
1313import { PubThemeDefaults } from "./themeDefaults";
1414
+1-1
contexts/DocumentContext.tsx
···11"use client";
22import { createContext, useContext } from "react";
33-import type { PostPageData } from "app/lish/[did]/[publication]/[rkey]/getPostPageData";
33+import type { PostPageData } from "app/(app)/lish/[did]/[publication]/[rkey]/getPostPageData";
4455// Derive types from PostPageData
66type NonNullPostPageData = NonNullable<PostPageData>;
+19
middleware.ts
···4747 if (!ua) return false;
4848 return botUserAgentRegex.test(ua);
4949}
5050+function isMainSiteHost(hostname: string): boolean {
5151+ return (
5252+ hostname === "leaflet.pub" ||
5353+ hostname.startsWith("localhost") ||
5454+ hostname.startsWith("127.0.0.1") ||
5555+ hostname.endsWith(".vercel.app")
5656+ );
5757+}
5858+5059export default async function middleware(req: NextRequest) {
5160 let hostname = req.headers.get("host")!;
5261 if (req.nextUrl.pathname === auth_callback_route) return authCallback(req);
5362 if (req.nextUrl.pathname === receive_auth_callback_route)
5463 return receiveAuthCallback(req);
6464+6565+ if (req.nextUrl.pathname === "/" && isMainSiteHost(hostname)) {
6666+ let hasAuth =
6767+ req.cookies.has("auth_token") || req.cookies.has("external_auth_token");
6868+ if (hasAuth) {
6969+ let navState = req.cookies.get("nav-state")?.value;
7070+ let target = navState === "reader" ? "/reader" : "/home";
7171+ return NextResponse.redirect(new URL(target, req.url));
7272+ }
7373+ }
55745675 if (hostname === "leaflet.pub") return;
5776 if (req.nextUrl.pathname === "/not-found") return;
+1-1
src/mergeIdentity.ts
···1111} from "drizzle/schema";
1212import { pool } from "supabase/pool";
1313import { Err, Ok, type Result } from "src/result";
1414-import { backfillAtprotoSubscriptionsForIdentity } from "app/lish/subscribeToPublication";
1414+import { backfillAtprotoSubscriptionsForIdentity } from "app/(app)/lish/subscribeToPublication";
15151616export type MergeError =
1717 | "merge_not_pending"
+1-1
src/notifications.ts
···33import { supabaseServerClient } from "supabase/serverClient";
44import { Tables, TablesInsert } from "supabase/database.types";
55import { AtUri } from "@atproto/syntax";
66-import { idResolver } from "app/(home-pages)/reader/idResolver";
66+import { idResolver } from "app/(app)/(home-pages)/reader/idResolver";
77import {
88 normalizeDocumentRecord,
99 normalizePublicationRecord,