iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
1
Modern Web

Chrome extension 學習手札系列 第 11

Chrome extension 學習手札 11 - 基本實作 - 番茄鐘 part6

  • 分享至 

  • xImage
  •  

今天應該是番茄鐘的最後一天了,由於卡了一點bug,原本打算四天解決的番茄鐘拖了六天orz。

本日目標: 使用自定義頁面chrome.stroage 製作一個編輯視窗,可以修改一些番茄鐘的設定

首先先建一個資料夾setting,並且放入三大元素(html,css,js),然後簡單的美化一下畫面

<div id="app">
    <h2>番茄鐘設定</h2>
    <hr />
    <div class="row">
        <label>每次工作時間(分鐘):</label>
        <input type="number" id="work-time" value="0" min="0" />
    </div>
    <div class="row">
        <label>每次短休息時間(分鐘):</label>
        <input type="number" id="rest-time" value="0" min="0" />
    </div>
    <div class="row">
        <label>每次長休息時間(分鐘):</label>
        <input type="number" id="long-rest-time" value="0" min="0" />
    </div>
    <div class="row">
        <div class="btn btn-blue" id="save">儲存</div>
        <div class="btn btn-white" id="reset">初始化</div>
    </div>
</div>

然後將設定按鈕放在右鍵清單

// MenuManager menus.setting
setting: {
    id: 'setting',
    title: '設定',
    contexts: ['browser_action'],
    enabled: true,
}

再使用chrome.tabs API 呼叫頁面

chrome.tabs.create({url: chrome.extension.getURL('setting/setting.html')})

因為這是一個自定義頁面,所以我們不清楚chrome物件是否能用到 Chrome Extension,讓我們console出來看一下

console.log(chrome)

看來功能都差不多,還好我們之前開發時有把延展性寫好,所以只需要一樣的連線方式跟後台腳本溝通就好了
所以我們先使用getSetting,然後用回傳的資料更新DOM

setting/setting.html

//與後台腳本建立一個長時間的連線
var port = chrome.runtime.connect({name:"pomodoro"})

const workTime = document.getElementById('work-time')
const restTime = document.getElementById('rest-time')
const longRestTime = document.getElementById('long-rest-time')
const save = document.getElementById('save')
const reset = document.getElementById('reset')

var pomodoroSetting = {
    workTime: 0,
    restTime: 0,
    longRestTime: 0
}


//接收setting資訊 & 儲存成功狀態
port.onMessage.addListener(function(response){
    if(typeof response === 'object' && response.PomodoroSetting){
        pomodoroSetting = response.PomodoroSetting
        refreshSetting()
    }else{
        //儲存結果
        if(response === true){
            alert("儲存成功")
        }
    }
})

//更新畫面資訊
function refreshSetting(){
    workTime.value = parseInt(pomodoroSetting.workTime)
    restTime.value = parseInt(pomodoroSetting.restTime)
    longRestTime.value = parseInt(pomodoroSetting.longRestTime)
}

//發送請求-取得資訊
port.postMessage({func:'getSetting'})

setting/setting.html

function saveSetting(){
    //送出資訊
    port.postMessage({
        func: 'setSetting',
        data: {
            workTime: workTime.value,
            restTime: restTime.value,
            longRestTime: longRestTime.value
        }
    })
    //更新資料
    port.postMessage({func:'getSetting'})
}

//賦予按鈕事件
save.addEventListener('click',saveSetting)
reset.addEventListener('click',refreshSetting)

接下來就是後台腳本要寫事件了,第一個函數是初始化的時候使用,還有基本的set/get,我覺得set以後就應該要終止番茄鐘並且重新計算,看個人需求囉

background/bg.js

class Pomodoro {
    .
    .
    .
    
    //檢查是否有資料,否則就儲存一份
    checkStroageAndRefresh(){
        var self = this
        this.getSetting()
            .then((setting)=>{
                if(Object.keys(setting).length){
                    self.workTime = setting.workTime
                    self.restTime = setting.restTime
                    self.longRestTime = setting.longRestTime
                }else{
                    self.setSetting({
                        workTime : 25,
                        restTime : 5,
                        longRestTime : 15
                    })
                }
            })
    }

    //取得setting資料
    getSetting(){
        return new Promise((resolve, reject) => {
            chrome.storage.local.get('PomodoroSetting', function(setting) {
                resolve(setting)
            });
        })
    }
    
    //設定setting資料
    setSetting(setting , usePromise = false){
        if(usePromise){
            return new Promise((resolve, reject) => {
                chrome.storage.local.set({'PomodoroSetting':setting}, function() {
                    resolve(true)
                });
            })
        }else{
            chrome.storage.local.set({'PomodoroSetting':setting})
        }
        
        //重設時鐘
        this.workTime = setting.workTime
        this.restTime = setting.restTime
        this.longRestTime = setting.longRestTime
        this.reset()
    }
    
    .
    .
    .

既然資料都有promise了,這樣port的onMessage應該就無法回傳回去,所以我上網參考了檢查Promise的做法,再讓非同步回傳資料
出處

background/bg.js

//global area
chrome.runtime.onConnect.addListener(function(port) {
    if (port.name === 'pomodoro') {
        port.onMessage.addListener(function(request) {
            let response = pomodoro.onMessage(request)
            if (typeof response.then === 'function') {
                response.then((result)=>{
                    port.postMessage(result)
                })
            }else{
                port.postMessage(response)
            }
        })
    }
})

噹噹~就大功告成拉,終於把蕃茄鐘做完囉!!!

補充:其實setting.html可以直接使用chrome.stroage取得與設定資料,但是為了同步蕃茄鐘狀態,所以我才讓所有資料的處理都統一放到後台腳本處理哦


上一篇
Chrome extension 學習手札 10 - 基本實作 - 番茄鐘 part5
下一篇
Chrome extension 學習手札 12 - 腳本實作 - 準備&介紹web Request
系列文
Chrome extension 學習手札30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言