mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 01:36:22 +00:00
add Finder & update main.js & cleanup some old files
This commit is contained in:
129
Gulpfile.js
129
Gulpfile.js
@@ -1,129 +0,0 @@
|
||||
var gulp = require('gulp')
|
||||
var styl = require('gulp-stylus')
|
||||
var autoprefixer = require('gulp-autoprefixer')
|
||||
var del = require('del')
|
||||
var runSequence = require('run-sequence')
|
||||
var plumber = require('gulp-plumber')
|
||||
var notify = require('gulp-notify')
|
||||
var rename = require('gulp-rename')
|
||||
var livereload = require('gulp-livereload')
|
||||
var inject = require('gulp-inject')
|
||||
|
||||
// for Dist
|
||||
var rev = require('gulp-rev')
|
||||
var ngAnnotate = require('gulp-ng-annotate')
|
||||
var templateCache = require('gulp-angular-templatecache')
|
||||
var uglify = require('gulp-uglify')
|
||||
var minifyCss = require('gulp-minify-css')
|
||||
var merge = require('merge-stream')
|
||||
var concat = require('gulp-concat')
|
||||
var minifyHtml = require('gulp-minify-html')
|
||||
|
||||
var config = require('./build.config.js')
|
||||
|
||||
gulp.task('build', function () {
|
||||
var tpls = gulp.src(['src/browser/main/**/*.html','!src/browser/main/index.html','!src/browser/main/index.inject.html'])
|
||||
.pipe(templateCache({}))
|
||||
.pipe(concat('tpls.js'))
|
||||
.pipe(ngAnnotate())
|
||||
.pipe(uglify())
|
||||
.pipe(gulp.dest('build'))
|
||||
var js = gulp.src(['src/browser/main/**/*.js', 'src/browser/shared/**/*.js'])
|
||||
.pipe(concat('app.js'))
|
||||
.pipe(ngAnnotate())
|
||||
.pipe(uglify())
|
||||
.pipe(gulp.dest('build'))
|
||||
var css = gulp.src(['src/browser/main/**/*.css', 'src/browser/shared/**/*.css'])
|
||||
.pipe(concat('all.css'))
|
||||
.pipe(minifyCss())
|
||||
.pipe(gulp.dest('build'))
|
||||
return merge(tpls, js, css)
|
||||
})
|
||||
|
||||
gulp.task('vendor', function () {
|
||||
var vendors = config.vendors
|
||||
|
||||
var vendorFiles = vendors.map(function (vendor) {
|
||||
return vendor.src
|
||||
})
|
||||
|
||||
vendorFiles.push('node_modules/font-awesome/**/font-awesome.css')
|
||||
vendorFiles.push('node_modules/font-awesome/**/fontawesome-webfont.*')
|
||||
vendorFiles.push('node_modules/font-awesome/**/FontAwesome.*')
|
||||
|
||||
return gulp.src(vendorFiles)
|
||||
.pipe(gulp.dest('src/browser/vendor'))
|
||||
})
|
||||
|
||||
gulp.task('styl', function () {
|
||||
return gulp.src('src/browser/main/styles/app.styl')
|
||||
.pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
|
||||
.pipe(styl())
|
||||
.pipe(autoprefixer())
|
||||
.pipe(gulp.dest('src/browser/main/styles/'))
|
||||
.pipe(livereload())
|
||||
.pipe(notify('Stylus!!'))
|
||||
})
|
||||
|
||||
gulp.task('styl-popup', function () {
|
||||
return gulp.src('src/browser/popup/styles/app.styl')
|
||||
.pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
|
||||
.pipe(styl())
|
||||
.pipe(autoprefixer())
|
||||
.pipe(gulp.dest('src/browser/popup/styles/'))
|
||||
.pipe(livereload())
|
||||
.pipe(notify('Stylus!! @POPUP'))
|
||||
})
|
||||
|
||||
gulp.task('bs', function () {
|
||||
return gulp.src('src/browser/shared/styles/bootstrap.styl')
|
||||
.pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
|
||||
.pipe(styl())
|
||||
.pipe(autoprefixer())
|
||||
.pipe(gulp.dest('src/browser/shared/styles'))
|
||||
.pipe(notify('Bootstrap compiled!!'))
|
||||
.pipe(livereload())
|
||||
})
|
||||
|
||||
gulp.task('inject', function (cb) {
|
||||
runSequence(['inject-main', 'inject-popup'], cb)
|
||||
})
|
||||
|
||||
gulp.task('inject-main', function () {
|
||||
return gulp.src('src/browser/main/index.inject.html')
|
||||
.pipe(inject(gulp.src(['src/browser/main/**/*.js', 'src/browser/main/**/*.css', 'src/browser/shared/**/*.js', 'src/browser/shared/**/*.css'], {read: false}), {
|
||||
relative: true
|
||||
}))
|
||||
.pipe(rename(function (path) {
|
||||
path.basename = 'index'
|
||||
}))
|
||||
.pipe(gulp.dest('src/browser/main/'))
|
||||
})
|
||||
|
||||
gulp.task('watch-main', function () {
|
||||
gulp.watch(
|
||||
['src/browser/main/index.inject.html', 'src/browser/main/**/*.js', 'src/browser/main/**/*.css', 'src/browser/shared/**/*.js', 'src/browser/shared/**/*.css'], ['inject-main'])
|
||||
|
||||
gulp.watch('src/browser/main/styles/**/*.styl', ['styl'])
|
||||
gulp.watch('src/browser/popup/styles/**/*.styl', ['styl-popup'])
|
||||
gulp.watch('src/browser/shared/styles/**/*.styl', ['bs'])
|
||||
livereload.listen()
|
||||
})
|
||||
gulp.task('inject-popup', function () {
|
||||
return gulp.src('src/browser/popup/index.inject.html')
|
||||
.pipe(inject(gulp.src(['src/browser/popup/**/*.js', 'src/browser/popup/**/*.css', 'src/browser/shared/**/*.js', 'src/browser/shared/**/*.css'], {read: false}), {
|
||||
relative: true
|
||||
}))
|
||||
.pipe(rename(function (path) {
|
||||
path.basename = 'index'
|
||||
}))
|
||||
.pipe(gulp.dest('src/browser/popup/'))
|
||||
})
|
||||
|
||||
gulp.task('del', function (cb) {
|
||||
del(['build/**/*'], cb)
|
||||
})
|
||||
|
||||
gulp.task('default', function (cb) {
|
||||
runSequence('del', 'build', 'watch', cb)
|
||||
})
|
||||
43
browser/finder/Components/FinderDetail.jsx
Normal file
43
browser/finder/Components/FinderDetail.jsx
Normal file
@@ -0,0 +1,43 @@
|
||||
var React = require('react/addons')
|
||||
|
||||
var CodeViewer = require('../../main/Components/CodeViewer')
|
||||
|
||||
var Markdown = require('../../main/Mixins/Markdown')
|
||||
|
||||
module.exports = React.createClass({
|
||||
mixins: [Markdown],
|
||||
propTypes: {
|
||||
currentArticle: React.PropTypes.object
|
||||
},
|
||||
render: function () {
|
||||
var article = this.props.currentArticle
|
||||
|
||||
if (article != null) {
|
||||
if (article.type === 'snippet') {
|
||||
return (
|
||||
<div className='FinderDetail'>
|
||||
<div className='header'>{article.callSign}</div>
|
||||
<div className='content'>
|
||||
<CodeViewer code={article.content} mode={article.mode}/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
} else if (article.type === 'blueprint') {
|
||||
|
||||
return (
|
||||
<div className='FinderDetail'>
|
||||
<div className='header'>{article.title}</div>
|
||||
<div className='content'>
|
||||
<div className='marked' dangerouslySetInnerHTML={{__html: ' ' + this.markdown(article.content)}}></div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div className='FinderDetail'>
|
||||
<div className='nothing'>Nothing selected</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
15
browser/finder/Components/FinderInput.jsx
Normal file
15
browser/finder/Components/FinderInput.jsx
Normal file
@@ -0,0 +1,15 @@
|
||||
var React = require('react/addons')
|
||||
|
||||
module.exports = React.createClass({
|
||||
propTypes: {
|
||||
onChange: React.PropTypes.func,
|
||||
search: React.PropTypes.string
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<div className='FinderInput'>
|
||||
<input value={this.props.search} onChange={this.props.onChange} type='text'/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
69
browser/finder/Components/FinderList.jsx
Normal file
69
browser/finder/Components/FinderList.jsx
Normal file
@@ -0,0 +1,69 @@
|
||||
var React = require('react/addons')
|
||||
|
||||
module.exports = React.createClass({
|
||||
propTypes: {
|
||||
articles: React.PropTypes.arrayOf,
|
||||
currentArticle: React.PropTypes.shape({
|
||||
id: React.PropTypes.number,
|
||||
type: React.PropTypes.string
|
||||
})
|
||||
},
|
||||
componentDidUpdate: function () {
|
||||
var index = this.props.articles.indexOf(this.props.currentArticle)
|
||||
var el = React.findDOMNode(this)
|
||||
var li = el.querySelectorAll('li')[index]
|
||||
|
||||
var overflowBelow = el.clientHeight + el.scrollTop < li.offsetTop + li.clientHeight
|
||||
if (overflowBelow) {
|
||||
el.scrollTop = li.offsetTop + li.clientHeight - el.clientHeight
|
||||
}
|
||||
var overflowAbove = el.scrollTop > li.offsetTop
|
||||
if (overflowAbove) {
|
||||
el.scrollTop = li.offsetTop
|
||||
}
|
||||
},
|
||||
render: function () {
|
||||
var list = this.props.articles.map(function (article) {
|
||||
if (article == null) {
|
||||
return (
|
||||
<li className={isActive ? 'active' : ''}>
|
||||
<div className='articleItem'>Undefined</div>
|
||||
<div className='divider'/>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
var isActive = this.props.currentArticle != null && (article.type === this.props.currentArticle.type && article.id === this.props.currentArticle.id)
|
||||
if (article.type === 'snippet') {
|
||||
return (
|
||||
<li className={isActive ? 'active' : ''}>
|
||||
<div className='articleItem'><i className='fa fa-code fa-fw'/> {article.callSign} / {article.description.substring(0, 10)}</div>
|
||||
<div className='divider'/>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
if (article.type === 'blueprint') {
|
||||
return (
|
||||
<li className={isActive ? 'active' : ''}>
|
||||
<div className='articleItem'><i className='fa fa-file-text-o fa-fw'/> {article.title}</div>
|
||||
<div className='divider'/>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<li className={isActive ? 'active' : ''}>
|
||||
<div className='articleItem'>Undefined</div>
|
||||
<div className='divider'/>
|
||||
</li>
|
||||
)
|
||||
}.bind(this))
|
||||
|
||||
return (
|
||||
<div className='FinderList'>
|
||||
<ul>
|
||||
{list}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
53
browser/finder/index.electron.html
Normal file
53
browser/finder/index.electron.html
Normal file
@@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CodeXen Popup</title>
|
||||
|
||||
<link rel="stylesheet" href="../vendor/fontawesome/css/font-awesome.min.css" media="screen" title="no title" charset="utf-8">
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<script>
|
||||
if (!Object.assign) {
|
||||
Object.defineProperty(Object, 'assign', {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function(target) {
|
||||
'use strict';
|
||||
if (target === undefined || target === null) {
|
||||
throw new TypeError('Cannot convert first argument to object');
|
||||
}
|
||||
|
||||
var to = Object(target);
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var nextSource = arguments[i];
|
||||
if (nextSource === undefined || nextSource === null) {
|
||||
continue;
|
||||
}
|
||||
nextSource = Object(nextSource);
|
||||
|
||||
var keysArray = Object.keys(Object(nextSource));
|
||||
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
|
||||
var nextKey = keysArray[nextIndex];
|
||||
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
|
||||
if (desc !== undefined && desc.enumerable) {
|
||||
to[nextKey] = nextSource[nextKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
return to;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
require('electron-stylus')(__dirname + '/../styles/finder/index.styl')
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content"></div>
|
||||
<script src="../ace/src-min/ace.js"></script>
|
||||
<script>
|
||||
require('node-jsx').install({ harmony: true, extension: '.jsx' })
|
||||
require('./index.jsx')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
0
browser/finder/index.html
Normal file
0
browser/finder/index.html
Normal file
188
browser/finder/index.jsx
Normal file
188
browser/finder/index.jsx
Normal file
@@ -0,0 +1,188 @@
|
||||
/* global localStorage */
|
||||
var remote = require('remote')
|
||||
var hideFinder = remote.getGlobal('hideFinder')
|
||||
var clipboard = require('clipboard')
|
||||
|
||||
var React = require('react/addons')
|
||||
|
||||
var FinderInput = require('./Components/FinderInput')
|
||||
var FinderList = require('./Components/FinderList')
|
||||
var FinderDetail = require('./Components/FinderDetail')
|
||||
|
||||
// filter start
|
||||
function basicFilter (keyword, articles) {
|
||||
if (keyword === '' || keyword == null) return articles
|
||||
var firstFiltered = articles.filter(function (article) {
|
||||
|
||||
var first = article.type === 'snippet' ? article.callSign : article.title
|
||||
if (first.match(new RegExp(keyword, 'i'))) return true
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
var secondFiltered = articles.filter(function (article) {
|
||||
var second = article.type === 'snippet' ? article.description : article.content
|
||||
if (second.match(new RegExp(keyword, 'i'))) return true
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
var thirdFiltered = articles.filter(function (article) {
|
||||
if (article.type === 'snippet') {
|
||||
if (article.content.match(new RegExp(keyword, 'i'))) return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
return firstFiltered.concat(secondFiltered, thirdFiltered).filter(function (value, index, self) {
|
||||
return self.indexOf(value) === index
|
||||
})
|
||||
}
|
||||
|
||||
function snippetFilter (articles) {
|
||||
return articles.filter(function (article) {
|
||||
return article.type === 'snippet'
|
||||
})
|
||||
}
|
||||
|
||||
function blueprintFilter (articles) {
|
||||
return articles.filter(function (article) {
|
||||
return article.type === 'blueprint'
|
||||
})
|
||||
}
|
||||
|
||||
function tagFilter (keyword, articles) {
|
||||
return articles.filter(function (article) {
|
||||
return article.Tags.some(function (tag) {
|
||||
return tag.name.match(new RegExp('^' + keyword, 'i'))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function searchArticle (search, articles) {
|
||||
var keywords = search.split(' ')
|
||||
|
||||
for (var keyword of keywords) {
|
||||
if (keyword.match(/^\$s/, 'i')) {
|
||||
articles = snippetFilter(articles)
|
||||
continue
|
||||
} else if (keyword.match(/^\$b/, 'i')) {
|
||||
articles = blueprintFilter(articles)
|
||||
continue
|
||||
} else if (keyword.match(/^#[A-Za-z0-9]+/)) {
|
||||
articles = tagFilter(keyword.substring(1, keyword.length), articles)
|
||||
continue
|
||||
}
|
||||
articles = basicFilter(keyword, articles)
|
||||
}
|
||||
|
||||
return articles
|
||||
}
|
||||
// Filter end
|
||||
|
||||
function fetchArticles () {
|
||||
var user = JSON.parse(localStorage.getItem('user'))
|
||||
if (user == null) {
|
||||
console.log('need to login')
|
||||
return []
|
||||
}
|
||||
|
||||
var articles = []
|
||||
user.Planets.forEach(function (planet) {
|
||||
var _planet = JSON.parse(localStorage.getItem('planet-' + planet.id))
|
||||
articles = articles.concat(_planet.Snippets, _planet.Blueprints)
|
||||
})
|
||||
console.log(articles.length + ' articles')
|
||||
|
||||
return articles
|
||||
}
|
||||
|
||||
var Finder = React.createClass({
|
||||
getInitialState: function () {
|
||||
var articles = fetchArticles()
|
||||
return {
|
||||
articles: articles,
|
||||
currentArticle: articles[0],
|
||||
search: ''
|
||||
}
|
||||
},
|
||||
componentDidMount: function () {
|
||||
document.addEventListener('keydown', this.handleKeyDown)
|
||||
document.addEventListener('click', this.handleClick)
|
||||
window.addEventListener('focus', this.handleFinderFocus)
|
||||
},
|
||||
componentWillUnmount: function () {
|
||||
document.removeEventListener('keydown', this.handleKeyDown)
|
||||
document.removeEventListener('click', this.handleClick)
|
||||
window.removeEventListener('focus', this.handleFinderFocus)
|
||||
},
|
||||
handleFinderFocus: function () {
|
||||
console.log('focusseeddddd')
|
||||
this.focusInput()
|
||||
var articles = fetchArticles()
|
||||
this.setState({
|
||||
articles: articles,
|
||||
currentArticle: articles[0],
|
||||
search: ''
|
||||
})
|
||||
},
|
||||
handleKeyDown: function (e) {
|
||||
if (e.keyCode === 38) {
|
||||
this.selectPrevious()
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
if (e.keyCode === 40) {
|
||||
this.selectNext()
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
if (e.keyCode === 13) {
|
||||
var article = this.state.currentArticle
|
||||
if (article.type === 'snippet') {
|
||||
clipboard.writeText(article.content)
|
||||
hideFinder()
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
if (e.keyCode === 27) {
|
||||
hideFinder()
|
||||
e.preventDefault()
|
||||
}
|
||||
},
|
||||
focusInput: function () {
|
||||
React.findDOMNode(this.refs.finderInput).querySelector('input').focus()
|
||||
},
|
||||
handleClick: function () {
|
||||
this.focusInput()
|
||||
},
|
||||
selectPrevious: function () {
|
||||
var index = this.refs.finderList.props.articles.indexOf(this.state.currentArticle)
|
||||
if (index > 0) {
|
||||
this.setState({currentArticle: this.refs.finderList.props.articles[index - 1]})
|
||||
}
|
||||
},
|
||||
selectNext: function () {
|
||||
var index = this.refs.finderList.props.articles.indexOf(this.state.currentArticle)
|
||||
if (index > -1 && index < this.refs.finderList.props.articles.length - 1) {
|
||||
this.setState({currentArticle: this.refs.finderList.props.articles[index + 1]})
|
||||
}
|
||||
},
|
||||
handleChange: function (e) {
|
||||
this.setState({search: e.target.value}, function () {
|
||||
this.setState({currentArticle: this.refs.finderList.props.articles[0]})
|
||||
})
|
||||
},
|
||||
render: function () {
|
||||
var articles = searchArticle(this.state.search, this.state.articles)
|
||||
return (
|
||||
<div className='Finder'>
|
||||
<FinderInput ref='finderInput' onChange={this.handleChange} search={this.state.search}/>
|
||||
<FinderList ref='finderList' currentArticle={this.state.currentArticle} articles={articles}/>
|
||||
<FinderDetail currentArticle={this.state.currentArticle}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
React.render(<Finder/>, document.getElementById('content'))
|
||||
@@ -7,9 +7,11 @@ var Select = require('react-select')
|
||||
var request = require('superagent')
|
||||
var PlanetActions = require('../Actions/PlanetActions')
|
||||
|
||||
var apiUrl = require('../../../config').apiUrl
|
||||
|
||||
var getOptions = function (input, callback) {
|
||||
request
|
||||
.get('http://localhost:8000/tags/search')
|
||||
.get(apiUrl + 'tags/search')
|
||||
.query({name: input})
|
||||
.send()
|
||||
.end(function (err, res) {
|
||||
|
||||
@@ -8,7 +8,7 @@ var AuthActions = require('../Actions/AuthActions')
|
||||
|
||||
var AuthStore = require('../Stores/AuthStore')
|
||||
|
||||
var apiUrl = 'http://localhost:8000/'
|
||||
var apiUrl = require('../../../config').apiUrl
|
||||
|
||||
module.exports = React.createClass({
|
||||
mixins: [Catalyst.LinkedStateMixin],
|
||||
|
||||
@@ -7,9 +7,11 @@ var Catalyst = require('../Mixins/Catalyst')
|
||||
|
||||
var PlanetActions = require('../Actions/PlanetActions')
|
||||
|
||||
var apiUrl = require('../../../config').apiUrl
|
||||
|
||||
var getOptions = function (input, callback) {
|
||||
request
|
||||
.get('http://localhost:8000/users/search')
|
||||
.get(apiUrl + 'users/search')
|
||||
.query({name: input})
|
||||
.send()
|
||||
.end(function (err, res) {
|
||||
|
||||
@@ -6,9 +6,11 @@ var Catalyst = require('../Mixins/Catalyst')
|
||||
|
||||
var PlanetActions = require('../Actions/PlanetActions')
|
||||
|
||||
var apiUrl = require('../../../config').apiUrl
|
||||
|
||||
var getOptions = function (input, callback) {
|
||||
request
|
||||
.get('http://localhost:8000/users/search')
|
||||
.get(apiUrl + 'users/search')
|
||||
.query({name: input})
|
||||
.send()
|
||||
.end(function (err, res) {
|
||||
|
||||
@@ -6,9 +6,11 @@ var Select = require('react-select')
|
||||
var request = require('superagent')
|
||||
var PlanetActions = require('../Actions/PlanetActions')
|
||||
|
||||
var apiUrl = require('../../../config').apiUrl
|
||||
|
||||
var getOptions = function (input, callback) {
|
||||
request
|
||||
.get('http://localhost:8000/tags/search')
|
||||
.get(apiUrl + 'tags/search')
|
||||
.query({name: input})
|
||||
.send()
|
||||
.end(function (err, res) {
|
||||
@@ -22,7 +24,7 @@ var getOptions = function (input, callback) {
|
||||
label: tag.name,
|
||||
value: tag.name
|
||||
}
|
||||
}),
|
||||
}),
|
||||
complete: false
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,47 +1,87 @@
|
||||
/* global localStorage */
|
||||
var React = require('react/addons')
|
||||
var ReactRouter = require('react-router')
|
||||
var RouteHandler = ReactRouter.RouteHandler
|
||||
var request = require('superagent')
|
||||
|
||||
var AuthStore = require('../Stores/AuthStore')
|
||||
|
||||
var apiUrl = require('../../../config').apiUrl
|
||||
|
||||
function fetchPlanet (planet) {
|
||||
request
|
||||
.get(apiUrl + planet.userName + '/' + planet.name)
|
||||
.send()
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
return
|
||||
}
|
||||
|
||||
var _planet = res.body
|
||||
_planet.userName = planet.userName
|
||||
|
||||
_planet.Snippets = _planet.Snippets.map(function (snippet) {
|
||||
snippet.type = 'snippet'
|
||||
return snippet
|
||||
})
|
||||
|
||||
_planet.Blueprints = _planet.Blueprints.map(function (blueprint) {
|
||||
blueprint.type = 'blueprint'
|
||||
return blueprint
|
||||
})
|
||||
|
||||
localStorage.setItem('planet-' + _planet.id, JSON.stringify(_planet))
|
||||
console.log('planet-' + _planet.id + ' fetched')
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = React.createClass({
|
||||
mixins: [ReactRouter.Navigation, ReactRouter.State],
|
||||
componentDidMount: function () {
|
||||
this.unsubscribe = AuthStore.listen(this.onListen)
|
||||
},
|
||||
componentWillUnmount: function () {
|
||||
this.unsubscribe()
|
||||
},
|
||||
onListen: function (res) {
|
||||
if (res == null || res.status == null) {
|
||||
return
|
||||
}
|
||||
mixins: [ReactRouter.Navigation, ReactRouter.State],
|
||||
componentDidMount: function () {
|
||||
this.unsubscribe = AuthStore.listen(this.onListen)
|
||||
|
||||
if (res.status === 'loggedIn' || res.status === 'registered') {
|
||||
var user = res.data
|
||||
var planet = user.Planets.length > 0 ? user.Planets[0] : null
|
||||
if (planet == null) {
|
||||
this.transitionTo('user', {userName: user.name})
|
||||
return
|
||||
}
|
||||
this.transitionTo('planetHome', {userName: user.name, planetName: planet.name})
|
||||
return
|
||||
}
|
||||
|
||||
if (res.status === 'loggedOut') {
|
||||
this.transitionTo('login')
|
||||
return
|
||||
}
|
||||
},
|
||||
render: function () {
|
||||
// Redirect Login state
|
||||
if (this.getPath() === '/') {
|
||||
this.transitionTo('/login')
|
||||
}
|
||||
return (
|
||||
<div className='Main'>
|
||||
<RouteHandler/>
|
||||
</div>
|
||||
)
|
||||
var user = JSON.parse(localStorage.getItem('user'))
|
||||
if (user != null) {
|
||||
user.Planets.forEach(fetchPlanet)
|
||||
return
|
||||
}
|
||||
this.transitionTo('login')
|
||||
},
|
||||
componentWillUnmount: function () {
|
||||
this.unsubscribe()
|
||||
},
|
||||
onListen: function (res) {
|
||||
if (res == null || res.status == null) {
|
||||
return
|
||||
}
|
||||
|
||||
if (res.status === 'loggedIn' || res.status === 'registered') {
|
||||
var user = res.data
|
||||
var planet = user.Planets.length > 0 ? user.Planets[0] : null
|
||||
if (planet == null) {
|
||||
this.transitionTo('user', {userName: user.name})
|
||||
return
|
||||
}
|
||||
this.transitionTo('planetHome', {userName: user.name, planetName: planet.name})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (res.status === 'loggedOut') {
|
||||
this.transitionTo('login')
|
||||
return
|
||||
}
|
||||
},
|
||||
render: function () {
|
||||
// Redirect Login state
|
||||
if (this.getPath() === '/') {
|
||||
this.transitionTo('/login')
|
||||
}
|
||||
return (
|
||||
<div className='Main'>
|
||||
<RouteHandler/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -10,6 +10,8 @@ var UserNavigator = require('../Components/UserNavigator')
|
||||
var AuthStore = require('../Stores/AuthStore')
|
||||
var PlanetStore = require('../Stores/PlanetStore')
|
||||
|
||||
var apiUrl = require('../../../config').apiUrl
|
||||
|
||||
module.exports = React.createClass({
|
||||
mixins: [React.addons.LinkedStateMixin, ReactRouter.Navigation, ReactRouter.State],
|
||||
propTypes: {
|
||||
@@ -44,7 +46,7 @@ module.exports = React.createClass({
|
||||
},
|
||||
fetchUser: function (userName) {
|
||||
request
|
||||
.get('http://localhost:8000/' + userName)
|
||||
.get(apiUrl + userName)
|
||||
.send()
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
|
||||
@@ -4,7 +4,7 @@ var request = require('superagent')
|
||||
|
||||
var AuthActions = require('../Actions/AuthActions')
|
||||
|
||||
var apiUrl = 'http://localhost:8000/'
|
||||
var apiUrl = require('../../../config').apiUrl
|
||||
|
||||
var AuthStore = Reflux.createStore({
|
||||
init: function () {
|
||||
|
||||
@@ -4,7 +4,7 @@ var request = require('superagent')
|
||||
|
||||
var PlanetActions = require('../Actions/PlanetActions')
|
||||
|
||||
var apiUrl = 'http://localhost:8000/'
|
||||
var apiUrl = require('../../../config').apiUrl
|
||||
|
||||
var PlanetStore = Reflux.createStore({
|
||||
init: function () {
|
||||
@@ -70,6 +70,8 @@ var PlanetStore = Reflux.createStore({
|
||||
return blueprint
|
||||
})
|
||||
|
||||
localStorage.setItem('planet-' + planet.id, JSON.stringify(planet))
|
||||
|
||||
planet.Articles = planet.Snippets.concat(planet.Blueprints).sort(function (a, b) {
|
||||
a = new Date(a.updatedAt)
|
||||
b = new Date(b.updatedAt)
|
||||
@@ -94,6 +96,7 @@ var PlanetStore = Reflux.createStore({
|
||||
}
|
||||
|
||||
var planet = res.body
|
||||
localStorage.remove('planet-' + planet.id)
|
||||
|
||||
this.trigger({
|
||||
status: 'planetDeleted',
|
||||
@@ -186,6 +189,11 @@ var PlanetStore = Reflux.createStore({
|
||||
.end(function (req, res) {
|
||||
var snippet = res.body
|
||||
snippet.type = 'snippet'
|
||||
|
||||
var planet = JSON.parse(localStorage.getItem('planet-' + snippet.PlanetId))
|
||||
planet.Snippets.unshift(snippet)
|
||||
localStorage.setItem('planet-' + snippet.PlanetId, JSON.stringify(planet))
|
||||
|
||||
this.trigger({
|
||||
status: 'articleCreated',
|
||||
data: snippet
|
||||
@@ -209,6 +217,17 @@ var PlanetStore = Reflux.createStore({
|
||||
|
||||
var snippet = res.body
|
||||
snippet.type = 'snippet'
|
||||
|
||||
var planet = JSON.parse(localStorage.getItem('planet-' + snippet.PlanetId))
|
||||
planet.Snippets.some(function (_snippet, index) {
|
||||
if (snippet.id === _snippet) {
|
||||
planet.Snippets[index] = snippet
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
localStorage.setItem('planet-' + snippet.PlanetId, JSON.stringify(planet))
|
||||
|
||||
this.trigger({
|
||||
status: 'articleUpdated',
|
||||
data: snippet
|
||||
@@ -230,6 +249,17 @@ var PlanetStore = Reflux.createStore({
|
||||
}
|
||||
|
||||
var snippet = res.body
|
||||
|
||||
var planet = JSON.parse(localStorage.getItem('planet-' + snippet.PlanetId))
|
||||
planet.Snippets.some(function (_snippet, index) {
|
||||
if (snippet.id === _snippet) {
|
||||
planet.splice(index, 1)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
localStorage.setItem('planet-' + snippet.PlanetId, JSON.stringify(planet))
|
||||
|
||||
this.trigger({
|
||||
status: 'articleDeleted',
|
||||
data: snippet
|
||||
@@ -247,6 +277,11 @@ var PlanetStore = Reflux.createStore({
|
||||
.end(function (req, res) {
|
||||
var blueprint = res.body
|
||||
blueprint.type = 'blueprint'
|
||||
|
||||
var planet = JSON.parse(localStorage.getItem('planet-' + blueprint.PlanetId))
|
||||
planet.Blueprints.unshift(blueprint)
|
||||
localStorage.setItem('planet-' + blueprint.PlanetId, JSON.stringify(planet))
|
||||
|
||||
this.trigger({
|
||||
status: 'articleCreated',
|
||||
data: blueprint
|
||||
@@ -270,6 +305,17 @@ var PlanetStore = Reflux.createStore({
|
||||
|
||||
var blueprint = res.body
|
||||
blueprint.type = 'blueprint'
|
||||
|
||||
var planet = JSON.parse(localStorage.getItem('planet-' + blueprint.PlanetId))
|
||||
planet.Blueprints.some(function (_blueprint, index) {
|
||||
if (blueprint.id === _blueprint) {
|
||||
planet.Blueprints[index] = blueprint
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
localStorage.setItem('planet-' + blueprint.PlanetId, JSON.stringify(blueprint))
|
||||
|
||||
this.trigger({
|
||||
status: 'articleUpdated',
|
||||
data: blueprint
|
||||
@@ -291,6 +337,17 @@ var PlanetStore = Reflux.createStore({
|
||||
}
|
||||
|
||||
var blueprint = res.body
|
||||
|
||||
var planet = JSON.parse(localStorage.getItem('planet-' + blueprint.PlanetId))
|
||||
planet.Blueprints.some(function (_blueprint, index) {
|
||||
if (blueprint.id === _blueprint) {
|
||||
planet.splice(index, 1)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
localStorage.setItem('planet-' + blueprint.PlanetId, JSON.stringify(planet))
|
||||
|
||||
this.trigger({
|
||||
status: 'articleDeleted',
|
||||
data: blueprint
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
<link rel="stylesheet" href="../vendor/fontawesome/css/font-awesome.min.css" media="screen" title="no title" charset="utf-8">
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
|
||||
<script>
|
||||
if (!Object.assign) {
|
||||
Object.defineProperty(Object, 'assign', {
|
||||
@@ -39,6 +39,8 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
require('electron-stylus')(__dirname + '/../styles/main/index.styl')
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
77
browser/styles/finder/index.styl
Normal file
77
browser/styles/finder/index.styl
Normal file
@@ -0,0 +1,77 @@
|
||||
@import '../../../node_modules/nib/lib/nib'
|
||||
@import '../vars'
|
||||
@import '../mixins/*'
|
||||
global-reset()
|
||||
@import '../shared/*'
|
||||
|
||||
body
|
||||
font-family "Lato"
|
||||
color textColor
|
||||
font-size fontSize
|
||||
|
||||
.Finder
|
||||
absolute top bottom left right
|
||||
.FinderInput
|
||||
position absolute
|
||||
top 11px
|
||||
left 11px
|
||||
right 11px
|
||||
margin 0 auto
|
||||
height 44px
|
||||
box-sizing border-box
|
||||
border-bottom solid 1px borderColor
|
||||
input
|
||||
display block
|
||||
width 100%
|
||||
border solid 1px borderColor
|
||||
padding 0 10px
|
||||
font-size 1em
|
||||
height 33px
|
||||
border-radius 5px
|
||||
box-sizing border-box
|
||||
border-radius 16.5px
|
||||
&:focus, &.focus
|
||||
border-color brandBorderColor
|
||||
outline none
|
||||
.FinderList
|
||||
absolute left bottom
|
||||
top 55px
|
||||
border-right solid 1px borderColor
|
||||
box-sizing border-box
|
||||
width 250px
|
||||
overflow-y auto
|
||||
&>ul>li
|
||||
.articleItem
|
||||
padding 10px
|
||||
border solid 2px transparent
|
||||
box-sizing border-box
|
||||
.divider
|
||||
box-sizing border-box
|
||||
border-bottom solid 1px borderColor
|
||||
&.active
|
||||
.articleItem
|
||||
border-color brandColor
|
||||
|
||||
.FinderDetail
|
||||
absolute right bottom
|
||||
top 55px
|
||||
left 250px
|
||||
.header
|
||||
absolute top left right
|
||||
height 44px
|
||||
box-sizing border-box
|
||||
padding 0 10px
|
||||
border-bottom solid 1px borderColor
|
||||
line-height 44px
|
||||
font-size 1.3em
|
||||
.content
|
||||
.ace_editor, .marked
|
||||
position absolute
|
||||
top 49px
|
||||
left 5px
|
||||
right 5px
|
||||
bottom 5px
|
||||
box-sizing border-box
|
||||
.marked
|
||||
marked()
|
||||
overflow-y auto
|
||||
@@ -1,48 +0,0 @@
|
||||
module.exports = {
|
||||
vendors: [
|
||||
{
|
||||
name: 'ace',
|
||||
src: 'node_modules/@rokt33r/ace-builds/src/**/*'
|
||||
},
|
||||
{
|
||||
name: 'angular',
|
||||
src: 'node_modules/angular/angular.js'
|
||||
},
|
||||
{
|
||||
name: 'angular-bootstrap',
|
||||
src: 'node_modules/angular-bootstrap/dist/ui-bootstrap-tpls.js'
|
||||
},
|
||||
{
|
||||
name: 'angular-sanitize',
|
||||
src: 'node_modules/angular-sanitize/angular-sanitize.js'
|
||||
},
|
||||
{
|
||||
name: 'angular-ui-router',
|
||||
src: 'node_modules/angular-ui-router/build/angular-ui-router.js'
|
||||
},
|
||||
{
|
||||
name: 'ui-select',
|
||||
src: 'node_modules/ui-select/dist/select.js'
|
||||
},
|
||||
{
|
||||
name: 'satellizer',
|
||||
src: 'node_modules/satellizer/satellizer.js'
|
||||
},
|
||||
{
|
||||
name: 'angular-md5',
|
||||
src: 'node_modules/angular-md5/angular-md5.js'
|
||||
},
|
||||
{
|
||||
name: 'moment',
|
||||
src: 'node_modules/moment/moment.js'
|
||||
},
|
||||
{
|
||||
name: 'angular-hotkeys',
|
||||
src: 'node_modules/angular-hotkeys/build/hotkeys.js'
|
||||
},
|
||||
{
|
||||
name: 'marked',
|
||||
src: 'node_modules/marked/lib/marked.js'
|
||||
}
|
||||
]
|
||||
}
|
||||
4
config.js
Normal file
4
config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
apiUrl: 'http://codexen-server-dex2-ezebi636yb.elasticbeanstalk.com/'
|
||||
// apiUrl: 'http://localhost:8000/'
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
# Event List
|
||||
|
||||
|name|Description|Delivery|
|
||||
|----|----|----|
|
||||
|userSignIn|a user signed in||
|
||||
|userSignOut|a user signed out||
|
||||
|snippetUpdated|snippet has been updated or created|snippet|
|
||||
219
main.js
219
main.js
@@ -1,6 +1,7 @@
|
||||
var app = require('app') // Module to control application life.
|
||||
var BrowserWindow = require('browser-window') // Module to create native browser window.
|
||||
|
||||
var Menu = require('menu')
|
||||
var Tray = require('tray')
|
||||
// Report crashes to our server.
|
||||
require('crash-reporter').start()
|
||||
|
||||
@@ -13,25 +14,209 @@ var mainWindow = null
|
||||
// })
|
||||
|
||||
app.on('ready', function () {
|
||||
// menu start
|
||||
var template = [
|
||||
{
|
||||
label: 'Electron',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About Electron',
|
||||
selector: 'orderFrontStandardAboutPanel:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Services',
|
||||
submenu: []
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Hide Electron',
|
||||
accelerator: 'Command+H',
|
||||
selector: 'hide:'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
selector: 'hideOtherApplications:'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
selector: 'unhideAllApplications:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
selector: 'terminate:'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'Command+Z',
|
||||
selector: 'undo:'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+Command+Z',
|
||||
selector: 'redo:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'Command+X',
|
||||
selector: 'cut:'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'Command+C',
|
||||
selector: 'copy:'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'Command+V',
|
||||
selector: 'paste:'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'Command+A',
|
||||
selector: 'selectAll:'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'Command+R',
|
||||
click: function () {
|
||||
BrowserWindow.getFocusedWindow().reload()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle DevTools',
|
||||
accelerator: 'Alt+Command+I',
|
||||
click: function () {
|
||||
BrowserWindow.getFocusedWindow().toggleDevTools()
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'Command+M',
|
||||
selector: 'performMiniaturize:'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'Command+W',
|
||||
selector: 'performClose:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
selector: 'arrangeInFront:'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: []
|
||||
}
|
||||
]
|
||||
|
||||
var menu = Menu.buildFromTemplate(template)
|
||||
|
||||
Menu.setApplicationMenu(menu)
|
||||
// menu end
|
||||
var appIcon = new Tray(__dirname + '/tray-icon.png')
|
||||
appIcon.setToolTip('This is my application.')
|
||||
appIcon.on('clicked', function () {
|
||||
if (mainWindow == null) {
|
||||
makeNewMainWindow()
|
||||
}
|
||||
mainWindow.show()
|
||||
})
|
||||
|
||||
makeNewMainWindow()
|
||||
|
||||
function makeNewMainWindow () {
|
||||
console.log('new Window!')
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 920,
|
||||
height: 640,
|
||||
'web-preferences': {
|
||||
'overlay-scrollbars': true
|
||||
}
|
||||
})
|
||||
app.on('activate-with-no-open-windows', function () {
|
||||
if (mainWindow == null) {
|
||||
makeNewMainWindow()
|
||||
return
|
||||
}
|
||||
mainWindow.show()
|
||||
})
|
||||
|
||||
mainWindow.loadUrl('file://' + __dirname + '/browser/main/index.electron.html')
|
||||
var popUpWindow = new BrowserWindow({
|
||||
width: 600,
|
||||
height: 400,
|
||||
show: false,
|
||||
frame: false,
|
||||
'always-on-top': true,
|
||||
'web-preferences': {
|
||||
'overlay-scrollbars': true,
|
||||
'skip-taskbar': true
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.on('closed', function () {
|
||||
console.log('main closed')
|
||||
mainWindow = null
|
||||
app.dock.hide()
|
||||
})
|
||||
app.dock.show()
|
||||
popUpWindow.loadUrl('file://' + __dirname + '/browser/finder/index.electron.html')
|
||||
|
||||
popUpWindow.on('blur', function () {
|
||||
popUpWindow.hide()
|
||||
})
|
||||
popUpWindow.setVisibleOnAllWorkspaces(true)
|
||||
|
||||
var globalShortcut = require('global-shortcut')
|
||||
|
||||
globalShortcut.register('ctrl+tab+shift', function () {
|
||||
if (mainWindow != null && !mainWindow.isFocused()) {
|
||||
mainWindow.hide()
|
||||
}
|
||||
popUpWindow.show()
|
||||
})
|
||||
|
||||
global.hideFinder = function () {
|
||||
if (mainWindow == null || !mainWindow.isVisible()) {
|
||||
Menu.sendActionToFirstResponder('hide:')
|
||||
}
|
||||
popUpWindow.hide()
|
||||
}
|
||||
})
|
||||
|
||||
function makeNewMainWindow () {
|
||||
console.log('new Window!')
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 920,
|
||||
height: 640,
|
||||
'web-preferences': {
|
||||
'overlay-scrollbars': true
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.loadUrl('file://' + __dirname + '/browser/main/index.electron.html')
|
||||
|
||||
mainWindow.on('closed', function () {
|
||||
console.log('main closed')
|
||||
mainWindow = null
|
||||
app.dock.hide()
|
||||
})
|
||||
app.dock.show()
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "codexen-app-builder",
|
||||
"name": "codexen-app",
|
||||
"version": "0.2.0",
|
||||
"description": "CodeXen App Builder",
|
||||
"description": "CodeXen App",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"start": "npm run serve | npm run dev",
|
||||
"serve": "./node_modules/.bin/http-server ./browser -p 8080",
|
||||
@@ -31,6 +32,7 @@
|
||||
"homepage": "https://github.com/Rokt33r/codexen-app#readme",
|
||||
"dependencies": {
|
||||
"dotenv": "^1.1.0",
|
||||
"electron-stylus": "^0.1.0",
|
||||
"halogen": "^0.1.10",
|
||||
"markdown-it": "^4.3.1",
|
||||
"moment": "^2.10.3",
|
||||
|
||||
BIN
tray-icon.png
Normal file
BIN
tray-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 463 B |
BIN
tray-icon@2x.png
Normal file
BIN
tray-icon@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 924 B |
BIN
tray-icon@4x.png
Normal file
BIN
tray-icon@4x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
Reference in New Issue
Block a user