跟我一塊兒使用electron搭建一個文件瀏覽器應用吧(三)

第二篇博客中咱們能夠看到咱們構建的桌面應用會顯示咱們的文件及文件夾。
In the second blog, we can see that the desktop application we built will display our files and folders.
可是有一點就是它不能進行點擊查看裏面的內容,接下來咱們繼續改造咱們的項目吧~
But one thing is that it can't Click to see the contents. Next, let's continue to transform our project.
第一步重構代碼,將代碼進行邏輯分組
The first step is to refactor the code and group it logically.css

fileSystem.js
'use strict';

const async = require('async');
const fs = require('fs');
const osenv = require('osenv');
const path = require('path');

let shell;

if (process.versions.electron) {
  shell = require('electron').shell;
} else {
  shell = window.require('nw.gui').Shell;
}

function getUsersHomeFolder() {
  return osenv.home();
}

function getFilesInFolder(folderPath, cb) {
  fs.readdir(folderPath, cb);
}

function inspectAndDescribeFile(filePath, cb) {
  let result = { file: path.basename(filePath), path: filePath, type: '' };
  fs.stat(filePath, (err, stat) => {
    if (err) {
      cb(err);
    }       else {
      if (stat.isFile()) {
        result.type = 'file';
      }
      if (stat.isDirectory()) {
        result.type = 'directory';
      }
      cb(err, result);
    }
  });
}

function inspectAndDescribeFiles(folderPath, files, cb) {
  async.map(files, (file, asyncCb) => {
    let resolvedFilePath = path.resolve(folderPath, file);
    inspectAndDescribeFile(resolvedFilePath, asyncCb);
  }, cb);
}

function openFile(filePath) {
  shell.openItem(filePath);
}

module.exports = {
  getUsersHomeFolder,
  getFilesInFolder,
  inspectAndDescribeFiles,
    openFile
};
userInterface.js
'use strict';

let document;
const fileSystem = require('./fileSystem');
const search = require('./search');
const path = require('path');

function displayFolderPath(folderPath) {
  document.getElementById('current-folder')
    .innerHTML = convertFolderPathIntoLinks(folderPath);
  bindCurrentFolderPath();
}

function clearView() {
  const mainArea = document.getElementById('main-area');
  let firstChild = mainArea.firstChild;
  while (firstChild) {
    mainArea.removeChild(firstChild);
    firstChild = mainArea.firstChild;
  }
}

function loadDirectory(folderPath) {
  return function (window) {
    if (!document) document = window.document;
        search.resetIndex();
    displayFolderPath(folderPath);
    fileSystem.getFilesInFolder(folderPath, (err, files) => {
      clearView();
      if (err) {
        return alert('Sorry, we could not load your folder');
      }
      fileSystem.inspectAndDescribeFiles(folderPath, files, displayFiles);
    });
  };
}

function displayFile(file) {
  const mainArea = document.getElementById('main-area');
  const template = document.querySelector('#item-template');
  let clone = document.importNode(template.content, true);
  search.addToIndex(file);
  clone.querySelector('img').src = `images/${file.type}.svg`;
  clone.querySelector('img').setAttribute('data-filePath', file.path);
  if (file.type === 'directory') {
    clone.querySelector('img')
      .addEventListener('dblclick', () => {
        loadDirectory(file.path)();
      }, false);
        } else {
        clone.querySelector('img')
        .addEventListener('dblclick', () => {
        fileSystem.openFile(file.path);
        },
        false);
    }
  clone.querySelector('.filename').innerText = file.file;
  mainArea.appendChild(clone);
}


function displayFiles(err, files) {
  if (err) {
    return alert('Sorry, we could not display your files');
  }
  files.forEach(displayFile);
}

function bindDocument (window) {
  if (!document) {
    document = window.document;
  }
}

function bindSearchField(cb) {
  document.getElementById('search').addEventListener('keyup', cb, false);
}

function filterResults(results) {
  const validFilePaths = results.map((result) => { return result.ref; });
  const items = document.getElementsByClassName('item');
  for (var i = 0; i < items.length; i++) {
    let item = items[i];
    let filePath = item.getElementsByTagName('img')[0]
      .getAttribute('data-filepath');
    if (validFilePaths.indexOf(filePath) !== -1) {
      item.style = null;
    } else {
      item.style = 'display:none;';
    }
  }
}

function resetFilter() {
  const items = document.getElementsByClassName('item');
  for (var i = 0; i < items.length; i++) {
    items[i].style = null;
  }
}

function convertFolderPathIntoLinks (folderPath) {
  const folders = folderPath.split(path.sep);
  const contents    = [];
  let pathAtFolder = '';
  folders.forEach((folder) => {
     pathAtFolder += folder + path.sep;
     contents.push(`<span class="path" data-path="${pathAtFolder.slice(0,-1)}">${folder}</span>`);
  });
  return contents.join(path.sep).toString();
}

function bindCurrentFolderPath() {
  const load = (event) => {
    const folderPath = event.target.getAttribute('data-path');
    loadDirectory(folderPath)();
  };

  const paths = document.getElementsByClassName('path');
  for (var i = 0; i < paths.length; i++) {
    paths[i].addEventListener('click', load, false);
  }
}

module.exports = { bindDocument, displayFiles, loadDirectory, bindSearchField, filterResults, resetFilter };
app.js
'use strict';

const fileSystem = require('./fileSystem');
const userInterface = require('./userInterface');
const search = require('./search');

function main() {
  userInterface.bindDocument(window);
  let folderPath = fileSystem.getUsersHomeFolder();
  userInterface.loadDirectory(folderPath)(window);
  userInterface.bindSearchField((event) => {
    const query = event.target.value;
    if (query === '') {
      userInterface.resetFilter();
    } else {
      search.find(query, userInterface.filterResults);
    }
  });
}

window.onload = main;
app.css
body {
     padding: 0;
     margin: 0;
     font-family: 'Helvetica','Arial','sans';
}

#toolbar {
     top: 0px;
     position: fixed;
     background: red;
     width: 100%;
     z-index: 2;
}

#current-folder {
     float: left;
     color: white;
     background: rgba(0,0,0,0.2);
     padding: 0.5em 1em;
     min-width: 10em;
     border-radius: 0.2em;
     margin: 1em;
}

#main-area {
     clear: both;
     margin: 2em;
     margin-top: 3em;
     z-index: 1;
}

.item {
     position: relative;
     float: left;
     padding: 1em;
     margin: 1em;
     width: 6em;
     height: 6em;
     text-align: center;
}

.item .filename {
     padding-top: 1em;
     font-size: 10pt;
}

#search {
     float: right;
     padding: 0.5em;
     min-width: 10em;
     border-radius: 3em;
     margin: 2em 1em;
     border: none;
     outline: none;
}

span.path:hover, img:hover {
     opacity: 0.7;
     cursor: pointer;
}
index.html
<html>
  <head>
    <title>Lorikeet</title>
    <link rel="stylesheet" href="app.css" />
    <script src="app.js"></script>
  </head>
  <body>
    <template id="item-template">
      <div class="item">
        <img class="icon" />
        <div class="filename"></div>
      </div>
    </template>
    <div id="toolbar">
      <div id="current-folder"></div>
            <input type="search" id="search" results="5" placeholder="Search" />
    </div>
    <div id="main-area"></div>
  </body>
</html>
search.js
'use strict';

const lunr = require('lunr');
let index;

function resetIndex() {
  index = lunr(function () {
    this.field('file');
    this.field('type');
    this.ref('path');
  });
}

function addToIndex(file) {
  index.add(file);
}

function find(query, cb) {
  if (!index) {
    resetIndex();
  }

  const results = index.search(query);
  cb(results);
}

module.exports = { addToIndex, find, resetIndex };

安裝lunr.js他支持對文件夾和文件的搜索
Install lunr. js, which supports searching for folders and files
cnpm install lunr --save
這個lunr的版本號最好爲0.7.2,不用最新的。
The lunr version number is best 0.7.2, not the latest.
運行項目咱們能夠看到效果爲
We can see the effect of running the project is as follows
html

本文的例子學習自 <<跨平臺桌面應用開發基於Electron與NW.js>>這本書shell

相關文章
相關標籤/搜索