Edition via drag & drop des items
This commit is contained in:
parent
06c809a114
commit
1136b693fd
@ -16,7 +16,7 @@ git clone https://forge.cadoles.com/wpetit/pitaya.git
|
|||||||
cd pitaya
|
cd pitaya
|
||||||
git checkout develop
|
git checkout develop
|
||||||
npm install
|
npm install
|
||||||
npm start
|
DEBUG=pitaya* npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
@ -6,7 +6,6 @@ html, body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: 'Droid Sans', 'Ubuntu Sans', sans-serif;
|
font-family: 'Droid Sans', 'Ubuntu Sans', sans-serif;
|
||||||
background: url('../img/background.png') no-repeat;
|
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-color: rgb(34, 107, 160);
|
background-color: rgb(34, 107, 160);
|
||||||
@ -16,6 +15,11 @@ html, body {
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alert.alert-default {
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
/* Launcher View */
|
/* Launcher View */
|
||||||
|
|
||||||
.launcher {
|
.launcher {
|
||||||
@ -23,6 +27,7 @@ html, body {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
background: url('../img/background.png') no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.launcher .category-header {
|
.launcher .category-header {
|
||||||
@ -109,27 +114,80 @@ html, body {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit ul.desktop-apps {
|
.edit .workspace {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit .left-menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit .item-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit .apps-list .icon-theme-selector > select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit .apps-list ul.desktop-apps {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
height: 100%;
|
||||||
|
margin: 10px 0 0 0;
|
||||||
|
padding: 0 10px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit li.desktop-app {
|
.edit .apps-list li.desktop-app {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit .desktop-app > .app-icon {
|
.edit .desktop-app > .app-icon {
|
||||||
height: 50px;
|
height: 35px;
|
||||||
width: 50px;
|
width: 35px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.edit .profile-tree {
|
||||||
|
flex: 3;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit .profile-tree ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit .profile-tree > .tree-item > ul {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit .profile-tree .tree-item .alert {
|
||||||
|
padding: 5px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit .profile-tree .tree-item .app-icon {
|
||||||
|
height: 25px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit .app-item-edit {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Animations */
|
/* Animations */
|
||||||
|
|
||||||
.pulse {
|
.pulse {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"icon": "chromium-browser",
|
"icon": "chromium-browser",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"label": "Chromium Browser",
|
"label": "Chromium Browser 1",
|
||||||
"icon": "chromium-browser",
|
"icon": "chromium-browser",
|
||||||
"exec": "/usr/bin/chromium-browser"
|
"exec": "/usr/bin/chromium-browser"
|
||||||
}
|
}
|
||||||
@ -24,7 +24,7 @@
|
|||||||
"icon": "chromium-browser",
|
"icon": "chromium-browser",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"label": "Chromium Browser",
|
"label": "Chromium Browser 2",
|
||||||
"icon": "chromium-browser",
|
"icon": "chromium-browser",
|
||||||
"exec": "/usr/bin/chromium-browser"
|
"exec": "/usr/bin/chromium-browser"
|
||||||
}
|
}
|
||||||
|
@ -1 +1,61 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" ><path d="M0 0h512v512H0z" fill="transparent" stroke="#fff" stroke-width="0"></path><path d="M256 16C123.45 16 16 123.45 16 256s107.45 240 240 240 240-107.45 240-240S388.55 16 256 16zm0 60c99.41 0 180 80.59 180 180s-80.59 180-180 180S76 355.41 76 256 156.59 76 256 76zm-80.625 60c-.97-.005-2.006.112-3.063.313v-.032c-18.297 3.436-45.264 34.743-33.375 46.626l73.157 73.125-73.156 73.126c-14.63 14.625 29.275 58.534 43.906 43.906L256 299.906l73.156 73.156c14.63 14.628 58.537-29.28 43.906-43.906l-73.156-73.125 73.156-73.124c14.63-14.625-29.275-58.5-43.906-43.875L256 212.157l-73.156-73.125c-2.06-2.046-4.56-3.015-7.47-3.03z" fill="#fff"></path></svg>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
sodipodi:docname="default-icon.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata12">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs10" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1600"
|
||||||
|
inkscape:window-height="850"
|
||||||
|
id="namedview8"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.65186406"
|
||||||
|
inkscape:cx="59.383922"
|
||||||
|
inkscape:cy="222.95767"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg2" />
|
||||||
|
<path
|
||||||
|
d="M0 0h512v512H0z"
|
||||||
|
fill="transparent"
|
||||||
|
stroke="#fff"
|
||||||
|
stroke-width="0"
|
||||||
|
id="path4" />
|
||||||
|
<path
|
||||||
|
d="M256 16C123.45 16 16 123.45 16 256s107.45 240 240 240 240-107.45 240-240S388.55 16 256 16zm0 60c99.41 0 180 80.59 180 180s-80.59 180-180 180S76 355.41 76 256 156.59 76 256 76zm-80.625 60c-.97-.005-2.006.112-3.063.313v-.032c-18.297 3.436-45.264 34.743-33.375 46.626l73.157 73.125-73.156 73.126c-14.63 14.625 29.275 58.534 43.906 43.906L256 299.906l73.156 73.156c14.63 14.628 58.537-29.28 43.906-43.906l-73.156-73.125 73.156-73.124c14.63-14.625-29.275-58.5-43.906-43.875L256 212.157l-73.156-73.125c-2.06-2.046-4.56-3.015-7.47-3.03z"
|
||||||
|
fill="#fff"
|
||||||
|
id="path6"
|
||||||
|
style="fill:#a4a4a4;fill-opacity:1" />
|
||||||
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 712 B After Width: | Height: | Size: 2.1 KiB |
@ -1 +1,154 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><svg width='50px' height='50px' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="uil-hourglass"><rect x="0" y="0" width="100" height="100" fill="none" class="bk"></rect><g><path fill="none" stroke="#ffffff" stroke-width="5" stroke-miterlimit="10" d="M58.4,51.7c-0.9-0.9-1.4-2-1.4-2.3s0.5-0.4,1.4-1.4 C70.8,43.8,79.8,30.5,80,15.5H70H30H20c0.2,15,9.2,28.1,21.6,32.3c0.9,0.9,1.4,1.2,1.4,1.5s-0.5,1.6-1.4,2.5 C29.2,56.1,20.2,69.5,20,85.5h10h40h10C79.8,69.5,70.8,55.9,58.4,51.7z" class="glass"></path><clipPath id="uil-hourglass-clip1"><rect x="15" y="20" width="70" height="25" class="clip"><animate attributeName="height" from="25" to="0" dur="1s" repeatCount="indefinite" vlaues="25;0;0" keyTimes="0;0.5;1"></animate><animate attributeName="y" from="20" to="45" dur="1s" repeatCount="indefinite" vlaues="20;45;45" keyTimes="0;0.5;1"></animate></rect></clipPath><clipPath id="uil-hourglass-clip2"><rect x="15" y="55" width="70" height="25" class="clip"><animate attributeName="height" from="0" to="25" dur="1s" repeatCount="indefinite" vlaues="0;25;25" keyTimes="0;0.5;1"></animate><animate attributeName="y" from="80" to="55" dur="1s" repeatCount="indefinite" vlaues="80;55;55" keyTimes="0;0.5;1"></animate></rect></clipPath><path d="M29,23c3.1,11.4,11.3,19.5,21,19.5S67.9,34.4,71,23H29z" clip-path="url(#uil-hourglass-clip1)" fill="#d2d2d2" class="sand"></path><path d="M71.6,78c-3-11.6-11.5-20-21.5-20s-18.5,8.4-21.5,20H71.6z" clip-path="url(#uil-hourglass-clip2)" fill="#d2d2d2" class="sand"></path><animateTransform attributeName="transform" type="rotate" from="0 50 50" to="180 50 50" repeatCount="indefinite" dur="1s" values="0 50 50;0 50 50;180 50 50" keyTimes="0;0.7;1"></animateTransform></g></svg>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="50px"
|
||||||
|
height="50px"
|
||||||
|
viewBox="0 0 100 100"
|
||||||
|
preserveAspectRatio="xMidYMid"
|
||||||
|
class="uil-hourglass"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="hourglass.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata34">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs32" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1600"
|
||||||
|
inkscape:window-height="850"
|
||||||
|
id="namedview30"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="13.350176"
|
||||||
|
inkscape:cx="-10.530194"
|
||||||
|
inkscape:cy="27.889305"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g6" />
|
||||||
|
<rect
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="100"
|
||||||
|
height="100"
|
||||||
|
fill="none"
|
||||||
|
class="bk"
|
||||||
|
id="rect4" />
|
||||||
|
<g
|
||||||
|
id="g6">
|
||||||
|
<path
|
||||||
|
fill="none"
|
||||||
|
stroke="#ffffff"
|
||||||
|
stroke-width="5"
|
||||||
|
stroke-miterlimit="10"
|
||||||
|
d="M58.4,51.7c-0.9-0.9-1.4-2-1.4-2.3s0.5-0.4,1.4-1.4 C70.8,43.8,79.8,30.5,80,15.5H70H30H20c0.2,15,9.2,28.1,21.6,32.3c0.9,0.9,1.4,1.2,1.4,1.5s-0.5,1.6-1.4,2.5 C29.2,56.1,20.2,69.5,20,85.5h10h40h10C79.8,69.5,70.8,55.9,58.4,51.7z"
|
||||||
|
class="glass"
|
||||||
|
id="path8"
|
||||||
|
style="fill:#a4a4a4;fill-opacity:1" />
|
||||||
|
<clipPath
|
||||||
|
id="uil-hourglass-clip1">
|
||||||
|
<rect
|
||||||
|
x="15"
|
||||||
|
y="20"
|
||||||
|
width="70"
|
||||||
|
height="25"
|
||||||
|
class="clip"
|
||||||
|
id="rect11">
|
||||||
|
<animate
|
||||||
|
attributeName="height"
|
||||||
|
from="25"
|
||||||
|
to="0"
|
||||||
|
dur="1s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
vlaues="25;0;0"
|
||||||
|
keyTimes="0;0.5;1"
|
||||||
|
id="animate13" />
|
||||||
|
<animate
|
||||||
|
attributeName="y"
|
||||||
|
from="20"
|
||||||
|
to="45"
|
||||||
|
dur="1s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
vlaues="20;45;45"
|
||||||
|
keyTimes="0;0.5;1"
|
||||||
|
id="animate15" />
|
||||||
|
</rect>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath
|
||||||
|
id="uil-hourglass-clip2">
|
||||||
|
<rect
|
||||||
|
x="15"
|
||||||
|
y="55"
|
||||||
|
width="70"
|
||||||
|
height="25"
|
||||||
|
class="clip"
|
||||||
|
id="rect18">
|
||||||
|
<animate
|
||||||
|
attributeName="height"
|
||||||
|
from="0"
|
||||||
|
to="25"
|
||||||
|
dur="1s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
vlaues="0;25;25"
|
||||||
|
keyTimes="0;0.5;1"
|
||||||
|
id="animate20" />
|
||||||
|
<animate
|
||||||
|
attributeName="y"
|
||||||
|
from="80"
|
||||||
|
to="55"
|
||||||
|
dur="1s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
vlaues="80;55;55"
|
||||||
|
keyTimes="0;0.5;1"
|
||||||
|
id="animate22" />
|
||||||
|
</rect>
|
||||||
|
</clipPath>
|
||||||
|
<path
|
||||||
|
d="M29,23c3.1,11.4,11.3,19.5,21,19.5S67.9,34.4,71,23H29z"
|
||||||
|
clip-path="url(#uil-hourglass-clip1)"
|
||||||
|
fill="#d2d2d2"
|
||||||
|
class="sand"
|
||||||
|
id="path24"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="M71.6,78c-3-11.6-11.5-20-21.5-20s-18.5,8.4-21.5,20H71.6z"
|
||||||
|
clip-path="url(#uil-hourglass-clip2)"
|
||||||
|
fill="#d2d2d2"
|
||||||
|
class="sand"
|
||||||
|
id="path26"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<animateTransform
|
||||||
|
attributeName="transform"
|
||||||
|
type="rotate"
|
||||||
|
from="0 50 50"
|
||||||
|
to="180 50 50"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
dur="1s"
|
||||||
|
values="0 50 50;0 50 50;180 50 50"
|
||||||
|
keyTimes="0;0.7;1"
|
||||||
|
id="animateTransform28" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 4.0 KiB |
@ -2,6 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Lanceur - Pitaya</title>
|
<title>Lanceur - Pitaya</title>
|
||||||
<link rel="stylesheet" href="css/style.css" />
|
<link rel="stylesheet" href="css/style.css" />
|
||||||
|
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
@ -12,14 +12,7 @@ var App = React.createClass({
|
|||||||
|
|
||||||
var editMode = this.props.processOpts.edit || false;
|
var editMode = this.props.processOpts.edit || false;
|
||||||
|
|
||||||
var view = editMode ?
|
var view = editMode ? <EditView /> : <LauncherView />;
|
||||||
<Provider store={store}>
|
|
||||||
{ function() { return <EditView />; }.bind(this) }
|
|
||||||
</Provider> :
|
|
||||||
<Provider store={store}>
|
|
||||||
{ function() { return <LauncherView />; }.bind(this) }
|
|
||||||
</Provider>
|
|
||||||
;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="pitaya">
|
<div id="pitaya">
|
||||||
|
@ -11,7 +11,7 @@ module.exports = React.createClass({
|
|||||||
mixins: [LazyLoad],
|
mixins: [LazyLoad],
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return { icon: DEFAULT_ICON, currentTheme: undefined };
|
return { icon: DEFAULT_ICON, currentTheme: '' };
|
||||||
},
|
},
|
||||||
|
|
||||||
onInViewport: function() {
|
onInViewport: function() {
|
||||||
@ -23,7 +23,7 @@ module.exports = React.createClass({
|
|||||||
var currentTheme = this.state.currentTheme;
|
var currentTheme = this.state.currentTheme;
|
||||||
var newTheme = this.props.theme;
|
var newTheme = this.props.theme;
|
||||||
|
|
||||||
if( !this.isInViewport() || newTheme === currentTheme ) return;
|
if( !this.isInViewport() || newTheme === currentTheme ) return;
|
||||||
|
|
||||||
this.setState({ icon: LOADING_ICON, currentTheme: newTheme });
|
this.setState({ icon: LOADING_ICON, currentTheme: newTheme });
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
var Util = require('../../util');
|
var Util = require('../../util');
|
||||||
var AppIcon = require('../common/app-icon.jsx');
|
var AppIcon = require('../common/app-icon.jsx');
|
||||||
|
var DragSource = require('react-dnd').DragSource;
|
||||||
|
|
||||||
module.exports = React.createClass({
|
var DesktopAppItem = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
||||||
@ -11,8 +12,10 @@ module.exports = React.createClass({
|
|||||||
var category = desktopEntry.Categories;
|
var category = desktopEntry.Categories;
|
||||||
var icon = desktopEntry.Icon;
|
var icon = desktopEntry.Icon;
|
||||||
|
|
||||||
return (
|
var connectDragSource = this.props.connectDragSource;
|
||||||
<li className="desktop-app">
|
|
||||||
|
return connectDragSource(
|
||||||
|
<li className="desktop-app list-group-item">
|
||||||
<AppIcon className="desktop-app-icon" icon={icon} theme={this.props.theme} />
|
<AppIcon className="desktop-app-icon" icon={icon} theme={this.props.theme} />
|
||||||
<span className="desktop-app-label">{label}</span>
|
<span className="desktop-app-label">{label}</span>
|
||||||
</li>
|
</li>
|
||||||
@ -21,3 +24,32 @@ module.exports = React.createClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var dragSourceSpec = {
|
||||||
|
|
||||||
|
beginDrag: function(props) {
|
||||||
|
return props;
|
||||||
|
},
|
||||||
|
|
||||||
|
endDrag: function(props, monitor) {
|
||||||
|
|
||||||
|
if (!monitor.didDrop()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dropResult = monitor.getDropResult();
|
||||||
|
|
||||||
|
return props.onItemDropped(props.desktopEntry, dropResult);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
function dragSourceCollect(connect, monitor) {
|
||||||
|
return {
|
||||||
|
connectDragSource: connect.dragSource(),
|
||||||
|
isDragging: monitor.isDragging()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = DragSource('NEW_ITEM', dragSourceSpec, dragSourceCollect)(DesktopAppItem);
|
||||||
|
@ -1,39 +1,33 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
var Util = require('../../util');
|
var Util = require('../../util');
|
||||||
var DesktopAppItem = require('./desktop-app-item.jsx');
|
var DesktopAppItem = require('./desktop-app-item.jsx');
|
||||||
var IconThemeSelector = require('./icon-theme-selector.jsx');
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var debug = require('debug')('pitaya:desktop-app-list');
|
var debug = require('../../util/debug')('pitaya:desktop-app-list');
|
||||||
|
|
||||||
module.exports = React.createClass({
|
var DesktopAppList = React.createClass({
|
||||||
|
|
||||||
getInitialState: function() {
|
|
||||||
return {
|
|
||||||
selectedTheme: null
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
||||||
var items = this.props.desktopApps.map(function(desktopApp, i) {
|
var items = this.props.desktopApps.map(function(desktopApp, i) {
|
||||||
var desktopEntry = desktopApp.content['Desktop Entry'];
|
var desktopEntry = desktopApp.content['Desktop Entry'];
|
||||||
return <DesktopAppItem theme={this.state.selectedTheme} key={desktopApp.path} desktopEntry={desktopEntry} />;
|
return (
|
||||||
|
<DesktopAppItem theme={this.props.selectedTheme}
|
||||||
|
key={desktopApp.path}
|
||||||
|
desktopEntry={desktopEntry}
|
||||||
|
onItemDropped={this.props.onItemDropped} />
|
||||||
|
);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="apps-list">
|
||||||
<IconThemeSelector onThemeSelected={this.onThemeSelected} />
|
<ul className="desktop-apps list-group">
|
||||||
<ul className="desktop-apps">
|
|
||||||
{items}
|
{items}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
onThemeSelected: function(theme) {
|
|
||||||
console.log('Selected theme %s', theme);
|
|
||||||
this.setState({ selectedTheme: theme });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.exports = DesktopAppList;
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
var connect = require('react-redux').connect;
|
var connect = require('react-redux').connect;
|
||||||
|
var ProfileTree = require('./profile-tree.jsx');
|
||||||
var DesktopAppList = require('./desktop-app-list.jsx');
|
var DesktopAppList = require('./desktop-app-list.jsx');
|
||||||
var actions = require('../../actions');
|
var ItemForm = require('./item-form.jsx');
|
||||||
|
var IconThemeSelector = require('./icon-theme-selector.jsx');
|
||||||
|
|
||||||
|
var actions = require('../../store/actions');
|
||||||
|
var DragDropContext = require('react-dnd').DragDropContext;
|
||||||
|
var HTML5Backend = require('react-dnd/modules/backends/HTML5');
|
||||||
|
|
||||||
var EditView = React.createClass({
|
var EditView = React.createClass({
|
||||||
|
|
||||||
@ -13,18 +19,49 @@ var EditView = React.createClass({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="edit">
|
<div className="edit">
|
||||||
<DesktopAppList desktopApps={this.props.desktopApps} />
|
<div className="menu-bar">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className="workspace">
|
||||||
|
<div className="left-menu">
|
||||||
|
<IconThemeSelector onThemeSelected={this.onThemeSelected} />
|
||||||
|
<DesktopAppList
|
||||||
|
theme={this.props.theme}
|
||||||
|
desktopApps={this.props.desktopApps}
|
||||||
|
onItemDropped={this.onItemDropped} />
|
||||||
|
</div>
|
||||||
|
<ProfileTree />
|
||||||
|
<ItemForm />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
onItemDropped: function(desktopEntry, targetItem) {
|
||||||
|
|
||||||
|
var newProfileItem = {
|
||||||
|
label: desktopEntry.Name,
|
||||||
|
icon: desktopEntry.Icon,
|
||||||
|
exec: desktopEntry.Exec
|
||||||
|
};
|
||||||
|
|
||||||
|
this.props.dispatch(actions.edit.addProfileItem(newProfileItem, targetItem));
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
onThemeSelected: function(theme) {
|
||||||
|
this.props.dispatch(actions.edit.selectTheme(theme));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function select(state) {
|
function select(state) {
|
||||||
return {
|
return {
|
||||||
desktopApps: state.desktopApps
|
desktopApps: state.desktopApps,
|
||||||
|
profile: state.profile,
|
||||||
|
theme: state.theme
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = connect(select)(EditView);
|
module.exports = DragDropContext(HTML5Backend)(connect(select)(EditView));
|
||||||
|
@ -39,9 +39,11 @@ module.exports = React.createClass({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<select value={selectedTheme} onChange={this.onChange}>
|
<div className="icon-theme-selector">
|
||||||
{options}
|
<select className="form-control" value={selectedTheme} onChange={this.onChange}>
|
||||||
</select>
|
{options}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
16
js/components/edit/item-form.jsx
Normal file
16
js/components/edit/item-form.jsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
var React = require('react');
|
||||||
|
|
||||||
|
var ItemForm = React.createClass({
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="item-form">
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = ItemForm;
|
67
js/components/edit/profile-tree.jsx
Normal file
67
js/components/edit/profile-tree.jsx
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
var React = require('react');
|
||||||
|
var connect = require('react-redux').connect;
|
||||||
|
var actions = require('../../store/actions');
|
||||||
|
var TreeItem = require('./tree-item.jsx');
|
||||||
|
|
||||||
|
var TreeNode = React.createClass({
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
|
||||||
|
var data = this.props.data || {};
|
||||||
|
var subItems = data.items || [];
|
||||||
|
|
||||||
|
var listElements = subItems.map(function(subItem, i) {
|
||||||
|
return (
|
||||||
|
<li key={i} >
|
||||||
|
<TreeNode data={subItem} onItemMoved={this.props.onItemMoved} />
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
var appEntry = data.icon || data.label ?
|
||||||
|
<TreeItem data={data} onItemMoved={this.props.onItemMoved} /> :
|
||||||
|
null
|
||||||
|
;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="tree-item">
|
||||||
|
{appEntry}
|
||||||
|
<ul>
|
||||||
|
{listElements}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var ProfileTree = React.createClass({
|
||||||
|
|
||||||
|
componentDidMount: function() {
|
||||||
|
this.props.dispatch(actions.launcher.loadProfile('./default-profile.json'));
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="profile-tree">
|
||||||
|
<TreeNode data={this.props.profile} onItemMoved={this.onItemMoved} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
onItemMoved: function(movedItem, targetItem) {
|
||||||
|
this.props.dispatch(actions.edit.moveProfileItem(movedItem, targetItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function select(state) {
|
||||||
|
return {
|
||||||
|
profile: state.profile
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = connect(select)(ProfileTree);
|
86
js/components/edit/tree-item.jsx
Normal file
86
js/components/edit/tree-item.jsx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
var React = require('react/addons');
|
||||||
|
var classNames = require('classnames');
|
||||||
|
var AppIcon = require('../common/app-icon.jsx');
|
||||||
|
var DragSource = require('react-dnd').DragSource;
|
||||||
|
var DropTarget = require('react-dnd').DropTarget;
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
var TreeItem = React.createClass({
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
|
||||||
|
var data = this.props.data;
|
||||||
|
var appIcon = data.icon ? <AppIcon icon={data.icon} /> : null;
|
||||||
|
|
||||||
|
var connectDragSource = this.props.connectDragSource;
|
||||||
|
var connectDropTarget = this.props.connectDropTarget;
|
||||||
|
|
||||||
|
var classes = classNames({
|
||||||
|
'alert': true,
|
||||||
|
'alert-default': !this.props.isDragging && !this.props.isOver,
|
||||||
|
'alert-info': this.props.isDragging,
|
||||||
|
'alert-success': this.props.isOver
|
||||||
|
});
|
||||||
|
|
||||||
|
return connectDropTarget(connectDragSource(
|
||||||
|
<div className={classes}>
|
||||||
|
{appIcon}
|
||||||
|
<span className="app-label">{data.label}</span>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var dragSourceSpec = {
|
||||||
|
|
||||||
|
beginDrag: function(props) {
|
||||||
|
return props.data;
|
||||||
|
},
|
||||||
|
|
||||||
|
endDrag: function(props, monitor) {
|
||||||
|
|
||||||
|
if (!monitor.didDrop()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dropResult = monitor.getDropResult();
|
||||||
|
|
||||||
|
return props.onItemMoved(props.data, dropResult);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var dropTargetSpec = {
|
||||||
|
|
||||||
|
drop: function(props, monitor, component) {
|
||||||
|
return props.data;
|
||||||
|
},
|
||||||
|
|
||||||
|
canDrop: function(props, monitor) {
|
||||||
|
var draggedItem = monitor.getItem();
|
||||||
|
return !_.isEqual(draggedItem, props.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
function dragSourceCollect(connect, monitor) {
|
||||||
|
return {
|
||||||
|
connectDragSource: connect.dragSource(),
|
||||||
|
isDragging: monitor.isDragging()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function dropTargetCollect(connect, monitor) {
|
||||||
|
return {
|
||||||
|
connectDropTarget: connect.dropTarget(),
|
||||||
|
isOver: monitor.isOver()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = DropTarget(['ITEM', 'NEW_ITEM'], dropTargetSpec, dropTargetCollect)(
|
||||||
|
DragSource('ITEM', dragSourceSpec, dragSourceCollect)(TreeItem)
|
||||||
|
);
|
@ -2,7 +2,7 @@ var React = require('react');
|
|||||||
var CategoryHeader = require('./category-header.jsx');
|
var CategoryHeader = require('./category-header.jsx');
|
||||||
var AppList = require('./app-list.jsx');
|
var AppList = require('./app-list.jsx');
|
||||||
var AnimateMixin = require('../mixins/animate');
|
var AnimateMixin = require('../mixins/animate');
|
||||||
var actions = require('../../actions');
|
var actions = require('../../store/actions');
|
||||||
var connect = require('react-redux').connect;
|
var connect = require('react-redux').connect;
|
||||||
var debug = require('../../util/debug')('launcher-view');
|
var debug = require('../../util/debug')('launcher-view');
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ module.exports = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var computeComponentsVisibilityDebounced = debounce(computeComponentsVisibility, 250);
|
var computeComponentsVisibilityDebounced = debounce(computeComponentsVisibility, 100);
|
||||||
|
|
||||||
// Start listening for changes
|
// Start listening for changes
|
||||||
window.document.addEventListener('scroll', computeComponentsVisibilityDebounced, true);
|
window.document.addEventListener('scroll', computeComponentsVisibilityDebounced, true);
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
var Util = require('../util');
|
var Util = require('../../util');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
// Action types
|
// Action types
|
||||||
var LOAD_DESKTOP_APPS = exports.LOAD_PROFILE = 'LOAD_DESKTOP_APPS';
|
var LOAD_DESKTOP_APPS = exports.LOAD_PROFILE = 'LOAD_DESKTOP_APPS';
|
||||||
var LOAD_DESKTOP_APPS_SUCCESS = exports.LOAD_DESKTOP_APPS_SUCCESS = 'LOAD_DESKTOP_APPS_SUCCESS';
|
var LOAD_DESKTOP_APPS_SUCCESS = exports.LOAD_DESKTOP_APPS_SUCCESS = 'LOAD_DESKTOP_APPS_SUCCESS';
|
||||||
var LOAD_DESKTOP_APPS_FAILED = exports.LOAD_DESKTOP_APPS_FAILED = 'LOAD_DESKTOP_APPS_FAILED';
|
var LOAD_DESKTOP_APPS_FAILED = exports.LOAD_DESKTOP_APPS_FAILED = 'LOAD_DESKTOP_APPS_FAILED';
|
||||||
|
var MOVE_PROFILE_ITEM = exports.MOVE_PROFILE_ITEM = 'MOVE_PROFILE_ITEM';
|
||||||
|
var ADD_PROFILE_ITEM = exports.ADD_PROFILE_ITEM = 'ADD_PROFILE_ITEM';
|
||||||
|
|
||||||
|
// Actions creators
|
||||||
|
|
||||||
// Actions creator
|
|
||||||
exports.loadDesktopApps = function() {
|
exports.loadDesktopApps = function() {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
|
|
||||||
@ -27,3 +30,20 @@ exports.loadDesktopApps = function() {
|
|||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
exports.moveProfileItem = function(movedItem, targetItem) {
|
||||||
|
return {
|
||||||
|
type: 'MOVE_PROFILE_ITEM',
|
||||||
|
movedItem: movedItem,
|
||||||
|
targetItem: targetItem
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.addProfileItem = function(newItem, targetItem) {
|
||||||
|
return {
|
||||||
|
type: 'ADD_PROFILE_ITEM',
|
||||||
|
newItem: newItem,
|
||||||
|
targetItem: targetItem
|
||||||
|
};
|
||||||
|
};
|
@ -1,4 +1,4 @@
|
|||||||
var Util = require('../util');
|
var Util = require('../../util');
|
||||||
|
|
||||||
var LOAD_PROFILE = exports.LOAD_PROFILE = 'LOAD_PROFILE';
|
var LOAD_PROFILE = exports.LOAD_PROFILE = 'LOAD_PROFILE';
|
||||||
var LOAD_PROFILE_SUCCESS = exports.LOAD_PROFILE_SUCCESS = 'LOAD_PROFILE_SUCCESS';
|
var LOAD_PROFILE_SUCCESS = exports.LOAD_PROFILE_SUCCESS = 'LOAD_PROFILE_SUCCESS';
|
@ -2,9 +2,11 @@ var redux = require('redux');
|
|||||||
var thunkMiddleware = require('redux-thunk');
|
var thunkMiddleware = require('redux-thunk');
|
||||||
var loggerMiddleware = require('redux-logger');
|
var loggerMiddleware = require('redux-logger');
|
||||||
var reducers = require('./reducers');
|
var reducers = require('./reducers');
|
||||||
|
var loggerMiddleware = require('./middlewares/logger');
|
||||||
|
|
||||||
var createStore = redux.applyMiddleware(
|
var createStore = redux.applyMiddleware(
|
||||||
thunkMiddleware
|
thunkMiddleware,
|
||||||
|
loggerMiddleware
|
||||||
)(redux.createStore);
|
)(redux.createStore);
|
||||||
|
|
||||||
var appReducer = redux.combineReducers({
|
var appReducer = redux.combineReducers({
|
||||||
|
15
js/store/middlewares/logger.js
Normal file
15
js/store/middlewares/logger.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
var debug = require('../../util/debug')('store:logger');
|
||||||
|
|
||||||
|
module.exports = function loggerMiddleware(store) {
|
||||||
|
return function(next) {
|
||||||
|
return function(action) {
|
||||||
|
debug('Action %j', action);
|
||||||
|
debug('Store current state %j', store.getState());
|
||||||
|
next(action);
|
||||||
|
debug('Store new state %j', store.getState());
|
||||||
|
if(action.error) {
|
||||||
|
console.error(action.error.stack || action.error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -1,8 +1,8 @@
|
|||||||
var actions = require('../../actions');
|
var actions = require('../actions');
|
||||||
|
|
||||||
module.exports = function(state, action) {
|
module.exports = function(state, action) {
|
||||||
|
|
||||||
var desktopApps = [];
|
var desktopApps = state || [];
|
||||||
|
|
||||||
if( action.type === actions.edit.LOAD_DESKTOP_APPS_SUCCESS ) {
|
if( action.type === actions.edit.LOAD_DESKTOP_APPS_SUCCESS ) {
|
||||||
desktopApps = action.desktopApps;
|
desktopApps = action.desktopApps;
|
||||||
|
@ -1,17 +1,72 @@
|
|||||||
var actions = require('../../actions');
|
var _ = require('lodash');
|
||||||
|
var actions = require('../actions');
|
||||||
|
|
||||||
module.exports = function(oldProfile, action) {
|
module.exports = function(oldProfile, action) {
|
||||||
|
|
||||||
var newProfile = oldProfile || null;
|
|
||||||
|
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
|
|
||||||
case actions.launcher.LOAD_PROFILE_SUCCESS:
|
case actions.launcher.LOAD_PROFILE_SUCCESS:
|
||||||
newProfile = action.profile;
|
return _.cloneDeep(action.profile);
|
||||||
break;
|
|
||||||
|
case actions.edit.MOVE_PROFILE_ITEM:
|
||||||
|
return moveProfileItem(oldProfile, action.movedItem, action.targetItem);
|
||||||
|
|
||||||
|
case actions.edit.ADD_PROFILE_ITEM:
|
||||||
|
return addProfileItem(oldProfile, action.newItem, action.targetItem);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return oldProfile || null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function moveProfileItem(oldProfile, movedItem, targetItem) {
|
||||||
|
|
||||||
|
var newProfile = _.cloneDeep(oldProfile);
|
||||||
|
var previousParent = treeFind(newProfile, movedItem).parent;
|
||||||
|
var newParent = treeFind(newProfile, targetItem).item;
|
||||||
|
|
||||||
|
previousParent.items = _.reject(previousParent.items, function(item) {
|
||||||
|
return _.isEqual(item, movedItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
newParent.items = newParent.items || [];
|
||||||
|
newParent.items.push(_.cloneDeep(movedItem));
|
||||||
|
|
||||||
return newProfile;
|
return newProfile;
|
||||||
|
|
||||||
};
|
}
|
||||||
|
|
||||||
|
function addProfileItem(oldProfile, newItem, targetItem) {
|
||||||
|
|
||||||
|
var newProfile = _.cloneDeep(oldProfile);
|
||||||
|
var newParent = treeFind(newProfile, targetItem).item;
|
||||||
|
|
||||||
|
newParent.items = newParent.items || [];
|
||||||
|
newParent.items.push(_.cloneDeep(newItem));
|
||||||
|
|
||||||
|
return newProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
function treeFind(branch, obj) {
|
||||||
|
|
||||||
|
var items = branch.items;
|
||||||
|
|
||||||
|
if(!items) return;
|
||||||
|
|
||||||
|
for( var i = 0, item = items[i]; (item = items[i]); i++ ) {
|
||||||
|
|
||||||
|
if( _.isEqual(item, obj) ) {
|
||||||
|
return {item: item, parent: branch};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(item.items) {
|
||||||
|
var result = treeFind(item, obj);
|
||||||
|
if(result) return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -3,10 +3,15 @@ var util = require('util');
|
|||||||
|
|
||||||
module.exports = function createLogger(namespace) {
|
module.exports = function createLogger(namespace) {
|
||||||
var logger = debug('pitaya:'+namespace);
|
var logger = debug('pitaya:'+namespace);
|
||||||
var console = global.window ? global.window.console : global.console;
|
var isNWContext = 'window' in global;
|
||||||
|
var console = isNWContext ? global.window.console : global.console;
|
||||||
logger.log = function() {
|
logger.log = function() {
|
||||||
var str = util.format.apply(util, arguments);
|
if(isNWContext) {
|
||||||
console.log(str);
|
console.log.apply(console, arguments);
|
||||||
|
} else {
|
||||||
|
var str = util.format.apply(util, arguments);
|
||||||
|
console.log(str);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return logger;
|
return logger;
|
||||||
};
|
};
|
||||||
|
@ -24,9 +24,11 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bootstrap": "^3.3.5",
|
"bootstrap": "^3.3.5",
|
||||||
|
"classnames": "^2.1.3",
|
||||||
"debug": "^2.2.0",
|
"debug": "^2.2.0",
|
||||||
"glob": "^5.0.14",
|
"glob": "^5.0.14",
|
||||||
"ini": "^1.3.4",
|
"ini": "^1.3.4",
|
||||||
|
"lodash": "^3.10.1",
|
||||||
"minimist": "^1.1.3",
|
"minimist": "^1.1.3",
|
||||||
"node-jsx": "^0.13.3",
|
"node-jsx": "^0.13.3",
|
||||||
"react": "^0.13.3",
|
"react": "^0.13.3",
|
||||||
|
Loading…
Reference in New Issue
Block a user