Skip to content
This repository has been archived by the owner on Jul 7, 2024. It is now read-only.
/ Orion Public archive

Add welcome window (with Terms and Conditions) #106

Merged
merged 4 commits into from
May 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { app, dialog, shell } from 'electron'
import { autoUpdater } from 'electron-updater'
import { join as pathJoin } from 'path'
import pjson from '../package.json'
import Settings from 'electron-settings'
import './report'
import rootDir from 'app-root-dir'
import setupTrayIcon from './setup-tray-icon'
Expand All @@ -24,6 +25,7 @@ import {

import LoadingWindow from './windows/Loading/window'
import StorageWindow from './windows/Storage/window'
import WelcomeWindow from './windows/Welcome/window'

// Let's create the main window
app.mainWindow = null
Expand Down Expand Up @@ -72,7 +74,18 @@ function askWhichNodeToUse (apiVersion) {
return btnId === 1
}

app.on('ready', () => {
/**
* This method will:
* 1. setup the tray icon (except on macOS)
* 2. check for updates
* 3. show loading window
* 4. check if an API is already running
* 5. start the daemon if not
* 6. connect to the API
* 7. connect to the Siderus peers (and add them as bootstrap nodes)
* 8. show storage window
*/
function startOrion () {
// On MacOS it's expected for the app not to close, and to re-open it from Launchpad
if (process.platform !== 'darwin') {
setupTrayIcon()
Expand Down Expand Up @@ -238,6 +251,28 @@ app.on('ready', () => {
app.quit()
})
})
}

app.on('start-orion', () => {
startOrion()
})

app.on('ready', () => {
const userAgreement = Settings.getSync('userAgreement')

if (userAgreement) {
startOrion()
} else {
// If the user did not accept our ToS, show the welcome window
const welcomeWindow = WelcomeWindow.create(app)
welcomeWindow.on('closed', () => {
// If the user did not accept ToS, but closed the welcome window, quit (don't run the the bg)
const userAgreement = Settings.getSync('userAgreement')
if (!userAgreement) {
app.quit()
}
})
}
})

app.on('activate', () => {
Expand Down
89 changes: 89 additions & 0 deletions app/windows/Welcome/Components/TermsOfServicePage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React from 'react'
import styled from 'styled-components'
import ToS from './ToS'
import { shell } from 'electron'

import {
Window,
Content,
Toolbar,
Actionbar,
Button,
CheckBox
} from 'react-photonkit'

const StyledContent = styled.div`
h1:first-child {
margin-top: 0px;
}
`

const TermsSection = styled.section`
background: white;
height: calc(100vh - 250px);
overflow: auto;
padding: 0px 10px;
`

const ToSLink = <a onClick={() => shell.openExternal('https://siderus.io/tos.html')} href='#'>Siderus Terms of Service</a>
const PrivacyLink = <a onClick={() => shell.openExternal('https://siderus.io/privacy')} href='#'>Privacy policy</a>
const checkboxLabel = <span>I have read and I agree to {ToSLink} and {PrivacyLink}</span>

class TermsOfServicePage extends React.Component {
state = {
checked: false
}

handleCheckChange = () => {
this.setState(prevState => ({ checked: !prevState.checked }))
}

handleSubmit = (event) => {
event.preventDefault()
if (!this.state.checked) return

this.props.onAccept()
}

render () {
const { onQuit } = this.props
const { checked } = this.state

return (
<form onSubmit={this.handleSubmit}>
<Window>
<Content>
<StyledContent>
<h1>Terms of Service</h1>
<p>In order to continue, you need to accept the Terms of Service:</p>
<TermsSection>
<ToS />
</TermsSection>
<CheckBox
label={checkboxLabel}
checked={checked}
onChange={this.handleCheckChange}
/>
</StyledContent>
</Content>
<Toolbar ptType="footer">
<Actionbar>
<Button text="Quit" ptStyle="default" onClick={onQuit} />
{
checked &&
<Button
text="Done"
ptStyle="primary"
type="submit"
pullRight
/>
}
</Actionbar>
</Toolbar>
</Window>
</form>
)
}
}

export default TermsOfServicePage
31 changes: 31 additions & 0 deletions app/windows/Welcome/Components/ToS.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react'
import request from 'request-promise-native'
import Spinner from 'react-spin'

class ToS extends React.Component {
state = {}

constructor () {
super()
this.fetchContent()
}

fetchContent = () => {
request({ uri: 'https://siderus.io/tos.html' })
.then(res => this.setState({ tos: res }))
.catch(err => {
console.error(err)
throw err
})
}

render () {
return (
this.state.tos
? <div dangerouslySetInnerHTML={{ __html: this.state.tos }} />
: <Spinner />
)
}
}

export default ToS
38 changes: 38 additions & 0 deletions app/windows/Welcome/Components/WelcomePage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react'
import OrionLogo from '../../../../docs/logo.svg'
import styled from 'styled-components'

import {
Window,
Content,
Toolbar,
Actionbar,
Button
} from 'react-photonkit'

const Centered = styled.div`
text-align: center !important;
`

function WelcomePage ({ onNext }) {
return (
<Window>
<Content>
<Centered>
<OrionLogo width='150px' />
<h1>Siderus Orion</h1>
<h3>Welcome</h3>
<p>Siderus Orion is the easiest way to start using the decentralised web with IPFS and Siderus Network. It supports a larger number of dApps as wel as the IPFS Browser Companion, to speed up your connection when surfing the decentralised web.</p>
<p>This wizard will help you with the initial requirements.</p>
</Centered>
</Content>
<Toolbar ptType="footer">
<Actionbar>
<Button text="Next" ptStyle="primary" onClick={onNext} pullRight />
</Actionbar>
</Toolbar>
</Window>
)
}

export default WelcomePage
21 changes: 21 additions & 0 deletions app/windows/Welcome/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>

<head>
<title>Welcome</title>
<style>
.window-content {
padding: 24px !important;
display: initial !important;
background-color: rgb(236, 236, 236) !important;
}
</style>
</head>

<body>
<div id="host"></div>
</body>

<!-- Electron Javascript -->
<script src="loader.js" charset="utf-8"></script>
</html>
7 changes: 7 additions & 0 deletions app/windows/Welcome/loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Spinner from 'spin.js'

var target = document.getElementById('host')
new Spinner().spin(target)

// After the spinner is rendered, we require the actual component
setTimeout(() => require('./renderer.jsx'), 0)
39 changes: 39 additions & 0 deletions app/windows/Welcome/renderer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react'
import ReactDom from 'react-dom'

import WelcomePage from './Components/WelcomePage'
import TermsOfServicePage from './Components/TermsOfServicePage'
import { remote } from 'electron'
import Settings from 'electron-settings'

class WelcomeWindow extends React.Component {
state = {
page: 0
}

handleNext = () => {
this.setState({ page: 1 })
}

handleQuit = () => {
window.close()
}

handleAccept = () => {
Settings.setSync('userAgreement', true)
remote.app.emit('start-orion')
window.close()
}

render () {
const { page } = this.state

return (
page === 0
? <WelcomePage onNext={this.handleNext} />
: <TermsOfServicePage onQuit={this.handleQuit} onAccept={this.handleAccept} />
)
}
}

ReactDom.render(<WelcomeWindow />, document.querySelector('#host'))
70 changes: 70 additions & 0 deletions app/windows/Welcome/window.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* This window will prompt the user with the a short description about Orion
* and with the Terms of Service which need to be read and accepted
*/

import path from 'path'
import url from 'url'

import { BrowserWindow, remote } from 'electron'

import isRenderer from 'is-electron-renderer'

// Allow us to use create() in both electron windows and main process
let BrowserWindowClass
if (isRenderer) {
BrowserWindowClass = remote.BrowserWindow
} else {
BrowserWindowClass = BrowserWindow
}

module.exports = {}

module.exports.create = function createResolveIPNSWindow (app) {
// Create the browser modal window.
let thisWindow = new BrowserWindowClass({
title: 'Welcome',
parent: app.mainWindow,
modal: true,

width: 600,
minWidth: 600,
height: 600,
minHeight: 600,

maximizable: false,
resizable: true,
fullscreenable: false,
icon: path.join(__dirname, '../../../docs/logo.png'),

show: false,
webPreferences: {
preload: path.join(__dirname, '../../report.js')
}
})

// Show menu only on StorageList
thisWindow.setMenu(null)

// Show the window only when ready
thisWindow.once('ready-to-show', () => {
thisWindow.show()
})

// Load the index.html of the app.
thisWindow.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))

// Emitted when the window is closed.
thisWindow.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
thisWindow = null
})

return thisWindow
}