Spis treści
- Wprowadzenie
- File System Access API
- Działająca aplikacja na Github Pages
- Pełen kod aplikacji na Github
- Podsumowanie
Wprowadzenie
Ukazał się już na portalu post o File System Access API:
I w momencie pisania tamtego artykułu wydawało się, że zostanie ono raczej tylko ciekawostką zaimplementowaną tylko w Chrome.
W lutym 2022 tego roku okazało się, że ekosystem Apple również dostanie to API i będzie w nim wspierane. W mocno ograniczonej formie, jako Origin Private File System – ale jednak.
Warto więc odświeżyć temat, pokazując jak napisać mega uproszczoną przeglądarkę plików, która pozwoli otworzyć folder oraz wyświetlić zagnieżdżone w nim foldery oraz pliki.
Zapraszam do czytania 🙂
File System Access API
Krótkie wtrącenie o Origin Private File System
OPFS różni się od implementacji desktopowej. Wersja desktopowa pozwala czytać rzeczywiste pliki i foldery na dysku twardym użytkownika komputera – stąd straszne ostrzeżenie w momencie gdy aplikacja pyta o uprawienia 🙂
OPFS działa w nieco inny sposób – mamy możliwość tworzenia i odczytywania plików i katalogów w ramach jednej domeny i nie ma gwarancji, w jaki sposób przeglądarka będzie nasze pliki reprezentować – mogą być one “bezpośrednio” na dysku bądź też w bazie danych.
Przykładowo – plików utworzonych w ramach domeny https://www.wp.pl/ nie da się odczytać w ramach https://frontcave.pl/
Jeśli chcesz sprawdzić jak działa OPFS, możesz wejść np z iPhone na przykład implementacji:
https://radek-anuszewski.github.io/file-system-acces-api-ios-mac/
Link był fragmentem newslettera który wysyłam co dwa tygodnie liście mailowej, na którą możesz zapisać się tutaj (dostaniesz też ciekawy dokument dotyczący Reacta):
Stworzenie prostej przeglądarki plików tekstowych
Założenia
Przeglądarka wczyta pliki tekstowe i foldery z wybranego katalogu oraz umożliwi wyświetlenie zawartości plików tekstowych po kliknięciu.
Więc implementacja będzie zawierać:
- Wczytanie zagnieżdżonych plików i folderów X poziomów w dół
- Odfiltrowanie plików innych niż z rozszerzeniem txt
- Wyświetlanie zawartości pliku po kliknięciu
Implementacja
Akcję otwarcia pickera z folderami podepniemy pod przycisk:
document.querySelector('#selectMain').addEventListener('click', async () => { data = {}; const mainDirectoryHandle = await window.showDirectoryPicker(); await readElements(mainDirectoryHandle, data, 0); drawElements(data); });
Funkcja showDirectoryPicker spowoduje otwarcie pickera z możliwością wyboru katalogu.
Zwrócony zostanie handler typu FileSystemDirectoryHandle, który w metodzie entries zwróci nam handlery do zawartych w nim folderów i plików.
Skorzysta z tej metody funkcja readElements
:
const readElements = async (handle, elData, level, maxLevel = 5) => { if (level >= maxLevel) { return; } for await (const [elName, elHandle] of handle.entries()) { if (elHandle.kind === 'directory' || elHandle.name.endsWith('.txt')) { elData[elName] = { name: elName, kind: elHandle.kind, handle: elHandle, ...(elHandle.kind === 'directory' ? {data: {}} : {}), ...(elHandle.kind === 'file' ? {file: await elHandle.getFile()} : {}), } if (elHandle.kind === 'directory') { await readElements(elHandle, elData[elName].data, level + 1); } } } }
Wewnątrz funkcji odczytujemy zawartość handlera i wpisujemy ją do obiektu – jeśli trafimy na folder tworzymy nowy zagnieżdżony obiekt, do którego rekurencyjnie dopiszemy zawartość tego folderu – parametr maxLevel
o wartości 5 oznacza, że zejdziemy maksymalnie 5 poziomów w dół.
Jeśli trafimy na plik, od razu pobierzemy go za pomocą metody getFile.
Jak pewnie udało Ci się zauważyć, za pomocą ifa odfiltrowywujemy wszystko, co nie jest katalogiem bądź plikiem z rozszerzeniem txt. W dalszej części artykułu znajdziesz link do działającej aplikacji w Github Pages – najlepiej stwórz sobie zagnieżdżoną strukturę folderów z plikami txt, by lepiej móc zobaczyć działanie aplikacji.
W momencie gdy mamy już obiekt z danymi, na jego podstawie możemy stworzyć DOM naszej przeglądarki plików za pomocą metody drawElements
:
const drawElements = (elData, indentText = '') => { for (const key in elData) { if (elData.hasOwnProperty(key)) { const el = elData[key]; const directory = el.kind === 'directory'; const div = document.createElement('div'); div.innerHTML = `${indentText}${directory ? `<strong>${el.name}</strong>` : el.name}`; div.style.padding = '5px 0'; if (el.kind === 'file') { div.style.cursor = 'pointer'; div.onclick = async () => document.querySelector('#fileText').innerHTML = await el.file.text(); } document.querySelector('#elements').appendChild(div); if (directory) { drawElements(el.data, indentText + '--'); } } } };
Struktura HTML jest płaska, zagnieżdżenie folderów pokazywane jest za pomocą ilości znaków ==
. Jeżeli natrafiamy na plik, podpinamy pod renderowany element metodę, która z pliku za pomocą metody text wyciąga zawartość tekstową którą następnie można wyświetlić. Foldery odróżniają się od plików tym, że są pogrubione:
Działająca aplikacja na Github Pages
Działającą aplikację znajdziesz pod adresem:
https://radek-anuszewski.github.io/simple-file-browser/
Dobrze testować ją na zagnieżdżonych folderach z kilkoma plikami tekstowymi, wtedy najlepiej widać że możemy wczytywać pliki i foldery niżej głębiej niż tylko w folderze głównym.
Pełen kod aplikacji na Github
https://github.com/radek-anuszewski/simple-file-browser
Podsumowanie
Choć wsparcie tylko dla OPFS w ekosystemie Apple nie wydaje się być mocno użyteczne, pamiętajmy że to kolejny krok w rozszerzeniu wsparcia. Stąd warto pamiętać o File System Access API i co jakiś czas odświeżać wiedzę o nim, ponieważ widać że twórcy przeglądarek coraz bardziej się do niego przekonują.