0.3.3 外网下载修复
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
} from "@/components/ui/sheet";
|
||||
import { clamp, MIN_AGENT_STEPS, MAX_AGENT_STEPS } from "@/lib/constants";
|
||||
|
||||
type AgentMessage = { role: "user" | "assistant"; content: string };
|
||||
|
||||
@@ -79,8 +80,6 @@ type ChatSession = {
|
||||
|
||||
type PanelPage = "chat" | "tools" | "history" | "account" | "settings";
|
||||
|
||||
const clamp = (n: number, min: number, max: number) => Math.max(min, Math.min(max, n));
|
||||
|
||||
const generateId = () => {
|
||||
if (typeof crypto !== "undefined" && "randomUUID" in crypto) return crypto.randomUUID();
|
||||
return `sess_${Math.random().toString(16).slice(2, 10)}`;
|
||||
@@ -194,8 +193,8 @@ export function DocumentAiAgentPanel({
|
||||
const p = (window.localStorage.getItem("doc_ai_provider") || "").trim();
|
||||
const m = window.localStorage.getItem("doc_ai_model") || "";
|
||||
const parsed = Number(stepsRaw);
|
||||
if (Number.isFinite(parsed) && parsed >= 1) {
|
||||
setMaxSteps(Math.max(1, Math.min(24, Math.floor(parsed))));
|
||||
if (Number.isFinite(parsed) && parsed >= MIN_AGENT_STEPS) {
|
||||
setMaxSteps(clamp(Math.floor(parsed), MIN_AGENT_STEPS, MAX_AGENT_STEPS));
|
||||
}
|
||||
if (p === "local" || p === "online") setAiProvider(p);
|
||||
if (typeof m === "string") setAiModel(m);
|
||||
@@ -270,7 +269,7 @@ export function DocumentAiAgentPanel({
|
||||
// ignore
|
||||
}
|
||||
// 只在 documentId 变化时读取一次
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
}, [documentId]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -688,14 +687,14 @@ export function DocumentAiAgentPanel({
|
||||
<input
|
||||
className="w-[72px] rounded border px-2 py-1 text-xs"
|
||||
type="number"
|
||||
min={1}
|
||||
max={24}
|
||||
min={MIN_AGENT_STEPS}
|
||||
max={MAX_AGENT_STEPS}
|
||||
step={1}
|
||||
value={maxSteps}
|
||||
onChange={(e) => {
|
||||
const v = Number(e.target.value);
|
||||
if (!Number.isFinite(v)) return;
|
||||
setMaxSteps(Math.max(1, Math.min(24, Math.floor(v))));
|
||||
setMaxSteps(clamp(Math.floor(v), MIN_AGENT_STEPS, MAX_AGENT_STEPS));
|
||||
}}
|
||||
disabled={loading}
|
||||
/>
|
||||
|
||||
@@ -23,11 +23,12 @@ import { CustomSideMenu } from "./menus/CustomSideMenu";
|
||||
import { CustomSlashMenu } from "./menus/CustomSlashMenu";
|
||||
import { MoveEmbedPickerHost } from "@/components/documents/move-embed-picker-host";
|
||||
import { useDebouncedCallback } from "@/hooks/use-debounced-callback";
|
||||
import { DocumentToc, type TocEntry } from "@/components/editor/document-toc";
|
||||
import { DocumentToc, type TocEntry } from "@/components/editor/document-toc";
|
||||
import { useSearchPaletteStore } from "@/store/search-palette";
|
||||
import { useEditorBridgeStore } from "@/store/editor-bridge";
|
||||
import type { ReferenceTarget } from "@/types/search";
|
||||
import FullScreenTableEditor from "@/components/online-table/FullScreenTableEditor";
|
||||
import { clamp, MIN_BLOCK_LEVEL, MAX_BLOCK_LEVEL } from "@/lib/constants";
|
||||
import { ASSETS_CHANGED_EVENT, emitAssetsChanged } from "@/lib/events";
|
||||
|
||||
interface BlockNoteEditorProps {
|
||||
@@ -64,7 +65,7 @@ const buildHeadingToc = (blocks: Block<CustomBlockSchema>[]): TocEntry[] => {
|
||||
const walk = (targetBlocks: Block<CustomBlockSchema>[]) => {
|
||||
targetBlocks.forEach((block) => {
|
||||
if (block.type === "heading") {
|
||||
const level = Math.min(5, Math.max(1, Number(block.props.level) || 1));
|
||||
const level = clamp(Number(block.props.level) || 1, MIN_BLOCK_LEVEL, MAX_BLOCK_LEVEL);
|
||||
counters[level - 1] += 1;
|
||||
for (let i = level; i < counters.length; i += 1) {
|
||||
counters[i] = 0;
|
||||
|
||||
@@ -656,9 +656,6 @@ const MediaBlockContent = ({ block, editor }: any) => {
|
||||
>
|
||||
查看原文件
|
||||
</DropdownMenuItem>
|
||||
{assetType === "file" && isOfficeDoc && (
|
||||
<DropdownMenuItem onClick={() => void openWithOnlyOffice()}>使用 ONLYOFFICE 打开</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
void downloadAsset();
|
||||
|
||||
@@ -273,7 +273,7 @@ export function MindmapAiAgentPanel({
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
}, [mindmapId]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -2502,8 +2502,8 @@ const MindmapBlockView = ({
|
||||
const handleImageConfirm = async () => {
|
||||
const url = imageUrl.trim();
|
||||
// 获取原始图片尺寸,如果没有则使用默认值
|
||||
let width = Number(imageWidth) || 0;
|
||||
let height = Number(imageHeight) || 0;
|
||||
const width = Number(imageWidth) || 0;
|
||||
const height = Number(imageHeight) || 0;
|
||||
|
||||
if (!url) {
|
||||
window.alert("请输入图片链接");
|
||||
|
||||
@@ -14,6 +14,7 @@ import { useDebouncedCallback } from "@/hooks/use-debounced-callback";
|
||||
import { ImagePickerProvider } from "@/components/media/image-picker-context";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { DocumentAiAgentPanel } from "./DocumentAiAgentPanel";
|
||||
import { CONTENT_LOADING_DELAY_MS } from "@/lib/constants";
|
||||
|
||||
const BlockNoteEditor = dynamic(
|
||||
() => import("@/components/editor/blocknote-editor").then((mod) => mod.BlockNoteEditor),
|
||||
@@ -96,7 +97,7 @@ export function DocumentContent({
|
||||
}
|
||||
}, [documentId, editorBridge, openTableId, router]);
|
||||
|
||||
/* eslint-disable react-hooks/set-state-in-effect */
|
||||
|
||||
useEffect(() => {
|
||||
setPageTitle(title ?? "无标题");
|
||||
}, [title]);
|
||||
@@ -108,7 +109,7 @@ export function DocumentContent({
|
||||
useEffect(() => {
|
||||
setStats(initialStats ?? defaultStats);
|
||||
}, [initialStats]);
|
||||
/* eslint-enable react-hooks/set-state-in-effect */
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let canceled = false;
|
||||
@@ -128,12 +129,12 @@ export function DocumentContent({
|
||||
clearTimeout(contentLoadingTimerRef.current);
|
||||
contentLoadingTimerRef.current = null;
|
||||
}
|
||||
// 避免“秒闪”的加载提示:只有当加载超过短阈值时才显示提示
|
||||
// 避免"秒闪"的加载提示:只有当加载超过短阈值时才显示提示
|
||||
contentLoadingTimerRef.current = setTimeout(() => {
|
||||
if (!canceled) {
|
||||
setShowContentLoadingIndicator(true);
|
||||
}
|
||||
}, 200);
|
||||
}, CONTENT_LOADING_DELAY_MS);
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/documents/content?documentId=${encodeURIComponent(documentId)}`, {
|
||||
|
||||
Reference in New Issue
Block a user