Skip to content

Commit

Permalink
feat: Text file saving & fix(pdf-viewer): Promise.withResolvers is …
Browse files Browse the repository at this point in the history
…not a function (wojtekmaj/react-pdf#1811)
  • Loading branch information
NriotHrreion committed Aug 5, 2024
1 parent bd59593 commit 1eaecbd
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 7 deletions.
4 changes: 3 additions & 1 deletion app/(pages)/explorer/viewer/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"use client";

import React, { useEffect } from "react";
import dynamic from "next/dynamic";
import { toast } from "react-toastify";

import { parseStringPath, useExplorer } from "@/hooks/useExplorer";
Expand All @@ -15,7 +16,8 @@ import TextViewer from "@/components/viewers/text-viewer";
import ImageViewer from "@/components/viewers/image-viewer";
import VideoViewer from "@/components/viewers/video-viewer";
import AudioViewer from "@/components/viewers/audio-viewer";
import PDFViewer from "@/components/viewers/pdf-viewer";
/** @see https://github.com/wojtekmaj/react-pdf/issues/1811#issuecomment-2151416080 */
const PDFViewer = dynamic(() => import("@/components/viewers/pdf-viewer"), { ssr: false }) as typeof React.Component<ViewerProps>;

export function getViewer(type: string): typeof React.Component<ViewerProps> | null {
switch(type) {
Expand Down
30 changes: 30 additions & 0 deletions app/api/fs/file/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,33 @@ export async function GET(req: NextRequest) {
return error(500);
}
}

export async function PATCH(req: NextRequest) {
const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
if(!validateToken(token)) return error(403);

const { searchParams } = new URL(req.url);
const targetPath = searchParams.get("path") ?? "/";
const content = (await req.formData()).get("content");

if(!content) error(400);

try {
if(!targetPath || !fs.existsSync(targetPath)) return error(404);

const stat = fs.statSync(targetPath);

if(!stat.isFile()) return error(400);

fs.writeFileSync(targetPath, content?.toString() ?? "");

return packet({});
} catch (err) {
// eslint-disable-next-line no-console
console.log("[Server: /api/fs/file] "+ err);

return error(500);
}
}
38 changes: 36 additions & 2 deletions components/viewers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,42 @@ export default abstract class Viewer<P extends ViewerProps, S = {}> extends Reac
}
}

/** @todo */
protected async saveFile() {}
protected async saveFile(data: string) {
try {
const { status } = await axios.patch(
`/api/fs/file?path=${this.props.path}`,
{ content: data },
{
headers: {
"Content-Type": "multipart/form-data"
}
}
);

if(status === 200) toast.success("保存成功");
} catch (_err) {
const err = _err as AxiosError;
const status = err.response?.status ?? 0;

switch(status) {
case 400:
toast.error(`该路径或请求无效 (${status})`);
break;
case 401:
toast.error(`未登录 (${status})`);
break;
case 403:
toast.error(`无效的访问token (${status})`);
break;
case 404:
toast.error(`找不到该文件 (${status})`);
break;
case 500:
toast.error(`服务器内部错误 (${status})`);
break;
}
}
}

public componentDidMount() {
document.title = this.name +" - "+ this.props.path;
Expand Down
2 changes: 1 addition & 1 deletion components/viewers/text-viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default class TextViewer extends Viewer<TextViewerProps, TextViewerState>
}

private async handleSave() {
await this.saveFile();
await this.saveFile(this.state.value);
this.setState({ edited: false });
}

Expand Down
3 changes: 0 additions & 3 deletions components/viewers/video-viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ interface VideoViewerState {
}

export default class VideoViewer extends Viewer<VideoViewerProps, VideoViewerState> {
private readonly isFlv: boolean;
private blob: Blob = new Blob();
private videoRef = React.createRef<HTMLVideoElement>();

Expand All @@ -42,8 +41,6 @@ export default class VideoViewer extends Viewer<VideoViewerProps, VideoViewerSta
duration: 0,
currentTime: 0
};

this.isFlv = this.props.fileName.split(".").findLast(() => true) === "flv";
}

private handlePlayButtonClick() {
Expand Down

0 comments on commit 1eaecbd

Please sign in to comment.