后台单页和公告改为正文优先编辑,保存与发布分开。

列表按列对照真实路径和状态,避免把 /p/ 前缀和发布操作混在一起。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-20 01:07:21 +08:00
parent 40bbad2c82
commit 803b694659
15 changed files with 1611 additions and 473 deletions

View File

@@ -145,6 +145,36 @@ export default function MarkdownEditor({
null
);
const savedSel = useRef<{ start: number; end: number } | null>(null);
const fullscreenMounted = useRef(false);
const rememberCaret = () => {
const el = taRef.current;
if (!el) return;
savedSel.current = { start: el.selectionStart, end: el.selectionEnd };
};
const toggleFullscreen = () => {
rememberCaret();
setFullscreen((v) => !v);
};
useEffect(() => {
if (!fullscreenMounted.current) {
fullscreenMounted.current = true;
return;
}
if (mode !== "write") return;
const sel = savedSel.current;
const el = taRef.current;
if (!el || !sel) return;
// 进出全屏后把焦点和光标放回退出前的位置
const frame = requestAnimationFrame(() => {
el.focus();
const max = el.value.length;
el.setSelectionRange(Math.min(sel.start, max), Math.min(sel.end, max));
});
return () => cancelAnimationFrame(frame);
}, [fullscreen]);
useEffect(() => {
if (!fullscreen) return;
@@ -152,7 +182,10 @@ export default function MarkdownEditor({
if (e.key === "Escape") {
e.preventDefault();
if (popover) setPopover(null);
else setFullscreen(false);
else {
rememberCaret();
setFullscreen(false);
}
}
};
const prev = document.body.style.overflow;
@@ -452,6 +485,8 @@ export default function MarkdownEditor({
const onTextareaKeyDown = (e: ReactKeyboardEvent<HTMLTextAreaElement>) => {
if ((e.ctrlKey || e.metaKey) && e.key === "Enter") {
// 输入法组字期间的 Enter 不是提交
if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return;
e.preventDefault();
onSubmitShortcut?.();
return;
@@ -954,7 +989,8 @@ export default function MarkdownEditor({
className="j13-md-tool"
data-tip={fullscreen ? "退出全屏 (Esc)" : "全屏写作"}
aria-label={fullscreen ? "退出全屏" : "全屏写作"}
onClick={() => setFullscreen((v) => !v)}
onMouseDown={(e) => e.preventDefault()}
onClick={toggleFullscreen}
>
{fullscreen ? <Minimize2 size={15} /> : <Maximize2 size={15} />}
</button>