Преглед на файлове

Before putting state on tree itself

Benoît Hubert преди 7 години
родител
ревизия
f795640539
променени са 2 файла, в които са добавени 187 реда и са изтрити 24 реда
  1. 143 0
      react-admin/gulpfile.js
  2. 44 24
      react-admin/src/components/Home.js

+ 143 - 0
react-admin/gulpfile.js

@@ -0,0 +1,143 @@
+const gulp = require('gulp');
+const sourcemaps = require('gulp-sourcemaps');
+const source = require('vinyl-source-stream');
+const buffer = require('vinyl-buffer');
+const browserify = require('browserify');
+const watchify = require('watchify');
+const babelify = require('babelify');
+const pathmod = require('pathmodify');
+const babel = require('gulp-babel');
+const uglify = require('gulp-uglify');
+const gutil = require('gulp-util');
+const zip = require('gulp-zip');
+const fs = require('fs');
+const path = require('path');
+const es = require('event-stream');
+const Promise = require('bluebird');
+
+function slugify(str)
+{
+  str = str.replace(/^\s+|\s+$/g, ''); // trim
+  str = str.toLowerCase();
+
+  // remove accents, swap ñ for n, etc
+  var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
+  var to   = "aaaaeeeeiiiioooouuuunc------";
+
+  for (var i=0, l=from.length ; i<l ; i++)
+    str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
+
+
+  str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
+    .replace(/\s+/g, '-') // collapse whitespace and replace by -
+    .replace(/-+/g, '-'); // collapse dashes
+
+  return str;      // Trim - from end of text
+}
+
+Promise.promisifyAll(fs);
+// const archiveFiles = [
+//   'style.css',
+//   'screenshot.png',
+//   '*.php'
+// ];
+// const builtFiles = [
+//   'js/*'
+// ];
+const watchedFiles = [
+  'src/markdown/**/*'
+];
+
+// const themeName = 'reago';
+
+function buildClient(watch, done) {
+  var bundler =
+    browserify('./src/index.js', { debug: true })
+      .plugin(pathmod, {mods: [
+        pathmod.mod.dir('node_modules', __dirname + '/node_modules'),
+      ]})
+      // Transform JSX      https://github.com/andreypopp/reactify/issues/58
+      // Fix unexpected ... https://github.com/babel/babel-loader/issues/170
+      .transform(babelify, { presets: ['es2015', 'stage-0', 'react'] });
+  return new Promise(function (resolve, reject) {
+    bundler.bundle()
+      .on('error', function(err) { console.error(err); this.emit('end'); })
+      .pipe(source('bundle.admin.js'))
+      .pipe(buffer())
+      .pipe(uglify())
+      .pipe(sourcemaps.init({ loadMaps: true }))
+      .pipe(sourcemaps.write('./'))
+      .pipe(gulp.dest(path.normalize(__dirname + '/../js/dist')))
+      .on('end', resolve);
+  });
+}
+
+function extractMarkdown() {
+  // return new Promise(function (resolve, reject) {
+    return fs.readdirAsync('src/markdown')
+    .then(subdirs => Promise.reduce(
+      subdirs,
+      (carry, dir) =>
+        fs.readdirAsync('src/markdown/' + dir)
+        .then(files => Promise.reduce(
+          files,
+          (carry, f) => fs.readFileAsync('src/markdown/' + dir + '/' + f)
+            .then(buf => buf.toString())
+            .then(content => {
+              const basename = path.basename(f, '.md');
+              const re = /(\d+)\. (.*)/;
+              const matches = basename.match(re);
+              const title = ! matches ? basename :
+                parseInt(matches[1], 10) + '. ' + matches[2];
+              return carry.concat({
+                title,
+                path: '/' + slugify(title),
+                content,
+                type: 'page',
+                dragTo: 'section'
+              });
+            }),
+          []
+        ))
+        .then(items => carry.concat({ title: dir, path: '/' + slugify(dir), type: 'section', items })),
+      []
+    ))
+    .then(JSON.stringify)
+    .then(markdownJson => fs.writeFileAsync('src/resources/markdown.json', markdownJson))
+  // });
+}
+
+// function makeZip(cb) {
+//   return extractThemeVersion()
+//     .then(themeVersion => {
+//       var base = 'dist/' + themeVersion;
+//       var tmp = base + '/reago';
+//       var rebasedFiles = base + '/**/*';
+//       es.concat(
+//           gulp.src(archiveFiles)
+//               .pipe(gulp.dest(tmp)),
+//             gulp.src(builtFiles)
+//                 .pipe(gulp.dest( tmp + '/js')),
+//           gulp.src(rebasedFiles, { base })
+//               .pipe(zip(themeName + '-' + themeVersion + '.zip'))
+//               .pipe(gulp.dest('dist'))
+//       ).on('end', cb)
+//     });
+// }
+
+gulp.task('watch', function() {
+  gulp.watch(['src'], buildClient);
+  gulp.watch(watchedFiles, extractMarkdown);
+});
+
+gulp.task('buildClient', function() {
+  return buildClient();
+});
+
+gulp.task('extractMarkdown', function() {
+  return extractMarkdown();
+});
+
+// gulp.task('makeZip', makeZip);
+
+gulp.task('default', gulp.series('buildClient', 'extractMarkdown', 'watch'));

+ 44 - 24
react-admin/src/components/Home.js

@@ -41,8 +41,8 @@ class Tree extends React.Component {
     const { items } = this.props;
     return (
       <div>
-        {items.map(item =>
-          <TreeNode item={item} key={item.title} level={0} />
+        {items.map((item, i) =>
+          <TreeNode item={item} key={item.title} index={i} level={0} />
         )}
       </div>
     );
@@ -63,6 +63,7 @@ class TreeNode extends React.Component {
     this.state = {
       dragOver: false
     };
+    this.hid = getHandleId();
   }
 
   onMouseDown(e) {
@@ -87,18 +88,35 @@ class TreeNode extends React.Component {
 
   onDragOver(e) {
     e.stopPropagation();
+     // 'drag-over';
+    const coordKeys = Object.keys(e).filter(k => k.match(/^[a-z]+(X|Y)$/));
+    // coordKeys.forEach(k => console.log(k, '=>', e[k]));
+    console.log('dragover', e.target, e.currentTarget, e.relatedTarget, e.dataTransfer); //, this.state.dragOver, this.props.item.title,
+      // var domRect = element.getBoundingClientRect();var domRect = element.getBoundingClientRect(); );
+    const { pageY } = e;
+    const aboveMidLine = pageY < this.draggableMidLine;
+    // console.log(aboveMidLine);
+
+// console.log(this.draggable, e.target);
+//     if(this.draggable !== e.target) return;
     this.setState({
-      dragOver: true
+      dragOver: true, aboveMidLine
     });
-     // 'drag-over';
-    console.log('dragover', e, this.state.dragOver, this.props.item.title);
+    console.log(this.props.index);
+
+  }
+
+  componentDidMount() {
+    const { y, height } = this.draggable.getBoundingClientRect();
+    this.draggableMidLine = y + (height / 2);
   }
 
   onDragLeave(e) {
     e.stopPropagation();
-    this.setState({
-      dragOver: false
-    });
+      this.setState({
+        dragOver: false
+      });
+    // console.log(e.pageY);
     // this.dragOver = '';
     // console.log('dragleave', this.state.dragOver);
   }
@@ -106,24 +124,26 @@ class TreeNode extends React.Component {
   render() {
     const { title, items } = this.props.item;
     const { level } = this.props;
-    const { dragOver } = this.state;
-    console.log('render', dragOver);
+    const { dragOver, aboveMidLine } = this.state;
     const paddingLeft = (level * 15) + 'px';
+    const dragPlaceholderStyles = {
+      minHeight: '39px', border: '1px dashed blue'
+    }
     return (
-      <div
-        className={ "tree-node" + (dragOver ? ' drag-over' : '') }
-        style={{ paddingLeft }}
-        onMouseDown={this.onMouseDown}
-        onDragStart={this.onDragStart}
-        onDragOver={this.onDragOver}
-        onDragLeave={this.onDragLeave}
-        ref={(div) => { this.draggable = div; }}
-        draggable>
-        <h5><i id={ getHandleId() } className="material-icons drag-handle">drag_handle</i><span>{ title }</span></h5>
-        {(items || []).map(item =>
-          <TreeNode item={item} key={item.title} level={level + 1} />
-        )}
-      </div>
+        <div
+          className={ "tree-node" + (dragOver ? ' drag-over' : '') }
+          style={{ paddingLeft }}
+          onMouseDown={this.onMouseDown}
+          onDragStart={this.onDragStart}
+          onDragOver={this.onDragOver}
+          onDragLeave={this.onDragLeave}
+          ref={(div) => { this.draggable = div; }}
+          draggable>
+          <h5><i id={ this.hid } className="material-icons drag-handle">drag_handle</i><span>{ title }</span></h5>
+          {(items || []).map((item, i) =>
+            <TreeNode item={item} index={i} key={item.title} level={level + 1} />
+          )}
+        </div>
     );
   }
 }