mirror of
https://github.com/desktop/desktop
synced 2024-10-31 11:07:25 +00:00
Merge branch 'master' into check-for-updates
This commit is contained in:
commit
245fd76da0
21 changed files with 2174 additions and 82 deletions
|
@ -26,6 +26,7 @@ addons:
|
|||
- g++-4.8
|
||||
|
||||
cache:
|
||||
timeout: 600
|
||||
directories:
|
||||
- node_modules
|
||||
|
||||
|
|
1925
npm-shrinkwrap.json
generated
1925
npm-shrinkwrap.json
generated
File diff suppressed because it is too large
Load diff
11
package.json
11
package.json
|
@ -3,7 +3,7 @@
|
|||
"productName": "GitHub",
|
||||
"bundleID": "com.github.GitHubClient",
|
||||
"companyName": "GitHub, Inc.",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"main": "./app/main-process/main.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -15,7 +15,7 @@
|
|||
},
|
||||
"description": "The People's Glorious GitHub Client",
|
||||
"scripts": {
|
||||
"test": "electron-mocha --renderer --require ts-node/register test/*.ts test/*.tsx",
|
||||
"test": "cross-env TEST_ENV=1 electron-mocha --renderer --require ts-node/register test/*.ts test/*.tsx",
|
||||
"postinstall": "typings install",
|
||||
"start": "npm run build:dev && node script/start",
|
||||
"compile:dev": "tsc && cross-env NODE_ENV=development webpack --config webpack.development.js",
|
||||
|
@ -35,6 +35,7 @@
|
|||
"event-kit": "^2.0.0",
|
||||
"keytar": "^3.0.2",
|
||||
"octokat": "^0.5.0-beta.0",
|
||||
"ohnogit": "0.0.14",
|
||||
"react": "^15.0.2",
|
||||
"react-dom": "^15.0.2"
|
||||
},
|
||||
|
@ -54,18 +55,24 @@
|
|||
"babel-preset-stage-0": "^6.5.0",
|
||||
"chai": "^3.5.0",
|
||||
"cross-env": "^1.0.8",
|
||||
"css-loader": "^0.23.1",
|
||||
"electron-mocha": "2.1.0",
|
||||
"electron-packager": "^7.0.1",
|
||||
"electron-prebuilt": "1.1.3",
|
||||
"electron-winstaller": "^2.3.0",
|
||||
"express": "^4.13.4",
|
||||
"extract-text-webpack-plugin": "^1.0.1",
|
||||
"fs-extra": "^0.30.0",
|
||||
"got": "^6.3.0",
|
||||
"html-webpack-plugin": "^2.21.0",
|
||||
"mocha": "^2.4.5",
|
||||
"node-sass": "^3.7.0",
|
||||
"react-addons-test-utils": "^15.0.2",
|
||||
"react-transform-hmr": "^1.0.4",
|
||||
"request": "^2.72.0",
|
||||
"rimraf": "^2.5.2",
|
||||
"sass-loader": "^3.2.0",
|
||||
"style-loader": "^0.13.1",
|
||||
"to-camel-case": "^1.0.0",
|
||||
"ts-loader": "^0.8.2",
|
||||
"ts-node": "^0.7.2",
|
||||
|
|
15
script/build
15
script/build
|
@ -19,9 +19,6 @@ fs.removeSync(path.join(projectRoot, 'dist'))
|
|||
console.log('Installing dependencies…')
|
||||
installDependencies()
|
||||
|
||||
console.log('Copying `static`…')
|
||||
fs.copySync(path.join(projectRoot, 'static'), path.join(buildRoot, 'static'), {clobber: true})
|
||||
|
||||
const options = {
|
||||
platform: process.platform,
|
||||
arch: 'x64',
|
||||
|
@ -29,10 +26,18 @@ const options = {
|
|||
'build-version': appPackage.version,
|
||||
asar: false, // TODO: Probably wanna enable this down the road.
|
||||
out: path.join(projectRoot, 'dist'),
|
||||
icon: path.join(buildRoot, 'static', 'icon'),
|
||||
icon: path.join(projectRoot, 'static', 'icon'),
|
||||
dir: path.join(projectRoot, 'build'),
|
||||
overwrite: true,
|
||||
prune: false, // We only install production dependencies above.
|
||||
ignore: [
|
||||
'/node_modules/electron-prebuilt($|/)',
|
||||
'/node_modules/electron-packager($|/)',
|
||||
'/\\.git($|/)',
|
||||
'/node_modules/\\.bin($|/)',
|
||||
'/node_modules/nodegit/vendor/libgit2/tests($|/)',
|
||||
'/node_modules/ohnogit/spec($|/)'
|
||||
],
|
||||
|
||||
// OS X
|
||||
'app-bundle-id': appPackage.bundleID,
|
||||
|
@ -72,6 +77,8 @@ packager(options, (error, appPaths) => {
|
|||
})
|
||||
|
||||
function installDependencies () {
|
||||
fs.copySync(path.join(projectRoot, '.npmrc'), path.join(buildRoot, '.npmrc'))
|
||||
|
||||
let packageJson = appPackage
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
packageJson = debugPackageJson(packageJson)
|
||||
|
|
27
src/app.tsx
27
src/app.tsx
|
@ -18,18 +18,6 @@ interface AppProps {
|
|||
usersStore: UsersStore
|
||||
}
|
||||
|
||||
const AppStyle = {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flexGrow: 1
|
||||
}
|
||||
|
||||
const ContentStyle = {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexGrow: 1
|
||||
}
|
||||
|
||||
export default class App extends React.Component<AppProps, AppState> {
|
||||
private api: API
|
||||
|
||||
|
@ -76,19 +64,16 @@ export default class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
WebkitAppRegion: 'drag',
|
||||
flexShrink: 0,
|
||||
height: 20,
|
||||
width: '100%'
|
||||
}}/>
|
||||
<div id='desktop-app-title-bar'>
|
||||
<span className='app-title'>GitHub Desktop</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private renderApp() {
|
||||
const selectedRepo = this.state.repos[this.state.selectedRow]
|
||||
return (
|
||||
<div style={ContentStyle}>
|
||||
<div id='desktop-app-contents'>
|
||||
<ReposList selectedRow={this.state.selectedRow}
|
||||
onSelectionChanged={row => this.handleSelectionChanged(row)}
|
||||
user={this.state.user}
|
||||
|
@ -101,7 +86,7 @@ export default class App extends React.Component<AppProps, AppState> {
|
|||
|
||||
private renderNotLoggedIn() {
|
||||
return (
|
||||
<div style={ContentStyle}>
|
||||
<div id='desktop-app-contents'>
|
||||
<NotLoggedIn/>
|
||||
</div>
|
||||
)
|
||||
|
@ -109,7 +94,7 @@ export default class App extends React.Component<AppProps, AppState> {
|
|||
|
||||
public render() {
|
||||
return (
|
||||
<div style={AppStyle}>
|
||||
<div id='desktop-app-chrome'>
|
||||
{this.renderTitlebar()}
|
||||
{this.state.user ? this.renderApp() : this.renderNotLoggedIn()}
|
||||
</div>
|
||||
|
|
|
@ -13,6 +13,12 @@ import {IPCLogEntry} from './lib/ipc-log-entry'
|
|||
|
||||
const Octokat = require('octokat')
|
||||
|
||||
if (!process.env.TEST_ENV) {
|
||||
/* This is the magic trigger for webpack to go compile
|
||||
* our sass into css and inject it into the DOM. */
|
||||
require('../styles/desktop.scss')
|
||||
}
|
||||
|
||||
ipcRenderer.on('log', (event: any, {msg, type}: IPCLogEntry) => {
|
||||
switch (type) {
|
||||
case 'log':
|
||||
|
@ -34,7 +40,9 @@ ipcRenderer.on('url-action', (event, msg) => {
|
|||
const usersStore = new UsersStore(localStorage, tokenStore)
|
||||
usersStore.loadFromStore()
|
||||
|
||||
ReactDOM.render(<App usersStore={usersStore}/>, document.getElementById('content'))
|
||||
document.body.classList.add(`platform-${process.platform}`)
|
||||
|
||||
ReactDOM.render(<App usersStore={usersStore}/>, document.getElementById('desktop-app-container'))
|
||||
|
||||
async function addUserWithCode(code: string) {
|
||||
try {
|
||||
|
|
|
@ -53,7 +53,7 @@ export default class AppWindow {
|
|||
this.window.show()
|
||||
})
|
||||
|
||||
this.window.loadURL(`file://${__dirname}/../../static/index.html`)
|
||||
this.window.loadURL(`file://${__dirname}/../../index.html`)
|
||||
}
|
||||
|
||||
public onClose(fn: () => void) {
|
||||
|
|
|
@ -2,19 +2,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<link rel='stylesheet' href='styles.css'>
|
||||
</head>
|
||||
<body>
|
||||
<div id='content'></div>
|
||||
<script>
|
||||
var src = '../bundle.js'
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
src = 'http://localhost:3000/build/bundle.js'
|
||||
}
|
||||
|
||||
var scriptTag = document.createElement('script')
|
||||
scriptTag.src = src
|
||||
document.head.appendChild(scriptTag)
|
||||
</script>
|
||||
<div id='desktop-app-container'></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
* {
|
||||
font-family: system, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Lucida Grande";
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:not(input):not(textarea),
|
||||
:not(input):not(textarea)::after,
|
||||
:not(input):not(textarea)::before {
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
input, button, textarea, :focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
img {
|
||||
user-drag: none;
|
||||
-webkit-user-drag: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#content {
|
||||
display: flex;
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* https://css-tricks.com/cascading-svg-fill-color/ */
|
||||
svg.octicon { fill: currentColor; }
|
79
styles/_globals.scss
Normal file
79
styles/_globals.scss
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Globals
|
||||
//
|
||||
// This file is for things that have to apply globally, if your style
|
||||
// doesn't fit into that description it probably belongs in ui/
|
||||
|
||||
// Reset the box-sizing, lifted from bootstrap reboot css, see:
|
||||
// https://github.com/twbs/bootstrap/blob/bfc16c4a829ba596db28f5f42d7a3e429e6ea2e1/scss/_reboot.scss#L9
|
||||
//
|
||||
// Change from `box-sizing: content-box` to `border-box` so that when you add
|
||||
// `padding` or `border`s to an element, the overall declared `width` does not
|
||||
// change. For example, `width: 100px;` will always be `100px` despite the
|
||||
// `border: 10px solid red;` and `padding: 20px;`.
|
||||
//
|
||||
// Credit: https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
//
|
||||
// Reset HTML, body, and more
|
||||
//
|
||||
|
||||
// We never want the window to be scrollable, everything has to fit
|
||||
// or be placed into a scrollable container.
|
||||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
html {
|
||||
// Sets a specific default `font-size` for user with `rem` type scales.
|
||||
font-size: $font-size-root;
|
||||
}
|
||||
|
||||
body {
|
||||
// Make the `body` use the `font-size-root`
|
||||
font-family: $font-family-base;
|
||||
font-size: $font-size-base;
|
||||
line-height: $line-height-base;
|
||||
// Go easy on the eyes and use something other than `#000` for text
|
||||
color: $primary-text-color;
|
||||
// By default, `<body>` has no `background-color` so we set one as a best practice.
|
||||
background-color: $primary-background-color;
|
||||
}
|
||||
|
||||
:not(input):not(textarea) {
|
||||
&, &::after, &::before {
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
input, button, textarea, :focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
img {
|
||||
-webkit-user-drag: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#content {
|
||||
display: flex;
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
1
styles/_mixins.scss
Normal file
1
styles/_mixins.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@import "mixins/platform";
|
3
styles/_type.scss
Normal file
3
styles/_type.scss
Normal file
|
@ -0,0 +1,3 @@
|
|||
//
|
||||
// Typography
|
||||
//
|
2
styles/_ui.scss
Normal file
2
styles/_ui.scss
Normal file
|
@ -0,0 +1,2 @@
|
|||
@import "ui/app";
|
||||
@import "ui/octicons";
|
24
styles/_variables.scss
Normal file
24
styles/_variables.scss
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Variables
|
||||
//
|
||||
// This files contains variables accessible to all other scss files.
|
||||
// Structure and naming copied largely from bootstrap, see
|
||||
// https://github.com/twbs/bootstrap/blob/bfc16c4a829ba596db28f5f42d7a3e429e6ea2e1/scss/_variables.scss
|
||||
|
||||
// Colors
|
||||
|
||||
$primary-text-color: #5f717f;
|
||||
$primary-background-color: #fff;
|
||||
|
||||
// Typography
|
||||
//
|
||||
// Font, line-height, and color for body text, headings, and more.
|
||||
|
||||
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif !default;
|
||||
$font-family-monospace: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
$font-family-base: $font-family-sans-serif;
|
||||
|
||||
// Pixel value used to responsively scale all typography. Applied to the `<html>` element.
|
||||
$font-size-root: 16px;
|
||||
$font-size-base: $font-size-root;
|
||||
|
||||
$line-height-base: 1.5;
|
6
styles/desktop.scss
Normal file
6
styles/desktop.scss
Normal file
|
@ -0,0 +1,6 @@
|
|||
@import "variables";
|
||||
@import "mixins";
|
||||
|
||||
@import "globals";
|
||||
|
||||
@import "ui"
|
27
styles/mixins/_platform.scss
Normal file
27
styles/mixins/_platform.scss
Normal file
|
@ -0,0 +1,27 @@
|
|||
// A mixin which takes a content block that should only
|
||||
// be applied when the current (real or emulated) operating
|
||||
// system is windows
|
||||
//
|
||||
// This helper mixin is useful in so far that it allows us
|
||||
// to keep platform specific styles next to cross-platform
|
||||
// styles instead of splitting them out and possibly forgetting
|
||||
// about them.
|
||||
@mixin win32 {
|
||||
body.platform-win32 & {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// A mixin which takes a content block that should only
|
||||
// be applied when the current (real or emulated) operating
|
||||
// system is macOS.
|
||||
//
|
||||
// This helper mixin is useful in so far that it allows us
|
||||
// to keep platform specific styles next to cross-platform
|
||||
// styles instead of splitting them out and possibly forgetting
|
||||
// about them.
|
||||
@mixin darwin {
|
||||
body.platform-darwin & {
|
||||
@content;
|
||||
}
|
||||
}
|
38
styles/ui/_app.scss
Normal file
38
styles/ui/_app.scss
Normal file
|
@ -0,0 +1,38 @@
|
|||
#desktop-app {
|
||||
|
||||
// This is just a dummy wrapper needed because react doesn't like
|
||||
// being installed into <body>, see https://github.com/facebook/react/issues/3207
|
||||
&-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// The main react component div
|
||||
&-chrome {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// App title bar, currently only shown on macOS but will be used on
|
||||
// Windows as well as soon as we enable frameless windows.
|
||||
&-title-bar {
|
||||
-webkit-app-region: drag;
|
||||
-webkit-user-select: none;
|
||||
flex-shrink: 0;
|
||||
height: 20px;
|
||||
width: 100%;
|
||||
|
||||
.app-title { display: none; }
|
||||
}
|
||||
|
||||
// main non-window chrome wrapper
|
||||
&-contents {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1
|
||||
}
|
||||
}
|
4
styles/ui/_octicons.scss
Normal file
4
styles/ui/_octicons.scss
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* https://css-tricks.com/cascading-svg-fill-color/ */
|
||||
svg.octicon {
|
||||
fill: currentColor;
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
|
||||
module.exports = {
|
||||
entry: [
|
||||
|
@ -17,6 +18,10 @@ module.exports = {
|
|||
test: /\.tsx?$/,
|
||||
loaders: ['babel', 'ts'],
|
||||
include: path.join(__dirname, 'src')
|
||||
},
|
||||
{
|
||||
test: /\.(jpe?g|png|gif|ico)$/,
|
||||
loaders: ["file?name=[path][name].[ext]"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -25,6 +30,7 @@ module.exports = {
|
|||
packageMains: ['webpack', 'browser', 'web', 'browserify', ['jam', 'main'], 'main']
|
||||
},
|
||||
target: 'electron',
|
||||
plugins: [new HtmlWebpackPlugin({ 'template': 'static/index.html' })],
|
||||
externals: function (context, request, callback) {
|
||||
try {
|
||||
// Attempt to resolve the module via Node
|
||||
|
|
|
@ -18,6 +18,7 @@ const config = {
|
|||
publicPath: 'http://localhost:3000/build/'
|
||||
},
|
||||
plugins: [
|
||||
...common.plugins,
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoErrorsPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
|
@ -30,6 +31,14 @@ const config = {
|
|||
externals: common.externals
|
||||
}
|
||||
|
||||
// This will cause the compiled CSS (and sourceMap) to be
|
||||
// embedded within the compiled javascript bundle and added
|
||||
// as a blob:// uri at runtime.
|
||||
config.module.loaders.push({
|
||||
test: /\.scss$/,
|
||||
loaders: ["style", "css?sourceMap", "sass?sourceMap"]
|
||||
});
|
||||
|
||||
config.target = webpackTargetElectronRenderer(config)
|
||||
|
||||
module.exports = config
|
||||
|
|
|
@ -4,12 +4,14 @@ const common = require('./webpack.common')
|
|||
|
||||
const webpack = require('webpack')
|
||||
const webpackTargetElectronRenderer = require('webpack-target-electron-renderer')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
|
||||
const config = {
|
||||
devtool: 'cheap-module-source-map',
|
||||
entry: common.entry,
|
||||
output: common.output,
|
||||
plugins: [
|
||||
...common.plugins,
|
||||
new webpack.optimize.UglifyJsPlugin(),
|
||||
new webpack.optimize.OccurrenceOrderPlugin(true),
|
||||
new webpack.DefinePlugin({
|
||||
|
@ -22,6 +24,17 @@ const config = {
|
|||
externals: common.externals
|
||||
}
|
||||
|
||||
// This will cause the compiled CSS to be output to a
|
||||
// styles.css and a <link rel="stylesheet"> tag to be
|
||||
// appended to the index.html HEAD at compile time
|
||||
config.module.loaders.push({
|
||||
test: /\.scss$/,
|
||||
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader')
|
||||
})
|
||||
|
||||
// Necessary to be able to use ExtractTextPlugin as a loader.
|
||||
config.plugins.push(new ExtractTextPlugin('styles.css'))
|
||||
|
||||
config.target = webpackTargetElectronRenderer(config)
|
||||
|
||||
module.exports = config
|
||||
|
|
Loading…
Reference in a new issue