├── public ├── robots.txt ├── favicon.ico ├── img │ └── icons │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── apple-touch-icon.png │ │ ├── mstile-150x150.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-180x180.png │ │ ├── msapplication-icon-144x144.png │ │ ├── android-chrome-maskable-192x192.png │ │ ├── android-chrome-maskable-512x512.png │ │ └── safari-pinned-tab.svg └── index.html ├── .browserslistrc ├── docs ├── demo.png └── demo2.jpg ├── src ├── assets │ ├── logo.png │ └── logo.svg ├── views │ ├── About.vue │ └── Home.vue ├── plugins │ ├── vuetify.js │ └── dayjs.js ├── store │ └── index.js ├── main.js ├── App.vue ├── router │ └── index.js ├── registerServiceWorker.js ├── components │ ├── TimePicker.vue │ ├── ColorPicker.vue │ └── HelloWorld.vue └── background.js ├── babel.config.js ├── vue.config.js ├── .gitignore ├── Dockerfile ├── deploy.sh ├── .github └── workflows │ └── nodejs.yml ├── README.md └── package.json /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /docs/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/docs/demo.png -------------------------------------------------------------------------------- /docs/demo2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/docs/demo2.jpg -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /src/views/About.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | publicPath:'/day-progress/', 3 | "transpileDependencies": [ 4 | "vuetify" 5 | ] 6 | } -------------------------------------------------------------------------------- /public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-maskable-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/android-chrome-maskable-192x192.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-maskable-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiaod/day-progress/HEAD/public/img/icons/android-chrome-maskable-512x512.png -------------------------------------------------------------------------------- /src/plugins/vuetify.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuetify from 'vuetify/lib'; 3 | 4 | Vue.use(Vuetify); 5 | 6 | export default new Vuetify({ 7 | icons: { 8 | iconfont: 'mdiSvg', 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | Vue.use(Vuex) 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | }, 9 | mutations: { 10 | }, 11 | actions: { 12 | }, 13 | modules: { 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /src/plugins/dayjs.js: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs' 2 | import relativeTime from 'dayjs/plugin/relativeTime' 3 | import calendar from 'dayjs/plugin/calendar' 4 | import 'dayjs/locale/zh-cn' 5 | dayjs.extend(calendar) 6 | dayjs.locale('zh-cn') 7 | dayjs.extend(relativeTime) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | 23 | #Electron-builder output 24 | /dist_electron -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import './registerServiceWorker' 4 | import router from './router' 5 | import store from './store' 6 | import vuetify from './plugins/vuetify'; 7 | import './plugins/dayjs' 8 | 9 | Vue.config.productionTip = false 10 | 11 | new Vue({ 12 | router, 13 | store, 14 | vuetify, 15 | render: h => h(App) 16 | }).$mount('#app') 17 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # specify the node base image with your desired version node: 2 | FROM node:12.18.4-alpine3.9 3 | # replace this with your application's default port 4 | EXPOSE 8888 5 | 6 | # Create app directory 7 | RUN mkdir -p /home/Service 8 | WORKDIR /home/Service 9 | 10 | # Bundle app source 11 | COPY . /home/Service 12 | # RUN npm config set registry https://registry.npm.taobao.org 13 | RUN ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/ npm install 14 | 15 | CMD [ "npm","start" ] -------------------------------------------------------------------------------- /src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | Artboard 46 2 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # abort on errors 4 | set -e 5 | 6 | # build 7 | npm run build 8 | 9 | # navigate into the build output directory 10 | cd dist 11 | 12 | # if you are deploying to a custom domain 13 | # echo 'www.example.com' > CNAME 14 | 15 | git init 16 | git add -A 17 | git commit -m 'deploy' 18 | 19 | # if you are deploying to https://.github.io 20 | # git push -f git@github.com:/.github.io.git master 21 | 22 | # if you are deploying to https://.github.io/ 23 | git push -f git@github.com:tiaod/day-progress.git master:gh-pages 24 | 25 | cd - 26 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import Home from '../views/Home.vue' 4 | 5 | Vue.use(VueRouter) 6 | 7 | const routes = [ 8 | { 9 | path: '/', 10 | name: 'Home', 11 | component: Home 12 | }, 13 | { 14 | path: '/about', 15 | name: 'About', 16 | // route level code-splitting 17 | // this generates a separate chunk (about.[hash].js) for this route 18 | // which is lazy-loaded when the route is visited. 19 | component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') 20 | } 21 | ] 22 | 23 | const router = new VueRouter({ 24 | routes 25 | }) 26 | 27 | export default router 28 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 11 | 12 | 13 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { register } from 'register-service-worker' 4 | 5 | if (process.env.NODE_ENV === 'production') { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | ready () { 8 | console.log( 9 | 'App is being served from cache by a service worker.\n' + 10 | 'For more details, visit https://goo.gl/AFskqB' 11 | ) 12 | }, 13 | registered () { 14 | console.log('Service worker has been registered.') 15 | }, 16 | cached () { 17 | console.log('Content has been cached for offline use.') 18 | }, 19 | updatefound () { 20 | console.log('New content is downloading.') 21 | }, 22 | updated () { 23 | console.log('New content is available; please refresh.') 24 | }, 25 | offline () { 26 | console.log('No internet connection found. App is running in offline mode.') 27 | }, 28 | error (error) { 29 | console.error('Error during service worker registration:', error) 30 | } 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /src/components/TimePicker.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | -------------------------------------------------------------------------------- /src/components/ColorPicker.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Use Node.js 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: '12.x' 19 | - name: Cache node modules 20 | uses: actions/cache@v1 21 | env: 22 | cache-name: cache-node-modules 23 | with: 24 | path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS 25 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 26 | restore-keys: | 27 | ${{ runner.os }}-build-${{ env.cache-name }}- 28 | ${{ runner.os }}-build- 29 | ${{ runner.os }}- 30 | - run: npm ci 31 | - run: npm run build 32 | - name: Tencent Cloud COS Action 33 | uses: TencentCloud/cos-action@v1 34 | with: 35 | secret_id: ${{ secrets.TENCENT_CLOUD_SECRET_ID }} 36 | secret_key: ${{ secrets.TENCENT_CLOUD_SECRET_KEY }} 37 | cos_bucket: ${{ secrets.COS_BUCKET }} 38 | cos_region: ${{ secrets.COS_REGION }} 39 | local_path: dist 40 | remote_path: /day-progress/ 41 | clean: true -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # day-progress 2 | 3 | ![demo](docs/demo.png) 4 | 5 | 显示今天剩余时间的进度条。以起床时间开始,睡觉时间结束(默认是9:00~22:00),让你直观感受时间流逝,把握时间完成工作,从而按时睡觉。 6 | 7 | 之所以写这个,是因为找了很多个显示时间进度条的项目都不满足我的需求,那些项目都是统计0:00~24:00的,容易给人晚上时间很多的错觉,从而习惯熬夜。 8 | 9 | [在线DEMO](https://tiaod.github.io/day-progress/) 10 | 11 | 推荐使用[Wallpaper engine](https://www.wallpaperengine.io/)或者[lively](https://github.com/rocksdanister/lively)之类的工具设置为桌面背景。 12 | 13 | 看着时间像手机电池电量一样减少,感觉是很奇妙的。 14 | 15 | ## Features 16 | - 自定义开始和结束时间 17 | - 暗色/亮色模式 18 | - 自定义主题颜色 19 | - 设置背景图片(需要填写背景图片的地址) 20 | - 参数保存到url,方便复制链接到lively设置壁纸 21 | 22 | ![demo2](docs/demo2.jpg) 23 | # Project setup 24 | ``` 25 | npm install 26 | ``` 27 | 28 | ### Compiles and hot-reloads for development 29 | ``` 30 | npm run serve 31 | ``` 32 | 33 | ### Compiles and minifies for production 34 | ``` 35 | npm run build 36 | ``` 37 | # Docker 38 | build docke image from Dockfile 39 | ``` 40 | docker build -t imagename:imagetag . 41 | ``` 42 | create docker container 43 | ``` 44 | docker run -p 8888:8080 -itd --name containname imagename:imagetag npm run serve 45 | ``` 46 | access 47 | ``` 48 | localhost:8888/day-progress 49 | ``` 50 | Run a command in a running container 51 | ``` 52 | docker exec -it containname sh 53 | ``` 54 | 55 | Compiles and minifies for production 56 | ``` 57 | npm run build 58 | ``` 59 | ### Customize configuration 60 | See [Configuration Reference](https://cli.vuejs.org/config/). 61 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-progress", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "electron:build": "vue-cli-service electron:build", 9 | "electron:serve": "vue-cli-service electron:serve", 10 | "postinstall": "electron-builder install-app-deps", 11 | "postuninstall": "electron-builder install-app-deps" 12 | }, 13 | "main": "background.js", 14 | "dependencies": { 15 | "core-js": "^3.6.4", 16 | "dayjs": "^1.8.26", 17 | "electron-tray-indicator": "^0.1.0", 18 | "lodash": "^4.17.15", 19 | "register-service-worker": "^1.7.1", 20 | "vue": "^2.6.11", 21 | "vue-router": "^3.1.6", 22 | "vuetify": "^2.2.11", 23 | "vuex": "^3.1.3" 24 | }, 25 | "devDependencies": { 26 | "@mdi/js": "^5.1.45", 27 | "@vue/cli-plugin-babel": "~4.3.0", 28 | "@vue/cli-plugin-pwa": "~4.3.0", 29 | "@vue/cli-plugin-router": "~4.3.0", 30 | "@vue/cli-plugin-vuex": "~4.3.0", 31 | "@vue/cli-service": "~4.3.0", 32 | "electron": "^7.2.4", 33 | "pug": "^2.0.4", 34 | "pug-plain-loader": "^1.0.0", 35 | "sass": "^1.19.0", 36 | "sass-loader": "^8.0.0", 37 | "stylus": "^0.54.7", 38 | "stylus-loader": "^3.0.2", 39 | "vue-cli-plugin-electron-builder": "~1.4.6", 40 | "vue-cli-plugin-vuetify": "~2.0.5", 41 | "vue-template-compiler": "^2.6.11", 42 | "vuetify-loader": "^1.3.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/background.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import { app, protocol, BrowserWindow, Tray } from 'electron' 4 | import { progress, clean } from 'electron-tray-indicator' 5 | import path from 'path' 6 | import { 7 | createProtocol, 8 | /* installVueDevtools */ 9 | } from 'vue-cli-plugin-electron-builder/lib' 10 | const isDevelopment = process.env.NODE_ENV !== 'production' 11 | 12 | // Keep a global reference of the window object, if you don't, the window will 13 | // be closed automatically when the JavaScript object is garbage collected. 14 | let win 15 | 16 | // Scheme must be registered before the app is ready 17 | protocol.registerSchemesAsPrivileged([{scheme: 'app', privileges: { secure: true, standard: true } }]) 18 | 19 | function createWindow () { 20 | // Create the browser window. 21 | win = new BrowserWindow({ width: 800, height: 600, webPreferences: { 22 | nodeIntegration: true 23 | }, frame: true, transparent:true}) 24 | 25 | if (process.env.WEBPACK_DEV_SERVER_URL) { 26 | // Load the url of the dev server if in development mode 27 | win.loadURL(process.env.WEBPACK_DEV_SERVER_URL) 28 | if (!process.env.IS_TEST) win.webContents.openDevTools() 29 | } else { 30 | createProtocol('app') 31 | // Load the index.html when not in development 32 | win.loadURL('app://./index.html') 33 | } 34 | 35 | win.on('closed', () => { 36 | win = null 37 | }) 38 | } 39 | 40 | // Quit when all windows are closed. 41 | app.on('window-all-closed', () => { 42 | // On macOS it is common for applications and their menu bar 43 | // to stay active until the user quits explicitly with Cmd + Q 44 | if (process.platform !== 'darwin') { 45 | app.quit() 46 | } 47 | }) 48 | 49 | app.on('activate', () => { 50 | // On macOS it's common to re-create a window in the app when the 51 | // dock icon is clicked and there are no other windows open. 52 | if (win === null) { 53 | createWindow() 54 | } 55 | }) 56 | 57 | // This method will be called when Electron has finished 58 | // initialization and is ready to create browser windows. 59 | // Some APIs can only be used after this event occurs. 60 | app.on('ready', async () => { 61 | if (isDevelopment && !process.env.IS_TEST) { 62 | // Install Vue Devtools 63 | // Devtools extensions are broken in Electron 6.0.0 and greater 64 | // See https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/378 for more info 65 | // Electron will not launch with Devtools extensions installed on Windows 10 with dark mode 66 | // If you are not using Windows 10 dark mode, you may uncomment these lines 67 | // In addition, if the linked issue is closed, you can upgrade electron and uncomment these lines 68 | // try { 69 | // await installVueDevtools() 70 | // } catch (e) { 71 | // console.error('Vue Devtools failed to install:', e.toString()) 72 | // } 73 | 74 | } 75 | createWindow() 76 | let tray = new Tray(path.join(__dirname, 'assets/logo.png')) 77 | }) 78 | 79 | // Exit cleanly on request from parent process in development mode. 80 | if (isDevelopment) { 81 | if (process.platform === 'win32') { 82 | process.on('message', data => { 83 | if (data === 'graceful-exit') { 84 | app.quit() 85 | } 86 | }) 87 | } else { 88 | process.on('SIGTERM', () => { 89 | app.quit() 90 | }) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 93 | 94 | 152 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 196 | -------------------------------------------------------------------------------- /public/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 148 | 149 | 150 | --------------------------------------------------------------------------------