feat: integrate pixel teacher presence and resilient classroom preview
This commit is contained in:
1 parent
12d800ec51
commit
7951cca700
60 files changed
+3313
-180
No files matched your search
@@ -0,0 +1,54 @@
|
||||
import { useRef } from 'react';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import {
|
||||
CLASSROOM_SIDEBAR_DEFAULT_WIDTH,
|
||||
CLASSROOM_SIDEBAR_MIN_WIDTH,
|
||||
CLASSROOM_SIDEBAR_MAX_WIDTH,
|
||||
normalizeClassroomSidebarWidth,
|
||||
} from '@/lib/classroom-layout';
|
||||
|
||||
export function ClassroomSidebarResizer() {
|
||||
const width = useSettingsStore((state) => normalizeClassroomSidebarWidth(state.classroomSidebarWidth));
|
||||
const setWidth = useSettingsStore((state) => state.setClassroomSidebarWidth);
|
||||
const drag = useRef<{ pointerId: number; x: number; width: number } | null>(null);
|
||||
return <div
|
||||
role="separator"
|
||||
aria-label="调整左侧功能栏宽度"
|
||||
aria-orientation="vertical"
|
||||
aria-controls="classroom-sidebar"
|
||||
aria-valuemin={CLASSROOM_SIDEBAR_MIN_WIDTH}
|
||||
aria-valuemax={CLASSROOM_SIDEBAR_MAX_WIDTH}
|
||||
aria-valuenow={width}
|
||||
aria-valuetext={`${width} 像素`}
|
||||
title="拖动调整宽度,双击恢复默认"
|
||||
tabIndex={0}
|
||||
className="no-drag absolute inset-y-0 right-0 z-10 w-1.5 cursor-col-resize touch-none select-none transition-colors hover:bg-[#82986755] focus-visible:bg-[#82986755] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[#71845f]"
|
||||
onDoubleClick={() => setWidth(CLASSROOM_SIDEBAR_DEFAULT_WIDTH)}
|
||||
onPointerDown={(event) => {
|
||||
if (event.button !== 0) return;
|
||||
event.preventDefault();
|
||||
event.currentTarget.setPointerCapture(event.pointerId);
|
||||
drag.current = { pointerId: event.pointerId, x: event.clientX, width };
|
||||
}}
|
||||
onPointerMove={(event) => {
|
||||
if (drag.current?.pointerId !== event.pointerId) return;
|
||||
setWidth(drag.current.width + event.clientX - drag.current.x);
|
||||
}}
|
||||
onPointerUp={(event) => {
|
||||
if (drag.current?.pointerId !== event.pointerId) return;
|
||||
drag.current = null;
|
||||
event.currentTarget.releasePointerCapture(event.pointerId);
|
||||
}}
|
||||
onLostPointerCapture={() => { drag.current = null; }}
|
||||
onPointerCancel={() => { drag.current = null; }}
|
||||
onKeyDown={(event) => {
|
||||
const next = event.key === 'ArrowRight' ? width + 8
|
||||
: event.key === 'ArrowLeft' ? width - 8
|
||||
: event.key === 'Home' ? CLASSROOM_SIDEBAR_MIN_WIDTH
|
||||
: event.key === 'End' ? CLASSROOM_SIDEBAR_MAX_WIDTH : null;
|
||||
if (next === null) return;
|
||||
event.preventDefault();
|
||||
setWidth(next);
|
||||
}}
|
||||
/>;
|
||||
}
|
||||
Reference in new issue
Block a user