@bbki.ng/site 0.0.49 → 0.0.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/package.json +2 -2
- package/src/app.tsx +8 -26
- package/src/components/ImageUploader.tsx +51 -0
- package/src/components/with_wrapper/index.tsx +15 -0
- package/src/pages/extensions/png/png_projects.tsx +8 -27
- package/src/pages/upload/index.tsx +37 -0
- package/src/types/upload.ts +16 -0
- package/src/utils/index.ts +4 -0
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bbki.ng/site",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.50",
|
|
4
4
|
"description": "code behind bbki.ng",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"url": "git+https://github.com/bbbottle/bbki.ng.git"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@bbki.ng/components": "workspace:2.1.
|
|
19
|
+
"@bbki.ng/components": "workspace:2.1.28",
|
|
20
20
|
"@supabase/supabase-js": "^1.30.6",
|
|
21
21
|
"classnames": "2.3.1",
|
|
22
22
|
"react": "^18.0.0",
|
package/src/app.tsx
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import React, { useContext } from "react";
|
|
2
2
|
import { Routes, Route, Outlet } from "react-router-dom";
|
|
3
|
-
import {
|
|
4
|
-
Nav,
|
|
5
|
-
Page,
|
|
6
|
-
ThreeColLayout,
|
|
7
|
-
NotFound,
|
|
8
|
-
ErrorBoundary,
|
|
9
|
-
} from "@bbki.ng/components";
|
|
3
|
+
import { Nav, Page, NotFound } from "@bbki.ng/components";
|
|
10
4
|
import { HotKeyNav, Stickers } from "./components";
|
|
5
|
+
import { threeColWrapper } from "@/components/with_wrapper";
|
|
11
6
|
import { Cover } from "./pages";
|
|
12
7
|
|
|
13
8
|
import Png from "@/pages/extensions/png";
|
|
@@ -25,7 +20,7 @@ import {
|
|
|
25
20
|
GlobalLoadingContext,
|
|
26
21
|
GlobalLoadingStateProvider,
|
|
27
22
|
} from "@/global_loading_state_provider";
|
|
28
|
-
import {
|
|
23
|
+
import { UploadPage } from "@/pages/upload";
|
|
29
24
|
|
|
30
25
|
const Layout = () => {
|
|
31
26
|
const { isLoading } = useContext(GlobalLoadingContext);
|
|
@@ -42,20 +37,6 @@ const Layout = () => {
|
|
|
42
37
|
);
|
|
43
38
|
};
|
|
44
39
|
|
|
45
|
-
const threeColWrapper =
|
|
46
|
-
<T extends object>(Component: any) =>
|
|
47
|
-
(props: T) => {
|
|
48
|
-
return (
|
|
49
|
-
<ThreeColLayout
|
|
50
|
-
middleRenderer={() => (
|
|
51
|
-
<ErrorBoundary>
|
|
52
|
-
<Component {...props} />
|
|
53
|
-
</ErrorBoundary>
|
|
54
|
-
)}
|
|
55
|
-
/>
|
|
56
|
-
);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
40
|
const NowInMidCol = threeColWrapper(NowPage);
|
|
60
41
|
const ContentInMidCol = threeColWrapper(Txt);
|
|
61
42
|
const ArticleInMidCol = threeColWrapper(ArticlePage);
|
|
@@ -73,18 +54,19 @@ export const App = () => {
|
|
|
73
54
|
<Routes>
|
|
74
55
|
<Route path="/" element={<Layout />}>
|
|
75
56
|
<Route index element={<CoverInMidCol />} />
|
|
57
|
+
|
|
76
58
|
<Route path="/projects" element={<Png />} />
|
|
77
59
|
<Route path="/projects/:id" element={<PhotoProjects />} />
|
|
78
60
|
|
|
79
|
-
<Route path="now" element={<NowInMidCol />} />
|
|
80
|
-
<Route path="tags" element={<TagsInMidCol />} />
|
|
81
|
-
<Route path="tags/:tag" element={<TagsResultInMidCol />} />
|
|
82
|
-
|
|
83
61
|
<Route path="blog" element={<ContentInMidCol />} />
|
|
84
62
|
<Route path="blog/:title" element={<ArticleInMidCol />} />
|
|
85
63
|
<Route path="blog/:title/:id" element={<PhotoProjects />} />
|
|
64
|
+
<Route path="tags" element={<TagsInMidCol />} />
|
|
65
|
+
<Route path="tags/:tag" element={<TagsResultInMidCol />} />
|
|
86
66
|
|
|
67
|
+
<Route path="now" element={<NowInMidCol />} />
|
|
87
68
|
<Route path="login" element={<LoginInMidCol />} />
|
|
69
|
+
<Route path="upload" element={<UploadPage />} />
|
|
88
70
|
</Route>
|
|
89
71
|
<Route path="*" element={<NotFound />} />
|
|
90
72
|
</Routes>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { useContext } from "react";
|
|
2
|
+
import { DropImage } from "@bbki.ng/components";
|
|
3
|
+
import { AuthRequired } from "@/auth_required";
|
|
4
|
+
import { useUploader } from "@/hooks/use_uploader";
|
|
5
|
+
import { ImageUploaderProps } from "@/types/upload";
|
|
6
|
+
import { GlobalLoadingContext } from "@/global_loading_state_provider";
|
|
7
|
+
|
|
8
|
+
export const ImageUploader = (props: ImageUploaderProps) => {
|
|
9
|
+
const {
|
|
10
|
+
onUploadFinish,
|
|
11
|
+
onUploadError = () => {},
|
|
12
|
+
onUploadSuccess = () => {},
|
|
13
|
+
onBeforeUpload = () => Promise.resolve(),
|
|
14
|
+
projectId,
|
|
15
|
+
projectName,
|
|
16
|
+
...rest
|
|
17
|
+
} = props;
|
|
18
|
+
|
|
19
|
+
const { setIsLoading } = useContext(GlobalLoadingContext);
|
|
20
|
+
const uploader = useUploader();
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<AuthRequired shouldBeKing>
|
|
24
|
+
<DropImage
|
|
25
|
+
{...rest}
|
|
26
|
+
className="mb-256"
|
|
27
|
+
onUploadFinish={onUploadFinish}
|
|
28
|
+
uploader={async (file) => {
|
|
29
|
+
await onBeforeUpload();
|
|
30
|
+
setIsLoading(true);
|
|
31
|
+
try {
|
|
32
|
+
const res = await uploader(
|
|
33
|
+
projectId || "",
|
|
34
|
+
projectName || "",
|
|
35
|
+
file
|
|
36
|
+
);
|
|
37
|
+
await onUploadSuccess(res);
|
|
38
|
+
return setIsLoading(false);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
setIsLoading(false);
|
|
41
|
+
onUploadError();
|
|
42
|
+
console.error(e, "failed to upload image.");
|
|
43
|
+
}
|
|
44
|
+
}}
|
|
45
|
+
ghost
|
|
46
|
+
>
|
|
47
|
+
{() => null}
|
|
48
|
+
</DropImage>
|
|
49
|
+
</AuthRequired>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { FunctionComponent } from "react";
|
|
3
3
|
import { ArticlePage } from "@/components/article";
|
|
4
|
+
import { ThreeColLayout, ErrorBoundary } from "@bbki.ng/components";
|
|
4
5
|
|
|
5
6
|
export const withArticleWrapper =
|
|
6
7
|
(Component: FunctionComponent<any>): FunctionComponent<any> =>
|
|
@@ -11,3 +12,17 @@ export const withArticleWrapper =
|
|
|
11
12
|
</ArticlePage>
|
|
12
13
|
);
|
|
13
14
|
};
|
|
15
|
+
|
|
16
|
+
export const threeColWrapper =
|
|
17
|
+
<T extends object>(Component: any) =>
|
|
18
|
+
(props: T) => {
|
|
19
|
+
return (
|
|
20
|
+
<ThreeColLayout
|
|
21
|
+
middleRenderer={() => (
|
|
22
|
+
<ErrorBoundary>
|
|
23
|
+
<Component {...props} />
|
|
24
|
+
</ErrorBoundary>
|
|
25
|
+
)}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
2
|
import { MySuspense } from "@/components";
|
|
3
3
|
import { useParams } from "react-router-dom";
|
|
4
4
|
import { useProjects } from "@/hooks/use_projects";
|
|
5
|
-
import { AuthRequired } from "@/auth_required";
|
|
6
5
|
import { imageFormatter } from "@/utils";
|
|
7
|
-
import {
|
|
8
|
-
import { useUploader } from "@/hooks/use_uploader";
|
|
9
|
-
import { GlobalLoadingContext } from "@/global_loading_state_provider";
|
|
6
|
+
import { Gallery, Nav } from "@bbki.ng/components";
|
|
10
7
|
import { usePaths } from "@/hooks";
|
|
8
|
+
import { ImageUploader } from "@/components/ImageUploader";
|
|
11
9
|
|
|
12
10
|
const ProjectDetail = () => {
|
|
13
11
|
const { id } = useParams();
|
|
14
|
-
const { setIsLoading } = useContext(GlobalLoadingContext);
|
|
15
|
-
const uploader = useUploader();
|
|
16
12
|
const { projects, refresh } = useProjects(id, true);
|
|
17
13
|
|
|
18
14
|
useEffect(() => {
|
|
@@ -22,26 +18,11 @@ const ProjectDetail = () => {
|
|
|
22
18
|
}, []);
|
|
23
19
|
|
|
24
20
|
const renderUploader = () => (
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
await refresh();
|
|
31
|
-
}}
|
|
32
|
-
uploader={async (file) => {
|
|
33
|
-
setIsLoading(true);
|
|
34
|
-
try {
|
|
35
|
-
return await uploader(projects.id || "", id || "", file);
|
|
36
|
-
} catch (e) {
|
|
37
|
-
console.error(e, "failed to upload image.");
|
|
38
|
-
}
|
|
39
|
-
}}
|
|
40
|
-
ghost
|
|
41
|
-
>
|
|
42
|
-
{() => null}
|
|
43
|
-
</DropImage>
|
|
44
|
-
</AuthRequired>
|
|
21
|
+
<ImageUploader
|
|
22
|
+
onUploadFinish={refresh}
|
|
23
|
+
projectId={projects.id}
|
|
24
|
+
projectName={id}
|
|
25
|
+
/>
|
|
45
26
|
);
|
|
46
27
|
|
|
47
28
|
return (
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { ArticlePage } from "@/components/article";
|
|
3
|
+
import { threeColWrapper } from "@/components/with_wrapper";
|
|
4
|
+
import { ImageUploader } from "@/components/ImageUploader";
|
|
5
|
+
import { UploadResult } from "@/types/upload";
|
|
6
|
+
import { Button } from "@bbki.ng/components";
|
|
7
|
+
import { copyToClipboard } from "@/utils";
|
|
8
|
+
|
|
9
|
+
const Upload = () => {
|
|
10
|
+
const [source, setSource] = useState("");
|
|
11
|
+
const buildSource = (result: UploadResult) =>
|
|
12
|
+
`<Img
|
|
13
|
+
src="${result.src}"
|
|
14
|
+
height={${result.height}}
|
|
15
|
+
width={${result.width}}
|
|
16
|
+
renderedWidth={${result.width}}
|
|
17
|
+
removeBlurBgAfterLoad
|
|
18
|
+
/>`;
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<ArticlePage title="图片素材上传">
|
|
22
|
+
<>
|
|
23
|
+
<ImageUploader
|
|
24
|
+
onUploadSuccess={(res) => {
|
|
25
|
+
setSource(buildSource(res));
|
|
26
|
+
}}
|
|
27
|
+
/>
|
|
28
|
+
{source && <pre>{source}</pre>}
|
|
29
|
+
<Button className="m-16" onClick={() => copyToClipboard(source)}>
|
|
30
|
+
复制代码
|
|
31
|
+
</Button>
|
|
32
|
+
</>
|
|
33
|
+
</ArticlePage>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const UploadPage = threeColWrapper(Upload);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ImageDropProps } from "@bbki.ng/components/lib";
|
|
2
|
+
|
|
3
|
+
export type UploadResult = {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
src: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export interface ImageUploaderProps
|
|
10
|
+
extends Pick<ImageDropProps<undefined>, "onUploadFinish" | "placeholder"> {
|
|
11
|
+
onBeforeUpload?: () => void;
|
|
12
|
+
onUploadError?: () => void;
|
|
13
|
+
onUploadSuccess?: (res: UploadResult) => void;
|
|
14
|
+
projectId?: string;
|
|
15
|
+
projectName?: string;
|
|
16
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -141,3 +141,7 @@ export const getRandomInt = (min: number, max: number) => {
|
|
|
141
141
|
max = Math.floor(max);
|
|
142
142
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
143
143
|
};
|
|
144
|
+
|
|
145
|
+
export const copyToClipboard = async (value: string) => {
|
|
146
|
+
await navigator.clipboard.writeText(value);
|
|
147
|
+
};
|