summaryrefslogtreecommitdiff
path: root/src/ollama_web/static/app.js
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-08-16 19:07:08 +0900
committertanaka takashi <isazaka@gmail.com>2026-08-16 19:07:08 +0900
commit239c206659d02f5e89b3f54aa050aff6a71dcdd5 (patch)
treef436807878bfa868e56581e562769c733a45eeb2 /src/ollama_web/static/app.js
parent28b2684da9cf8e48cff811b9f5b35997815cb530 (diff)
fix(ui): コピー失敗時のエラーハンドリングを追加
Clipboard API が利用できない非セキュアコンテキストや、ブラウザの権限拒否で writeText が失敗した場合に、未処理例外となってコピーボタンが無反応に見える問題を修正。 navigator.clipboard.writeText の存在を事前に確認し、非同期処理を try/catch で囲むことで同期例外と Promise の拒否をまとめて処理する。成功時はチェックマーク、失敗時は警告マークを一時表示し、詳細はコンソールへ記録する。アラートは表示しない。
Diffstat (limited to 'src/ollama_web/static/app.js')
-rw-r--r--src/ollama_web/static/app.js26
1 files changed, 18 insertions, 8 deletions
diff --git a/src/ollama_web/static/app.js b/src/ollama_web/static/app.js
index 54fb2e0..65aa17b 100644
--- a/src/ollama_web/static/app.js
+++ b/src/ollama_web/static/app.js
@@ -189,14 +189,24 @@ function addMessage(role, rawText, showCopy = false) {
copyBtn.setAttribute("aria-label", t("common.copy", "Copy"));
copyBtn.textContent = "📋";
copyBtn.hidden = !showCopy;
- copyBtn.addEventListener("click", () => {
+ copyBtn.addEventListener("click", async () => {
const raw = div.dataset.rawText || "";
- navigator.clipboard.writeText(raw).then(() => {
- copyBtn.textContent = "✓";
- setTimeout(() => {
- copyBtn.textContent = "📋";
- }, 1200);
- });
+ let feedback = "✓";
+
+ try {
+ if (!navigator.clipboard?.writeText) {
+ throw new Error("Clipboard API is unavailable");
+ }
+ await navigator.clipboard.writeText(raw);
+ } catch (err) {
+ console.error("failed to copy message", err);
+ feedback = "⚠";
+ }
+
+ copyBtn.textContent = feedback;
+ setTimeout(() => {
+ copyBtn.textContent = "📋";
+ }, 1200);
});
div.appendChild(copyBtn);
chatEl.appendChild(div);
@@ -959,4 +969,4 @@ function updateTokenGaugeFromSession() {
}
loadSessions();
-loadModelCapabilities(); \ No newline at end of file
+loadModelCapabilities();