Skip to content

Commit 29d78a1

Browse files
authored
Merge pull request #180 from ut-code/terminal-resize
ターミナルなどの幅計算修正、全画面表示機能
2 parents b15173a + 09251bd commit 29d78a1

File tree

11 files changed

+461
-90
lines changed

11 files changed

+461
-90
lines changed

app/[lang]/[pageId]/pageContent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export function PageContent(props: PageContentProps) {
107107
<StyledMarkdown
108108
content={section.rawContent.replace(
109109
/-repl\s*\n/,
110-
`-repl:${section.id}`
110+
`-repl:${section.id}\n`
111111
)}
112112
/>
113113
</div>

app/[lang]/[pageId]/styledSyntaxHighlighter.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
tomorrowNight,
77
} from "react-syntax-highlighter/dist/esm/styles/hljs";
88
import { lazy, Suspense, useEffect, useState } from "react";
9+
import clsx from "clsx";
910

1011
// SyntaxHighlighterはファイルサイズがでかいので & HydrationErrorを起こすので、SSRを無効化する
1112
const SyntaxHighlighter = lazy(() => {
@@ -136,7 +137,12 @@ export function StyledSyntaxHighlighter(props: {
136137
}
137138
function FallbackPre({ children }: { children: string }) {
138139
return (
139-
<pre className="border-2 border-current/20 mx-2 my-2 rounded-box p-4! bg-base-300! text-base-content!">
140+
<pre
141+
className={clsx(
142+
"border-2 border-current/20 mx-2 my-2 rounded-box p-4! bg-base-300! text-base-content!",
143+
"w-full overflow-auto"
144+
)}
145+
>
140146
{children}
141147
</pre>
142148
);

app/globals.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ mycdark:
115115
@apply border-primary!;
116116
}
117117

118+
.rounded-box-modal {
119+
@apply rounded-box;
120+
@variant max-md {
121+
--radius-box: 0px !important;
122+
}
123+
}
124+
118125
/* CDNからダウンロードするURLを指定したらなんかエラー出るので、npmでインストールしてlayout.tsxでimportすることにした */
119126
@theme {
120127
/*

app/sidebar.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export function Sidebar({ pagesList }: { pagesList: LanguageEntry[] }) {
118118
}, [currentLangIndex]);
119119

120120
return (
121-
<div className="bg-base-200 h-full w-80 overflow-y-auto">
121+
<div className="bg-base-200 h-full w-80 flex flex-col">
122122
<h2 className="hidden lg:flex flex-row items-center p-4 gap-2">
123123
{/* サイドバーが常時表示されているlg以上の場合のみ */}
124124
<Link href="/" className="flex-1 flex items-center">
@@ -136,7 +136,7 @@ export function Sidebar({ pagesList }: { pagesList: LanguageEntry[] }) {
136136
<label
137137
htmlFor="drawer-toggle"
138138
aria-label="open sidebar"
139-
className="btn btn-ghost"
139+
className="btn btn-ghost w-full justify-start"
140140
>
141141
<svg
142142
className="w-8 h-8"
@@ -156,7 +156,16 @@ export function Sidebar({ pagesList }: { pagesList: LanguageEntry[] }) {
156156
</label>
157157
</span>
158158

159-
<ul className="menu w-full">
159+
<ul
160+
className="menu w-full h-max flex-nowrap grow-1 overflow-y-auto overflow-x-clip"
161+
style={{
162+
scrollbarGutter: "stable",
163+
// DaisyUIはスクロールバーカラーを変更しているが、sidebarを開いた際にはさらに暗い色に変更してしまう
164+
// ここではsidebarの状態によらずDaisyUIがデフォルトで設定しているスクロールバーカラーを復元
165+
scrollbarColor:
166+
"color-mix(in oklch, currentColor 35%, transparent) transparent",
167+
}}
168+
>
160169
{pagesList.map((group, i) => (
161170
<li key={group.id}>
162171
<details

app/terminal/editor.tsx

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useChangeTheme } from "@/themeToggle";
66
import { useEmbedContext } from "./embedContext";
77
import { langConstants } from "./runtime";
88
import { MarkdownLang } from "@/[lang]/[pageId]/styledSyntaxHighlighter";
9+
import { MinMaxButton, Modal } from "./modal";
910

1011
// https://github.com/securingsincity/react-ace/issues/27 により普通のimportができない
1112
const AceEditor = lazy(async () => {
@@ -104,18 +105,38 @@ export function EditorComponent(props: EditorProps) {
104105
}, [files, props.filename, props.initContent, writeFile]);
105106

106107
const [fontSize, setFontSize] = useState<number>();
108+
const [windowHeight, setWindowHeight] = useState<number>(1000);
107109
const [initAce, setInitAce] = useState(false);
108110
useEffect(() => {
109-
setFontSize(
110-
parseFloat(getComputedStyle(document.documentElement).fontSize)
111-
); // 1rem
112-
setInitAce(true);
111+
const update = () => {
112+
setFontSize(
113+
parseFloat(getComputedStyle(document.documentElement).fontSize)
114+
); // 1rem
115+
setWindowHeight(window.innerHeight);
116+
setInitAce(true);
117+
};
118+
update();
119+
window.addEventListener("resize", update);
120+
return () => window.removeEventListener("resize", update);
113121
}, []);
114-
// 最小8行 or 初期内容+1行
115-
const editorHeight = Math.max(props.initContent.split("\n").length + 1, 8);
122+
// 現在の内容の行数、最小8行、最大50vh
123+
const editorHeight = Math.max(
124+
Math.min(
125+
code.split("\n").length,
126+
Math.floor((windowHeight * 0.5) / ((fontSize || 16) + 1))
127+
),
128+
8
129+
);
130+
131+
const [isModal, setIsModal] = useState(false);
116132

117133
return (
118-
<div className="border border-accent border-2 shadow-md m-2 rounded-box overflow-hidden">
134+
<Modal
135+
id={`edit-${props.filename}`}
136+
className={clsx("overflow-hidden", "flex flex-col")}
137+
open={isModal}
138+
setOpen={setIsModal}
139+
>
119140
<div className="flex flex-row items-center bg-base-200">
120141
<span className="mt-2 mb-1 ml-3 mr-2 text-sm text-left">
121142
<span>
@@ -127,9 +148,7 @@ export function EditorComponent(props: EditorProps) {
127148
</span>
128149
<button
129150
className={clsx(
130-
"btn btn-xs btn-soft btn-warning mt-1 mb-1",
131-
// btn-warning は文字色を変えるがsvgの色は変えてくれないので、 stroke-warning を追加指定している
132-
"stroke-warning hover:stroke-warning-content active:stroke-warning-content",
151+
"btn btn-sm btn-soft btn-warning my-1",
133152
// codeの内容が変更された場合のみ表示する
134153
(props.readonly || code == props.initContent) && "invisible"
135154
)}
@@ -140,6 +159,7 @@ export function EditorComponent(props: EditorProps) {
140159
className="w-3 h-3"
141160
viewBox="0 0 24 24"
142161
fill="none"
162+
stroke="currentColor"
143163
xmlns="http://www.w3.org/2000/svg"
144164
>
145165
<g id="Edit / Undo">
@@ -153,8 +173,10 @@ export function EditorComponent(props: EditorProps) {
153173
/>
154174
</g>
155175
</svg>
156-
元の内容に戻す
176+
<span className="hidden md:inline">元の内容に戻す</span>
157177
</button>
178+
<div className="flex-1" />
179+
<MinMaxButton open={isModal} id={`edit-${props.filename}`} />
158180
</div>
159181
{fontSize !== undefined && initAce ? (
160182
<Suspense
@@ -168,7 +190,7 @@ export function EditorComponent(props: EditorProps) {
168190
theme={theme}
169191
tabSize={langConstants(props.language || "text").tabSize}
170192
width="100%"
171-
height={editorHeight * (fontSize + 1) + "px"}
193+
height={isModal ? "100%" : editorHeight * (fontSize + 1) + "px"}
172194
className="font-mono!" // Aceのデフォルトフォントを上書き
173195
readOnly={props.readonly}
174196
fontSize={fontSize}
@@ -182,26 +204,30 @@ export function EditorComponent(props: EditorProps) {
182204
/>
183205
</Suspense>
184206
) : (
185-
<FallbackPre editorHeight={editorHeight}>{code}</FallbackPre>
207+
<FallbackPre isModal={isModal} editorHeight={editorHeight}>
208+
{code}
209+
</FallbackPre>
186210
)}
187-
</div>
211+
</Modal>
188212
);
189213
}
190214

191215
function FallbackPre({
192216
children,
193217
editorHeight,
218+
isModal,
194219
}: {
195220
children: string;
196221
editorHeight: number;
222+
isModal?: boolean;
197223
}) {
198224
// AceEditorはなぜかline-heightが小さい
199225
// fontSize + 1px になるっぽい?
200226
return (
201227
<pre
202228
className="font-mono overflow-auto bg-base-300 px-2 cursor-wait"
203229
style={{
204-
height: `calc((1em + 1px) * ${editorHeight})`,
230+
height: isModal ? "100%" : `calc((1em + 1px) * ${editorHeight})`,
205231
lineHeight: "calc(1em + 1px)",
206232
}}
207233
>

0 commit comments

Comments
 (0)