Skip to content

Commit bb14920

Browse files
committed
Merge branch 'main' into runtime-workspace
2 parents 5836fd9 + 29d78a1 commit bb14920

File tree

12 files changed

+832
-208
lines changed

12 files changed

+832
-208
lines changed

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,24 @@ npx prisma dev
1515
```
1616
を実行し、`t` キーを押して表示される DATABASE_URL をコピー
1717

18-
ルートディレクトリに .env.local という名前のファイルを作成し、以下の内容を記述
18+
ルートディレクトリに .env または .env.local という名前のファイルを作成し、以下の内容を記述
1919
```dotenv
2020
API_KEY=GeminiAPIキー
2121
BETTER_AUTH_URL=http://localhost:3000
2222
DATABASE_URL="postgres://... (prisma devの出力)"
23+
GOOGLE_CLIENT_ID=
24+
GOOGLE_CLIENT_SECRET=
25+
GITHUB_CLIENT_ID=
26+
GITHUB_CLIENT_SECRET=
2327
```
2428

29+
* `API_KEY` はGeminiのAPIキーを作成して設定します。未設定の場合チャットが使えません
30+
* `GITHUB_CLIENT_ID` `GITHUB_CLIENT_SECRET` はGitHub OAuthのクライアントIDとシークレットを設定します。未設定の場合「GitHubでログイン」が使えません。
31+
作り方については https://www.better-auth.com/docs/authentication/github を参照
32+
* `GOOGLE_CLIENT_ID` `GOOGLE_CLIENT_SECRET` はGoogle OAuthのクライアントIDとシークレットを設定します。未設定の場合「Googleでログイン」が使えません。
33+
作り方については https://www.better-auth.com/docs/authentication/google を参照 (GitHubのほうがかんたんかも)
34+
35+
2536
別のターミナルで、
2637
```bash
2738
npx drizzle-kit migrate
@@ -51,9 +62,10 @@ npm run lint
5162
### 本番環境の場合
5263

5364
上記の環境変数以外に、
54-
* BETTER_AUTH_SECRET に任意の文字列
55-
* GOOGLE_CLIENT_IDとGOOGLE_CLIENT_SECRETにGoogle OAuthのクライアントIDとシークレット https://www.better-auth.com/docs/authentication/google
56-
* GITHUB_CLIENT_IDとGITHUB_CLIENT_SECRETにGitHub OAuthのクライアントIDとシークレット https://www.better-auth.com/docs/authentication/github
65+
66+
* `BETTER_AUTH_SECRET` に任意の文字列
67+
68+
が必要です。
5769

5870
現在は本番環境(my-code.utcode.net)はCoolifyでデプロイしています。
5971
Cloudflare Worker のビルドログとステータス表示が見れますが、そちらは使っていません。

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
@@ -7,6 +7,7 @@ import {
77
} from "react-syntax-highlighter/dist/esm/styles/hljs";
88
import { lazy, Suspense, useEffect, useState } from "react";
99
import { LangConstants } from "@my-code/runtime/languages";
10+
import clsx from "clsx";
1011

1112
// SyntaxHighlighterはファイルサイズがでかいので & HydrationErrorを起こすので、SSRを無効化する
1213
const SyntaxHighlighter = lazy(() => {
@@ -44,7 +45,12 @@ export function StyledSyntaxHighlighter(props: {
4445
}
4546
function FallbackPre({ children }: { children: string }) {
4647
return (
47-
<pre className="border-2 border-current/20 mx-2 my-2 rounded-box p-4! bg-base-300! text-base-content!">
48+
<pre
49+
className={clsx(
50+
"border-2 border-current/20 mx-2 my-2 rounded-box p-4! bg-base-300! text-base-content!",
51+
"w-full overflow-auto"
52+
)}
53+
>
4854
{children}
4955
</pre>
5056
);

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
@@ -5,6 +5,7 @@ import clsx from "clsx";
55
import { useChangeTheme } from "@/themeToggle";
66
import { useEmbedContext } from "./embedContext";
77
import { LangConstants } from "@my-code/runtime/languages";
8+
import { MinMaxButton, Modal } from "./modal";
89

910
// https://github.com/securingsincity/react-ace/issues/27 により普通のimportができない
1011
const AceEditor = lazy(async () => {
@@ -48,15 +49,30 @@ export function EditorComponent(props: EditorProps) {
4849
}, [files, props.filename, props.initContent, writeFile]);
4950

5051
const [fontSize, setFontSize] = useState<number>();
52+
const [windowHeight, setWindowHeight] = useState<number>(1000);
5153
const [initAce, setInitAce] = useState(false);
5254
useEffect(() => {
53-
setFontSize(
54-
parseFloat(getComputedStyle(document.documentElement).fontSize)
55-
); // 1rem
56-
setInitAce(true);
55+
const update = () => {
56+
setFontSize(
57+
parseFloat(getComputedStyle(document.documentElement).fontSize)
58+
); // 1rem
59+
setWindowHeight(window.innerHeight);
60+
setInitAce(true);
61+
};
62+
update();
63+
window.addEventListener("resize", update);
64+
return () => window.removeEventListener("resize", update);
5765
}, []);
58-
// 最小8行 or 初期内容+1行
59-
const editorHeight = Math.max(props.initContent.split("\n").length + 1, 8);
66+
// 現在の内容の行数、最小8行、最大50vh
67+
const editorHeight = Math.max(
68+
Math.min(
69+
code.split("\n").length,
70+
Math.floor((windowHeight * 0.5) / ((fontSize || 16) + 1))
71+
),
72+
8
73+
);
74+
75+
const [isModal, setIsModal] = useState(false);
6076

6177
if (
6278
process.env.NODE_ENV === "development" &&
@@ -68,7 +84,12 @@ export function EditorComponent(props: EditorProps) {
6884
}
6985

7086
return (
71-
<div className="border border-accent border-2 shadow-md m-2 rounded-box overflow-hidden">
87+
<Modal
88+
id={`edit-${props.filename}`}
89+
className={clsx("overflow-hidden", "flex flex-col")}
90+
open={isModal}
91+
setOpen={setIsModal}
92+
>
7293
<div className="flex flex-row items-center bg-base-200">
7394
<span className="mt-2 mb-1 ml-3 mr-2 text-sm text-left">
7495
<span>
@@ -80,9 +101,7 @@ export function EditorComponent(props: EditorProps) {
80101
</span>
81102
<button
82103
className={clsx(
83-
"btn btn-xs btn-soft btn-warning mt-1 mb-1",
84-
// btn-warning は文字色を変えるがsvgの色は変えてくれないので、 stroke-warning を追加指定している
85-
"stroke-warning hover:stroke-warning-content active:stroke-warning-content",
104+
"btn btn-sm btn-soft btn-warning my-1",
86105
// codeの内容が変更された場合のみ表示する
87106
(props.readonly || code == props.initContent) && "invisible"
88107
)}
@@ -93,6 +112,7 @@ export function EditorComponent(props: EditorProps) {
93112
className="w-3 h-3"
94113
viewBox="0 0 24 24"
95114
fill="none"
115+
stroke="currentColor"
96116
xmlns="http://www.w3.org/2000/svg"
97117
>
98118
<g id="Edit / Undo">
@@ -106,8 +126,10 @@ export function EditorComponent(props: EditorProps) {
106126
/>
107127
</g>
108128
</svg>
109-
元の内容に戻す
129+
<span className="hidden md:inline">元の内容に戻す</span>
110130
</button>
131+
<div className="flex-1" />
132+
<MinMaxButton open={isModal} id={`edit-${props.filename}`} />
111133
</div>
112134
{fontSize !== undefined && initAce ? (
113135
<Suspense
@@ -121,7 +143,7 @@ export function EditorComponent(props: EditorProps) {
121143
theme={theme}
122144
tabSize={props.language.tabSize ?? 4}
123145
width="100%"
124-
height={editorHeight * (fontSize + 1) + "px"}
146+
height={isModal ? "100%" : editorHeight * (fontSize + 1) + "px"}
125147
className="font-mono!" // Aceのデフォルトフォントを上書き
126148
readOnly={props.readonly}
127149
fontSize={fontSize}
@@ -135,26 +157,30 @@ export function EditorComponent(props: EditorProps) {
135157
/>
136158
</Suspense>
137159
) : (
138-
<FallbackPre editorHeight={editorHeight}>{code}</FallbackPre>
160+
<FallbackPre isModal={isModal} editorHeight={editorHeight}>
161+
{code}
162+
</FallbackPre>
139163
)}
140-
</div>
164+
</Modal>
141165
);
142166
}
143167

144168
function FallbackPre({
145169
children,
146170
editorHeight,
171+
isModal,
147172
}: {
148173
children: string;
149174
editorHeight: number;
175+
isModal?: boolean;
150176
}) {
151177
// AceEditorはなぜかline-heightが小さい
152178
// fontSize + 1px になるっぽい?
153179
return (
154180
<pre
155181
className="font-mono overflow-auto bg-base-300 px-2 cursor-wait"
156182
style={{
157-
height: `calc((1em + 1px) * ${editorHeight})`,
183+
height: isModal ? "100%" : `calc((1em + 1px) * ${editorHeight})`,
158184
lineHeight: "calc(1em + 1px)",
159185
}}
160186
>

0 commit comments

Comments
 (0)