【文】用gemini做番茄鐘

毛毳
·
·
IPFS
·

昨天突然心血來潮,想說用gemini來做個番茄鐘。

在這之前,其實也曾經用過其他AI做那種很簡單的,桌面小寵物。就是會在網頁上跳來跳去,顯示時間或簡短對話框的東西。

本來只想做最陽春版本的,就是把代碼貼到書籤網址裡面就可以直接使用的那種。可惜,每次做一做,代碼太長,後面都會失效,用不出來。

以下是唯一成功,看起來還行的書籤版。如果想嘗試,可以直接貼入書籤網址,應該會跑出來。

javascript:(function(){ if(document.getElementById('pet-pomo-container')) return; var myPetImage = "https://i.ibb.co/xtSJwHnb/image.png"; var workMinutes = 25; var time = workMinutes 60; var timer = null; var taskHistory = []; var isDragging = false; var startX, startY, dragOffsetX, dragOffsetY; var container = document.createElement('div'); container.id = 'pet-pomo-container'; container.style.cssText = "position:fixed; bottom:20px; right:20px; z-index:2147483647; text-align:center; font-family:'Microsoft JhengHei', sans-serif; user-select:none; width:120px;"; var bubble = document.createElement('div'); bubble.style.cssText = "background:#fff; border:2px solid #555; border-radius:10px; padding:8px 5px; margin-bottom:5px; box-shadow:0 4px 10px rgba(0,0,0,0.15); cursor:move; font-size:15px; color:#333; font-weight:bold; position:relative;"; var timeSpan = document.createElement('span'); timeSpan.innerText = "25:00"; var statusSpan = document.createElement('span'); statusSpan.innerHTML = "<br><span style='font-size:11px; color:#888; font-weight:normal;'>點圖開始</span>"; bubble.appendChild(timeSpan); bubble.appendChild(statusSpan); var img = document.createElement('img'); img.src = myPetImage; img.style.cssText = "width:120px; height:auto; cursor:pointer; display:block; margin:0 auto; pointer-events: auto;"; img.ondragstart = function() { return false; }; var ctrlBar = document.createElement('div'); ctrlBar.style.cssText = "margin-top:5px; display:flex; justify-content:center; gap:5px;"; var btnExport = document.createElement('button'); btnExport.innerText = "匯出"; btnExport.style.cssText = "font-size:12px; cursor:pointer; border:1px solid #999; background:#f0f0f0; border-radius:4px; padding:2px 6px;"; var btnClose = document.createElement('button'); btnClose.innerText = "關閉"; btnClose.style.cssText = "font-size:12px; cursor:pointer; border:1px solid #999; background:#ffdddd; border-radius:4px; padding:2px 6px;"; ctrlBar.appendChild(btnExport); ctrlBar.appendChild(btnClose); container.appendChild(bubble); container.appendChild(img); container.appendChild(ctrlBar); document.body.appendChild(container); container.addEventListener('mousedown', function(e) { if(e.target.tagName === 'BUTTON') return; startX = e.clientX; startY = e.clientY; isDragging = false; var rect = container.getBoundingClientRect(); dragOffsetX = e.clientX - rect.left; dragOffsetY = e.clientY - rect.top; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); }); function onMouseMove(e) { var moveX = Math.abs(e.clientX - startX); var moveY = Math.abs(e.clientY - startY); if (moveX > 3 || moveY > 3) { isDragging = true; container.style.right = 'auto'; container.style.bottom = 'auto'; container.style.left = (e.clientX - dragOffsetX) + 'px'; container.style.top = (e.clientY - dragOffsetY) + 'px'; } } function onMouseUp(e) { document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); if (!isDragging && e.target === img) { toggleTimer(); } } function updateDisplay() { var m = Math.floor(time / 60).toString().padStart(2,'0'); var s = (time % 60).toString().padStart(2,'0'); timeSpan.innerText = m + ":" + s; if (timer) { statusSpan.innerHTML = "<br><span style='font-size:11px; color:#28a745; font-weight:normal;'>計時中...</span>"; } else { statusSpan.innerHTML = "<br><span style='font-size:11px; color:#888; font-weight:normal;'>" + (time < workMinutes 60 ? "暫停" : "點圖開始") + "</span>"; } } function toggleTimer() { if(timer) { clearInterval(timer); timer = null; updateDisplay(); } else { if(time <= 0) time = workMinutes 60; updateDisplay(); timer = setInterval(function(){ time--; updateDisplay(); if(time <= 0) { clearInterval(timer); timer = null; completeTask(); } }, 1000); } } function completeTask() { timeSpan.innerText = "完成!"; statusSpan.innerHTML = "<br>休息一下"; setTimeout(function(){ var taskName = prompt("辛苦了!這次完成了什麼?"); if(taskName) { var now = new Date(); taskHistory.push({ date: now.toLocaleDateString(), time: now.toLocaleTimeString(), task: taskName, duration: workMinutes }); alert("已記錄!目前累積 " + taskHistory.length + " 筆。"); } time = workMinutes 60; updateDisplay(); }, 100); } btnExport.onclick = function() { if(taskHistory.length === 0) { alert("沒有紀錄喔!"); return; } var csvContent = "\uFEFF日期,時間,事項,長度(分)\n"; taskHistory.forEach(function(row){ csvContent += row.date + "," + row.time + "," + row.task + "," + row.duration + "\n"; }); var blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); var link = document.createElement("a"); link.href = URL.createObjectURL(blob); var timestamp = new Date().getHours() + "點" + new Date().getMinutes() + "分"; link.download = "專注紀錄_" + timestamp + ".csv"; document.body.appendChild(link); link.click(); document.body.removeChild(link); }; btnClose.onclick = function() { if(taskHistory.length > 0 && !confirm("還有紀錄未匯出,確定關閉?")) return; if(timer) clearInterval(timer); document.body.removeChild(container); };})();

大概會長以上模樣。

但是這種簡易版,就沒有可以自己設定時間的功能,只能固定二十五分鐘,且跳頁就需要重新再開一個,適合在同個網頁的人使用。

加上也沒有統計圖表,紀錄時間,設定書籤等複雜功能(?)。所以本來很懶惰,早就忘記之前怎麼做成擴充功能的我,想了想,還是決定做成擴充功能好了(喂)。

明明本來是因為懶惰,不想花太多時間,結果反而因為做成書籤版本一直跑不出來,浪費了更多時間呢⋯⋯(嘆氣)。

後來,我就依照gemini的指示,一步步新增文件,不用動腦的把東西全部貼上去就好。

請在你的電腦建立一個資料夾(例如 my-pomo),並在裡面準備以下 3 個核心檔案:

1. manifest.json (擴充功能的身分證)

這個檔案告訴瀏覽器你的插件具備哪些權限(如通知、儲存)。

2. popup.html (點擊右上角出現的介面)

這裡我們加入簡單的 HTML 結構,包含計時器與統計按鈕。

3. popup.js (控制計時邏輯)

這段邏輯處理了你要求的:25-5-25-5-25-5-25-15 循環,以及標籤儲存。

🛠️ 如何把這 3 個檔案裝進你的 Chrome?

準備圖示:找一張透明背景的番茄或寵物圖片,命名為 icon.png 放在資料夾中。

打開擴充功能頁面:在 Chrome 網址列輸入 chrome://extensions/。

開啟開發者模式:勾選右上角的「開發者模式」。

載入檔案:點擊左上角的「載入拆解封裝的擴充功能」,選擇你剛才建立的資料夾。

釘選它:點擊 Chrome 右上角的拼圖圖示,把你的「寵物番茄鐘」釘選出來。

新增文件,我是用「visual Studio Code」應用程式。

才能做出它指定要的那些文件。

做出來以後,就可以到他剛剛說的。

打開擴充功能頁面:在 Chrome 網址列輸入 chrome://extensions/。

開啟開發者模式:勾選右上角的「開發者模式」。

載入檔案:點擊左上角的「載入拆解封裝的擴充功能」,選擇你剛才建立的資料夾。

把這個文件夾載入上傳上去,就會跑出來了。

就會有這個擴充功能了。

不過,這只是第一步而已,因為接下來就會開始反覆出現錯誤,叫他修正,貼上,錯誤,修正,貼上⋯⋯無限循環(痛苦)。

錯誤大概有:

按了暫停鍵,再按一次沒反應。

建立書籤之後刪不掉。

沒有辦法拖移擋路的小寵物。

設定好的圖顯示不出來,AI自己幫我改成小狗圖案(?)。

倒數完成後,只有一個頁面會顯示。

如果按錯要重新計時按鈕沒有出現。

本來沒問題的部分,因為修改其他有問題的地方,結果出現問題⋯⋯

諸如此類的,加上要新增一些想要的功能:圓餅圖、長條圖、匯出功能⋯⋯

所以一直反覆測試,請他修正。直到最後,終於有個比較像樣的成品誕生了!

雖然還有想加入的功能,但深怕讓他一個新增,又會有新的問題出現。所以暫時我就先收手不繼續增加改良了,實在是昨天做煩了(笑)。

目前只要沒有把它關掉,他就會在網頁的右下角出現。小圖示和框框的顏色都可以自己客製化,按下之後就代表開始執行這項任務。

像我按下畫筆的書籤,就代表開始計時畫畫。框設定是橘色的。

然後右上角有個設定面板可以打開。有長條圖、圓餅圖,也可以匯出資料。

也可以自己制定時間,左工作時間,右休息時間,制定書籤,選擇顏色,選擇圖片(圖片要貼上有圖片格式的網址才會在按下的時候出現那個圖片),也可以把資料全部刪除。

如果匯出資料,他會長這樣:

計時完成,會跳出輸入紀錄,也可以空白。

休息會長這樣:他會自己跳出個內建的咖啡杯。

休息完會跳出視窗。

大概就這樣。

如果有人有興趣的話,我再把檔案放到雲端。如果測試還有其他有問題的地方,也歡迎跟我說,有可能是我還沒發現的部分@@


CC BY-NC-ND 4.0 授权

喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!

logbook icon
毛毳大家好,這裡是毛毳,平時喜歡分享短文、圖畫、小說等文章 歡迎大家來訪
  • 来自作者
  • 相关推荐

【繪】閃亮

【繪】臉陷進去

【繪】呆滯