Принудительное отображение footer-nav с помощью cookie

Здравствуйте,

Я создаю приложение для своего форума на устройствах iOS. К счастью, существует проект PWABuilder, который предоставляет готовый проект XCode для упаковки веб-приложения в нативное приложение. Это отлично сработало и с моим форумом на Discourse, однако в нём отсутствует кнопка «Назад» или другие элементы, упрощающие навигацию.

Приложение iOS, созданное с помощью PWABuilder (без навигационной панели внизу):

Однако в iOS PWA есть нижняя панель с кнопкой «Назад». Пока что мне не удалось найти способ отображать её вне iOS PWA.

В iOS PWA есть навигационная панель внизу, но принудительно отобразить её вне этого контекста пока не получается (я не нашёл простого способа):

Теперь мой вопрос: можно ли отображать эту панель также внутри WKWebView? У меня есть идея, как это решить. Приложения, созданные с помощью PWABuilder, позволяют устанавливать куки при использовании. А если отображать эту навигационную панель, когда у пользователя есть кука, например, с именем «mobile_footer_nav»? Тогда проблема будет решена.

Настройки, которые можно установить в приложении, созданном с помощью PWABuilder (установка куки при использовании приложения):

Буду очень признателен, если команда разработчиков рассмотрит эту возможность.

(Я знаю, что существует приложение DiscourseHub, но отдельное приложение для форума — более элегантное решение, которое проще для пользователя в использовании и понимании.)

1 лайк

Discourse отображает этот нижний колонтитул на основе определённых условий. Добавление футера происходит здесь.

discourse/app/assets/javascripts/discourse/app/templates/application.hbs at a0bbc346cb5d5b89d1a3efdfa89869349a8b067f · discourse/discourse · GitHub

showFooterNav определяется здесь.

discourse/app/assets/javascripts/discourse/app/controllers/application.js at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub

Если хотя бы одно из этих условий истинно, навигация будет отображаться.

isiOSPWA() и isAppWebview() определяются здесь.

discourse/app/assets/javascripts/discourse/app/lib/utilities.js at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub

Например, isAppWebview() выглядит следующим образом.

discourse/app/assets/javascripts/discourse/app/lib/utilities.js at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub

Вы можете добавить дополнительное условие в вашу тему — на вашем сайте Discourse — для проверки куки, например так:

const isWKWebView = () => {
  // проверьте наличие куки и верните true, если она существует
  // или используйте любой другой метод для определения, использует ли пользователь ваше приложение
}

Для других классов вы обычно могли бы изменить showFooterNav() следующим образом:

api.modifyClass("controller:application", {
  pluginId: "show-footer-nav",
  @discourseComputed
  showFooterNav() {
    // ...
  }
});

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

Тем не менее, вы всё ещё можете изменить значение showFooterNav с помощью чего-то подобного:

<script type="text/discourse-plugin" version="0.8">
  const isWKWebView = () => {
    // проверьте и верните ваше условие
  };

  if (isWKWebView()) {
    const applicationController = api.container.lookup("controller:application");
    applicationController.set("showFooterNav", true);
  }
</script>

на вкладке «Header» вашей темы или в инициализаторе, если вы используете удалённую тему.

5 лайков

Большое спасибо за быструю помощь. К сожалению, у меня возникает ошибка.

Я вставил эти строки кода в заголовок темы и также добавил проверку наличия куки в функцию isWKWebView(). Если куки нет, ничего не происходит. Пока это работает. Но если куки есть, эта панель, к сожалению, не отображается, и в консоли появляется ошибка: “TypeError: Attempted to assign to readonly property.”

1 лайк

Я, кажется, пробовал это только локально, поэтому, возможно, в этом причина.

Попробуйте использовать

applicationController.set("showFooterNav", true);

вместо

applicationController.showFooterNav = true;

Я отредактирую пост с этим изменением.

2 лайка

Работает идеально! Большое спасибо :slight_smile:

Мой финальный код:

<script type="text/discourse-plugin" version="0.8">
function getCookie(cname) {
  let name = cname + "=";
  let decodedCookie = decodeURIComponent(document.cookie);
  let ca = decodedCookie.split(';');
  for(let i = 0; i < ca.length; i++) {
    let c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

if (getCookie("app-platform") != "") {
    const applicationController = api.container.lookup("controller:application");
    applicationController.set("showFooterNav", true);
}
</script>
2 лайка