Прогрессивные веб-приложения: расширение возможностей ваших PWA

1. Добро пожаловать

В этой лабораторной работе вы возьмёте существующее веб-приложение и добавите к нему расширенные возможности. Это шестая из серии сопутствующих практических работ в рамках семинара Progressive Web App . Предыдущая лабораторная работа была посвящена Prompting & Measuring Install . В этой серии ещё две практические работы.

Чему вы научитесь

  • Открывайте и сохраняйте файлы из файловой системы пользователя с помощью API доступа к файловой системе.
  • Зарегистрируйте установленный PWA как обработчик файлов с помощью File Handling API.
  • Выберите нужный экран для открытия окна с помощью API размещения окон на нескольких экранах
  • Предотвратите переход экрана в спящий режим с помощью API Screen Wake Lock

Что вам следует знать

  • JavaScript

Что вам понадобится

  • Браузер, поддерживающий указанные выше API. Для некоторых API вам может потребоваться браузер с активной пробной версией Developer Trial или Origin Trial.

2. Подготовка

Начните с клонирования или загрузки начального кода, необходимого для выполнения этой лабораторной работы:

Если вы клонируете репозиторий, убедитесь, что вы находитесь на ветке pwa05--empowering-your-pwa . ZIP-архив также содержит код для этой ветки.

Для этой кодовой базы требуется Node.js 14 или выше. После того, как код будет готов, выполните команду npm ci из командной строки в папке с кодом, чтобы установить все необходимые зависимости. Затем выполните npm start , чтобы запустить сервер разработки для этой кодовой лаборатории.

Файл README.md исходного кода содержит пояснения ко всем распространяемым файлам. Кроме того, ниже перечислены основные существующие файлы, с которыми вы будете работать в ходе этой лабораторной работы:

Ключевые файлы

  • js/lib/actions.js — Предоставляет базовый класс для меню

Важное архитектурное примечание

В ходе этой практической работы вы будете редактировать js/lib/action.js , который управляет действиями различных кнопок в меню приложения. Вы можете получить доступ к любому свойству в конструкторе инициализированного меню, которое будет включать this.editor для экземпляра основного текстового редактора. В ходе этой практической работы вы будете использовать два важных метода редактора:

  • this.editor.setContent(content) — устанавливает содержимое редактора в соответствии с предоставленным аргументом content.
  • this.editor.content() — Получает текущее содержимое редактора

3. Управление файлами

Открытие, сохранение и создание новых файлов на компьютере пользователя теперь стало возможным благодаря API доступа к файловой системе . В сочетании с API обработки файлов , позволяющим пользователям открывать файлы непосредственно в вашем PWA, ваше PWA может быть легко интегрировано в повседневную жизнь пользователя.

Открыть из приложения

Первое действие, которое нужно подключить, — это возможность открыть файл из файловой системы пользователя из приложения. В js/lib/actions.js , в методе open класса Actions , напишите код, который выполняет следующие действия:

  • Откройте средство выбора файлов, которое возьмет text/markdown файл с расширениями .md или .markdown
  • Установите заголовок страницы на основе имени открытого файла, а также PWA Edit
  • Сохраните обработчик файлов в this.handler
  • Установите содержимое редактора в соответствии с текстовым содержимым файла.
  • Сохраните обработчик в хранилище объектов settings в базе данных settings-store IndexedDB.

Положительный момент: Помните: конструкторы классов не могут быть async функциями, но внутри них можно вызывать Promises.

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

Для выполнения первого действия в конструкторе класса Actions в js/lib/actions.js выполните следующие действия:

  • Откройте базу данных settings-store
  • Получить сохраненный обработчик из хранилища объектов settings
  • Установите this.handler на полученное значение, а заголовок страницы — на имя файла обработчика (плюс PWA Edit ), если есть сохраненный обработчик.

Чтобы сбросить состояние приложения (что можно сделать с помощью CTRL / CMD + Shift + R ), обновите метод reset класса Actions в js/lib/actions.js выполнив следующие действия:

  • Установите заголовок документа на PWA Edit
  • Установите содержимое редактора на пустую строку
  • Установите this.handler на null
  • Удалить сохраненный обработчик из хранилища объектов settings

Открыть из файловой системы пользователя

Теперь, когда вы можете открывать файлы из своего приложения, разрешите пользователям открывать файлы из вашего приложения! Регистрация в качестве обработчика файлов для устройства позволит пользователю открывать файлы в вашем приложении из любой точки своей файловой системы.

Минус: для этого может потребоваться включить пробную версию Developer или Origin. Если вам нужно включить пробную версию Developer, рекомендуется сделать это в Chrome Canary, а не в обычном браузере. Если вам нужно включить пробную версию Origin, зарегистрируйтесь в ней как обычно и добавьте тег в index.html

Для начала в manifest.json добавьте запись file_handlers , которая выполняет следующие действия:

  • Открывается /
  • Принимает файлы text/markdown с расширениями .md или .markdown .

Это позволит пользователям открывать файлы в вашем приложении, но не будет фактически открывать их в самом приложении. Для этого в классе Actions в файле js/lib/actions.js выполните следующие действия:

  • Добавьте в конструктор потребитель window.launchQueue , вызывающий this.open с обработчиком, если таковой имеется.
  • Обновите this.open , чтобы принять дополнительный обработчик запуска.
    • Если он существует и является экземпляром FileSystemFileHandle , используйте его как обработчик файлов для функции
    • Если этого не произошло, откройте средство выбора файлов.

После выполнения обоих вышеперечисленных действий установите PWA и попробуйте открыть с его помощью файл из файловой системы!

Сохранение файла

Пользователь может выбрать два варианта сохранения: сохранение изменений в уже открытом файле или сохранение в новом файле. С помощью API File System Access сохранение в новом файле фактически означает создание нового файла и получение обработчика файла, поэтому для начала давайте сохраним из существующего обработчика.

В методе save класса Actions в js/lib/actions.js выполните следующие действия:

  • Получить обработчик можно либо из this.handler , либо, если его нет, получить сохраненный обработчик из базы данных.
  • Создайте FileSystemWritableFileStream обработчика файлов
  • Записать содержимое редактора в поток
  • Закрыть поток

Как только вы сможете сохранять файл, пора реализовать функцию «сохранить как». Для этого в методе saveAs класса Actions в js/lib/actions.js выполните следующие действия:

  • Отобразить средство выбора сохраняемого файла, описав его как Markdown File и настроив его на прием text/markdown файлов с расширением .md
  • Установите this.handler на возвращаемый обработчик
  • Сохранить обработчик в хранилище объектов settings
  • Дождитесь завершения this.save , чтобы сохранить содержимое в новом файле.

После этого вернитесь к методу save , проверьте, существует ли handler , прежде чем пытаться записать в него данные, и, если его там нет, дождитесь завершения this.saveAs .

4. Показать предварительный просмотр

При использовании редактора Markdown пользователи хотят видеть предварительный просмотр отрендеренного контента. Используя API управления окнами , вы можете открыть предварительный просмотр отрендеренного контента на основном экране пользователя.

Перед началом работы создайте файл js/preview.js и добавьте в него следующий код, чтобы отображался предварительный просмотр при загрузке:

import { openDB } from 'idb';
import { marked } from 'marked';

window.addEventListener('DOMContentLoaded', async () => {
  const preview = document.querySelector('.preview');
  const db = await openDB('settings-store');
  const content = (await db.get('settings', 'content')) || '';

  preview.innerHTML = marked(content);
});

Предварительный просмотр должен вести себя следующим образом:

  • Когда пользователь нажимает кнопку предварительного просмотра, а предварительный просмотр не открыт, он должен открыть предварительный просмотр.
  • Когда пользователь нажимает кнопку предварительного просмотра и предварительный просмотр открыт, он должен закрыть предварительный просмотр.
  • Когда пользователь закрывает или обновляет PWA, предварительный просмотр должен закрываться.

Рассматривая их по порядку, начнем с редактирования метода preview в классе Actions в js/lib/actions.js чтобы сделать следующее:

  • Получите доступные экраны с помощью API управления окнами
  • Отфильтруйте экраны, чтобы найти основной экран.
  • Откройте окно для /preview с заголовком Markdown preview , занимающим половину доступной ширины и всю доступную высоту основного экрана, и расположите его так, чтобы он занимал всю доступную правую половину экрана. Доступные размеры не включают зарезервированные области экрана, такие как системная строка меню, панель инструментов, статус или местоположение.
  • Сохранить это открытое окно в this.previewWindow
  • В верхней части метода проверьте, существует ли this.previewWindow , и если да, закройте окно и снимите this.previewWindow вместо открытия предварительного просмотра окна.

Наконец, выполните следующие действия в конце конструктора класса Actions в js/lib/actions.js :

  • Закройте this.previewWindow во время события beforeunload

5. Фокус

Наконец, мы хотим предложить пользователям режим письма без отвлекающих факторов. Отсутствие отвлекающих факторов означает не только отсутствие помех от других приложений, но и предотвращение засыпания экрана. Для этого воспользуйтесь API Screen Wake Lock .

Кнопка блокировки экрана будет работать так же, как кнопка предварительного просмотра, переключаясь между включенным и выключенным состояниями. Для этого в методе focus класса Actions в js/lib/actions.js выполните следующие действия:

  • Проверьте, есть ли в документе полноэкранный элемент.
  • Если это так:
    • Выйти из полноэкранного режима
    • Если this.wakeLock существует, снимите блокировку пробуждения и сбросьте this.wakeLock
  • Если этого не произойдет:
    • Запросите сигнализатор блокировки пробуждения и установите его на this.wakeLock
    • Запросить, чтобы текст документа отображался на весь экран.

6. Поздравляем!

Вы узнали, как управлять системными файлами и интегрировать PWA с системой с помощью API доступа к файловой системе и API обработки файлов, открывать окна на разных экранах с помощью API управления окнами и предотвращать переход экрана в спящий режим с помощью API блокировки экрана.

Следующая лабораторная работа в серии — Service Worker includes