#+TITLE: Creating a Firefox PWA for Discord on Linux
#+DATE: 2022-07-04
#+FILETAGS: programming

In this tutorial, I'll explain how to set up, install, and configure a Firefox [[https://en.wikipedia.org/wiki/Progressive_web_application][PWA]] (Progressive Web Application) for Discord that integrates into your system, and some background on why you'd want to do so over the regular desktop version. I've tested these steps on Arch Linux and Xubuntu 20.04.

* Background
:PROPERTIES:
:CUSTOM_ID: background
:END:
If you've ever used Discord on Linux, you probably know that it is clunky and not nearly as polished or feature-complete as it is on, say, Windows.

Streaming has no audio, and while using [[https://soundux.rocks/][Soundux]] as a workaround for audio passthrough is a solution, it can be annoying to use, and doesn't always work. For example, in my experience, Soundux fails to pick up audio from Java Minecraft (and I believe by extension all Java applications). In addition, I've recently had issues with audio output, with no sound being produced other than voices in VC.

Another major issue with desktop Discord is the fact it isn't sandboxed at all, meaning it has full access to your system at any time. In addition, if you're desktop is using X.org, Discord (and any other application, for that matter) is able to snoop on all key inputs, even if they're from applications. Make of this what you will.

Not to mention the issues with the updater, which has been excellently covered in [[https://www.youtube.com/watch?v=3OEfr7L-gUk][this video by Brodie Robertson]].

There is of course a second way to use Discord on Linux, which is simply the web application. It does everything that the desktop application does, including streaming (albeit without audio), and it doesn't ever require being updated. The only potential downside is the lack of push-to-talk, but if like me this is something you don't use, then this isn't an issue. In addition, since it's just a web page not a fully-fledged application it doesn't have the security/privacy concern of being able to access your entire system like the desktop version.

The only frustration I have with the web version is the fact that it doesn't look like a standalone application on your desktop, it's just a tab in your browser. Being able to remove as much of the top bar as possible would be nice. This is where PWAs come into play.

Unfortunately, support for SSB (Site Specific Browser) mode and PWAs was [[https://bugzilla.mozilla.org/show_bug.cgi?id=1682593][dropped]] in Firefox 86 last year.

Luckily, *Progressive Web Apps for Firefox* ([[https://github.com/filips123/PWAsForFirefox][filips123/PWAsForFirefox]]) exists to fill the lapse in functionality.

#+begin_quote
This project creates a custom modified Firefox runtime to allow websites to be installed as standalone apps and provides a console tool and browser extension to install, manage and use them.

#+end_quote

* Installation
:PROPERTIES:
:CUSTOM_ID: installation
:END:
First, install the [[https://addons.mozilla.org/en-US/firefox/addon/pwas-for-firefox/][PWAs for Firefox extension from the Firefox add-ons store]]. Once you open it up, it will guide you through the installation process, including installing the companion application. If you're on Arch Linux, it's available on the AUR under =firefox-pwa= and =firefox-pwa-bin=. (=bin= for the binary precompiled version, go for this one if you don't want to compile it yourself.)

*If you are on Ubuntu or one of its derivatives,* the snap version of Firefox that came with your system will not be able to communicate with the companion application, I'm assuming due to snaps' containerization, at least in my testing on Xubuntu 22.04. See [[https://askubuntu.com/a/1404401][this Stack Overflow answer]] for a guide on switching to the standard Debian package version of Firefox.

* Create the Discord PWA
:PROPERTIES:
:CUSTOM_ID: create-the-discord-pwa
:END:
Navigate to Discord [[https://discord.com/channels/@me][https://discord.com]] (*not the app*, we need the root of the PWA to be the index page so all pages under the Discord domain are considered part of the PWA) and click on /Install current site/ in the extension. Change the /Name/ field of the PWA to just "Discord", the default will include the tagline and be a bit overly long. Change the /Start URL/ to [[https://discord.com/app]] so the PWA opens to the app page, not the landing page. And... you're done! You can leave all the other fields as-is and press /Install web app/. You've created a PWA for Firefox, it's as simple as that. You can now open it from within the extension by clicking on the external link button.

However, there's more configuration to be done. Firefox PWA creates a Firefox profile for the PWAs that's completely separate from your main profile, so we're going to have to do some configuration there. (By default, all of your PWAs share a single /Default/ profile under the /Profiles/ tab of the extension, but if you want to have different PWAs have different profiles you can configure it there.)

* Configure the PWA Firefox profile
:PROPERTIES:
:CUSTOM_ID: configure-the-pwa-firefox-profile
:END:
It's up to you how want to configure the profile, but here's what I did and recommend.

- In the :gear: /General/ portion, there's a new settings section, /Progressive Web Apps/. For me I checked /Open out of scope URLs in a default browser,/ which makes it so non-Discord links you visit within the PWA profile are opened in your main Firefox profile instead of within the PWA. This is also important considering any external sites you visit within the PWA aren't otherwise going to be added to your main profile's history.
- Under :jigsaw: /Extensions & Themes/, you You might also want to [[https://addons.mozilla.org/en-US/firefox/addon/discord-dark-rebrand/][choose a theme that matches Discord's theming]].
- Under :lock: /Privacy & Security/ / /History/, set that history to /Use custom settings/ for history and uncheck all the boxes. This will make it so the profile won't keep any history (which is unnecessary in a PWA), but still will remember cookies so you don't have to log in again each time you reopen it.

If you shut down your computer with the PWA open, Firefox will think that your previous session didn't close properly and will reopen your old windows. I haven't figured out a way to prevent this, but if you want to mess with advanced configuration, here's how.

Within the PWA, we don't have access to the URL bar, so to enter the preferences, press Ctrl + Shift + I to enter the developer tools. Enter the console and type in the following:

#+begin_src js
document.location.href = "about:config"
#+end_src

Firefox will make you type =allow pasting= beforehand.

* Launching the PWA from the command line
:PROPERTIES:
:CUSTOM_ID: launching-the-pwa-from-the-command-line
:END:
*If you are using a distro with a desktop environment,* Discord should already be in your applications drawer, so unless you want to be able to launch Discord from the command line, you can skip this step.

I have uninstalled the desktop Discord application =discord=, and I want to replace it with a shell script that launches the PWA. This will enable you to launch the PWA from the command line simply by typing =discord=, and also from an application launcher like [[https://github.com/davatorium/rofi][rofi]]. This way, we don't have to rely on launching Discord from the PWAsForFirefox extension.

Luckily, PWAs for Firefox provides a CLI. First, we need to find the ID of the Discord PWA:

#+begin_src sh
firefoxpwa profile list
#+end_src

This will output the following. After the entry for /Discord/, the string of letters and numbers is the site ID. Your ID will be different.

#+begin_example
========================= Default ==========================
Description: Default profile for all sites
ID: 00000000000000000000000000

Sites:
- Discord: https://discord.com/ (01G705MTCT1Q1HHFM7DVDFAPCY)
#+end_example

You can now launch the PWA using the following command.

#+begin_src sh
firefoxpwa site launch 01G705MTCT1Q1HHFM7DVDFAPCY
#+end_src

Let's create the launch script. Open =/usr/bin/discord= (if this exists already, uninstall the desktop Discord application) with your favorite text editor. You'll need to use =sudo=. Add the following to the file, replacing the site ID with the one you found earlier:

#+begin_src sh
#!/usr/bin/env bash
firefoxpwa site launch 01G705MTCT1Q1HHFM7DVDFAPCY
#+end_src

Finally, make it an executable:

#+begin_src sh
sudo chmod +x /usr/bin/discord
#+end_src

You're done! You've created a PWA for Discord that looks and behaves like a desktop application, but without a lot of the hassle involved with the actual desktop app.

Note that if you decide to reinstall the normal Electron-based desktop Discord application, you'll have to move/delete =/usr/bin/discord= first, as desktop Discord needs to put its executable there.

* Conclusion
:PROPERTIES:
:CUSTOM_ID: conclusion
:END:
Of course, this isn't a perfect solution. Dragging and dropping files into the PWA doesn't work for uploading, there might be some improved voice chat performance in the normal desktop version not available in the browser/PWA version, push-to-talk doesn't work, and streaming still has no audio.

However, if you've already been using primarily the browser version of Discord, creating a PWA is a nice upgrade until Discord finally makes a good client. Here's to hoping that day actually comes.

Anyhow, I hope this was helpful!
