diff --git a/app/lish/[did]/[publication]/PublicationPostItem.tsx b/app/lish/[did]/[publication]/PublicationPostItem.tsx
index 6c9d5975..5b47b0f8 100644
--- a/app/lish/[did]/[publication]/PublicationPostItem.tsx
+++ b/app/lish/[did]/[publication]/PublicationPostItem.tsx
@@ -8,6 +8,7 @@ type CommonProps = {
author?: React.ReactNode;
date?: React.ReactNode;
interactions?: React.ReactNode;
+ footer?: React.ReactNode;
};
type LargeProps = CommonProps & {
@@ -90,6 +91,7 @@ export function PublicationPostItemSmall(props: CommonProps) {
textClassName="text-sm"
/>
+ {props.footer}
>
);
@@ -126,6 +128,7 @@ export function PublicationPostItemMedium(props: MediumProps) {
)}
+ {props.footer}
>
);
@@ -177,6 +180,7 @@ export function PublicationPostItemLarge(props: LargeProps) {
)}
{body}
+ {props.footer}
>
);
diff --git a/app/lish/[did]/[publication]/[rkey]/PostContent.tsx b/app/lish/[did]/[publication]/[rkey]/PostContent.tsx
index fa40bf56..3c056487 100644
--- a/app/lish/[did]/[publication]/[rkey]/PostContent.tsx
+++ b/app/lish/[did]/[publication]/[rkey]/PostContent.tsx
@@ -8,7 +8,6 @@ import {
PubLeafletBlocksUnorderedList,
PubLeafletBlocksOrderedList,
PubLeafletBlocksWebsite,
- PubLeafletDocument,
PubLeafletPagesLinearDocument,
PubLeafletPagesCanvas,
PubLeafletBlocksHorizontalRule,
@@ -47,7 +46,7 @@ import { slugify } from "src/utils/slugify";
import { PostNotAvailable } from "components/Blocks/BlueskyPostBlock/BlueskyEmbed";
import { useIframeChannel } from "src/hooks/useIframeChannel";
import { usePubTheme } from "components/ThemeManager/PublicationThemeProvider";
-import { useDocument } from "contexts/DocumentContext";
+import { useDocument, useDocumentOptional } from "contexts/DocumentContext";
import { openPage as openPageAction } from "./postPageState";
import { CheckboxChecked } from "components/Icons/CheckboxChecked";
import { CheckboxEmpty } from "components/Icons/CheckboxEmpty";
@@ -155,6 +154,8 @@ export let Block = ({
isLast?: boolean;
}) => {
let b = block;
+ let currentPublicationUri =
+ useDocumentOptional()?.publication?.uri ?? null;
let blockProps = {
style: {
scrollMarginTop: "4rem",
@@ -250,7 +251,12 @@ export let Block = ({
: "small";
return (
-
+
);
}
diff --git a/components/Blocks/StandardSitePostBlock/StandardSitePostItem.tsx b/components/Blocks/StandardSitePostBlock/StandardSitePostItem.tsx
index c59c3b5f..a553e4cd 100644
--- a/components/Blocks/StandardSitePostBlock/StandardSitePostItem.tsx
+++ b/components/Blocks/StandardSitePostBlock/StandardSitePostItem.tsx
@@ -1,17 +1,23 @@
"use client";
import { AtUri } from "@atproto/api";
+import Link from "next/link";
import {
PublicationPostItemSmall,
PublicationPostItemMedium,
PublicationPostItemLarge,
} from "app/lish/[did]/[publication]/PublicationPostItem";
import { LocalizedDate } from "app/lish/[did]/[publication]/LocalizedDate";
-import { getDocumentURL } from "app/lish/createPub/getPublicationURL";
+import {
+ getDocumentURL,
+ getPublicationURL,
+} from "app/lish/createPub/getPublicationURL";
import { getFirstParagraph } from "src/utils/getFirstParagraph";
import { blobRefToSrc } from "src/utils/blobRefToSrc";
import { useStandardSitePost } from "components/StandardSitePostDataProvider";
import { useEntity, useReplicache } from "src/replicache";
import { InteractionPreview } from "components/InteractionsPreview";
+import { PubIcon } from "components/ActionBar/Publications";
+import { PublicationThemeProvider } from "components/ThemeManager/PublicationThemeProvider";
import type { StandardSitePostData } from "app/api/rpc/[command]/get_standard_site_posts";
export type StandardSitePostSize = "large" | "medium" | "small";
@@ -19,9 +25,13 @@ export type StandardSitePostSize = "large" | "medium" | "small";
export function StandardSitePostItem({
uri,
size = "medium",
+ showPubTheme = true,
+ currentPublicationUri,
}: {
uri: string;
size?: StandardSitePostSize;
+ showPubTheme?: boolean;
+ currentPublicationUri?: string | null;
}) {
const { data, isLoading } = useStandardSitePost(uri);
const { rootEntity } = useReplicache();
@@ -39,7 +49,41 @@ export function StandardSitePostItem({
);
}
- return ;
+ return (
+
+ );
+}
+
+export function WithStandardSitePostPublicationTheme({
+ post,
+ enabled,
+ children,
+}: {
+ post: StandardSitePostData;
+ enabled: boolean;
+ children: React.ReactNode;
+}) {
+ if (!enabled || !post.publication?.record?.theme) return <>{children}>;
+ let pubCreator: string;
+ try {
+ pubCreator = new AtUri(post.publication.uri).host;
+ } catch {
+ return <>{children}>;
+ }
+ return (
+
+ {children}
+
+ );
}
function StandardSitePostItemPlaceholder({
@@ -116,9 +160,13 @@ function StandardSitePostItemPlaceholder({
export function StandardSitePostItemView({
post,
size = "medium",
+ showPubTheme = true,
+ currentPublicationUri,
}: {
post: StandardSitePostData;
size?: StandardSitePostSize;
+ showPubTheme?: boolean;
+ currentPublicationUri?: string | null;
}) {
const docUrl = getDocumentURL(
post.record,
@@ -170,16 +218,26 @@ export function StandardSitePostItemView({
/>
);
+ const showPubFooter =
+ !!post.publication?.record &&
+ (!currentPublicationUri || post.publication.uri !== currentPublicationUri);
+
+ const pubFooter = showPubFooter && post.publication ? (
+
+ ) : null;
+
const commonProps = {
href: docUrl,
title: post.record.title,
author: authorLabel,
date,
interactions,
+ footer: pubFooter,
};
+ let item: React.ReactNode;
if (size === "large") {
- return (
+ item = (
);
- }
- if (size === "medium") {
- return (
+ } else if (size === "medium") {
+ item = (
);
+ } else {
+ item = ;
}
- return ;
+
+ return (
+
+ {item}
+
+ );
+}
+
+function PubFooter({
+ publication,
+}: {
+ publication: NonNullable;
+}) {
+ if (!publication.record) return null;
+ const pubUrl = getPublicationURL(publication);
+ return (
+
+
+ {publication.record.name}
+
+ );
}
diff --git a/components/Blocks/StandardSitePostBlock/index.tsx b/components/Blocks/StandardSitePostBlock/index.tsx
index 208787f4..93a817f8 100644
--- a/components/Blocks/StandardSitePostBlock/index.tsx
+++ b/components/Blocks/StandardSitePostBlock/index.tsx
@@ -2,11 +2,13 @@ import { BlockProps, BlockLayout } from "../Block";
import { useEntity, useReplicache } from "src/replicache";
import { useUIState } from "src/useUIState";
import { Popover } from "components/Popover";
+import { Toggle } from "components/Toggle";
import { SettingsTriggerButton } from "../SettingsTriggerButton";
import {
StandardSitePostItem,
type StandardSitePostSize,
} from "./StandardSitePostItem";
+import { useLeafletPublicationData } from "components/PageSWRDataProvider";
export const StandardSitePostBlock = (
props: BlockProps & { preview?: boolean },
@@ -17,6 +19,13 @@ export const StandardSitePostBlock = (
let uri = useEntity(props.entityID, "block/standard-site-post")?.data.value;
let sizeFact = useEntity(props.entityID, "standard-site-post/size");
let size: StandardSitePostSize = sizeFact?.data.value ?? "medium";
+ let showPubThemeFact = useEntity(
+ props.entityID,
+ "standard-site-post/show-publication-theme",
+ );
+ let showPubTheme = showPubThemeFact?.data.value !== false;
+ let editorPub = useLeafletPublicationData();
+ let currentPublicationUri = editorPub.data?.publications?.uri ?? null;
if (!uri) return null;
@@ -30,7 +39,12 @@ export const StandardSitePostBlock = (
}
>
-
+
);
};
@@ -39,6 +53,11 @@ function StandardSitePostSettingsButton(props: { entityID: string }) {
let { rep } = useReplicache();
let sizeFact = useEntity(props.entityID, "standard-site-post/size");
let size: StandardSitePostSize = sizeFact?.data.value ?? "medium";
+ let showPubThemeFact = useEntity(
+ props.entityID,
+ "standard-site-post/show-publication-theme",
+ );
+ let showPubTheme = showPubThemeFact?.data.value !== false;
return (
+
+ {
+ if (!rep) return;
+ rep.mutate.assertFact({
+ entity: props.entityID,
+ attribute: "standard-site-post/show-publication-theme",
+ data: { type: "boolean", value: !showPubTheme },
+ });
+ }}
+ >
+ Use Publication Theme
+
);
}
diff --git a/components/ThemeManager/ThemeProvider.tsx b/components/ThemeManager/ThemeProvider.tsx
index ce109b51..b66828cc 100644
--- a/components/ThemeManager/ThemeProvider.tsx
+++ b/components/ThemeManager/ThemeProvider.tsx
@@ -243,6 +243,7 @@ export const BaseThemeProvider = ({
// Dynamically load Google Fonts when fonts change
useEffect(() => {
+ if (local) return;
const loadGoogleFont = (url: string | null, fontFamily: string) => {
if (!url) return;
@@ -281,6 +282,7 @@ export const BaseThemeProvider = ({
loadGoogleFont(headingGoogleFontsUrl, headingFontConfig.fontFamily);
loadGoogleFont(bodyGoogleFontsUrl, bodyFontConfig.fontFamily);
}, [
+ local,
headingGoogleFontsUrl,
bodyGoogleFontsUrl,
headingFontConfig.fontFamily,
diff --git a/lexicons/api/lexicons.ts b/lexicons/api/lexicons.ts
index 3afca7b0..6cb98832 100644
--- a/lexicons/api/lexicons.ts
+++ b/lexicons/api/lexicons.ts
@@ -1609,6 +1609,9 @@ export const schemaDict = {
type: 'string',
knownValues: ['large', 'medium', 'small'],
},
+ showPublicationTheme: {
+ type: 'boolean',
+ },
},
},
},
diff --git a/lexicons/api/types/pub/leaflet/blocks/standardSitePost.ts b/lexicons/api/types/pub/leaflet/blocks/standardSitePost.ts
index 9f4d9e86..2de04fbb 100644
--- a/lexicons/api/types/pub/leaflet/blocks/standardSitePost.ts
+++ b/lexicons/api/types/pub/leaflet/blocks/standardSitePost.ts
@@ -19,6 +19,7 @@ export interface Main {
uri: string
cid?: string
size?: 'large' | 'medium' | 'small' | (string & {})
+ showPublicationTheme?: boolean
}
const hashMain = 'main'
diff --git a/lexicons/pub/leaflet/blocks/standardSitePost.json b/lexicons/pub/leaflet/blocks/standardSitePost.json
index d88f57bb..0febeaa5 100644
--- a/lexicons/pub/leaflet/blocks/standardSitePost.json
+++ b/lexicons/pub/leaflet/blocks/standardSitePost.json
@@ -22,6 +22,9 @@
"medium",
"small"
]
+ },
+ "showPublicationTheme": {
+ "type": "boolean"
}
}
}
diff --git a/lexicons/src/blocks.ts b/lexicons/src/blocks.ts
index 9ae64709..28baef5c 100644
--- a/lexicons/src/blocks.ts
+++ b/lexicons/src/blocks.ts
@@ -60,6 +60,7 @@ export const PubLeafletBlocksStandardSitePost: LexiconDoc = {
uri: { type: "string", format: "at-uri" },
cid: { type: "string" },
size: { type: "string", knownValues: ["large", "medium", "small"] },
+ showPublicationTheme: { type: "boolean" },
},
},
},
diff --git a/src/replicache/attributes.ts b/src/replicache/attributes.ts
index 37182432..a3b0a0a3 100644
--- a/src/replicache/attributes.ts
+++ b/src/replicache/attributes.ts
@@ -95,6 +95,10 @@ const BlockAttributes = {
type: "standard-site-post-size-union",
cardinality: "one",
},
+ "standard-site-post/show-publication-theme": {
+ type: "boolean",
+ cardinality: "one",
+ },
"block/math": {
type: "string",
cardinality: "one",
diff --git a/src/utils/factsToPagesRecord.ts b/src/utils/factsToPagesRecord.ts
index a6b2af67..dbc251fb 100644
--- a/src/utils/factsToPagesRecord.ts
+++ b/src/utils/factsToPagesRecord.ts
@@ -381,10 +381,17 @@ export async function processBlocksToPages(opts: {
const [uri] = scan.eav(b.value, "block/standard-site-post");
if (!uri) return;
const [sizeFact] = scan.eav(b.value, "standard-site-post/size");
+ const [showPubThemeFact] = scan.eav(
+ b.value,
+ "standard-site-post/show-publication-theme",
+ );
const block: $Typed = {
$type: ids.PubLeafletBlocksStandardSitePost,
uri: uri.data.value,
...(sizeFact && { size: sizeFact.data.value }),
+ ...(showPubThemeFact?.data.value === false && {
+ showPublicationTheme: false,
+ }),
};
return block;
}