Skip to content

Commit 7fb7198

Browse files
feat: add mapImageUrl config option
1 parent dae11b1 commit 7fb7198

File tree

7 files changed

+58
-41
lines changed

7 files changed

+58
-41
lines changed

src/block.tsx

+16-13
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,14 @@ import {
44
BlockType,
55
ContentValueType,
66
BlockMapType,
7-
MapPageUrl
7+
MapPageUrl,
8+
MapImageUrl
89
} from "./types";
910
import Asset from "./components/asset";
1011
import Code from "./components/code";
1112
import PageIcon from "./components/page-icon";
1213
import PageHeader from "./components/page-header";
13-
import {
14-
classNames,
15-
getTextContent,
16-
getListNumber,
17-
toNotionImageUrl
18-
} from "./utils";
14+
import { classNames, getTextContent, getListNumber } from "./utils";
1915

2016
export const renderChildText = (properties: DecorationType[]) => {
2117
return properties?.map(([text, decorations], i) => {
@@ -62,6 +58,7 @@ interface Block {
6258
level: number;
6359
blockMap: BlockMapType;
6460
mapPageUrl: MapPageUrl;
61+
mapImageUrl: MapImageUrl;
6562

6663
fullPage?: boolean;
6764
zoom?: any;
@@ -75,7 +72,8 @@ export const Block: React.FC<Block> = props => {
7572
fullPage,
7673
blockMap,
7774
zoom,
78-
mapPageUrl
75+
mapPageUrl,
76+
mapImageUrl
7977
} = props;
8078
const blockValue = block?.value;
8179

@@ -101,12 +99,16 @@ export const Block: React.FC<Block> = props => {
10199
<div className="notion notion-app">
102100
<div className="notion-cursor-listener">
103101
<div className="notion-frame">
104-
<PageHeader blockMap={blockMap} mapPageUrl={mapPageUrl} />
102+
<PageHeader
103+
blockMap={blockMap}
104+
mapPageUrl={mapPageUrl}
105+
mapImageUrl={mapImageUrl}
106+
/>
105107

106108
<div className="notion-scroller">
107109
{page_cover && (
108110
<img
109-
src={toNotionImageUrl(page_cover)}
111+
src={mapImageUrl(page_cover)}
110112
alt={getTextContent(blockValue.properties.title)}
111113
className="notion-page-cover"
112114
style={{
@@ -129,6 +131,7 @@ export const Block: React.FC<Block> = props => {
129131
}
130132
block={block}
131133
big
134+
mapImageUrl={mapImageUrl}
132135
/>
133136
)}
134137

@@ -152,7 +155,7 @@ export const Block: React.FC<Block> = props => {
152155
<a className="notion-page-link" href={mapPageUrl(blockValue.id)}>
153156
{blockValue.format && (
154157
<div className="notion-page-icon">
155-
<PageIcon block={block} />
158+
<PageIcon block={block} mapImageUrl={mapImageUrl} />
156159
</div>
157160
)}
158161
<div className="notion-page-text">
@@ -243,7 +246,7 @@ export const Block: React.FC<Block> = props => {
243246
className="notion-asset-wrapper"
244247
style={{ width: value.format.block_width }}
245248
>
246-
<Asset block={block} zoom={zoom} />
249+
<Asset block={block} zoom={zoom} mapImageUrl={mapImageUrl} />
247250

248251
{value.properties.caption && (
249252
<figcaption className="notion-image-caption">
@@ -373,7 +376,7 @@ export const Block: React.FC<Block> = props => {
373376
)}
374377
>
375378
<div>
376-
<PageIcon block={block} />
379+
<PageIcon block={block} mapImageUrl={mapImageUrl} />
377380
</div>
378381
<div className="notion-callout-text">
379382
{renderChildText(blockValue.properties.title)}

src/components/asset.tsx

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import * as React from "react";
2-
import { BlockType, ContentValueType } from "../types";
3-
import { toNotionImageUrl } from "../utils";
2+
import { BlockType, ContentValueType, MapImageUrl } from "../types";
43

54
const types = ["video", "image", "embed"];
65

7-
const Asset: React.FC<{ block: BlockType; zoom?: any }> = ({ block, zoom }) => {
6+
const Asset: React.FC<{
7+
block: BlockType;
8+
mapImageUrl: MapImageUrl;
9+
zoom?: any;
10+
}> = ({ block, mapImageUrl, zoom }) => {
811
const zoomRef = React.useRef(zoom ? zoom.clone() : null);
912
const value = block.value as ContentValueType;
1013
const type = block.value.type;
@@ -36,7 +39,7 @@ const Asset: React.FC<{ block: BlockType; zoom?: any }> = ({ block, zoom }) => {
3639
);
3740
}
3841

39-
const src = toNotionImageUrl(value.properties.source[0][0]);
42+
const src = mapImageUrl(value.properties.source[0][0]);
4043

4144
function attachZoom(image: any) {
4245
if (zoomRef.current) {

src/components/page-header.tsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import * as React from "react";
22

3-
import { BlockMapType, MapPageUrl } from "../types";
3+
import { BlockMapType, MapPageUrl, MapImageUrl } from "../types";
44
import PageIcon from "./page-icon";
55

66
interface PageHeaderProps {
77
blockMap: BlockMapType;
88
mapPageUrl: MapPageUrl;
9+
mapImageUrl: MapImageUrl;
910
}
1011

11-
const PageHeader: React.FC<PageHeaderProps> = ({ blockMap, mapPageUrl }) => {
12+
const PageHeader: React.FC<PageHeaderProps> = ({
13+
blockMap,
14+
mapPageUrl,
15+
mapImageUrl
16+
}) => {
1217
const blockIds = Object.keys(blockMap);
1318
const activePageId = blockIds[0];
1419

@@ -69,6 +74,7 @@ const PageHeader: React.FC<PageHeaderProps> = ({ blockMap, mapPageUrl }) => {
6974
<PageIcon
7075
className="notion-nav-icon"
7176
block={breadcrumb.block}
77+
mapImageUrl={mapImageUrl}
7278
/>
7379
)}
7480

src/components/page-icon.tsx

+11-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import {
33
BlockType,
44
PageValueType,
55
BlockValueType,
6-
CalloutValueType
6+
CalloutValueType,
7+
MapImageUrl
78
} from "../types";
8-
import { toNotionImageUrl, getTextContent, classNames } from "../utils";
9+
import { getTextContent, classNames } from "../utils";
910

1011
const isIconBlock = (
1112
value: BlockValueType
@@ -15,19 +16,25 @@ const isIconBlock = (
1516

1617
interface AssetProps {
1718
block: BlockType;
19+
mapImageUrl: MapImageUrl;
1820
big?: boolean;
1921
className?: string;
2022
}
2123

22-
const PageIcon: React.FC<AssetProps> = ({ block, className, big }) => {
24+
const PageIcon: React.FC<AssetProps> = ({
25+
block,
26+
className,
27+
big,
28+
mapImageUrl
29+
}) => {
2330
if (!isIconBlock(block.value)) {
2431
return null;
2532
}
2633
const icon = block.value.format?.page_icon;
2734
const title = block.value.properties?.title;
2835

2936
if (icon?.includes("http")) {
30-
const url = toNotionImageUrl(icon);
37+
const url = mapImageUrl(icon);
3138

3239
return (
3340
<img

src/renderer.tsx

+7-13
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,25 @@
11
import React from "react";
22
import mediumZoom from "medium-zoom";
3-
import { BlockMapType, MapPageUrl } from "./types";
3+
import { BlockMapType, MapPageUrl, MapImageUrl } from "./types";
44
import { Block } from "./block";
5+
import { defaultMapImageUrl, defaultMapPageUrl } from "utils";
56

67
export interface NotionRendererProps {
78
blockMap: BlockMapType;
89
fullPage?: boolean;
910
mapPageUrl?: MapPageUrl;
10-
rootPageId?: string;
11+
mapImageUrl?: MapImageUrl;
1112

1213
currentId?: string;
1314
level?: number;
1415
zoom?: any;
1516
}
1617

17-
const defaultMapPageUrl = (rootPageId?: string) => (pageId = "") => {
18-
pageId = pageId.replace(/-/g, "");
19-
20-
if (rootPageId && pageId === rootPageId) {
21-
return "/";
22-
} else {
23-
return `/${pageId}`;
24-
}
25-
};
26-
2718
export const NotionRenderer: React.FC<NotionRendererProps> = ({
2819
level = 0,
2920
currentId,
21+
mapPageUrl = defaultMapPageUrl,
22+
mapImageUrl = defaultMapImageUrl,
3023
...props
3124
}) => {
3225
const { blockMap } = props;
@@ -40,7 +33,6 @@ export const NotionRenderer: React.FC<NotionRendererProps> = ({
4033
return null;
4134
}
4235

43-
const mapPageUrl = props.mapPageUrl || defaultMapPageUrl(props.rootPageId);
4436
const zoom =
4537
props.zoom ||
4638
(typeof window !== "undefined" &&
@@ -57,6 +49,7 @@ export const NotionRenderer: React.FC<NotionRendererProps> = ({
5749
block={currentBlock}
5850
zoom={zoom}
5951
mapPageUrl={mapPageUrl}
52+
mapImageUrl={mapImageUrl}
6053
{...props}
6154
>
6255
{currentBlock?.value?.content?.map(contentId => (
@@ -66,6 +59,7 @@ export const NotionRenderer: React.FC<NotionRendererProps> = ({
6659
level={level + 1}
6760
zoom={zoom}
6861
mapPageUrl={mapPageUrl}
62+
mapImageUrl={mapImageUrl}
6963
{...props}
7064
/>
7165
))}

src/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -322,3 +322,4 @@ export interface LoadPageChunkData {
322322
}
323323

324324
export type MapPageUrl = (pageId: string) => string;
325+
export type MapImageUrl = (image: string) => string;

src/utils.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,14 @@ export const getListNumber = (blockId: string, blockMap: BlockMapType) => {
4343
return group.indexOf(blockId) + 1;
4444
};
4545

46-
export const toNotionImageUrl = (url: string) => {
47-
const notionImageUrl = `https://www.notion.so${
48-
url.startsWith("/image") ? url : `/image/${encodeURIComponent(url)}`
46+
export const defaultMapImageUrl = (image: string = "") => {
47+
return `https://www.notion.so${
48+
image.startsWith("/image") ? image : `/image/${encodeURIComponent(image)}`
4949
}`;
50+
};
51+
52+
export const defaultMapPageUrl = (pageId: string = "") => {
53+
pageId = pageId.replace(/-/g, "");
5054

51-
// Our proxy uses Cloudflare's global CDN to cache these image assets
52-
return `https://ssfy.io/${encodeURIComponent(notionImageUrl)}`;
55+
return `/${pageId}`;
5356
};

0 commit comments

Comments
 (0)