├── .gitignore ├── .travis.yml ├── LICENSE.md ├── app ├── css │ └── app.css ├── img │ ├── cafe.jpg │ ├── close.png │ ├── drops.jpg │ ├── fire.jpg │ ├── foco.png │ ├── iconTemplate@2x.png │ ├── image.jpg │ ├── mute.png │ ├── night.jpeg │ ├── rain.jpg │ └── unmute.png ├── index.html ├── index.js ├── js │ ├── app.js │ └── template.js ├── package-lock.json ├── package.json └── resources │ ├── icons │ ├── icon.icns │ ├── icon.ico │ ├── icon.png │ └── iconlinux.png │ └── sound │ ├── cafe.mp3 │ ├── drops.mp3 │ ├── fire.mp3 │ ├── night.mp3 │ └── rain.mp3 ├── appveyor.yml ├── build ├── icon.icns ├── icon.ico ├── icon.png └── iconlinux.png ├── design └── design.png ├── npm-debug.log ├── package.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | *.app 4 | dist 5 | Plugin.sketch 6 | yarn.lock 7 | *npm-debug.log -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - 'node' 5 | 6 | before_install: 7 | - npm install 8 | 9 | before_script: 10 | - "export DISPLAY=:99.0" 11 | - "sh -e /etc/init.d/xvfb start" 12 | - sleep 5 # give xvfb some time to start 13 | 14 | cache: 15 | directories: 16 | - node_modules 17 | 18 | script: 19 | - npm run test 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Akash Nimare 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /app/css/app.css: -------------------------------------------------------------------------------- 1 | /** 2 | Set box-sizing to border-box for all elements by default. This makes it 3 | easier to ensure widths when adding padding and borders. */ 4 | 5 | html { 6 | box-sizing: border-box; 7 | -webkit-box-sizing: border-box; 8 | font-size: 100%; 9 | -webkit-text-size-adjust: 100%; 10 | -webkit-user-select: none; 11 | /* disable text highlighting as suggested by sindresorhus */ 12 | } 13 | 14 | *, 15 | *::before, 16 | *::after { 17 | box-sizing: inherit; 18 | -webkit-box-sizing: inherit; 19 | } 20 | 21 | body { 22 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 23 | margin: 0; 24 | background: #fff; 25 | -webkit-background-size: cover; 26 | background-size: cover; 27 | font-size: 1em; 28 | line-height: 1.4 29 | } 30 | 31 | ::-webkit-scrollbar { 32 | display: none; 33 | } 34 | 35 | h2 { 36 | margin: -15px 0 0 10px; 37 | font-size: 17px; 38 | color: #77b4e8; 39 | } 40 | 41 | ul { 42 | list-style-type: none; 43 | margin-left: -20px; 44 | padding: 0; 45 | margin-top: -20px; 46 | } 47 | 48 | li:first-child { 49 | border-top: none; 50 | margin-top: -10px; 51 | } 52 | 53 | li { 54 | float: left; 55 | margin: 0; 56 | padding: 26px 50px; 57 | text-align: center; 58 | border-top: 1px solid #000; 59 | } 60 | 61 | .player input { 62 | font-size: 100%; 63 | margin: 0; 64 | vertical-align: baseline; 65 | vertical-align: middle; 66 | line-height: normal 67 | } 68 | 69 | .player input[type="checkbox"] { 70 | box-sizing: border-box; 71 | padding: 0; 72 | height: 13px; 73 | width: 13px 74 | } 75 | 76 | .player input[type="range"] { 77 | float: left; 78 | width: 155px; 79 | margin: 5px 0 0 20px; 80 | } 81 | 82 | .player input[type="checkbox"] { 83 | display: none; 84 | } 85 | 86 | .player input[type="checkbox"]:checked+label { 87 | background-position: 0 0; 88 | background: rgba(0, 0, 0, 0.9); 89 | } 90 | 91 | .player input[type="checkbox"]:checked+label span { 92 | left: 30px; 93 | } 94 | 95 | .clear { 96 | clear: both 97 | } 98 | 99 | .container { 100 | background-color: #373a47; 101 | text-align: center; 102 | border: 1px solid #202020; 103 | box-shadow: inset 0 1px 3px rgba(255, 255, 255, .1), 0 3px 5px rgba(0, 0, 0, .1) 104 | } 105 | 106 | .player label { 107 | color: transparent; 108 | border-radius: 14px; 109 | border: 2px solid #f2f2f2; 110 | display: block; 111 | position: relative; 112 | text-indent: 100%; 113 | width: 56px; 114 | height: 26px; 115 | -webkit-transition: background-position .3s ease; 116 | cursor: pointer; 117 | font-size: .01em; 118 | float: left; 119 | } 120 | 121 | .player label span { 122 | background: #fff; 123 | content: ""; 124 | display: block; 125 | position: absolute; 126 | top: -1px; 127 | left: -1px; 128 | width: 23px; 129 | height: 23px; 130 | -webkit-transition: left .3s ease; 131 | -moz-transition: left .3s ease; 132 | transition: all .2s ease; 133 | border: 4px solid #f2f2f2; 134 | border-radius: 2em; 135 | } 136 | 137 | audio { 138 | display: inline-block; 139 | display: inline; 140 | zoom: 1 141 | } 142 | 143 | audio:not([controls]) { 144 | display: none; 145 | height: 0 146 | } 147 | 148 | .arrow { 149 | position: fixed; 150 | padding: 12px 0; 151 | background: transparent; 152 | } 153 | 154 | .arrow:before { 155 | content: ""; 156 | height: 0; 157 | width: 0; 158 | border-width: 0 8px 12px 8px; 159 | border-style: solid; 160 | border-color: transparent transparent black transparent; 161 | position: fixed; 162 | top: 0px; 163 | left: 50%; 164 | transform: translateX(-50%); 165 | } 166 | 167 | .close { 168 | background: transparent url('../img/close.png') no-repeat 4px 4px; 169 | background-size: 24px 24px; 170 | cursor: pointer; 171 | display: inline-block; 172 | height: 32px; 173 | position: fixed; 174 | right: 6px; 175 | text-indent: -10000px; 176 | top: 16px; 177 | width: 32px; 178 | opacity: 0.9; 179 | z-index: 1; 180 | } 181 | 182 | #mute-button { 183 | position: relative; 184 | display: inline-block; 185 | width: 35px; 186 | height: 35px; 187 | margin-left: -15px; 188 | cursor: pointer; 189 | } 190 | 191 | input:checked+.slider { 192 | background-color: #2196F3; 193 | } 194 | 195 | input:focus+.slider { 196 | box-shadow: 0 0 1px #2196F3; 197 | } 198 | 199 | input:checked+.slider:before { 200 | -webkit-transform: translateX(26px); 201 | -ms-transform: translateX(26px); 202 | transform: translateX(26px); 203 | } 204 | 205 | /* Rounded sliders */ 206 | 207 | .slider.round { 208 | border-radius: 34px; 209 | } 210 | 211 | .slider.round:before { 212 | border-radius: 50%; 213 | } 214 | 215 | .on { 216 | background-image: url('../img/mute.png'); 217 | background-size: cover; 218 | } 219 | 220 | .off { 221 | background-image: url('../img/unmute.png'); 222 | background-size: cover; 223 | } 224 | 225 | .control-section { 226 | background: #fff; 227 | margin-bottom: 25px; 228 | } 229 | 230 | .cafe { 231 | background: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url("../img/cafe.jpg"); 232 | background-position: center; 233 | } 234 | 235 | .rain { 236 | background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url('../img/rain.jpg') 237 | } 238 | 239 | .fire { 240 | background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url("../img/fire.jpg"); 241 | background-position: center; 242 | } 243 | 244 | .drops { 245 | background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url("../img/drops.jpg"); 246 | background-position: center; 247 | } 248 | 249 | .night { 250 | background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url("../img/night.jpeg"); 251 | background-position: center; 252 | } 253 | 254 | .player-section { 255 | display: block; 256 | width: 320px; 257 | } -------------------------------------------------------------------------------- /app/img/cafe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/cafe.jpg -------------------------------------------------------------------------------- /app/img/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/close.png -------------------------------------------------------------------------------- /app/img/drops.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/drops.jpg -------------------------------------------------------------------------------- /app/img/fire.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/fire.jpg -------------------------------------------------------------------------------- /app/img/foco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/foco.png -------------------------------------------------------------------------------- /app/img/iconTemplate@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/iconTemplate@2x.png -------------------------------------------------------------------------------- /app/img/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/image.jpg -------------------------------------------------------------------------------- /app/img/mute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/mute.png -------------------------------------------------------------------------------- /app/img/night.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/night.jpeg -------------------------------------------------------------------------------- /app/img/rain.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/rain.jpg -------------------------------------------------------------------------------- /app/img/unmute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/img/unmute.png -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Foco - Stay Focused 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 |
Close
15 |
16 |
17 | 19 |
20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const menubar = require("menubar"); 3 | const { Menu } = require("electron"); 4 | 5 | const APP_ICON = path.join(__dirname, "resources/icons", "icon"); 6 | 7 | const iconPath = () => { 8 | return APP_ICON + (process.platform === "win32" ? ".ico" : ".png"); 9 | }; 10 | 11 | const mb = menubar({ 12 | transparent: true, 13 | width: 305, 14 | height: 500, 15 | icon: iconPath(), 16 | resizable: false 17 | }); 18 | 19 | const template = [ 20 | { 21 | label: "Foco", 22 | submenu: [ 23 | { 24 | label: "Reload", 25 | accelerator: "CmdOrCtrl+R", 26 | click: (item, focusedWindow) => { 27 | if (focusedWindow) { 28 | focusedWindow.reload(); 29 | } 30 | } 31 | }, 32 | { 33 | label: "Quit App", 34 | accelerator: "CmdOrCtrl+Q", 35 | role: "quit" 36 | }, 37 | { 38 | label: "Toggle DevTools", 39 | accelerator: "Alt+Command+I", 40 | click: () => { 41 | mb.window.toggleDevTools(); 42 | } 43 | } 44 | ] 45 | } 46 | ]; 47 | 48 | mb.on("ready", () => { 49 | console.log("Foco is ready to boost your productivity"); 50 | 51 | // setting this manually otherwise it will go in left 52 | if (process.platform === "linux") { 53 | mb.setOption("x", 946); 54 | mb.setOption("y", 10); 55 | } 56 | 57 | const menu = Menu.buildFromTemplate(template); 58 | Menu.setApplicationMenu(menu); 59 | }); 60 | 61 | //right click menu for Tray 62 | mb.on("after-create-window", function() { 63 | const contextMenu = Menu.buildFromTemplate([ 64 | { 65 | label: "restart app", 66 | click: () => { 67 | mb.app.quit(); 68 | mb.app.relaunch(); 69 | } 70 | }, 71 | { type: "separator" }, 72 | { 73 | label: "Quit", 74 | click: () => { 75 | mb.app.quit(); 76 | } 77 | } 78 | ]); 79 | mb.tray.on("right-click", () => { 80 | mb.tray.popUpContextMenu(contextMenu); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /app/js/app.js: -------------------------------------------------------------------------------- 1 | const { remote } = require("electron"); 2 | 3 | // Build Player section 4 | class Create { 5 | constructor(switchEl, volumeEl, audioEl) { 6 | this.switchEl = switchEl; 7 | this.volumeEl = volumeEl; 8 | this.audioEl = audioEl; 9 | this.isPlaying = false; 10 | this.switchEl.addEventListener("click", this.toggle.bind(this)); 11 | this.volumeEl.onchange = this.adjustVolume.bind(this); 12 | } 13 | toggle() { 14 | console.log("toggle fired"); 15 | this.isPlaying ? this.pause() : this.play(); 16 | this.isPlaying = !this.isPlaying; 17 | } 18 | pause() { 19 | this.audioEl.stop; 20 | this.switchEl.checked = false; 21 | this.audioEl.pause(); 22 | console.log("stop"); 23 | } 24 | play() { 25 | console.log("start"); 26 | this.switchEl.checked = true; 27 | this.audioEl.play("hello", this.switchEl.checked); 28 | } 29 | adjustVolume(e) { 30 | console.log("volume adjusted"); 31 | this.audioEl.volume = this.volumeEl.value / 100; 32 | } 33 | } 34 | 35 | const domSounds = document.getElementsByTagName("ul")[0].children; 36 | const sounds = []; 37 | 38 | Array.from(domSounds).forEach(domSound => { 39 | sounds.push( 40 | new Create( 41 | domSound.children[3].children[0], 42 | domSound.children[3].children[2], 43 | domSound.children[2] 44 | ) 45 | ); 46 | }); 47 | 48 | const pauseAll = () => { 49 | sounds.forEach(sound => sound.pause()); 50 | }; 51 | 52 | const playAll = () => { 53 | sounds.forEach(sound => sound.play()); 54 | }; 55 | 56 | const toggleAudio = audio => { 57 | audio ? setAudio(false) : setAudio(true); 58 | }; 59 | 60 | const prefWindow = remote.getCurrentWindow(); 61 | const closeButton = document.getElementById("close-button"); 62 | const muteButton = document.getElementById("mute-button"); 63 | const setAudio = prefWindow.webContents.setAudioMuted; 64 | 65 | // Set Audio to true on app load 66 | setAudio(false); 67 | 68 | // Quit app on clicking close button 69 | closeButton.addEventListener("click", () => { 70 | prefWindow.close(); 71 | }); 72 | 73 | muteButton.addEventListener("click", function(e) { 74 | let isAudio = this.className; 75 | if (isAudio === "off") { 76 | this.className = "on"; 77 | this.title = "mute"; 78 | setAudio(false); 79 | } else { 80 | this.className = "off"; 81 | this.title = "unmute"; 82 | setAudio(true); 83 | } 84 | }); 85 | -------------------------------------------------------------------------------- /app/js/template.js: -------------------------------------------------------------------------------- 1 | const soundTemplate = name => { 2 | return `
  • 3 |

    ${name}

    4 |
    5 | 8 |
    9 | 10 | 13 | 14 |
    15 |
  • 16 | `; 17 | }; 18 | 19 | const soundNames = ["cafe", "fire", "night", "rain", "drops"]; 20 | 21 | const markup = `${soundNames.map(name => soundTemplate(name))}`; 22 | 23 | document.getElementById("sounds-section").innerHTML = markup; 24 | -------------------------------------------------------------------------------- /app/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foco", 3 | "version": "1.7.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "electron-positioner": { 8 | "version": "3.0.0", 9 | "resolved": "https://registry.npmjs.org/electron-positioner/-/electron-positioner-3.0.0.tgz", 10 | "integrity": "sha1-Gjt1ycweKd03xmOyP9h21P+rmZY=" 11 | }, 12 | "extend": { 13 | "version": "2.0.1", 14 | "resolved": "https://registry.npmjs.org/extend/-/extend-2.0.1.tgz", 15 | "integrity": "sha1-HugBBonnOV/5RIJByYZSvHWagmA=" 16 | }, 17 | "menubar": { 18 | "version": "5.2.3", 19 | "resolved": "https://registry.npmjs.org/menubar/-/menubar-5.2.3.tgz", 20 | "integrity": "sha1-jydhWXtKDuh+3wSofYqrGqwsROk=", 21 | "requires": { 22 | "electron-positioner": "3.0.0", 23 | "extend": "2.0.1" 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foco", 3 | "version": "1.7.0", 4 | "productName": "Foco", 5 | "description": "Stay focused with Foco and boosts productivity 🚀 by creating perfect productive environment.", 6 | "author": "Akash Nimare", 7 | "license": "MIT", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/akashnimare/foco" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/akashnimare/foco/issues" 14 | }, 15 | "main": "index.js", 16 | "homepage": "http://akashnimare.in", 17 | "dependencies": { 18 | "menubar": "5.2.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/resources/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/resources/icons/icon.icns -------------------------------------------------------------------------------- /app/resources/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/resources/icons/icon.ico -------------------------------------------------------------------------------- /app/resources/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/resources/icons/icon.png -------------------------------------------------------------------------------- /app/resources/icons/iconlinux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/resources/icons/iconlinux.png -------------------------------------------------------------------------------- /app/resources/sound/cafe.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/resources/sound/cafe.mp3 -------------------------------------------------------------------------------- /app/resources/sound/drops.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/resources/sound/drops.mp3 -------------------------------------------------------------------------------- /app/resources/sound/fire.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/resources/sound/fire.mp3 -------------------------------------------------------------------------------- /app/resources/sound/night.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/resources/sound/night.mp3 -------------------------------------------------------------------------------- /app/resources/sound/rain.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/app/resources/sound/rain.mp3 -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: build{build} 2 | 3 | platform: 4 | - x64 5 | os: Previous Visual Studio 2015 6 | 7 | cache: 8 | - node_modules 9 | 10 | install: 11 | - ps: Install-Product node 6 x64 12 | - git reset --hard HEAD 13 | - npm install npm -g 14 | - node --version 15 | - npm --version 16 | - python --version 17 | - npm install 18 | 19 | build: off 20 | 21 | test_script: 22 | - npm run test 23 | -------------------------------------------------------------------------------- /build/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/build/icon.icns -------------------------------------------------------------------------------- /build/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/build/icon.ico -------------------------------------------------------------------------------- /build/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/build/icon.png -------------------------------------------------------------------------------- /build/iconlinux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/build/iconlinux.png -------------------------------------------------------------------------------- /design/design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akashnimare/foco/bf1e08df553f156851eba73f1bc898ce55e5f87b/design/design.png -------------------------------------------------------------------------------- /npm-debug.log: -------------------------------------------------------------------------------- 1 | 0 info it worked if it ends with ok 2 | 1 verbose cli [ '/Users/akka/.nvm/versions/node/v6.9.4/bin/node', 3 | 1 verbose cli '/Users/akka/.nvm/versions/node/v6.9.4/bin/npm', 4 | 1 verbose cli 'start' ] 5 | 2 info using npm@3.10.10 6 | 3 info using node@v6.9.4 7 | 4 verbose run-script [ 'prestart', 'start', 'poststart' ] 8 | 5 info lifecycle foco@1.7.0~prestart: foco@1.7.0 9 | 6 silly lifecycle foco@1.7.0~prestart: no script for prestart, continuing 10 | 7 info lifecycle foco@1.7.0~start: foco@1.7.0 11 | 8 verbose lifecycle foco@1.7.0~start: unsafe-perm in lifecycle true 12 | 9 verbose lifecycle foco@1.7.0~start: PATH: /Users/akka/.nvm/versions/node/v6.9.4/lib/node_modules/npm/bin/node-gyp-bin:/Users/akka/dev/github/foco/node_modules/.bin:/Users/akka/.nvm/versions/node/v6.9.4/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/MacGPG2/bin:/opt/X11/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/Users/akka/Library/Android/sdk/tools:/Users/akka/Library/Android/sdk/platform-tools:/Users/akka/bin:/Users/akka/Library/Android/sdk/tools:/Users/akka/Library/Android/sdk/platform-tools:/Users/akka/bin 13 | 10 verbose lifecycle foco@1.7.0~start: CWD: /Users/akka/dev/github/foco 14 | 11 silly lifecycle foco@1.7.0~start: Args: [ '-c', 'yarn install && electron ./app' ] 15 | 12 silly lifecycle foco@1.7.0~start: Returned: code: 1 signal: null 16 | 13 info lifecycle foco@1.7.0~start: Failed to exec start script 17 | 14 verbose stack Error: foco@1.7.0 start: `yarn install && electron ./app` 18 | 14 verbose stack Exit status 1 19 | 14 verbose stack at EventEmitter. (/Users/akka/.nvm/versions/node/v6.9.4/lib/node_modules/npm/lib/utils/lifecycle.js:255:16) 20 | 14 verbose stack at emitTwo (events.js:106:13) 21 | 14 verbose stack at EventEmitter.emit (events.js:191:7) 22 | 14 verbose stack at ChildProcess. (/Users/akka/.nvm/versions/node/v6.9.4/lib/node_modules/npm/lib/utils/spawn.js:40:14) 23 | 14 verbose stack at emitTwo (events.js:106:13) 24 | 14 verbose stack at ChildProcess.emit (events.js:191:7) 25 | 14 verbose stack at maybeClose (internal/child_process.js:877:16) 26 | 14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5) 27 | 15 verbose pkgid foco@1.7.0 28 | 16 verbose cwd /Users/akka/dev/github/foco 29 | 17 error Darwin 17.3.0 30 | 18 error argv "/Users/akka/.nvm/versions/node/v6.9.4/bin/node" "/Users/akka/.nvm/versions/node/v6.9.4/bin/npm" "start" 31 | 19 error node v6.9.4 32 | 20 error npm v3.10.10 33 | 21 error code ELIFECYCLE 34 | 22 error foco@1.7.0 start: `yarn install && electron ./app` 35 | 22 error Exit status 1 36 | 23 error Failed at the foco@1.7.0 start script 'yarn install && electron ./app'. 37 | 23 error Make sure you have the latest version of node.js and npm installed. 38 | 23 error If you do, this is most likely a problem with the foco package, 39 | 23 error not with npm itself. 40 | 23 error Tell the author that this fails on your system: 41 | 23 error yarn install && electron ./app 42 | 23 error You can get information on how to open an issue for this project with: 43 | 23 error npm bugs foco 44 | 23 error Or if that isn't available, you can get their info via: 45 | 23 error npm owner ls foco 46 | 23 error There is likely additional logging output above. 47 | 24 verbose exit [ 1, true ] 48 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foco", 3 | "version": "1.7.0", 4 | "productName": "Foco", 5 | "description": "Stay focused with Foco and boosts productivity 🚀 by creating perfect productive environment.", 6 | "author": "Akash Nimare", 7 | "license": "MIT", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/akashnimare/foco" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/akashnimare/foco/issues" 14 | }, 15 | "main": "index.js", 16 | "scripts": { 17 | "postinstall": "electron-builder install-app-deps", 18 | "test": "standard", 19 | "start": "yarn install && electron ./app", 20 | "pack": "electron-builder --dir", 21 | "dist": "electron-builder", 22 | "clean": "rm -Rf node_modules && rm -Rf ./dist" 23 | }, 24 | "build": { 25 | "appId": "app.foco", 26 | "asar": true, 27 | "files": [ 28 | "**/*" 29 | ], 30 | "copyright": "Akash Nimare", 31 | "mac": { 32 | "category": "public.app-category.productivity", 33 | "identity": null 34 | }, 35 | "linux": { 36 | "category": "", 37 | "packageCategory": "GNOME;GTK;MUSIC;PRODUCTIVITY", 38 | "description": "Stay focused with Foco", 39 | "target": [ 40 | "deb", 41 | "zip", 42 | "AppImage" 43 | ], 44 | "maintainer": "Akash Nimare " 45 | }, 46 | "deb": { 47 | "synopsis": "Foco Desktop App" 48 | }, 49 | "dmg": { 50 | "icon": "build/icon.icns", 51 | "iconSize": 128, 52 | "contents": [ 53 | { 54 | "x": 380, 55 | "y": 240, 56 | "type": "link", 57 | "path": "/Applications" 58 | }, 59 | { 60 | "x": 122, 61 | "y": 240, 62 | "type": "file" 63 | } 64 | ] 65 | }, 66 | "win": { 67 | "target": "nsis", 68 | "icon": "build/icon.ico" 69 | }, 70 | "nsis": { 71 | "perMachine": true, 72 | "oneClick": false 73 | } 74 | }, 75 | "keywords": [ 76 | "electron", 77 | "productivity", 78 | "focus", 79 | "menubar", 80 | "menu", 81 | "mac", 82 | "app" 83 | ], 84 | "homepage": "http://akashnimare.in", 85 | "dependencies": { 86 | "menubar": "5.2.3" 87 | }, 88 | "devDependencies": { 89 | "electron-builder": "20.8.1", 90 | "electron": "1.8.4", 91 | "standard": "*" 92 | } 93 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Foco 2 | [![Build Status](https://travis-ci.org/akashnimare/foco.svg?branch=master)](https://travis-ci.org/akashnimare/foco) 3 | [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/akashnimare/foco?branch=master&svg=true)](https://ci.appveyor.com/project/akashnimare/foco/branch/master) 4 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard) 5 | 6 |

    7 |
    8 | Foco 9 |

    10 | 11 |

    A desktop menubar app based on Electron.

    12 | 13 | Foco is a cross-platform desktop app :computer: which runs in menubar. 14 | Foco boosts your productivity :rocket: by creating perfect productive environment. 15 | It has the best sounds for getting work done :raised_hands:. 16 | 17 | # Demo 18 | 👉 Watch it here. 19 |
    20 | 21 | [![Watch demo](https://cloud.githubusercontent.com/assets/2263909/18597112/0622a3b0-7c6a-11e6-897d-13f0aa36b6e4.png)](https://www.youtube.com/watch?v=6SG2Mjpv8YE) 22 | 23 | 24 | 25 | ## Installation 26 | [FR]: https://github.com/akashnimare/foco/releases 27 | 28 | ### OS X 29 | 30 | 1. Download [Foco-osx.x.x.x.dmg][FR] or [Foco-osx.x.x.x.zip][FR] 31 | 2. Open or unzip the file and drag the app into the `Applications` folder 32 | 3. Done! 33 | 34 | ### Windows 35 | coming soon :stuck_out_tongue_closed_eyes: 36 | 37 | ### Linux 38 | 39 | *Ubuntu, Debian 8+ (deb package):* 40 | 41 | 1. Download [Foco-linux.x.x.x.deb][FR] 42 | 2. Double click and install, or run `dpkg -i Foco-linux.x.x.x.deb` in the terminal 43 | 3. Start the app with your app launcher or by running `foco` in a terminal 44 | 45 | 46 | ### For developers 47 | Clone the source locally: 48 | 49 | ```sh 50 | $ git clone https://github.com/akashnimare/foco/ 51 | $ cd foco 52 | ``` 53 | If you're on Debian or Ubuntu, you'll also need to install 54 | `nodejs-legacy`: 55 | 56 | Use your package manager to install `npm`. 57 | 58 | ```sh 59 | $ sudo apt-get install npm nodejs-legacy 60 | ``` 61 | 62 | Install project dependencies: 63 | 64 | ```sh 65 | $ npm install 66 | ``` 67 | Start the app: 68 | 69 | ```sh 70 | $ npm start 71 | ``` 72 | 73 | ### Build installers 74 | 75 | Build app for OSX 76 | ```sh 77 | $ npm run build:osx 78 | ``` 79 | Build app for Linux 80 | ```sh 81 | $ npm run build:linux 82 | ``` 83 | 84 | ## Features 85 | 86 | - [x] Offline support 87 | - [x] Cross-platform 88 | - [x] Awesome sounds 89 | - [x] No singup/login required 90 | - [ ] Auto launch 91 | - [ ] Auto updates 92 | 93 | 94 | ## Usage 95 | 96 | Command/ctrl + R - Reload 97 | 98 | command + q - Quit App (while window is open). 99 | 100 | ## Built with 101 | - [Electron](https://electron.atom.io) 102 | - [Menubar](https://github.com/maxogden/menubar) 103 | 104 | ## Related 105 | - [zulip-electron](https://github.com/zulip/zulip-electron) 106 | 107 | ## License 108 | 109 | MIT © [Akash Nimare](http://akashnimare.in) 110 | --------------------------------------------------------------------------------