Skip to content

Commit

Permalink
Merge pull request #1 from aouerfelli/develop
Browse files Browse the repository at this point in the history
Merged changes for v1.1.0
  • Loading branch information
Ahmad Ouerfelli authored Jun 28, 2017
2 parents 7049701 + 2544ecc commit dfdbbfe
Show file tree
Hide file tree
Showing 17 changed files with 574 additions and 416 deletions.
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# http://EditorConfig.org
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
14 changes: 14 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"root": true,
"extends": "airbnb-base",
"env": {
"browser": true,
"node": true
},
"rules": {
"import/extensions": 0,
"import/no-extraneous-dependencies": 0,
"import/no-unresolved": [2, { "ignore": ["electron"] }],
"no-param-reassign": ["error", { "props": false }]
}
}
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
dist
node_modules
npm-debug.log
debug.log
*.log
.DS_Store
dist
92 changes: 92 additions & 0 deletions app/elements/action-button/action-button.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<template id="action-button-template">
<style>
/* This is the only workaround I could think of (besides having a duplicate copy of the needed styles) */
@import url('../styles/base.css');

.container {
display: inline-flex;
flex-direction: column-reverse;
align-items: center;
justify-content: center;
}

.button {
position: relative;
display: flex;
align-items: center;
justify-content: center;
padding: 0.375rem;
margin: 0.75rem;
margin-top: 0;
outline: none;
border: none;
background-color: transparent;
}

.button::before {
content: '';
position: absolute;
z-index: -1;
width: 0;
height: 0;
border-radius: 50%;
background-color: var(--color-grey);
opacity: 0;
transition: all 0.3s var(--curve-standard);
transition-property: width, height, opacity;
will-change: width, height, opacity;
}

.button:active::before {
width: 3rem;
height: 3rem;
opacity: 0.3;
}

.button .icon-container {
width: 2.25rem;
height: 2.25rem;
fill: var(--color-grey);
transition: fill 0.3s var(--curve-standard);
will-change: fill;
}

.button:focus .icon-container {
fill: var(--color-primary-light);
}

.button:hover .icon-container {
fill: var(--color-primary);
}

.button:active .icon-container {
fill: var(--color-primary-dark);
}

.label {
display: inline-block;
padding: 0.25rem 0.5rem;
font-size: 0.8em;
border-radius: var(--corner-radius);
color: var(--font-color-light);
background-color: var(--font-color-dark);
opacity: 0;
transition: opacity 0.3s var(--curve-sharp);
}

.button:hover ~ .label {
opacity: 0.7;
}
</style>

<div class="container">
<button class="button">
<svg class="icon-container" viewBox="0 0 24 24">
<path class="icon" d="" />
</svg>
</button>
<p class="label"></p>
</div>
</template>

<script src="action-button.js"></script>
105 changes: 105 additions & 0 deletions app/elements/action-button/action-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/* eslint-disable no-underscore-dangle */

class ActionButton extends HTMLElement {

static get observedAttributes() {
return ['label', 'icon'];
}

constructor() {
super();

const ownerDocument = document.currentScript.ownerDocument;
const template = ownerDocument.querySelector('#action-button-template');
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(template.content.cloneNode(true));

this._components = {
container: shadowRoot.querySelector('.container'),
button: shadowRoot.querySelector('.button'),
label: shadowRoot.querySelector('.label'),
icon: shadowRoot.querySelector('.icon'),
};
this._action = undefined;
}

getAttributeValue(attributeName) {
return this.hasAttribute(attributeName) ? this.getAttribute(attributeName) : '';
}

get label() {
return this.getAttributeValue(this._components.label.className);
}

set label(label) {
if (!label) {
return;
}

this._components.label.textContent = label;
}

get icon() {
return this.getAttributeValue(this._components.icon.className);
}

set icon(icon) {
if (!icon) {
return;
}

this._components.icon.setAttribute('d', icon);
}

connectedCallback() {
// Action is a noop function by default
this.setAction(() => {});
}

disconnectedCallback() {
// Remove action from element on callback
this.removeAction();
}

attributeChangedCallback(attributeName, oldValue, newValue) {
if (attributeName === this._components.label.className) {
this.label = newValue;
// Must check with baseVal property for icon because the className is a SVGAnimatedString object
} else if (attributeName === this._components.icon.className.baseVal) {
this.icon = newValue;
}
}

setAction(action) {
if (typeof action !== 'function') {
return;
}

// Remove the current action and replace it with the new one
this.removeAction();
this._action = action;
this._components.button.addEventListener('click', this._action);
}

removeAction() {
this._components.button.removeEventListener('click', this._action);
}

hideButton() {
this.setHidden(true);
}

showButton() {
this.setHidden(false);
}

setHidden(hidden) {
if (typeof hidden !== 'boolean') {
return;
}

this._components.container.style.display = hidden ? 'none' : '';
}
}

window.customElements.define('action-button', ActionButton);
107 changes: 56 additions & 51 deletions app/main.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,65 @@
const {app, BrowserWindow, ipcMain} = require('electron');
const { app, BrowserWindow, ipcMain } = require('electron');

let mainWindow, setupWindow, pauseWindow;
/** @constant { boolean }
*
* Checks if the current environment is in development by looking for the asar package.
* If the package exists, then the app is in production mode.
* Otherwise (if it is not found), then the program is in development mode.
*/
const DEVELOPMENT = process.mainModule.filename.indexOf('app.asar') === -1;

let mainWindow = null;
let setupWindow = null;
let pauseWindow = null;

const initializeWindow = (windowType, windowName) => {
windowType.loadURL(`file://${__dirname}/views/${windowName}.html`);
windowType.setMenu(null);
if (DEVELOPMENT) {
windowType.webContents.openDevTools();
}

windowType.once('ready-to-show', windowType.show);
};

const exitApp = () => {
// Do not exit the program on macOS (standard OS-specific behaviour).
// Instead, lose app focus and close all open windows.
if (process.platform === 'darwin') {
app.hide();
BrowserWindow.getAllWindows().forEach(win => win.close());
} else {
app.quit();
}
};

function createMainWindow () {
const createMainWindow = () => {
mainWindow = new BrowserWindow({
fullscreen: true,
frame: false
frame: false,
});
mainWindow.loadURL(`file://${__dirname}/views/index.html`);
mainWindow.setMenu(null);

mainWindow.once('ready-to-show', mainWindow.show);
initializeWindow(mainWindow, 'index');

mainWindow.on('closed', () => mainWindow = null);
}
mainWindow.on('closed', () => (mainWindow = null));
};

function createSetupModalWindow () {
const createSetupModalWindow = () => {
setupWindow = new BrowserWindow({
parent: mainWindow,
modal: true,
minWidth: 400,
minHeight: 300,
frame: false
frame: false,
});
setupWindow.loadURL(`file://${__dirname}/views/setup.html`);
setupWindow.setMenu(null);

setupWindow.once('ready-to-show', setupWindow.show);
initializeWindow(setupWindow, 'setup');

setupWindow.on('close', exitApp);

setupWindow.on('closed', () => setupWindow = null);
}
setupWindow.on('closed', () => (setupWindow = null));
};

function createPauseModalWindow () {
mainWindow.webContents.executeJavaScript(
'document.body.classList.add(\'dim\')'
);
const createPauseModalWindow = () => {
mainWindow.webContents.executeJavaScript('document.body.classList.add(\'dim\')');

pauseWindow = new BrowserWindow({
parent: mainWindow,
Expand All @@ -45,64 +68,46 @@ function createPauseModalWindow () {
height: 250,
resizable: false,
closable: false,
frame: false
frame: false,
});
pauseWindow.loadURL(`file://${__dirname}/views/pause.html`);
pauseWindow.setMenu(null);

pauseWindow.once('ready-to-show', pauseWindow.show);
initializeWindow(pauseWindow, 'pause');

pauseWindow.on('close', exitApp);

pauseWindow.on('closed', () => {
mainWindow.webContents.executeJavaScript(
'document.body.classList.remove(\'dim\')'
);
mainWindow.webContents.executeJavaScript('document.body.classList.remove(\'dim\')');
pauseWindow = null;
});
}
};

function createStartWindows () {
const createStartWindows = () => {
createMainWindow();
createSetupModalWindow();
}

function exitApp () {
// Do not exit the program on macOS (standard OS-specific behaviour).
// Instead, lose app focus and close all open windows.
if (process.platform === 'darwin') {
app.hide();
BrowserWindow.getAllWindows().forEach(win => win.close());
} else {
app.quit();
}
}
};

app.on('ready', createStartWindows);

app.on('window-all-closed', exitApp);

app.on('activate', createStartWindows);

ipcMain.on('setup-timer', (evt, settings) =>
mainWindow.webContents.send('start-timer', settings)
);
ipcMain.on('setup-timer', (evt, settings) => mainWindow.webContents.send('start-timer', settings));

ipcMain.on('pause', createPauseModalWindow);

/**
* Called after the pause window has been opened and it is safe to wait for a
* synchronous reply before continuing the counter.
* There is undoubtedly a better way of handling pause, but this works for now.
*
*
* @return the false boolean value for the paused flag in mainWindow
*/
ipcMain.on('pause-wait', evt => {
ipcMain.on('pause-wait', (evt) => {
// If it has already been closed before this channel, then return immediately
if (pauseWindow == null) {
if (pauseWindow === null) {
evt.returnValue = false;
} else {
pauseWindow.on('closed', () => evt.returnValue = false);
pauseWindow.on('closed', () => (evt.returnValue = false));
}
});

Expand Down
Loading

0 comments on commit dfdbbfe

Please sign in to comment.