Skip to content

Commit

Permalink
feat: add pages layout
Browse files Browse the repository at this point in the history
adds pages layout

refs #3
  • Loading branch information
hassan committed Dec 5, 2018
1 parent 4ab0059 commit bae0c99
Show file tree
Hide file tree
Showing 47 changed files with 3,310 additions and 53 deletions.
29 changes: 25 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"homepage": "./",
"main": "public/electron.js",
"keywords": [
"Example",
"Graasp Desktop",
"React",
"Electron"
],
Expand All @@ -21,24 +21,45 @@
},
"dependencies": {
"@material-ui/core": "3.5.1",
"@material-ui/icons": "3.0.1",
"classnames": "2.2.6",
"connected-react-router": "5.0.1",
"electron": "3.0.10",
"electron-devtools-installer": "2.2.4",
"electron-dl": "1.12.0",
"electron-is-dev": "1.0.1",
"electron-publisher-s3": "20.17.2",
"extract-zip": "1.6.7",
"history": "4.7.2",
"immutable": "4.0.0-rc.12",
"is-online": "8.0.0",
"prop-types": "15.6.2",
"react": "16.6.3",
"react-dev-utils": "6.1.1",
"react-dom": "16.6.3"
"react-dom": "16.6.3",
"react-loading": "2.0.3",
"react-redux": "5.1.1",
"react-redux-toastr": "7.4.4",
"react-router": "4.3.1",
"react-router-dom": "4.3.1",
"redux": "4.0.1",
"redux-devtools-extension": "2.13.5",
"redux-promise": "0.6.0",
"redux-thunk": "2.3.0",
"wait-on": "3.2.0"
},
"devDependencies": {
"concurrently": "4.1.0",
"cross-env": "5.2.0",
"electron": "3.0.10",
"electron-builder": "20.36.2",
"eslint-config-airbnb": "17.1.0",
"react-scripts": "2.1.1",
"version-bump-prompt": "4.2.1"
},
"build": {
"appId": "com.your-domain",
"compression": "normal",
"productName": "Example",
"productName": "Graasp Desktop",
"directories": {
"buildResources": "build",
"output": "dist"
Expand Down
166 changes: 160 additions & 6 deletions public/electron.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
const { app, BrowserWindow, shell, ipcMain, Menu, TouchBar } = require('electron');
const { TouchBarButton, TouchBarLabel, TouchBarSpacer } = TouchBar;

const { app, BrowserWindow, shell, ipcMain, Menu, dialog } = require('electron');
const path = require('path');
const isDev = require('electron-is-dev');
const fs = require('fs');
const isOnline = require('is-online');
const fsPromises = fs.promises;
const electronDl = require('electron-dl');
const { download } = electronDl;
const extract = require('extract-zip');


let mainWindow;

const savedSpacesPath = app.getPath('userData') + '/.meta';

createWindow = () => {
mainWindow = new BrowserWindow({
backgroundColor: '#F7F7F7',
minWidth: 880,
show: false,
titleBarStyle: 'hidden',
movable: true,
webPreferences: {
nodeIntegration: false,
preload: __dirname + '/preload.js',
webSecurity: false
},
height: 860,
width: 1280,
Expand Down Expand Up @@ -63,8 +71,9 @@ generateMenu = () => {
const template = [
{
label: 'File',
submenu: [{ role: 'about' }, { role: 'quit' }],
submenu: [{ label: 'Load Space', click() { app.quit() }}, { role: 'about' }, { role: 'quit' }],
},
{type:'separator'},
{
label: 'Edit',
submenu: [
Expand Down Expand Up @@ -126,6 +135,148 @@ generateMenu = () => {
app.on('ready', () => {
createWindow();
generateMenu();
ipcMain.on('space:get', async (event, { id, spaces }) => {
try {
const space = spaces.find(el => el.id === Number(id));
const { phases } = space;
for (const phase of phases) {
const { items = [] } = phase;
for (let i=0; i < items.length; i++) {
const { resource } = items[i];
if (resource) {
const {
uri,
hash,
type,
} = resource;
const fileName = `${hash}.${type}`;
const filePath = `${savedSpacesPath}/${fileName}`;
const fileAvailable = await checkFileAvailable({ filePath });
if (fileAvailable){
phase.items[i].asset = filePath;
} else {
const isConnected = await isOnline();
if(isConnected) {
await download(mainWindow, uri, { directory: savedSpacesPath, filename: fileName })
.then(dl => {
phase.items[i].asset = dl.getSavePath();
})
.catch(console.log('error'));
} else {
mainWindow.webContents.send(
'space:gotten',
1
);
}
}
}
}
}
mainWindow.webContents.send(
'space:gotten',
space
);
} catch (err) {
console.log('error:', err);
}
});
ipcMain.on('spaces:get', () => {
let spaces = [];
const spacesPath = `${savedSpacesPath}/ss.json`;
fs.readFile(spacesPath, 'utf8', (err, data) => {
// we dont have saved spaces yet
if (err) {
mainWindow.webContents.send(
'spaces:get',
spaces
);
} else {
spaces = JSON.parse(data);
mainWindow.webContents.send(
'spaces:get',
spaces
);
}
});
});
ipcMain.on('space:load', async (event, { fileLocation }) => {
try {
extract(fileLocation, {dir: savedSpacesPath}, async err => {
if (err) {
console.log(err);
} else {
let space = {};
const spacePath = `${savedSpacesPath}/space.json`;
fs.readFile(spacePath, 'utf8', async (err, data) => {
if (err) {
mainWindow.webContents.send(
'space:loaded',
1
);
} else {
let spaces = [];
space = JSON.parse(data);
const spacesPath = `${savedSpacesPath}/ss.json`;
fs.readFile(spacesPath, 'utf8', async (err, data) => {
// we dont have saved spaces yet
if (err) {
spaces.push(space);
const spacesString = JSON.stringify(spaces);
await fsPromises.writeFile(`${savedSpacesPath}/ss.json`, spacesString);
mainWindow.webContents.send(
'space:loaded',
spaces
);
} else {
try {
spaces = JSON.parse(data);
} catch (e) {
mainWindow.webContents.send(
'space:loaded',
2
);
}
const spaceId = Number(space.id);
const available = spaces.find(({ id }) => (Number(id) === spaceId));
if (!available) {
spaces.push(space);
const spacesString = JSON.stringify(spaces);
await fsPromises.writeFile(`${savedSpacesPath}/ss.json`, spacesString);
mainWindow.webContents.send(
'space:loaded',
spaces
);
} else {
mainWindow.webContents.send(
'space:loaded',
3
);
}
}
});
}
fs.unlink(spacePath, (err) => {
if (err) {
console.log(err);
}
});
});
}
});
} catch (err) {
console.log('error:', err);
}
});
ipcMain.on('show-open-dialog', ()=> {
const options = {
filters: [
{ name: 'zip', extensions: ['zip'] },
],
};
dialog.showOpenDialog(null, options, (filePaths) => {
mainWindow.webContents.send('open-dialog-paths-selected', filePaths)
});
})
});

app.on('window-all-closed', () => {
Expand All @@ -140,4 +291,7 @@ app.on('activate', () => {

ipcMain.on('load-page', (event, arg) => {
mainWindow.loadURL(arg);
});
});

const checkFileAvailable = ({ filePath }) =>
new Promise(resolve => fs.access(filePath, fs.constants.F_OK, err => resolve(!err)));
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>Graasp Desktop</title>
</head>
<body>
<noscript>
Expand Down
1 change: 1 addition & 0 deletions public/preload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
window.ipcRenderer = require('electron').ipcRenderer;
85 changes: 67 additions & 18 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,75 @@
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import ReduxToastr from 'react-redux-toastr';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import Home from './Home';
import VisitSpace from './components/VisitSpace';
import SearchSpace from './components/SearchSpace';
import Settings from './components/Settings';
import LoadSpace from './components/LoadSpace';
import SpaceScreen from './components/space/SpaceScreen';
import {
SETTINGS_PATH,
SPACE_PATH,
HOME_PATH,
SEARCH_SPACE_PATH,
VISIT_PATH,
LOAD_SPACE_PATH,
} from './config/paths';

const theme = createMuiTheme({
typography: {
useNextVariants: true,
},
palette: {
primary: { light: '#5348d3', main: '#5348d3', dark: '#5348d3' },
secondary: { light: '#00b904', main: '#00b904', dark: '#00b904' },
},
status: {
danger: 'red',
},
});

class App extends Component {
state = { height: 0 };

componentDidMount() {
this.updateWindowDimensions();
window.addEventListener('resize', this.updateWindowDimensions);
}

componentWillUnmount() {
window.removeEventListener('resize', this.updateWindowDimensions);
}

updateWindowDimensions = () => {
this.setState({ height: window.innerHeight - 100 });
};

render() {
const { height } = this.state;
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
<MuiThemeProvider theme={theme}>
<div>
<ReduxToastr
transitionIn="fadeIn"
preventDuplicates
transitionOut="fadeOut"
/>
</div>
<Router>
<div className="app" style={{ height }}>
<Switch>
<Route exact path={HOME_PATH} component={Home} />
<Route exact path={SEARCH_SPACE_PATH} component={SearchSpace} />
<Route exact path={VISIT_PATH} component={VisitSpace} />
<Route exact path={LOAD_SPACE_PATH} component={LoadSpace} />
<Route exact path={SETTINGS_PATH} component={Settings} />
<Route exact path={SPACE_PATH} component={SpaceScreen} />
</Switch>
</div>
</Router>
</MuiThemeProvider>
);
}
}
Expand Down
Loading

0 comments on commit bae0c99

Please sign in to comment.