У вас включен AdBlock или иной блокировщик рекламы.

Пожалуйста, отключите его, доход от рекламы помогает развитию сайта и появлению новых статей.

Спасибо за понимание.

В другой раз
DevGang блог о програмировании
Авторизоваться

Electron и Typescript - Приложение для просмотра файлов на рабочем столе 

Библиотека Electron проста в использовании для нативных настольных приложений со знанием веб-технологий. Если вы новичок в Electron и нуждаетесь в представлении, ознакомьтесь с этой статьей. В этой статье мы собираемся создать собственный файловый менеджер с возможностью просмотра нескольких папок или файлов одновременно. Мы будем использовать TypeScript поверх библиотеки Electron.

Приступим

Мы можем начать с проекта шаблона из этого github репозитория. Просто клонируйте проект и выполните следующие команды: 

npm install 
npm start 

Это запустит наше приложение и отобразит окно браузера, которое отображает версию Node и Electron, которую мы используем.

Теперь мы добавим кнопку для открытия диалогового окна выбора папок и кнопку ввода для отображения выбранных папок и файлов.

index.html
<label class="padding20">Folders: </label>
<input id="selectedfolders" class="inputtextwidth" type="text" 
       placeholder="Selected folders paths displayed here.." disabled>
<button class="inlinedisplay margin20" id="folderchooser">Choose folder to list files</button>

В renderer.ts у нас есть обработчик события клик у кнопок для отправки канала ipcRenderer.

renderer.ts
btn.addEventListener("click", (ev: Event) => {
    ipcRenderer.send("showFolderDialog");
});

В main.ts, у нас есть подписчик showfolderdialog, по событию которого затем откроется диалог. Диалог будет предоставлен Electron, который имеет свойства openfile и opendirectory с несколькими вариантами выбора. 

Затем, когда обещание выполняется, мы получаем пути к выбранным файлам, которые отображают путь для чтения каталога и получают все файлы внутри каталога. Их мы отправляем в функцию reduce, чтобы получить статистику файлов. Он будет отправлять файлы со статистикой, отправленной через канал filelist.

Функция Reduce состоит в том, чтобы объединить все файлы разных папок в один список.

Мы также отправляем пути к файлам отдельно, отправляя selectedfolders для отображения пути к папкам в поле ввода.

main.ts
ipcMain.on("showFolderDialog", (event: IpcMainEvent) => {
    let fileSelectionPromise = dialog.showOpenDialog({
        properties: ["openFile", "openDirectory", "multiSelections"]
    });
    
    fileSelectionPromise.then(function(obj) {
        event.sender.send("selectedfolders", obj.filePaths);

        let cumfileslist = obj.filePaths.map((filePath, index)=>{
            return fs.readdirSync(filePath, {withFileTypes: true})
                     .filter(dirent=>!dirent.isDirectory())
                     .map(dirent=>filePath + "/" + dirent.name);

        }).reduce((filesacc, files) => {
            filesacc = filesacc.concat(files);
            return filesacc;

        }).every((absolutefilepath, index, array) => {
            let stats:fs.Stats = fs.statSync(absolutefilepath);
            event.sender.send("fileslist", path.basename(absolutefilepath), stats);
            return true;
        });
    });
});

В renderer.ts, используются selectedfolders для создания слушателя событий, чтобы получить все пути к файлам, а затем объединить их с pipe и поместить его в значении.

renderer.ts
ipcRenderer.on("selectedfolders", (evt: IpcRendererEvent, selectedfolders: string[]) => {
    const selectedFolderElem: HTMLInputElement = document.getElementById("selectedfolders") as HTMLInputElement;
    selectedFolderElem.value = selectedFolderElem.value !== "" ? selectedFolderElem.value + "|"
                                                            : selectedFolderElem.value;
    selectedFolderElem.value += selectedfolders.join(" | ");
});

Чтобы получить список всех файлов, у нас может быть ul элемент и элемент шаблона, который можно развернуть для каждого отображения файла.

index.html
<div>
      <ul id="filelist" class="nopadding">
  </ul>
</div>
<template id="filerec">
  <div class="row">
      <li class="grid-container">
          <span></span>
          <span>234234</span>
          <span>234</span>
      </li>
  </div>
</template>

В renderer.ts он прослушивает элемент filelist, который получает параметры (имя файла, статистика) и заполняет все элементы span в шаблоне. Затем шаблон клонируется и добавляется к элементу ul.

renderer.ts
ipcRenderer.on("fileslist", (event: IpcRendererEvent, fileName: string, stats: fs.Stats) => {
    const filetemplate = document.getElementById("filerec") as HTMLTemplateElement;
    const filedisplayrec = filetemplate.content;
    const spanElements = filedisplayrec.querySelectorAll("span");

    spanElements[0].innerText = fileName;
    spanElements[1].innerText = stats.size.toString();
    spanElements[2].innerText = stats.mtime.toString();
    
    const nodeElement: Node = filedisplayrec.cloneNode(true);
    document.getElementById("filelist").appendChild(nodeElement);
});

Настольное приложение наконец-то будет выглядеть так. Полный исходный код доступен на github

Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоеденяйся в тусовку

Поделитесь своим опытом, расскажите о новом инструменте, библиотеке или фреймворке. Для этого не обязательно становится постоянным автором.

Попробовать