Skip to content

Commit

Permalink
버그 픽스 (#105)
Browse files Browse the repository at this point in the history
Close #103
  • Loading branch information
junhea authored Nov 11, 2023
2 parents 9ce9a18 + 6e498c6 commit 365f479
Show file tree
Hide file tree
Showing 25 changed files with 581 additions and 153 deletions.
23 changes: 23 additions & 0 deletions app/components/ContextMenuViewer/contextMenuViewer.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.container {
position: absolute;
background-color: var(--background);
border-radius: 6px;
border: 1px solid var(--grey-normal);
margin: 0;
padding: 0;
animation: var(--intro-animation);
box-sizing: border-box;
overflow: hidden;
}

.item {
min-width: 100px;
cursor: default;
list-style: none;
margin: 0;
padding: 10px;
}

.item:hover {
background-color: var(--grey-normal);
}
39 changes: 39 additions & 0 deletions app/components/ContextMenuViewer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useContextMenu } from '@/states/contextMenu';
import styles from './contextMenuViewer.module.css';
import { CSSProperties, useEffect } from 'react';

export default function ContextMenuViewer() {
const { menu, setMenu } = useContextMenu((state) => ({
menu: state.menu,
setMenu: state.setMenu,
}));

useEffect(() => {
if (menu === null) return;
const pointerDown = () => setMenu(null);
document.addEventListener('pointerdown', pointerDown);
return () => document.removeEventListener('pointerdown', pointerDown);
}, [menu, setMenu]);

if (menu === null) return <></>;

const style: CSSProperties = {};
// check x overflow
if (menu.position.x < window.innerWidth / 2) style.left = menu.position.x;
else style.right = window.innerWidth - menu.position.x;
// check y overflow
if (menu.position.y < window.innerHeight / 2) style.top = menu.position.y;
else style.bottom = window.innerHeight - menu.position.y;

return (
<ul className={styles.container} style={style}>
{menu.items.map((v) => {
return (
<li className={styles.item} key={v.label} onPointerDown={v.onClick}>
{v.label}
</li>
);
})}
</ul>
);
}
22 changes: 14 additions & 8 deletions app/components/DocumentCreateDialogue/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Dialogue from '@/components/Dialogue';
import FileInput from '@/components/Dialogue/Input/FileInput';
import TextInput from '@/components/Dialogue/Input/TextInput';
import { useToast } from '@/states/toast';
import { useViewer } from '@/states/viewer';
import { createDocument, uploadFile } from '@/utils/api';
import { throwError } from '@/utils/ui';
import { useRouter } from 'next/navigation';
Expand All @@ -21,14 +20,13 @@ export default function DocumentCreateDialogue({
}: DocumentCreateDialogueProps) {
const router = useRouter();
const [load, setLoad] = useState<boolean>(false);
const documentId = useViewer((state) => state.document?.documentId ?? 0);
const pushToast = useToast((state) => state.pushToast);

return (
<div className={styles.container} style={load ? { pointerEvents: 'none' } : undefined}>
<Dialogue
enabled={!load}
title={'문서 생성'}
title={'학습 생성'}
onCancel={onCancel}
onSubmit={(e) => {
e.preventDefault();
Expand All @@ -37,19 +35,27 @@ export default function DocumentCreateDialogue({
const titleInput = (e.target as any).title as HTMLInputElement;
const fileInput = (e.target as any).file as HTMLInputElement;

// check file
if (fileInput.files === null || fileInput.files.length === 0) {
throwError('요약할 파일을 입력해 주세요');
return setLoad(false);
}

// check title
if (titleInput.value.length === 0) {
throwError('문서의 제목을 입력해 주세요');
return setLoad(false);
// throwError('문서의 제목을 입력해 주세요');
// return setLoad(false);

// set to filename if left blank
titleInput.value = fileInput.files[0].name;
}

(async () => {
// create new Document
const newDocument = await createDocument(titleInput.value);

// upload file (if exists)
if (fileInput.files !== null && fileInput.files.length > 0) {
await uploadFile(documentId, fileInput.files[0]);
}
await uploadFile(newDocument.documentId, fileInput.files![0]);

pushToast({
id: new Date().getTime(),
Expand Down
4 changes: 2 additions & 2 deletions app/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useOverlay } from '@/states/overlay';
import DocumentCreateDialogue from '../DocumentCreateDialogue';
import Logo from '@/components/Logo';
import { useUser } from '@/states/user';
import { useViewer } from '@/states/viewer';
export default function Header() {
const { setOverlay } = useOverlay((state) => ({
setOverlay: state.setOverlay,
Expand All @@ -21,7 +22,7 @@ export default function Header() {
{userDataExists ? (
<ClickableBackgroundButton
invert={true}
text={'새로운 문서'}
text={'학습 생성'}
icon="add"
onClick={() =>
setOverlay(
Expand All @@ -33,7 +34,6 @@ export default function Header() {
}
/>
) : undefined}

<LoginButton />
</div>
</div>
Expand Down
10 changes: 10 additions & 0 deletions app/document/[documentId]/components/BottomToolBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import ClickableBackgroundButton from '@/components/BackgroundButton/ClickableBa
import { useViewer } from '@/states/viewer';
import 'material-symbols';
import SmallIconButton from '@/components/Button/SmallIconButton';
import { useOverlay } from '@/states/overlay';
import MixModePanel from '@/components/GraphCanvas/MixModePanel';

export default function BottomToolBar() {
const elementRef = useRef<HTMLDivElement>(null);
const [pos, setPos] = useState<Coord>({ x: 0, y: 0 });
const [drag, setDrag] = useState<Coord | undefined>(undefined);
const setOverlay = useOverlay((state) => state.setOverlay);

useEffect(() => {
if (!drag) return;
Expand Down Expand Up @@ -67,6 +70,13 @@ export default function BottomToolBar() {
invert={true}
onClick={() => setView('DATA')}
/>
<ClickableBackgroundButton
color={'primary'}
thin={true}
text={'MIX!'}
invert={false}
onClick={() => setOverlay(<MixModePanel />)}
/>
</div>
</div>
);
Expand Down
49 changes: 7 additions & 42 deletions app/document/[documentId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ const GraphCanvas = dynamic(() => import('@/components/GraphCanvas'), { ssr: fal
import 'material-symbols';
import AudioViewer from '@/components/DataViewer/AudioViewer';
import ClickableBackgroundButton from '@/components/BackgroundButton/ClickableBackgroundButton';
import Dialogue from '@/components/Dialogue';
import FileInput from '@/components/Dialogue/Input/FileInput';
import { useToast } from '@/states/toast';
import { uploadFile } from '@/utils/api';
import { useViewerEvents } from '@/utils/ui';
import Divider, { useDivider } from '@/components/Divider';

Expand Down Expand Up @@ -46,16 +42,17 @@ export default function DoucumentsPage({ params }: DocumentPageProps) {
const eventCallback = useCallback(
(type: ViewerEventType) => {
// reload on event
if (documentData === null) return loadDocument(documentId);
// TODO: implement other types of events
syncDocument();
},
[syncDocument],
[documentData, documentId, loadDocument, syncDocument],
);

// subscribe to events
useViewerEvents(documentId, eventCallback);

if (documentData === null) return <LoadingScreen message={'Loading document'} />;
if (documentData === null) return <LoadingScreen message={'요약 마인드맵 로드중'} />;

return (
<div className={styles.rootContainer}>
Expand Down Expand Up @@ -122,49 +119,17 @@ function DataViewer({ type }: DataViewerProps) {
return <PdfViewer dataSource={dataSource} />;
case 'audio':
return <AudioViewer dataSource={dataSource} />;
case 'none':
return <DataUploadDialogue />;
}
}

function DataUploadDialogue() {
const pushToast = useToast((state) => state.pushToast);
const documentId = useViewer((state) => state.document?.documentId);
return (
<div className={styles.uploadDialogue}>
<Dialogue
enabled={true}
title={'자료 업로드'}
onSubmit={(e) => {
if (documentId === undefined) return;
const fileInput = (e.target as any).file as HTMLInputElement;
// upload file (if exists)
(async () => {
if (fileInput.files !== null && fileInput.files.length > 0) {
await uploadFile(documentId, fileInput.files[0]);
}
})();
}}
>
<FileInput
name="file"
types={['application/pdf', 'audio/mpeg']}
typeNames={['pdf', 'mp3']}
onError={(msg) => pushToast({ id: new Date().getTime(), duraton: 3000, msg: msg })}
/>
</Dialogue>
</div>
);
}

function GraphViewer() {
const hasGraph = useViewer((state) => state.mindMapData?.keywords.length !== 0);
if (!hasGraph) return <p>no graph available</p>;
const mindMapData = useViewer((state) => state.mindMapData);
if (mindMapData === null) return <p>no graph available</p>;
return (
<>
<div className={styles.whiteBoardContainer}>
<Suspense fallback={<LoadingScreen message={'Loading renderer'} />}>
<GraphCanvas />
<Suspense fallback={<LoadingScreen message={'렌더러 로드중'} />}>
<GraphCanvas mindMapData={mindMapData} />
</Suspense>
</div>
</>
Expand Down
9 changes: 5 additions & 4 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
--grey-darker: #383b40;
--foreground-disabled: #c7cfd0;
--foreground: #ffffff;
--warning-color: #c2599a;
--background: #f4f6f8;
--background-accent: #e6f5f5;
--intro-animation: show 0.5s;
Expand Down Expand Up @@ -76,10 +77,10 @@ div.loading-container {

@keyframes barAnimation {
0% {
background-color: var(--primary-light);
background-color: var(--primary-dark);
}
50% {
background-color: var(--primary-dark);
background-color: var(--highlight);
}
100% {
background-color: var(--primary-light);
Expand Down Expand Up @@ -116,9 +117,9 @@ div.loading-bar {
}

mark {
text-decoration: dotted;
text-decoration: underline dotted;
text-decoration-color: red;
text-decoration-thickness: 2px;
text-decoration-thickness: 3px;
color: transparent;
background: transparent;
}
Expand Down
2 changes: 2 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Inter } from 'next/font/google';
import ToastViewer from './components/ToastViewer';
import OverlayViewer from './components/OverlayViewer';
import Header from './components/Header';
import ContextMenuViewer from './components/ContextMenuViewer';

const inter = Inter({ subsets: ['latin'] });

Expand All @@ -20,6 +21,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
{children}
</div>
<OverlayViewer />
<ContextMenuViewer />
</body>
</html>
);
Expand Down
4 changes: 3 additions & 1 deletion components/DataViewer/AudioViewer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ function useFocusKeyword(
useEffect(() => {
setCallback((keyword, location) => {
setAllKeyword(false);
setKeyWord(keyword, true);
setKeyWord(keyword, {
enabled: true,
});
setFocusIndex(location[0]);
setSelectIndex(location[0]);
if (audioRef.current === null) return;
Expand Down
Loading

0 comments on commit 365f479

Please sign in to comment.