ソースを参照

Gitbook Auto Published

willin 8 年 前
コミット
b2924249fb
1 ファイル変更258 行追加0 行削除
  1. 258 0
      experience/advanced/desktop-app.md

+ 258 - 0
experience/advanced/desktop-app.md

@@ -337,11 +337,269 @@ const moveDownItem = (arrOrigin, id, pid = '') => {
 };
 ```
 
+新增了重命名和切换启用状态的两个方法,不再展开。
+
 ### 优化
 
 * 以 class 形式封装
 * 抛出简单的外部接口
 
+```js
+/* eslint class-methods-use-this: [2, { "exceptMethods": ["_deleteItem","_moveUpItem","_moveDownItem"] }] */
+
+import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
+import uuid from 'uuid';
+import locales from '../locales';
+
+module.exports = class Category {
+  constructor(lang) {
+    this.locale = locales(lang);
+    this.DIR_PATH = `${process.env.HOME}/.hosts.js`;
+    this.FILE_PATH = `${this.DIR_PATH}/.category.js`;
+    this.init();
+  }
+
+  init() {
+    const defaultData = [{
+      name: this.locale.default,
+      order: 1,
+      id: 'default',
+      type: 'item',
+      enabled: true
+    }];
+    if (!existsSync(this.DIR_PATH)) {
+      mkdirSync(this.DIR_PATH);
+    }
+    if (!existsSync(this.FILE_PATH)) {
+      this.data = defaultData;
+    } else {
+      const data = readFileSync(this.FILE_PATH, 'utf-8');
+      try {
+        this.data = JSON.parse(data);
+      } catch (e) {
+        this.data = defaultData;
+      }
+    }
+  }
+
+  reorder() {
+    this.data = this.data.sort((x, y) => x.order - y.order > 0 ? 1 : -1)
+      .map((i, iIndex) => {
+        i.order = iIndex + 1;
+        if (i.type === 'folder') {
+          i.children = i.children.sort((x, y) => x.order - y.order > 0 ? 1 : -1).map((j, jIndex) => {
+            j.order = jIndex + 1;
+            return j;
+          });
+        }
+
+        return i;
+      });
+    return true;
+  }
+
+  _deleteItem(arr, id) {
+    const index = arr.findIndex(x => x.id === id);
+    // 异常捕获
+    if (index === -1) return false;
+    // 子菜单超过两个项目禁止删除
+    if (typeof arr[index].children === 'object' && arr[index].children.length > 1) return false;
+    arr.splice(index, 1);
+    return arr;
+  }
+
+  _moveUpItem(arr, id) {
+    const index = arr.findIndex(x => x.id === id);
+    if (index === -1) return false;
+    if (index - 1 === -1) return false;
+    arr[index].order -= 1;
+    arr[index - 1].order += 1;
+    return arr;
+  }
+
+  _moveDownItem(arr, id) {
+    const index = arr.findIndex(x => x.id === id);
+    if (index === -1) return false;
+    if (index + 1 === arr.length) return false;
+    arr[index].order += 1;
+    arr[index + 1].order -= 1;
+    return arr;
+  }
+
+  delete(id, pid = '') {
+    if (pid === '') {
+      const data = this._deleteItem(this.data, id);
+      if (data === false) return false;
+      this.data = data;
+    } else {
+      const index = this.data.findIndex(x => x.id === pid);
+      // 异常捕获
+      if (index === -1) return false;
+      const data = this._deleteItem(this.data[index].children, id);
+      if (data === false) return false;
+      this.data[index].children = data;
+    }
+    return this.reorder();
+  }
+
+  insert(name, pid = '', type = 'item') {
+    if (['item', 'folder'].indexOf(type) === -1) return false;
+    if (type === 'folder' && pid !== '') return false;
+    const item = {
+      name,
+      type,
+      id: uuid.v4()
+    };
+    if (type === 'item') {
+      item.enabled = false;
+    } else {
+      item.children = [];
+    }
+    if (pid === '') {
+      item.order = this.data.length + 1;
+      this.data.push(item);
+    } else {
+      const index = this.data.findIndex(x => x.id === pid);
+      // 异常捕获
+      if (index === -1) return false;
+      item.order = this.data[index].children.length + 1;
+      this.data[index].children.push(item);
+    }
+    return this.reorder();
+  }
+
+  moveUp(id, pid = '') {
+    if (id === 'default') return false;
+    let index;
+    if (pid === '') {
+      index = this.data.findIndex(x => x.id === id);
+      if (index === 1 || index === -1) return false;
+      const data = this._moveUpItem(this.data, id);
+      if (data === false) return false;
+      this.data = data;
+      return this.reorder();
+    }
+    index = this.data.findIndex(x => x.id === pid);
+    // 异常捕获
+    if (index === -1) return false;
+    const data = this._moveUpItem(this.data[index].children, id);
+    if (data === false) return false;
+    this.data[index].children = data;
+    return this.reorder();
+  }
+
+  moveDown(id, pid = '') {
+    if (id === 'default') return false;
+    if (pid === '') {
+      const data = this._moveDownItem(this.data, id);
+      if (data === false) return false;
+      this.data = data;
+      return this.reorder();
+    }
+    const index = this.data.findIndex(x => x.id === pid);
+    // 异常捕获
+    if (index === -1) return false;
+    const data = this._moveDownItem(this.data[index].children, id);
+    if (data === false) return false;
+    this.data[index].children = data;
+    return this.reorder();
+  }
+
+  rename(name, id, pid = '') {
+    if (pid === '') {
+      const index = this.data.findIndex(x => x.id === id);
+      // 异常捕获
+      if (index === -1) return false;
+      this.data[index].name = name;
+    } else {
+      const index = this.data.findIndex(x => x.id === pid);
+      // 异常捕获
+      if (index === -1) return false;
+      const indexChildren = this.data[index].children.findIndex(x => x.id === id);
+      // 异常捕获
+      if (indexChildren === -1) return false;
+      this.data[index].children[indexChildren].name = name;
+    }
+    return this.reorder();
+  }
+
+  toggle(id, pid = '') {
+    if (id === 'default') return false;
+    if (pid === '') {
+      const index = this.data.findIndex(x => x.id === id);
+      // 异常捕获
+      if (index === -1 || !Reflect.has(this.data[index], 'enabled')) return false;
+      this.data[index].enabled = !this.data[index].enabled;
+    } else {
+      const index = this.data.findIndex(x => x.id === pid);
+      // 异常捕获
+      if (index === -1) return false;
+      const indexChildren = this.data[index].children.findIndex(x => x.id === id);
+      // 异常捕获
+      if (indexChildren === -1) return false;
+      this.data[index].children[indexChildren].enabled = !this.data[index].children[indexChildren].enabled;
+    }
+    return true;
+  }
+
+  reload() {
+    return this.data;
+  }
+
+  save() {
+    writeFileSync(this.FILE_PATH, JSON.stringify(this.data, null, 2));
+    return true;
+  }
+};
+```
+
+该文件源码如有更新,在: <https://github.com/js-cool/Hosts.js/blob/master/src/lib/category.js> 上查看。
+
+#### Demo
+
+测试添加:
+
+```js
+import Category from './category';
+
+const categories = new Category();
+
+// 增加目录:
+categories.insert('目录名称', '', 'folder');
+
+// 增加项目:
+categories.insert('项目名称');
+categories.insert('项目名称', '目录 id');
+
+// 删除项目:
+categories.delete('根目录项目 id');
+categories.delete('项目 id', '目录 id');
+
+// 向上移动
+categories.moveUp('根目录项目 id');
+categories.moveUp('项目 id', '目录 id');
+
+// 向下移动
+categories.moveDown('根目录项目 id');
+categories.moveDown('项目 id', '目录 id');
+
+// 重命名
+categories.rename('项目名称', '根目录项目 id');
+categories.rename('项目名称', '项目 id', '目录 id');
+
+// 切换启用状态
+categories.toggle('根目录项目 id');
+categories.toggle('项目 id', '目录 id');
+
+// 保存更改到配置文件
+categories.save();
+
+// 获取最新的列表数据
+const data = categories.reload();
+
+console.log(JSON.stringify(data, null, 2));
+```
+
 ---
 
 Hosts.js项目源码: <https://github.com/js-cool/Hosts.js>