From f55f3da31dc87f98a7e4d02d9be9669f740032d9 Mon Sep 17 00:00:00 2001 From: reodesureodesu Date: Mon, 2 Mar 2026 19:52:28 +0900 Subject: [PATCH 1/7] =?UTF-8?q?=E8=AA=8D=E8=A8=BC=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E8=A1=A8=E7=A4=BA=E3=82=92=E6=94=B9=E5=96=84=E3=81=97?= =?UTF-8?q?=E3=83=81=E3=83=A3=E3=83=83=E3=83=88=E6=A9=9F=E8=83=BD=E3=82=92?= =?UTF-8?q?=E6=8B=A1=E5=BC=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 212 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 186 insertions(+), 26 deletions(-) diff --git a/index.html b/index.html index fa8bab5..7921b3a 100644 --- a/index.html +++ b/index.html @@ -63,6 +63,27 @@ background: linear-gradient(180deg, #ffffff 0%, #fbfffd 100%); } +#statusBar { + min-height: 38px; + padding: 9px 12px; + font-size: 0.85rem; + border-radius: 10px; + background: #eff6ff; + color: #1d4ed8; + display: none; + text-align: left; +} + +#statusBar.error { + background: #fef2f2; + color: #b91c1c; +} + +#statusBar.success { + background: #ecfdf5; + color: #047857; +} + #auth h2 { margin: 0 0 2px; font-size: 1.1rem; @@ -81,6 +102,29 @@ background: linear-gradient(180deg, #f8fcff 0%, #f2fbf6 100%); } +#toolbar { + display: flex; + gap: 8px; + padding: 10px 12px; + border-bottom: 1px solid var(--border); + background: #fff; +} + +#toolbar input { + padding: 8px 10px; +} + +.message-meta { + display: block; + margin-top: 6px; + font-size: 0.72rem; + opacity: 0.75; +} + +.hidden { + display: none !important; +} + #messages { flex: 1; overflow-y: auto; @@ -191,6 +235,31 @@ #aiBtn { background: #6366f1; } + +#themeToggle { + background: #111827; +} + +body.dark { + --bg-gradient: linear-gradient(160deg, #0f172a 0%, #111827 60%, #1f2937 100%); + --surface: #111827; + --surface-soft: #1f2937; + --text-primary: #f9fafb; + --text-muted: #9ca3af; + --border: #374151; +} + +body.dark #googleLogin, +body.dark #toolbar, +body.dark #inputArea { + background: #1f2937; + color: #f9fafb; +} + +body.dark .other { + background: #1f2937; + color: #f9fafb; +} @@ -200,14 +269,20 @@

ログインしてチャットを始めましょう

Google またはメールアドレスでサインインできます。

+
+
+
+ + +
@@ -225,7 +300,7 @@

ログインしてチャットを始めましょう

import { initializeApp } from "https://www.gstatic.com/firebasejs/10.12.0/firebase-app.js"; import { getAuth, GoogleAuthProvider, signInWithPopup, createUserWithEmailAndPassword, signInWithEmailAndPassword, -onAuthStateChanged, signOut } +onAuthStateChanged, signOut, updateProfile } from "https://www.gstatic.com/firebasejs/10.12.0/firebase-auth.js"; import { getFirestore, collection, addDoc, onSnapshot, query, orderBy, serverTimestamp } @@ -253,23 +328,103 @@

ログインしてチャットを始めましょう

const messagesDiv = document.getElementById("messages"); const msgInput = document.getElementById("msg"); const imageInput = document.getElementById("imageInput"); +const emailInput = document.getElementById("email"); +const passwordInput = document.getElementById("password"); +const displayNameInput = document.getElementById("displayName"); +const statusBar = document.getElementById("statusBar"); +const searchInput = document.getElementById("searchInput"); + +const authErrorMessages = { + "auth/email-already-in-use": "このメールアドレスはすでに登録されています。ログインをお試しください。", + "auth/invalid-email": "メールアドレスの形式が正しくありません。", + "auth/missing-password": "パスワードを入力してください。", + "auth/weak-password": "パスワードは6文字以上で入力してください。", + "auth/invalid-credential": "メールアドレスまたはパスワードが正しくありません。", + "auth/popup-closed-by-user": "Googleログインがキャンセルされました。" +}; + +let allMessages = []; + +const formatTime = (value)=> { + const date = value?.toDate ? value.toDate() : null; + if(!date) return "送信中..."; + return date.toLocaleTimeString("ja-JP", { hour: "2-digit", minute: "2-digit" }); +}; + +const setStatus = (message, type="info")=>{ + if(!message){ + statusBar.style.display = "none"; + statusBar.textContent = ""; + statusBar.className = ""; + return; + } + statusBar.textContent = message; + statusBar.style.display = "block"; + statusBar.className = type; +}; + +const showAuthError = (error)=>{ + const msg = authErrorMessages[error.code] || `認証エラーが発生しました (${error.code || "unknown"})`; + setStatus(msg, "error"); +}; + +const renderMessages = (messages, user)=>{ + const keyword = searchInput.value.trim().toLowerCase(); + messagesDiv.innerHTML = ""; + + messages + .filter((item)=>!keyword || (item.text || "").toLowerCase().includes(keyword)) + .forEach((data)=>{ + const div=document.createElement("div"); + div.className="msg "+(data.uid===user.uid?"me":"other"); + div.textContent=data.text||""; + + if(data.image){ + const img=document.createElement("img"); + img.src=data.image; + img.className="chatimg"; + div.appendChild(img); + } + + const meta = document.createElement("small"); + meta.className = "message-meta"; + meta.textContent = `${data.name || "匿名"}・${formatTime(data.createdAt)}`; + div.appendChild(meta); + + messagesDiv.appendChild(div); + }); + + messagesDiv.scrollTop=messagesDiv.scrollHeight; +}; /* ログイン */ document.getElementById("googleLogin").onclick = -()=> signInWithPopup(auth,googleProvider); +()=> signInWithPopup(auth,googleProvider) + .then(()=>setStatus("Googleでログインしました。", "success")) + .catch(showAuthError); document.getElementById("register").onclick = async()=>{ try{ - await createUserWithEmailAndPassword(auth, - email.value,password.value); - }catch(e){alert(e.message);} + setStatus(""); + const credential = await createUserWithEmailAndPassword(auth, + emailInput.value,passwordInput.value); + + if(displayNameInput.value.trim()){ + await updateProfile(credential.user, { + displayName: displayNameInput.value.trim() + }); + } + setStatus("新規登録に成功しました。", "success"); + }catch(e){showAuthError(e);} }; document.getElementById("login").onclick = async()=>{ try{ + setStatus(""); await signInWithEmailAndPassword(auth, - email.value,password.value); - }catch(e){alert(e.message);} + emailInput.value,passwordInput.value); + setStatus("ログインに成功しました。", "success"); + }catch(e){showAuthError(e);} }; document.getElementById("logout").onclick = @@ -290,29 +445,22 @@

ログインしてチャットを始めましょう

orderBy("createdAt")); onSnapshot(q,snap=>{ - messagesDiv.innerHTML=""; - snap.forEach(doc=>{ - const data=doc.data(); - const div=document.createElement("div"); - div.className="msg "+(data.uid===user.uid?"me":"other"); - div.innerHTML=data.text||""; - - if(data.image){ - const img=document.createElement("img"); - img.src=data.image; - img.className="chatimg"; - div.appendChild(img); - } - - messagesDiv.appendChild(div); - }); - messagesDiv.scrollTop=messagesDiv.scrollHeight; + allMessages = []; + snap.forEach((doc)=>allMessages.push(doc.data())); + renderMessages(allMessages, user); }); }); +searchInput.oninput = ()=>{ + if(auth.currentUser){ + renderMessages(allMessages, auth.currentUser); + } +}; + /* 送信 */ document.getElementById("send").onclick=async()=>{ if(!auth.currentUser)return; + if(!msgInput.value.trim() && !imageInput.files[0]) return; let imageBase64=null; const file=imageInput.files[0]; @@ -326,8 +474,9 @@

ログインしてチャットを始めましょう

} await addDoc(collection(db,"messages"),{ - text:msgInput.value, + text:msgInput.value.trim(), image:imageBase64, + name:auth.currentUser.displayName || emailInput.value || "匿名", uid:auth.currentUser.uid, createdAt:serverTimestamp() }); @@ -355,7 +504,18 @@

ログインしてチャットを始めましょう

}); const data=await res.json(); - msgInput.value=data.choices[0].message.content; + msgInput.value=data.choices?.[0]?.message?.content || "AI応答を取得できませんでした"; +}; + +msgInput.addEventListener("keydown", (event)=>{ + if(event.key === "Enter"){ + event.preventDefault(); + document.getElementById("send").click(); + } +}); + +document.getElementById("themeToggle").onclick = ()=>{ + document.body.classList.toggle("dark"); }; From d79e52fd19975168a7f3fe4a64cb94b96a5a3f5a Mon Sep 17 00:00:00 2001 From: reodesureodesu Date: Mon, 2 Mar 2026 20:21:28 +0900 Subject: [PATCH 2/7] Update index.html --- index.html | 689 ++++++++++++++++++++++++++++------------------------- 1 file changed, 364 insertions(+), 325 deletions(-) diff --git a/index.html b/index.html index 7921b3a..9652801 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,6 @@
-
LINE Ultimate
- -
-

ログインしてチャットを始めましょう

-

Google またはメールアドレスでサインインできます。

-
- - - - - - -
+
+ + -
-
- +
+ + LINE Ultimate +
+ +
+

ログインしてチャットを始めましょう

+

Google またはメールアドレスでサインインできます。

+
+ + + + + +
-
-
- -
- - + +
+
+ + 全体 +
+
+
+ +
+ + +
+
- +
- -
From 44f23ca2b4596ae597bb3aa00235c32ed0fb4088 Mon Sep 17 00:00:00 2001 From: reodesureodesu Date: Mon, 2 Mar 2026 20:31:13 +0900 Subject: [PATCH 3/7] Update index.html --- index.html | 120 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 15 deletions(-) diff --git a/index.html b/index.html index 9652801..01e3b1c 100644 --- a/index.html +++ b/index.html @@ -142,7 +142,7 @@ #statusBar.error { background: #fef2f2; color: #b91c1c; } #statusBar.success { background: #ecfdf5; color: #047857; } -#chat { display: none; flex: 1; flex-direction: column; background: linear-gradient(180deg, #f8fcff 0%, #f2fbf6 100%); } +#chat { display: none; flex: 1; flex-direction: column; background: linear-gradient(180deg, #f8fcff 0%, #f2fbf6 100%); min-height: 0; overflow: hidden; } #toolbar { display: flex; @@ -154,6 +154,7 @@ #messages { flex: 1; + min-height: 0; overflow-y: auto; padding: 16px 14px; display: flex; @@ -178,7 +179,31 @@ .message-meta { display: block; margin-top: 6px; font-size: 0.72rem; opacity: 0.75; } .chatimg { width: 100%; max-width: 190px; border-radius: 10px; margin-top: 8px; display: block; } -#inputArea { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 12px; border-top: 1px solid var(--border); background: var(--surface); } +.msg-actions { + margin-top: 8px; + display: flex; + gap: 6px; +} + +.msg-actions button { + padding: 4px 8px; + border-radius: 8px; + font-size: 0.7rem; +} + +.msg-edit { background: #0ea5e9; } +.msg-delete { background: #ef4444; } + +#bottomBar { + position: sticky; + bottom: 0; + z-index: 2; + background: var(--surface); + border-top: 1px solid var(--border); +} + + +#inputArea { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 12px; background: var(--surface); } #imageInput { grid-column: 1 / -1; } #actions { display: flex; gap: 8px; } @@ -197,7 +222,7 @@ --text-muted: #9ca3af; --border: #374151; } -body.dark #toolbar, body.dark #inputArea, body.dark #googleLogin { background: #1f2937; color: #f9fafb; } +body.dark #toolbar, body.dark #inputArea, body.dark #googleLogin, body.dark #bottomBar { background: #1f2937; color: #f9fafb; } body.dark .other { background: #1f2937; color: #f9fafb; } @@ -242,22 +267,24 @@

ログインしてチャットを始めましょう

全体
-
- -
- - +
+
+ +
+ + +
+
- +
-