1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 17:56:25 +00:00

update electron window

This commit is contained in:
Rokt33r
2015-06-12 17:36:43 +09:00
parent c81bddad2a
commit bcec0c665a
9 changed files with 268 additions and 327 deletions

View File

@@ -125,4 +125,4 @@ gulp.task('default', function (cb) {
runSequence('del', 'build', 'watch', cb)
})
// require('./gulp-electron')(gulp)
require('./gulp-electron')(gulp)

View File

@@ -10,34 +10,33 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<meta name="description" content="CodeXen - Short code storage service">
<link rel="stylesheet" href="../../all.css" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="../../vendor/css/font-awesome.css" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="../../main.css" media="screen" title="no title" charset="utf-8">
</head>
<body class="popup-body" ng-controller="PopUpController">
<!-- Dev!!-->
<button style="position:fixed;bottom:0;right:0;padding:5px;z-index:1000;" type="button" name="button" ng-click="toggleDev()">DEV!</button>
<div ng-click="focusSearchInput()" class="search-block">
<div class="search-block">
<input ng-change="filterList(searchNeedle)" search-input id="search-input" type="text" class="form-control" ng-model="searchNeedle" ng-change="refreshResult">
</div>
<div class="result-block row-fluid">
<ul ng-click="focusList()" class="result-list left-pane" ng-class="{focused:isFocusing == 2}">
<li ng-click="selectItem($index)" ng-repeat="snippet in filteredSnippets"><a ng-class="{selected:$index == selectIndex}" href="#">{{snippet.description}}</a></li>
<ul class="result-list left-pane" ng-class="{focused:isFocusing == 2}">
<li ng-click="selectSnippet($index)" ng-repeat="snippet in filteredSnippets" ng-class="{active:$index == selectIndex}"><a href="#">{{snippet.description}}</a></li>
</ul>
<div class="right-pane">
<div ng-click="focusControl()" class="result-detail-control">
<button ng-class="{focus: controlIndex == 1}" id="btnClipboard" type="button" name="button" class="btn btn-default"><i class="fa fa-clipboard"></i></button>
<button ng-class="{focus: controlIndex == 2}" id="btnEdit" type="button" name="button" class="btn btn-default"><i class="fa fa-edit"></i></button>
<button ng-class="{focus: controlIndex == 3}" id="btnShare" type="button" name="button" class="btn btn-default"><i class="fa fa-share"></i></button>
<div class="result-detail-control">
<button id="btnClipboard" type="button" name="button" class="btn btn-default"><i class="fa fa-clipboard"></i></button>
<button id="btnEdit" type="button" name="button" class="btn btn-default"><i class="fa fa-edit"></i></button>
<button id="btnShare" type="button" name="button" class="btn btn-default"><i class="fa fa-share"></i></button>
</div>
<div ng-click="focusContent()" id="aceView" class="result-detail-content"
<div id="aceView" class="result-detail-content"
ui-ace="{
showGutter: false,
useWrapMode: true,
mode:selectedItem.mode.toLowerCase(),
onLoad : aceLoaded
onLoad: aceLoaded,
theme: 'solarized_dark'
}"
readonly

View File

@@ -3,15 +3,6 @@
var remote = require('remote')
var ipc = require('ipc')
var SEARCH_INPUT = 1
var RESULT_LIST = 2
var RESULT_CONTROL = 3
var RESULT_CONTENT = 4
// var btnClipboard = document.getElementById('btnClipboard')
// var btnEdit = document.getElementById('btnEdit')
// var btnShare = document.getElementById('btnShare')
var aceView = document.getElementById('aceView')
angular.module('codexen.popup', [
'ui.ace',
'satellizer',
@@ -27,214 +18,146 @@ angular.module('codexen.popup', [
// Setup Events
remote.getCurrentWindow().on('focus', function () {
$scope.$apply(focusSearchInput)
loadSnippets()
})
hotkeys.bindTo($scope)
.add('down', function (e) {
switch ($scope.isFocusing) {
case RESULT_LIST:
selectNextItem()
break
case RESULT_CONTROL:
focusContent()
break
}
nextSnippet()
e.preventDefault()
})
.add('up', function (e) {
switch ($scope.isFocusing) {
case RESULT_LIST:
selectPriorItem()
break
case RESULT_CONTENT:
focusControl()
break
}
priorSnippet()
e.preventDefault()
})
.add('right', function (e) {
if ($scope.isFocusing === RESULT_LIST) {
focusControl()
return
}
if ($scope.isFocusing === RESULT_CONTROL) {
nextControl()
}
})
.add('left', function (e) {
if ($scope.isFocusing === RESULT_CONTROL) {
priorControl()
}
})
.add('esc', function (e) {
switch ($scope.isFocusing) {
case RESULT_LIST:
focusSearchInput()
break
case RESULT_CONTROL:
focusList()
break
case RESULT_CONTENT:
console.log('esc fr content')
focusControl()
break
case SEARCH_INPUT:
hidePopUp()
}
hidePopUp()
})
.add('shift+tab', function (e) {
e.preventDefault()
if ($scope.isFocusing === RESULT_CONTROL) {
priorControl()
return
}
})
.add('tab', function (e) {
e.preventDefault()
if ($scope.isFocusing === RESULT_LIST) {
focusControl()
return
}
if ($scope.isFocusing === RESULT_CONTROL) {
nextControl()
return
}
})
.add('enter', function (e) {
switch ($scope.isFocusing) {
case RESULT_LIST:
console.log($scope.selectedItem.content)
ipc.send('writeCode', $scope.selectedItem.content)
break
}
console.log($scope.selectedItem.content)
ipc.send('writeCode', $scope.selectedItem.content)
e.preventDefault()
})
$scope.aceLoaded = function (editor) {
editor.commands.addCommand({
name: 'escape',
bindKey: {win: 'esc', mac: 'esc'},
exec: function (editor) {
editor.blur()
focusControl()
$scope.$apply()
},
readOnly: true
})
}
$scope.$on('nextSnippetRequested', function (e) {
e.stopPropagation()
nextSnippet()
})
$scope.$on('priorSnippetRequested', function (e) {
e.stopPropagation()
priorSnippet()
})
$scope.$on('snippetSubmitted', function (e) {
if ($scope.filteredSnippets.length > 0) ipc.send('writeCode', $scope.selectedItem.content)
else console.log('\x07')
e.stopPropagation()
})
// Init Data
$scope.snippets = []
var userId = $auth.getPayload().sub
Snippet.findByUser(userId)
Snippet.findMine()
.success(function (data) {
$scope.snippets = data.snippets
$scope.snippets = data
filterList()
})
// Functions
// Result Item control
$scope.selectIndex = 0
$scope.selectSnippet = selectSnippet
$scope.filterList = filterList
$scope.focusSearchInput = focusSearchInput
// Search Filter
function loadSnippets () {
Snippet.findMine()
.success(function (data) {
$scope.snippets = data
filterList()
})
}
function filterList (needle) {
$scope.filteredSnippets = $filter('filter')($scope.snippets, needle)
$scope.selectIndex = 0
selectItem($scope.selectIndex)
firstSnippet()
}
function selectSnippet (index) {
if (index !== undefined) $scope.selectIndex = index
$scope.selectedItem = $scope.filteredSnippets[$scope.selectIndex]
}
function firstSnippet () {
$scope.selectIndex = 0
selectSnippet($scope.selectIndex)
}
function priorSnippet () {
if ($scope.selectIndex > 0) $scope.selectIndex -= 1
selectSnippet()
}
function nextSnippet () {
if ($scope.selectIndex < $scope.filteredSnippets.length - 1) {
$scope.selectIndex += 1
}
selectSnippet()
}
// Focusing Search Input
function focusSearchInput () {
document.getElementById('search-input').focus()
}
$scope.filterList = filterList
function hidePopUp () {
ipc.send('hidePopUp')
}
// Result Item control
$scope.selectIndex = 0
$scope.selectItem = selectItem
function selectItem (index) {
$scope.selectIndex = index
$scope.selectedItem = $scope.filteredSnippets[index]
$scope.controlIndex = 0
}
function selectNextItem () {
if ($scope.selectIndex >= ($scope.filteredSnippets.length - 1)) {
return
}
selectItem(++$scope.selectIndex)
}
function selectPriorItem () {
if ($scope.selectIndex === 0) {
focusSearchInput()
return
}
selectItem(--$scope.selectIndex)
}
// Focusing control
$scope.isFocusing = 0
function focusSearchInput () {
$scope.isFocusing = SEARCH_INPUT
document.getElementById('search-input').focus()
$scope.controlIndex = 0
}
$scope.focusSearchInput = focusSearchInput
function focusList () {
$scope.isFocusing = RESULT_LIST
document.getElementById('search-input').blur()
$scope.controlIndex = 0
}
$scope.focusList = focusList
function focusControl () {
if ($scope.controlIndex === 0) {
$scope.controlIndex = 1
}
$scope.isFocusing = RESULT_CONTROL
}
$scope.focusControl = focusControl
function focusContent () {
angular.element(aceView).scope().focus()
$scope.isFocusing = RESULT_CONTENT
}
$scope.controlIndex = 0
function nextControl () {
if ($scope.controlIndex === 3) {
$scope.controlIndex = 0
focusContent()
return
}
$scope.controlIndex ++
}
function priorControl () {
if ($scope.controlIndex === 1) {
focusList()
return
}
$scope.controlIndex --
}
})
.directive('searchInput', function () {
return {
restrict: 'A',
link: function (scope, el, attr) {
el.on('keydown', function (e) {
// Down key => Focus on Result list
if (e.keyCode === 40) {
scope.focusList()
e.preventDefault()
scope.$emit('nextSnippetRequested')
// e.preventDefault()
}
// Up key => Focus on Result list
if (e.keyCode === 38) {
scope.$emit('priorSnippetRequested')
// e.preventDefault()
}
// Up key => Focus on Result list
if (e.keyCode === 13) {
scope.$emit('snippetSubmitted')
}
// Esc key => Dismiss popup

View File

@@ -1,83 +0,0 @@
@import "../../src/variables";
@import "../../src/mixins";
$selected-color: white;
$selected-bg: $brand-primary;
$focused-shadow-color: $brand-primary;
.popup-body{
.search-block{
padding: 5px;
height:44px;
position:absolute;
top: 0;
width: 100%;
}
.result-block{
position:absolute;
top: 44px;
bottom: 0;
width: 100%;
overflow: hidden;
.left-pane{
margin: 0;
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 40%;
overflow-y: auto;
overflow-x: hidden;
}
.result-list{
list-style:none;
padding: 0;
&.focused{
border: solid 1px $brand-primary;
}
li{
a{
display:block;
padding: 5px 10px;
border-bottom: 1px solid $border-color;
&.selected{
color: $selected-color;
background-color: $selected-bg;
}
&:hover{
}
}
}
border-right: 1px solid $border-color;
}
.right-pane{
position: absolute;
left: 40%;
top: 0;
bottom: 0;
width: 60%;
overflow-y: auto;
overflow-x: hidden;
}
.result-detail-control{
position: absolute;
top: 0;
width: 100%;
height: 34px;
}
.result-detail-content{
position: absolute;
top: 34px;
bottom: 0;
width: 100%;
}
}
}

View File

@@ -10,7 +10,7 @@ angular.module('codexen.popup')
angular.module('codexen.popup')
.factory('Snippet', function ($http, apiUrl) {
.factory('Snippet', function ($http, $auth, apiUrl) {
var findByUser = function (user) {
var url = apiUrl + 'snippets/search'
@@ -21,16 +21,22 @@ angular.module('codexen.popup')
})
}
var findMine = function (params) {
var url = apiUrl + 'snippets/my'
return $http.get(url, {params: params})
}
var create = function (params) {
var url = apiUrl + 'snippets/create'
return $http.post(url, params)
}
var show = function (id) {
var show = function (id, params) {
var url = apiUrl + 'snippets/id/' + id
return $http.get(url)
return $http.get(url, {params: params})
}
var update = function (id, params) {
@@ -47,6 +53,7 @@ angular.module('codexen.popup')
return {
findByUser: findByUser,
findMine: findMine,
create: create,
show: show,
delete: destroy,

View File

@@ -0,0 +1,59 @@
.popup-body
.search-block
padding: 5px
height:44px
position:absolute
top: 0
width: 100%
.result-block
position:absolute
top: 44px
bottom: 0
width: 100%
overflow: hidden
.left-pane
margin: 0
position: absolute
left: 0
top: 0
bottom: 0
width: 40%
overflow-y: auto
overflow-x: hidden
.result-list
list-style:none
padding: 0
border-right: 1px solid $border-color
li
&:nth-child(even)
background-color $baseBackgroundColor
&:nth-child(odd)
background-color lighten($baseBackgroundColor, 2%)
&.active
color: $textColorSelected
background-color: $btnPrimary
a
display:block
padding: 5px 10px
border-bottom 1px solid $baseBorderColor
.right-pane
position: absolute
left: 40%
top: 0
bottom: 0
width: 60%
overflow-y: auto
overflow-x: hidden
.result-detail-control
position: absolute
top: 0
width: 100%
height: 34px
.result-detail-content
position: absolute
top: 34px
bottom: 0
width: 100%

View File

@@ -0,0 +1,13 @@
@import '../../src/styles/_vars'
@import '../../src/styles/mixins/*'
@import '../../src/styles/_bootstrap'
@import '../../src/styles/_index'
@import '../../src/styles/_shared'
@import '../../src/styles/modals/*'
@import '../../src/styles/directives/*'
@import '../../src/styles/states/*'
@import '_popup'

View File

@@ -1,61 +1,63 @@
var sass = require('gulp-sass')
require('dotenv').load()
var env = process.env
var styl = require('gulp-stylus')
var autoprefixer = require('gulp-autoprefixer')
var templateCache = require('gulp-angular-templatecache')
var globby = require('globby')
var template = require('gulp-template')
var concat = require('gulp-concat')
var del = require('del')
var runSequence = require('run-sequence')
var merge = require('merge-stream')
var plumber = require('gulp-plumber')
var notify = require('gulp-notify')
var changed = require('gulp-changed')
var cached = require('gulp-cached')
var remember = require('gulp-remember')
var livereload = require('gulp-livereload')
var childProcess = require('child_process')
var merge = require('merge-stream')
var config = require('./build.config.js')
// for Dist
var rev = require('gulp-rev')
var ngAnnotate = require('gulp-ng-annotate')
var uglify = require('gulp-uglify')
var minifyCss = require('gulp-minify-css')
module.exports = function (gulp) {
gulp.task('elec-env', function () {
return gulp.src('tpls/env.js')
.pipe(template({
apiUrl: env.BUILD_API_URL
}))
.pipe(gulp.dest('electron_build/config'))
})
/*
* Electron build
*/
gulp.task('elec-js', function(){
var src = gulp.src(['src/**/*.js'])
gulp.task('elec-js', function () {
var main = gulp.src('src/**/*.js')
.pipe(changed('electron_build'))
.pipe(gulp.dest('electron_build'))
var elecSrc = gulp.src(['electron_src/**/*.js'])
.pipe(changed('electron_build/electron'))
.pipe(gulp.dest('electron_build/electron'))
var elecHtml = gulp.src(['electron_src/**/*.html'])
var electron = gulp.src('electron_src/**/*.js')
.pipe(changed('electron_build/electron'))
.pipe(gulp.dest('electron_build/electron'))
return merge(src, elecSrc, elecHtml)
return merge(main, electron)
})
gulp.task('elec-sass', function () {
return gulp.src(['src/**/*.scss', 'electron_src/**/*.scss'])
.pipe(cached('styles'))
.pipe(sass().on('error', sass.logError))
gulp.task('elec-styl', function () {
return gulp.src('electron_src/styles/main.styl')
.pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
.pipe(styl())
.pipe(autoprefixer())
.pipe(remember('styles'))
.pipe(concat('all.css'))
.pipe(gulp.dest('electron_build'))
.pipe(notify('Stylus!!'))
.pipe(livereload())
})
gulp.task('elec-tpls', function(){
return gulp.src('src/**/*.tpl.html')
gulp.task('elec-tpls', function () {
var main = gulp.src('src/**/*.tpl.html')
.pipe(templateCache())
.pipe(gulp.dest('electron_build'))
var electron = gulp.src('electron_src/**/*.tpl.html')
.pipe(templateCache())
.pipe(gulp.dest('electron_build/electron'))
return merge(main, electron)
})
gulp.task('elec-index', function () {
@@ -72,13 +74,19 @@ module.exports = function (gulp) {
var scripts = filter(files, 'js')
var styles = filter(files, 'css')
return gulp.src('src/index.html')
var main = gulp.src('src/index.html')
.pipe(template({
scripts: scripts,
styles: styles,
env: 'build'
env: env
}))
.pipe(gulp.dest('electron_build'))
.pipe(livereload())
var electron = gulp.src('electron_src/**/index.html')
.pipe(gulp.dest('electron_build/electron'))
return merge(main, electron)
})
gulp.task('elec-vendor', function () {
@@ -88,6 +96,10 @@ module.exports = function (gulp) {
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('electron_build/vendor'))
})
@@ -99,17 +111,19 @@ module.exports = function (gulp) {
})
gulp.task('elec-build', function (cb) {
runSequence(['elec-js', 'elec-sass', 'elec-tpls', 'elec-vendor', 'elec-resources'], 'elec-index', cb)
runSequence(['elec-env', 'elec-js', 'elec-styl', 'elec-tpls', 'elec-vendor', 'elec-resources'], 'elec-index', cb)
})
gulp.task('elec-watch', function (cb) {
gulp.watch(['src/**/*.js', 'electron_src/**/*.js', 'electron_src/**/*.html'], ['elec-js'])
gulp.watch(['.env', 'tpls/env.js'], ['elec-env'])
gulp.watch(['src/**/*.scss', 'electron_src/**/*.scss'], ['elec-sass'])
gulp.watch(['src/**/*.js', 'electron_src/**/*.js'], ['elec-js'])
gulp.watch(['src/styles/**/*.styl', 'electron_src/styles/**/*.styl'], ['elec-styl'])
gulp.watch('src/**/*.tpl.html', ['elec-tpls'])
gulp.watch(['electron_build/**/*', '!electron_build/vendor/**/*', '!electron_build/electron/**/*'], ['elec-index'])
gulp.watch(['electron_build/**/*.js', 'src/index.html', 'src/index.html', 'electron_src/**/index.html'], ['elec-index'])
livereload.listen()
})

77
main.js
View File

@@ -12,8 +12,6 @@ app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
var robot = require('robotjs')
var clipboard = require('clipboard')
var Tray = require('tray')
@@ -22,6 +20,12 @@ var appIcon = null
app.on('ready', function () {
appIcon = new Tray('./icon.png')
appIcon.setToolTip('This is my application.')
appIcon.on('clicked', function () {
if (mainWindow == null) {
makeNewMainWindow()
}
mainWindow.show()
})
mainWindow = new BrowserWindow({
width: 800,
@@ -33,12 +37,9 @@ app.on('ready', function () {
mainWindow.loadUrl('file://' + __dirname + '/electron_build/index.html')
makeNewMainWindow()
// mainWindow.openDevTools()
mainWindow.on('closed', function () {
console.log('main closed')
mainWindow = null
})
var globalShortcut = require('global-shortcut')
@@ -56,14 +57,7 @@ app.on('ready', function () {
app.on('activate-with-no-open-windows', function () {
if (mainWindow == null) {
console.log('new WIndow!')
mainWindow = new BrowserWindow({width: 800, height: 600})
mainWindow.loadUrl('file://' + __dirname + '/electron_build/index.html')
mainWindow.on('closed', function () {
mainWindow = null
})
makeNewMainWindow()
}
mainWindow.show()
})
@@ -73,11 +67,11 @@ app.on('ready', function () {
})
var hidePopUp = function () {
if(fromMain){
if (fromMain) {
} else {
mainWindow.hide()
Menu.sendActionToFirstResponder('hide:');
mainWindow ? mainWindow.hide() : null
Menu.sendActionToFirstResponder('hide:')
}
popUpWindow.hide()
@@ -89,27 +83,22 @@ app.on('ready', function () {
})
ipc.on('writeCode', function (e, code) {
clipboard.writeText(code)
// setTimeout(function () {
// robot.typeString(code)
// }, 200)
hidePopUp()
})
var fromMain
// Register a 'ctrl+x' shortcut listener.
var ret = globalShortcut.register('ctrl+tab+shift', function () {
if (popUpWindow.isVisible()) {
hidePopUp()
return
}
fromMain = mainWindow.isFocused()
fromMain = mainWindow ? mainWindow.isFocused() : false
popUpWindow.show()
})
if (!ret) console.log('registerion fails')
// MENU
var Menu = require('menu')
var template = [
@@ -150,8 +139,8 @@ app.on('ready', function () {
{
label: 'Quit',
accelerator: 'Command+Q',
click: function() { app.quit(); }
},
click: function () { app.quit() }
}
]
},
{
@@ -189,7 +178,7 @@ app.on('ready', function () {
label: 'Select All',
accelerator: 'Command+A',
selector: 'selectAll:'
},
}
]
},
{
@@ -198,13 +187,13 @@ app.on('ready', function () {
{
label: 'Reload',
accelerator: 'Command+R',
click: function() { BrowserWindow.getFocusedWindow().reloadIgnoringCache(); }
click: function () { BrowserWindow.getFocusedWindow().reloadIgnoringCache() }
},
{
label: 'Toggle DevTools',
accelerator: 'Alt+Command+I',
click: function() { BrowserWindow.getFocusedWindow().toggleDevTools(); }
},
click: function () { BrowserWindow.getFocusedWindow().toggleDevTools() }
}
]
},
{
@@ -226,16 +215,36 @@ app.on('ready', function () {
{
label: 'Bring All to Front',
selector: 'arrangeInFront:'
},
}
]
},
{
label: 'Help',
submenu: []
},
];
}
]
menu = Menu.buildFromTemplate(template);
var menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu);
Menu.setApplicationMenu(menu)
function makeNewMainWindow () {
console.log('new Window!')
mainWindow = new BrowserWindow({
width: 800,
height: 600,
'web-preferences': {
'overlay-scrollbars': true
}
})
mainWindow.loadUrl('file://' + __dirname + '/electron_build/index.html')
mainWindow.on('closed', function () {
console.log('main closed')
mainWindow = null
app.dock.hide()
})
app.dock.show()
}
})