[init] all
This commit is contained in:
commit
e5867beeb9
|
@ -0,0 +1,7 @@
|
||||||
|
.vscode
|
||||||
|
.sass-cache
|
||||||
|
*.map
|
||||||
|
/node_modules
|
||||||
|
/public_html/css
|
||||||
|
/public_html/js
|
||||||
|
/package-lock.json
|
|
@ -0,0 +1,3 @@
|
||||||
|
RewriteEngine on
|
||||||
|
|
||||||
|
RewriteRule ^(.*)$ public_html/$1 [QSA,L]
|
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"name": "ptut-vhost",
|
||||||
|
"description": "PTUT",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": "xdrm-brackets <xdrm.brackets.dev@gmail.com> SeekDaSky <mascaro.lucas@yahoo.fr G. Fauvet <gfauvet@gmail.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"bundle:clean": "exit 0",
|
||||||
|
"bundle:prod": "cross-env NODE_ENV=production webpack --progress --hide-modules",
|
||||||
|
"bundle:dev": "cross-env NODE_ENV=development webpack --progress --hide-modules",
|
||||||
|
"bundle:watch": "cross-env NODE_ENV=development webpack --progress --watch --hide-modules",
|
||||||
|
"scss": "node-sass -r --output-style compressed --output ./public_html/css ./webpack/scss",
|
||||||
|
"watch-css": "node-sass -w -r --output-style compressed --output ./public_html/css ./webpack/scss",
|
||||||
|
"dev": "npm run bundle:clean; npm run bundle:dev; npm run watch-css",
|
||||||
|
"devjs": "npm run bundle:clean; npm run bundle:watch",
|
||||||
|
"build": "npm run bundle:clean; npm run bundle:prod; npm run scss"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uglifyjs-webpack-plugin": "^1.2.3",
|
||||||
|
"vue": "^2.5.9",
|
||||||
|
"vue-router": "^2.5.3"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not ie <= 8"
|
||||||
|
],
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-core": "^6.26.0",
|
||||||
|
"babel-loader": "^7.1.2",
|
||||||
|
"cross-env": "^5.0.5",
|
||||||
|
"babel-preset-env": "^1.6.0",
|
||||||
|
"babel-preset-stage-3": "^6.24.1",
|
||||||
|
"css-loader": "^0.28.7",
|
||||||
|
"extract-text-webpack-plugin": "^3.0.2",
|
||||||
|
"file-loader": "^1.1.4",
|
||||||
|
"node-sass": "^4.7.2",
|
||||||
|
"sass-loader": "^6.0.6",
|
||||||
|
"vue-loader": "^13.0.5",
|
||||||
|
"vue-svg-loader": "^0.5.0",
|
||||||
|
"vue-template-compiler": "^2.5.9",
|
||||||
|
"webpack": "^3.8.1",
|
||||||
|
"webpack-dev-server": "^2.9.5"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
RewriteEngine on
|
||||||
|
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteRule ^(.*)$ index.php?url=/$1 [QSA,L]
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?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"
|
||||||
|
enable-background="new 0 0 100 100"
|
||||||
|
id="Layer_1"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 100 100"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="menu.add.svg"
|
||||||
|
inkscape:version="0.92.2 5c3e80d, 2017-08-06"><metadata
|
||||||
|
id="metadata9"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs7" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1015"
|
||||||
|
id="namedview5"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="13.350176"
|
||||||
|
inkscape:cx="57.025698"
|
||||||
|
inkscape:cy="50.871048"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="29"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Layer_1" /><path
|
||||||
|
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#6b6e6a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 48.400391,22.099609 v 29 h -29 v 3.5 h 29 v 29 h 3.5 v -29 h 29 v -3.5 H 80.199219 51.900391 v -29 z"
|
||||||
|
id="polygon2"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccccccccccc" /></svg>
|
After Width: | Height: | Size: 2.8 KiB |
|
@ -0,0 +1,44 @@
|
||||||
|
<?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"
|
||||||
|
enable-background="new 0 0 100 100"
|
||||||
|
id="Layer_1"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 100 100"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="menu.add@hover.svg"
|
||||||
|
inkscape:version="0.92.2 5c3e80d, 2017-08-06"><metadata
|
||||||
|
id="metadata9"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs7" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1015"
|
||||||
|
id="namedview5"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="13.350176"
|
||||||
|
inkscape:cx="57.025698"
|
||||||
|
inkscape:cy="50.871048"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="29"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Layer_1" /><path
|
||||||
|
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#dddddd;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 48.400391,22.099609 v 29 h -29 v 3.5 h 29 v 29 h 3.5 v -29 h 29 v -3.5 H 80.199219 51.900391 v -29 z"
|
||||||
|
id="polygon2"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccccccccccc" /></svg>
|
After Width: | Height: | Size: 2.8 KiB |
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-289 382 32 30" style="enable-background:new -289 382 32 30;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
.st1{opacity:0.6;}
|
||||||
|
</style>
|
||||||
|
<path class="st0" d="M-273,409.5L-273,409.5c-4.1,0-6.8-0.6-7.9-1.7c-0.5-0.6-0.6-1.1-0.6-1.3c0-0.7,0.1-2.9,0.6-3.8 c0.1-0.3,0.5-1,4.5-2.4c-1.6-1.4-2.6-4-2.6-7.1c0-4.2,2.3-7,5.9-7.1l0.1,0c3.6,0.1,5.9,2.8,5.9,7.1c0,3.1-1,5.7-2.6,7.1 c4,1.4,4.4,2.1,4.5,2.4c0.4,0.9,0.5,3.1,0.6,3.8c0,0.2,0,0.7-0.6,1.3C-266.3,408.9-268.9,409.5-273,409.5z M-273,407.5L-273,407.5 c5.1,0,6.2-0.9,6.4-1.1c-0.1-1.1-0.2-2.3-0.3-2.7c-0.6-0.4-2.9-1.3-4.8-1.9l-0.7-0.2l-0.1-2l0.7-0.3c1.7-0.6,2.8-3.1,2.8-6.1 c0-3.1-1.5-5-3.9-5.1c-2.5,0-4,2-4,5.1c0,3,1.1,5.5,2.8,6.1l0.7,0.3l-0.1,2l-0.7,0.2c-1.9,0.6-4.2,1.5-4.8,1.9 c-0.1,0.4-0.3,1.6-0.3,2.7C-279.2,406.6-278,407.5-273,407.5z"/>
|
||||||
|
<g class="st1">
|
||||||
|
<path class="st0" d="M-257,402.8c0-0.7-0.1-2.9-0.6-3.8c-0.1-0.3-0.5-1-4.5-2.4c1.6-1.4,2.6-4,2.6-7.1c0-4.2-2.3-7-5.9-7.1l-0.1,0 c-1.9,0-3.5,0.8-4.5,2.2c0.6,0.3,1.2,0.6,1.8,1c0.7-0.8,1.6-1.3,2.8-1.3c2.4,0,3.9,2,3.9,5.1c0,3-1.1,5.5-2.8,6.1l-0.7,0.3l0.1,2 l0.7,0.2c1.9,0.6,4.3,1.5,4.8,1.9c0.1,0.4,0.3,1.6,0.3,2.7c-0.2,0.2-1,0.8-3.8,1c0.1,0.6,0.2,1.2,0.2,2c2.5-0.2,4.2-0.8,5-1.6 C-257,403.5-257,403-257,402.8z"/>
|
||||||
|
<path class="st0" d="M-287,402.7c0.1-1.1,0.2-2.3,0.3-2.7c0.6-0.4,2.9-1.3,4.8-1.9l0.7-0.2l0.1-2l-0.7-0.3 c-1.6-0.6-2.8-3.1-2.8-6.1c0-3.1,1.5-5,4-5.1c1.2,0,2.1,0.5,2.8,1.3c0.5-0.4,1.1-0.8,1.8-1c-1-1.4-2.6-2.2-4.5-2.2l-0.1,0 c-3.6,0-5.9,2.8-5.9,7.1c0,3.1,1,5.7,2.6,7.1c-4,1.4-4.4,2.1-4.5,2.4c-0.4,0.9-0.5,3.1-0.6,3.8c0,0.2,0,0.7,0.6,1.3 c0.8,0.9,2.5,1.4,5.1,1.6c0-0.7,0.1-1.4,0.2-2C-286,403.5-286.8,402.9-287,402.7z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,33 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<!-- HEADER -->
|
||||||
|
<head>
|
||||||
|
<title>xdrm-brackets</title>
|
||||||
|
|
||||||
|
<!-- META -->
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<meta name='author' content='xdrm-brackets (Adrien Marquès)'>
|
||||||
|
<meta name='description' content='[Home] Home page'>
|
||||||
|
|
||||||
|
<!-- STYLESHEET -->
|
||||||
|
<link type='text/css' rel='stylesheet' href='./css/layout.css'>
|
||||||
|
<link type='text/css' rel='stylesheet' href='./css/menu.css'>
|
||||||
|
<link type='text/css' rel='stylesheet' href='./css/dialog.css'>
|
||||||
|
<link type='text/css' rel='stylesheet' href='./css/container.css'>
|
||||||
|
|
||||||
|
<!-- FONT -->
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro|Arvo|Exo+2" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- BODY -->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id='vue'></div>
|
||||||
|
|
||||||
|
|
||||||
|
<script type='text/javascript' src='./js/bundle.js'></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,85 @@
|
||||||
|
var path = require('path');
|
||||||
|
var webpack = require('webpack');
|
||||||
|
var UglifyJSPlugin = require('uglifyjs-webpack-plugin');
|
||||||
|
|
||||||
|
const ExtractTextPlugin = require("extract-text-webpack-plugin");
|
||||||
|
|
||||||
|
const extractSass = new ExtractTextPlugin({
|
||||||
|
filename: "[name].css",
|
||||||
|
disable: process.env.NODE_ENV === "development"
|
||||||
|
});
|
||||||
|
|
||||||
|
var mod_common = {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: [
|
||||||
|
'vue-style-loader',
|
||||||
|
'css-loader'
|
||||||
|
],
|
||||||
|
}, {
|
||||||
|
test: /\.vue$/,
|
||||||
|
loader: 'vue-loader',
|
||||||
|
options: {
|
||||||
|
loaders: {} // other vue-loader options go here
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
test: /\.js$/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
exclude: /node_modules/
|
||||||
|
}, {
|
||||||
|
test: /\.(png|jpg|gif)$/,
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: { name: '[name].[ext]?[hash]' }
|
||||||
|
}, {
|
||||||
|
test: /\.svg$/,
|
||||||
|
loader: 'vue-svg-loader', // `vue-svg` for webpack 1.x
|
||||||
|
options: {
|
||||||
|
// optional [svgo](https://github.com/svg/svgo) options
|
||||||
|
svgo: {
|
||||||
|
plugins: [
|
||||||
|
{removeDoctype: true},
|
||||||
|
{removeComments: true}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
name: "main",
|
||||||
|
entry: './webpack/main.js',
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, './public_html/js'),
|
||||||
|
publicPath: '/js/',
|
||||||
|
filename: 'bundle.js'
|
||||||
|
},
|
||||||
|
module: mod_common,
|
||||||
|
devtool: (process.env.NODE_ENV==='development') ? '#eval-source-map' : false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
|
||||||
|
// http://vue-loader.vuejs.org/en/workflow/production.html
|
||||||
|
module.exports.plugins = (module.exports.plugins || []).concat([
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env': {
|
||||||
|
NODE_ENV: '"production"'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new UglifyJSPlugin({
|
||||||
|
sourceMap: true
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
minimize: true
|
||||||
|
})
|
||||||
|
])
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
import {GlobalStore} from './lib/gstore'
|
||||||
|
import VueRouter from 'vue-router'
|
||||||
|
import routes from './routes'
|
||||||
|
|
||||||
|
|
||||||
|
window.gs = new GlobalStore();
|
||||||
|
|
||||||
|
/* (1) Global data
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Get Full URI */
|
||||||
|
gs.set('URI', document.URL.replace(/^(?:[^\/]+\/\/|[^\/]+\/)/, '').split('/').filter(function(v,i){ return !!i && v.length; }));
|
||||||
|
|
||||||
|
/* (2) Store routes */
|
||||||
|
gs.set('routes', routes[0]);
|
||||||
|
|
||||||
|
/* (3) Init. vue router */
|
||||||
|
gs.set('router', new VueRouter({
|
||||||
|
routes: gs.get.routes
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Main components
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Menu - channel list */
|
||||||
|
gs.set('channel', {
|
||||||
|
list: {
|
||||||
|
me: { label: '0 online', icon: 'group' },
|
||||||
|
test1: { label: null, icon: '' },
|
||||||
|
test2: { label: null, icon: '' },
|
||||||
|
add: { label: null, icon: 'add', add: 1 }
|
||||||
|
},
|
||||||
|
|
||||||
|
active: 'me'
|
||||||
|
});
|
||||||
|
|
||||||
|
/* (2) Set current active menu item from URL */
|
||||||
|
if( gs.get.URI.length > 1 && gs.get.channel.list.hasOwnProperty(gs.get.URI[gs.get.URI.length-1]) )
|
||||||
|
gs.get.channel.active = gs.get.URI[gs.get.URI.length-1];
|
|
@ -0,0 +1,161 @@
|
||||||
|
/* classe API */
|
||||||
|
export class APIClient{
|
||||||
|
|
||||||
|
constructor(target){
|
||||||
|
|
||||||
|
this.target = target;
|
||||||
|
|
||||||
|
this.xhr = []; // tableau d'objets pour les requêtes ajax
|
||||||
|
this.buffer = null; // Contiendra le buffer pour debugger si erreur de parsage
|
||||||
|
this.error = { // error constants
|
||||||
|
'-1': 'Invalid target format: "METHOD module/method"',
|
||||||
|
'-2': 'XHR error',
|
||||||
|
'-3': 'Invalid JSON response',
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* transaction avec le serveur (http://{host}/api/)
|
||||||
|
*
|
||||||
|
* @param pTarget<String> URI cible, format "HTTP_METHOD uri/uri/uri"
|
||||||
|
* @param pArgs<Object> Le tableu d'arguments passé en POST (attribut<->postfield) à http://{host}/api/
|
||||||
|
* @param pHandler<Function> Fonction qui s'éxécutera lors de la réponse (1 argument -> réponse<Object>)
|
||||||
|
* @param pToken<String> Optionnel, token d'auth pour l'api
|
||||||
|
*
|
||||||
|
***************************************************************************************************
|
||||||
|
*
|
||||||
|
* @usecase
|
||||||
|
* 1. api.call(
|
||||||
|
* 2. "PUT newspaper/article/4"
|
||||||
|
* 2. { content: "New article content" },
|
||||||
|
* 3. function(resp){
|
||||||
|
* 4. alert(resp.error);
|
||||||
|
* 5. }
|
||||||
|
* 6. );
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
call(pTarget, pArgs, pHandler, pToken=null){
|
||||||
|
|
||||||
|
|
||||||
|
/* (1) Check @pHandler (for dispatching errors)
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Check if is a Function */
|
||||||
|
if( !(pHandler instanceof Function) )
|
||||||
|
throw new Error("3rd argument must be a function, but is of type '"+typeof(pHandler)+"' !");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Check @pTarget
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Check format */
|
||||||
|
if( !/^([A-Z]+) (.+)/i.test(pTarget) ){
|
||||||
|
pHandler({ error: -1, ErrorDescription: this.error['-1'] });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (2) Store locally data */
|
||||||
|
var lHttpMethod = RegExp.$1;
|
||||||
|
var lUri = RegExp.$2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (3) Create form data
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Create virtual form */
|
||||||
|
var lForm = new FormData();
|
||||||
|
|
||||||
|
/* (2) Add attributes */
|
||||||
|
for( var key in pArgs ){
|
||||||
|
|
||||||
|
// {2.1} If a file -> send as it //
|
||||||
|
if( pArgs[key] instanceof File )
|
||||||
|
lForm.append(key, pArgs[key]);
|
||||||
|
|
||||||
|
// {2.2} Else -> JSON stringify //
|
||||||
|
else
|
||||||
|
lForm.append(key, JSON.stringify(pArgs[key]));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (4) Create XHR request
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Clean ended requests */
|
||||||
|
for( var i = this.xhr.length-1 ; i >= 0 ; i-- ){
|
||||||
|
|
||||||
|
if( this.xhr[i] != null )
|
||||||
|
break;
|
||||||
|
|
||||||
|
this.xhr.pop();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (2) Push a new entry -> fetch its index */
|
||||||
|
i = this.xhr.push(null) - 1;
|
||||||
|
|
||||||
|
/* (3) Create XHR object */
|
||||||
|
this.xhr[i] = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttpRequest');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (5) Bind response event
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
var self = this; // to access the buffer
|
||||||
|
|
||||||
|
this.xhr[i].onreadystatechange = function(i){
|
||||||
|
|
||||||
|
/* (1) If request over */
|
||||||
|
if( this.xhr[i].readyState == 4 ){
|
||||||
|
|
||||||
|
/* (2) Update buffer (for debug) */
|
||||||
|
self.buffer = this.xhr[i].responseText;
|
||||||
|
|
||||||
|
/* (3) If request success */
|
||||||
|
if( [0, 200, 417].indexOf(this.xhr[i].status) > -1 ){
|
||||||
|
|
||||||
|
|
||||||
|
/* (3.1) Create default response (if JSON error) */
|
||||||
|
var response = {error:-3, ErrorDescription: self.error['-3']};
|
||||||
|
|
||||||
|
/* (3.2) Try to parse JSON */
|
||||||
|
try{ response = JSON.parse(this.xhr[i].responseText); }catch(e){}
|
||||||
|
|
||||||
|
/* (3.3) Launch @pHandler with response */
|
||||||
|
pHandler(response);
|
||||||
|
|
||||||
|
/* (4) If request error */
|
||||||
|
}else
|
||||||
|
pHandler({ error:-2, ErrorDescription: self.error['-2'] });
|
||||||
|
|
||||||
|
/* (5) Notify current xhr instance is done */
|
||||||
|
this.xhr[i] = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}.bind(this, i);
|
||||||
|
|
||||||
|
|
||||||
|
/* (6) Finish & send request
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Open the XHR */
|
||||||
|
this.xhr[i].open(lHttpMethod, this.target+lUri, true);
|
||||||
|
|
||||||
|
/* (2) Manage optional token */
|
||||||
|
if( pToken != null )
|
||||||
|
this.xhr[i].setRequestHeader('Authorization', 'Digest '+pToken);
|
||||||
|
|
||||||
|
/* (3) Custom header to notify we're using Ajax */
|
||||||
|
this.xhr[i].setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
||||||
|
|
||||||
|
/* (4) Make the call */
|
||||||
|
this.xhr[i].send( lForm );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
/* GlobalStore for VueJS */
|
||||||
|
export class GlobalStore{
|
||||||
|
|
||||||
|
constructor(){
|
||||||
|
|
||||||
|
this.get = {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
set(field, value){
|
||||||
|
this.get[field] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* (1) Imports
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) NPM libs */
|
||||||
|
import Vue from 'vue'
|
||||||
|
import VueRouter from 'vue-router'
|
||||||
|
import routes from './routes'
|
||||||
|
|
||||||
|
/* (2) Vues */
|
||||||
|
import wrapper from './vue/wrapper.vue'
|
||||||
|
|
||||||
|
/* (3) Data */
|
||||||
|
require('./common.js');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Initialisation
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Render view */
|
||||||
|
Vue.use(VueRouter);
|
||||||
|
new Vue({
|
||||||
|
el: '#vue',
|
||||||
|
router: gs.get.router,
|
||||||
|
render(h){ return h(wrapper); }
|
||||||
|
})
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* (1) Imports
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) NPM libs */
|
||||||
|
import Vue from 'vue'
|
||||||
|
import VueRouter from 'vue-router'
|
||||||
|
import routes from '../routes/home'
|
||||||
|
|
||||||
|
/* (2) Vues */
|
||||||
|
import wrapper_vue from '../vue/wrapper.vue'
|
||||||
|
|
||||||
|
/* (3) Data */
|
||||||
|
require('../data/common');
|
||||||
|
require('../data/home');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Initialisation
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Init Router */
|
||||||
|
const router = new VueRouter({
|
||||||
|
mode: 'history',
|
||||||
|
routes: require('./routes.js')
|
||||||
|
});
|
||||||
|
|
||||||
|
/* (2) Store router in gstore */
|
||||||
|
gstore.add('router', router);
|
||||||
|
|
||||||
|
/* (3) Render view */
|
||||||
|
Vue.use(VueRouter);
|
||||||
|
new Vue({
|
||||||
|
el: '#WRAPPER',
|
||||||
|
router,
|
||||||
|
render: h => h(wrapper_vue)
|
||||||
|
});
|
|
@ -0,0 +1,11 @@
|
||||||
|
export default{ 0: [
|
||||||
|
|
||||||
|
{
|
||||||
|
path: '/channel/:id',
|
||||||
|
component: require('./vue/channel.vue').default
|
||||||
|
}, {
|
||||||
|
path: '*',
|
||||||
|
redirect: '/channel/me'
|
||||||
|
}
|
||||||
|
|
||||||
|
] }
|
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
/* (1) Dimensions */
|
||||||
|
$menu-width: 4.3em;
|
||||||
|
$dialog-width: 15.2em;
|
||||||
|
$header-height: 3em;
|
||||||
|
|
||||||
|
/* (2) Main colors */
|
||||||
|
$menu-bg: #202225;
|
||||||
|
$dialog-header-bg: #2f3136;
|
||||||
|
$dialog-bg: #2f3136;
|
||||||
|
$container-bg: #36393e;
|
||||||
|
$header-bg: #36393f;
|
||||||
|
|
||||||
|
|
||||||
|
/* (1) Header specific
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Header border-bottom */
|
||||||
|
$bb-height: 1px;
|
||||||
|
$bb-offset: 2px;
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Menu Specific
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Menu item size */
|
||||||
|
$menu-item-size: #{$menu-width * .72};
|
||||||
|
$menu-item-space: .3em;
|
||||||
|
|
||||||
|
/* (2) Default menu item background */
|
||||||
|
$menu-item-bg: #2f3136;
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
@import 'constants';
|
||||||
|
|
||||||
|
#WRAPPER > div.container{
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: #{$menu-width + $dialog-width};
|
||||||
|
width: calc( 100% - #{$menu-width + $dialog-width} );
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background-color: $container-bg;
|
||||||
|
|
||||||
|
|
||||||
|
/* (1) Container HEADER */
|
||||||
|
& > div.header{
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: $header-height;
|
||||||
|
|
||||||
|
border-bottom: #{$bb-height} solid darken($container-bg, 5%);
|
||||||
|
box-shadow: 0 #{$bb-offset - $bb-height} 0 darken($container-bg, 2%);
|
||||||
|
|
||||||
|
z-index: 200;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (2) Container BODY */
|
||||||
|
& > div.body{
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: calc( #{$header-height} + #{$bb-offset} );
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: calc( 100% - #{$header-height} - #{$bb-offset} );
|
||||||
|
|
||||||
|
background-color: $container-bg;
|
||||||
|
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
@import 'constants';
|
||||||
|
|
||||||
|
#WRAPPER > div.dialog{
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: $menu-width;
|
||||||
|
width: $dialog-width;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background-color: $dialog-bg;
|
||||||
|
|
||||||
|
/* (1) Container HEADER */
|
||||||
|
& > div.header{
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: $header-height;
|
||||||
|
|
||||||
|
border-bottom: #{$bb-height} solid darken($dialog-header-bg, 5%);
|
||||||
|
box-shadow: 0 #{$bb-offset - $bb-height} 0 darken($dialog-header-bg, 2%);
|
||||||
|
|
||||||
|
z-index: 200;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (2) Container BODY */
|
||||||
|
& > div.body{
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: calc( #{$header-height} + #{$bb-offset} );
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: calc( 100% - #{$header-height} - #{$bb-offset} );
|
||||||
|
|
||||||
|
background-color: $dialog-bg;
|
||||||
|
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
*{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
font-family: 'Source Sans Pro';
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
& > #WRAPPER{
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
background-color: #f00;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
@import 'constants';
|
||||||
|
|
||||||
|
#WRAPPER > div.menu{
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: $menu-width;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background-color: $menu-bg;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
/* (1) Menu Item */
|
||||||
|
& > span.channel{
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: $menu-item-size;
|
||||||
|
height: $menu-item-size;
|
||||||
|
|
||||||
|
margin: #{$menu-item-space} 0;
|
||||||
|
|
||||||
|
border-radius: 50% / 50%;
|
||||||
|
|
||||||
|
background: $menu-item-bg center center no-repeat;
|
||||||
|
background-size: auto 55%;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
transition: border-radius .4s cubic-bezier(.49, .4, .26, 1.93),
|
||||||
|
background-color .4s ease-in-out,
|
||||||
|
border-color .2s ease-in-out;
|
||||||
|
|
||||||
|
// {1} First item have margin-top //
|
||||||
|
&:first-child{
|
||||||
|
margin-top: #{$menu-item-space * 1.8};
|
||||||
|
}
|
||||||
|
|
||||||
|
// {2} [data-add] have no background color //
|
||||||
|
&[data-add]{
|
||||||
|
background-color: #1e2124;
|
||||||
|
border: 1px dashed #535552;
|
||||||
|
|
||||||
|
&:hover{ border-color: #ddd; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// {3} Hover + current channel (except [data-add])//
|
||||||
|
&:not([data-add='1']):hover,
|
||||||
|
&:not([data-add='1']).active{
|
||||||
|
border-radius: 30% / 30%;
|
||||||
|
|
||||||
|
// if [data-special=1] -> colorize
|
||||||
|
&[data-special='1']{ background-color: #7289da; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// {4} sub label //
|
||||||
|
&[data-sub]:not([data-sub='']){
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
margin-bottom: #{$menu-item-space + 2em};
|
||||||
|
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
// show sub-text
|
||||||
|
&:before{
|
||||||
|
content: attr(data-sub);
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
top: calc( 100% + 1em );
|
||||||
|
left: 1em;
|
||||||
|
width: calc( 100% - 2em );
|
||||||
|
height: calc( 2em + #{$menu-item-space} );
|
||||||
|
|
||||||
|
font-size: .6em;
|
||||||
|
color: #777;
|
||||||
|
text-indent: -.7em;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
border-bottom: 2px solid #{$menu-item-bg};
|
||||||
|
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// {5} Specific icons //
|
||||||
|
&[data-icon='group']{
|
||||||
|
background-image: url('../asset/svg/menu.group.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-icon='add']{
|
||||||
|
background-image: url('../asset/svg/menu.add.svg');
|
||||||
|
&:hover{ background-image: url('../asset/svg/menu.add@hover.svg'); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<div class='body'>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template><script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
name: 'channel-',
|
||||||
|
|
||||||
|
data(){ return { gs: gs.get }; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class='dialog'>
|
||||||
|
|
||||||
|
<div class='header'>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='body'>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</template><script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
name: 'dialog-',
|
||||||
|
|
||||||
|
data(){ return { gs: gs.get }; },
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class='menu'>
|
||||||
|
|
||||||
|
<!-- First elements -->
|
||||||
|
|
||||||
|
<!-- Channel List -->
|
||||||
|
<span v-for='(c,link) in gs.channel.list'
|
||||||
|
@click='$router.push(`/channel/${link}`); gs.channel.active=link'
|
||||||
|
:class='link == gs.channel.active ? `channel active` : `channel`'
|
||||||
|
:data-sub='c.label'
|
||||||
|
:data-special='link == `me`?1:0'
|
||||||
|
:data-add='c.add'
|
||||||
|
:data-icon='c.icon'
|
||||||
|
>{{ c.name }}</span>
|
||||||
|
|
||||||
|
<!-- Last elements -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</template><script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
name: 'menu-',
|
||||||
|
|
||||||
|
data(){ return { gs: gs.get }; }
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,43 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="WRAPPER">
|
||||||
|
|
||||||
|
<!-- Side Menu -->
|
||||||
|
<menu-comp></menu-comp>
|
||||||
|
|
||||||
|
<!-- Side Dialog -->
|
||||||
|
<dialog-comp></dialog-comp>
|
||||||
|
|
||||||
|
<!-- Container -->
|
||||||
|
<div class='container'>
|
||||||
|
|
||||||
|
<div class='header'></div>
|
||||||
|
|
||||||
|
<router-view></router-view>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</template><script>
|
||||||
|
|
||||||
|
import menu_vue from './menu.vue'
|
||||||
|
import dialog_vue from './dialog.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
name: 'wrapper-',
|
||||||
|
|
||||||
|
data(){ return { gs: gs.get }; },
|
||||||
|
|
||||||
|
components: {
|
||||||
|
'MenuComp': menu_vue,
|
||||||
|
'DialogComp': dialog_vue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
Loading…
Reference in New Issue