Skip to content

Commit

Permalink
add url handler to electron app
Browse files Browse the repository at this point in the history
  • Loading branch information
timsuchanek committed Nov 30, 2017
1 parent 9bc8862 commit abf7242
Show file tree
Hide file tree
Showing 19 changed files with 192 additions and 104 deletions.
9 changes: 8 additions & 1 deletion packages/graphql-playground-electron/package.json
Expand Up @@ -54,6 +54,12 @@
"ext": "graphql",
"name": "GraphQL",
"role": "Editor"
},
"protocols": {
"name": "graphql-playground-protocol",
"schemes": [
"graphql-playground"
]
}
},
"scripts": {
Expand Down Expand Up @@ -96,6 +102,7 @@
"js-yaml": "^3.10.0",
"lodash.merge": "^4.6.0",
"minimist": "^1.2.0",
"query-string": "^5.0.1",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-redux": "^5.0.5",
Expand Down Expand Up @@ -130,7 +137,7 @@
"extract-text-webpack-plugin": "^2.0.0-beta.3",
"file-loader": "^0.11.2",
"fork-ts-checker-webpack-plugin": "^0.1.5",
"graphql-playground": "^1.2.1-beta.7",
"graphql-playground": "^1.2.1-beta.8",
"happypack": "^3.1.0",
"html-webpack-plugin": "^2.30.1",
"identity-obj-proxy": "^3.0.0",
Expand Down
79 changes: 67 additions & 12 deletions packages/graphql-playground-electron/src/ElectronApp.tsx
Expand Up @@ -15,6 +15,7 @@ import * as path from 'path'
import * as os from 'os'
import * as yaml from 'js-yaml'
import * as findUp from 'find-up'
import * as queryString from 'query-string'
// import { PermissionSession } from 'graphql-playground/lib/types'

const { dialog } = remote
Expand All @@ -24,7 +25,6 @@ const store = createStore()

interface State {
endpoint?: string
openInitialView: boolean
openTooltipTheme: boolean
theme: string
shareUrl?: string
Expand All @@ -33,6 +33,8 @@ interface State {
platformToken?: string
configString?: string
configPath?: string
folderName?: string
env?: any
}

export default class ElectronApp extends React.Component<{}, State> {
Expand All @@ -42,7 +44,6 @@ export default class ElectronApp extends React.Component<{}, State> {
super()
const { endpoint, platformToken } = this.getArgs()
this.state = {
openInitialView: !endpoint,
openTooltipTheme: false,
theme: 'dark',
endpoint,
Expand All @@ -65,11 +66,12 @@ export default class ElectronApp extends React.Component<{}, State> {
endpoint: args.endpoint,
subscriptionsEndpoint: args['subscriptions-endpoint'],
platformToken: args['platform-token'] || localStorage.platformToken,
env: args.env,
}
}

handleSelectEndpoint = (endpoint: string) => {
this.setState({ endpoint, openInitialView: false } as State)
this.setState({ endpoint } as State)
}

handleSelectFolder = (folderPath: string) => {
Expand All @@ -79,7 +81,6 @@ export default class ElectronApp extends React.Component<{}, State> {
const configString = fs.readFileSync(configPath, 'utf-8')

this.setState({
openInitialView: false,
configString,
configPath,
} as State)
Expand Down Expand Up @@ -122,6 +123,8 @@ export default class ElectronApp extends React.Component<{}, State> {
ipcRenderer.on('Tab', this.readTabMessage)
ipcRenderer.on('File', this.readFileMessage)
ipcRenderer.on('OpenSelectedFile', this.readOpenSelectedFileMessage)
ipcRenderer.on('OpenUrl', this.handleUrl)
window.addEventListener('keydown', this.handleKeyDown)
}

componentWillUnmount() {
Expand All @@ -131,9 +134,59 @@ export default class ElectronApp extends React.Component<{}, State> {
'OpenSelectedFile',
this.readOpenSelectedFileMessage,
)
ipcRenderer.removeListener('OpenUrl', this.handleUrl)
window.removeEventListener('keydown', this.handleKeyDown)
}

readFileMessage = (error, message) => {
handleKeyDown = e => {
if (e.key === '{' && e.metaKey) {
this.prevTab()
}
if (e.key === '}' && e.metaKey) {
this.nextTab()
}
}

handleUrl = (event, url) => {
const cutIndex = url.indexOf('//')
const query = url.slice(cutIndex + 2)
const input = queryString.parse(query)
if (input.env) {
try {
input.env = JSON.parse(input.env)
} catch (e) {
//
}
}

const endpoint = input.endpoint
let configString
let folderName
let configPath
const platformToken = input.platformToken

if (input.cwd) {
configPath = findUp.sync(['.graphqlconfig', '.graphqlconfig.yml'], {
cwd: input.cwd,
})
configString = configPath
? fs.readFileSync(configPath, 'utf-8')
: undefined
folderName = configPath
? path.basename(path.dirname(configPath))
: undefined
}

this.setState({
configString,
folderName,
env: input.env,
endpoint,
platformToken,
})
}

readFileMessage = (event, message) => {
switch (message) {
case 'Open':
this.showOpenDialog()
Expand Down Expand Up @@ -273,20 +326,20 @@ export default class ElectronApp extends React.Component<{}, State> {
const {
theme,
endpoint,
openInitialView,
openTooltipTheme,
platformToken,
configString,
} = this.state

return (
<Provider store={store}>
<div className={cx('root', theme)}>
<div className={cx('root', theme, { noConfig: !configString })}>
<style jsx={true} global={true}>{`
.app-content .left-content {
letter-spacing: 0.5px;
}
body .root .tabs.isApp {
padding-left: 74px;
body .root.noConfig .tabs {
padding-left: 80px;
}
`}</style>
<style jsx={true}>{`
Expand All @@ -308,20 +361,22 @@ export default class ElectronApp extends React.Component<{}, State> {
}
`}</style>
<InitialView
isOpen={openInitialView}
isOpen={!endpoint && !configString}
onSelectFolder={this.handleSelectFolder}
onSelectEndpoint={this.handleSelectEndpoint}
/>
{(endpoint || this.state.configString) && (
{(endpoint || configString) && (
<div className="playground">
<Playground
getRef={this.setRef}
endpoint={endpoint}
isElectron={true}
platformToken={platformToken}
configString={this.state.configString}
configString={configString}
onSaveConfig={this.saveConfig}
canSaveConfig={true}
env={this.state.env}
folderName={this.state.folderName}
/>
</div>
)}
Expand Down
Expand Up @@ -191,11 +191,14 @@ class InitialView extends React.Component<
style={modalStyle}
>
<div className="initial-view-content">
{history.length > 0
? <div className="initial-view-recent">
<div className="initial-view-recent-header">RECENT</div>
<div className="initial-view-recent-list">
{history.map(data =>
{history.length > 0 ? (
<div className="initial-view-recent">
<div className="initial-view-recent-header">RECENT</div>
<div className="initial-view-recent-list">
{[]
.concat(history)
.reverse()
.map(data => (
<div
className="list-item"
// tslint:disable-next-line
Expand All @@ -219,46 +222,44 @@ class InitialView extends React.Component<
Last opened {format(data.lastOpened, 'DD.MM.YYYY')}
</span>
</div>
</div>,
)}
</div>
</div>
))}
</div>
: <div className="initial-view-recent">
<div className="initial-view-recent-header">EXAMPLES</div>
<div className="initial-view-recent-list">
{examples.map(example =>
<div
className="list-item"
// tslint:disable-next-line
onClick={() =>
this.props.onSelectEndpoint(example.endpoint)}
>
<div
className="list-item-name"
title={example.endpoint}
>
{example.name}
</div>
<div className="list-item-date">
<Icon
src={require('graphcool-styles/icons/fill/world.svg')}
color={$v.gray40}
width={14}
height={14}
/>
<span>
{example.endpoint}
</span>
</div>
</div>,
)}
</div>
</div>}
</div>
) : (
<div className="initial-view-recent">
<div className="initial-view-recent-header">EXAMPLES</div>
<div className="initial-view-recent-list">
{examples.map(example => (
<div
className="list-item"
// tslint:disable-next-line
onClick={() =>
this.props.onSelectEndpoint(example.endpoint)
}
>
<div className="list-item-name" title={example.endpoint}>
{example.name}
</div>
<div className="list-item-date">
<Icon
src={require('graphcool-styles/icons/fill/world.svg')}
color={$v.gray40}
width={14}
height={14}
/>
<span>{example.endpoint}</span>
</div>
</div>
))}
</div>
</div>
)}
<div className="initial-view-workspace">
<h1 className="title">New workspace</h1>
<p className="description">
Either load a local repository with a .graphqlconfig file, or just
open a HTTP endpoint
Either load a local repository with a .graphqlconfig file, or
just open a HTTP endpoint
</p>
<div className="toggle">
<Toggle
Expand All @@ -267,7 +268,7 @@ class InitialView extends React.Component<
onChange={this.handleChangeMode}
/>
</div>
{selectedMode === 'url endpoint' &&
{selectedMode === 'url endpoint' && (
<form className="container-input" onSubmit={this.handleSubmit}>
<input
className="input"
Expand All @@ -276,8 +277,9 @@ class InitialView extends React.Component<
onChange={this.handleChangeEndpoint}
/>
<button>OPEN</button>
</form>}
{selectedMode === 'local' &&
</form>
)}
{selectedMode === 'local' && (
<div
className="container-input"
onClick={this.handleClickLocal}
Expand All @@ -289,7 +291,8 @@ class InitialView extends React.Component<
onChange={this.handleChangeEndpoint}
/>
<button>OPEN</button>
</div>}
</div>
)}
</div>
</div>
</Modal>
Expand Down

0 comments on commit abf7242

Please sign in to comment.