From 2b0dd2cbae04d728508a8872575c16f52d8ffc58 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 5 Apr 2022 23:45:26 +0300
Subject: [PATCH 01/18] fix CSP by compiling the i18n templates as well

---
 build/webpack.base.conf.js |   8 +++
 package.json               |   2 +-
 yarn.lock                  | 110 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 118 insertions(+), 2 deletions(-)

diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
index f442b2a0..8d530ecc 100644
--- a/build/webpack.base.conf.js
+++ b/build/webpack.base.conf.js
@@ -98,6 +98,14 @@ module.exports = {
           }
         }
       },
+      {
+        test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
+        type: 'javascript/auto',
+        loader: '@intlify/vue-i18n-loader',
+        include: [ // Use `Rule.include` to specify the files of locale messages to be pre-compiled
+          path.resolve(__dirname, 'src/i18n')
+        ]
+      },
     ]
   },
   plugins: [
diff --git a/package.json b/package.json
index 70149440..b50e7cfc 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,6 @@
     "escape-html": "1.0.3",
     "localforage": "1.10.0",
     "parse-link-header": "1.0.1",
-    "phoenix": "1.4.0",
     "phoenix": "1.6.2",
     "punycode.js": "2.1.0",
     "qrcode": "1",
@@ -49,6 +48,7 @@
     "@babel/plugin-transform-runtime": "7.17.0",
     "@babel/preset-env": "7.16.11",
     "@babel/register": "7.17.7",
+    "@intlify/vue-i18n-loader": "^5.0.0",
     "@ungap/event-target": "0.2.3",
     "@vue/babel-helper-vue-jsx-merge-props": "1.2.1",
     "@vue/babel-plugin-jsx": "1.1.1",
diff --git a/yarn.lock b/yarn.lock
index 3710bfcc..ed5c18c8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1206,6 +1206,17 @@
   resolved "https://registry.yarnpkg.com/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.0-5.tgz#6251e6917198362fa56510eb256cfb6aa6d30a32"
   integrity sha512-aNmBT4bOecrFsZTog1l6AJDQHPP3ocXV+WQ3Ogy8WZCqstB/ahfhH4CPu5i4N9Hw0MBKXqE+LX+NbUxcj8cVTw==
 
+"@intlify/bundle-utils@next":
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/@intlify/bundle-utils/-/bundle-utils-3.0.0.tgz#d7667b3e6c5889988d9fd27acc2c7c068a2bfbc3"
+  integrity sha512-y43Z5Q3ZJvxqtD8xUH6U3yrlZeay7ZTqkzv1GQ4b0mGQtk5uptOT9Ra4qvGuUv8QyPQsortrA/OHWUD5ax5ZNQ==
+  dependencies:
+    "@intlify/message-compiler" next
+    "@intlify/shared" next
+    jsonc-eslint-parser "^1.0.1"
+    source-map "^0.6.1"
+    yaml-eslint-parser "^0.3.2"
+
 "@intlify/core-base@9.1.9":
   version "9.1.9"
   resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.1.9.tgz#e4e8c951010728e4af3a0d13d74cf3f9e7add7f6"
@@ -1234,6 +1245,14 @@
     "@intlify/shared" "9.1.9"
     source-map "0.6.1"
 
+"@intlify/message-compiler@next":
+  version "9.2.0-beta.34"
+  resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.2.0-beta.34.tgz#a1a85c43f578e8ab00d30774963291fe2fdbc0b9"
+  integrity sha512-l7JjkXJBW2l6cFZqPvI6oWU6QZn/i70agU6QB02W1O+6quFCFNpsiPswgYyQrmfHt4F4qYhLJUMZltIW/cqcbw==
+  dependencies:
+    "@intlify/shared" "9.2.0-beta.34"
+    source-map "0.6.1"
+
 "@intlify/message-resolver@9.1.9":
   version "9.1.9"
   resolved "https://registry.yarnpkg.com/@intlify/message-resolver/-/message-resolver-9.1.9.tgz#3155ccd2f5e6d0dc16cad8b7f1d8e97fcda05bfc"
@@ -1253,6 +1272,11 @@
   resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.1.9.tgz#0baaf96128b85560666bec784ffb01f6623cc17a"
   integrity sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==
 
+"@intlify/shared@9.2.0-beta.34", "@intlify/shared@next":
+  version "9.2.0-beta.34"
+  resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.2.0-beta.34.tgz#e8e9a93455eadcc9785fe2e2437fe037fc267f7d"
+  integrity sha512-hbUKcVbTOkLVpnlSeZE1OPgEI7FpvhuZF/gb84xECTjXEImIa3u0fIcJKUUffv3dlAx8fMOE5xKgDzngidm0tw==
+
 "@intlify/vue-devtools@9.1.9":
   version "9.1.9"
   resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.1.9.tgz#2be8f4dbe7f7ed4115676eb32348141d411e426b"
@@ -1262,6 +1286,17 @@
     "@intlify/runtime" "9.1.9"
     "@intlify/shared" "9.1.9"
 
+"@intlify/vue-i18n-loader@^5.0.0":
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/@intlify/vue-i18n-loader/-/vue-i18n-loader-5.0.0.tgz#26f7b9d55b3feb5d50cdbbd537c7ed4b2396b3fb"
+  integrity sha512-rlqWLHrXdchvI9jsI5XA7/3UqE+4pgBD40d+9DWdyRkKeXfMMO9lmkp21jOKC8afWcK0NW5qzYTjp+JEJ6ymZA==
+  dependencies:
+    "@intlify/bundle-utils" next
+    "@intlify/shared" next
+    js-yaml "^4.1.0"
+    json5 "^2.2.0"
+    loader-utils "^2.0.0"
+
 "@jridgewell/resolve-uri@^3.0.3":
   version "3.0.5"
   resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c"
@@ -1740,6 +1775,11 @@ acorn-jsx@^5.0.0:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e"
 
+acorn-jsx@^5.2.0:
+  version "5.3.2"
+  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
+  integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
+
 acorn@^6.0.2, acorn@^6.0.7:
   version "6.1.1"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f"
@@ -1749,6 +1789,11 @@ acorn@^6.4.1:
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
   integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
 
+acorn@^7.1.1, acorn@^7.4.1:
+  version "7.4.1"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
+  integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
+
 agent-base@2:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7"
@@ -1916,6 +1961,11 @@ argparse@^1.0.7:
   dependencies:
     sprintf-js "~1.0.2"
 
+argparse@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
+  integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+
 arr-diff@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@@ -3993,10 +4043,22 @@ eslint-utils@^1.3.0, eslint-utils@^1.3.1:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512"
 
+eslint-utils@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
+  integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==
+  dependencies:
+    eslint-visitor-keys "^1.1.0"
+
 eslint-visitor-keys@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
 
+eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
+  integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
+
 eslint@5.16.0:
   version "5.16.0"
   resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea"
@@ -4055,6 +4117,15 @@ espree@^5.0.1:
     acorn-jsx "^5.0.0"
     eslint-visitor-keys "^1.0.0"
 
+espree@^6.0.0:
+  version "6.2.1"
+  resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a"
+  integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==
+  dependencies:
+    acorn "^7.1.1"
+    acorn-jsx "^5.2.0"
+    eslint-visitor-keys "^1.1.0"
+
 esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1:
   version "2.7.3"
   resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
@@ -5699,6 +5770,13 @@ js-yaml@^3.13.0, js-yaml@^3.13.1:
     argparse "^1.0.7"
     esprima "^4.0.0"
 
+js-yaml@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
+  integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
+  dependencies:
+    argparse "^2.0.1"
+
 js-yaml@~3.7.0:
   version "3.7.0"
   resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
@@ -5757,6 +5835,22 @@ json5@^2.1.2:
   dependencies:
     minimist "^1.2.5"
 
+json5@^2.2.0:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
+  integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
+
+jsonc-eslint-parser@^1.0.1:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/jsonc-eslint-parser/-/jsonc-eslint-parser-1.4.1.tgz#8cbe99f6f5199acbc5a823c4c0b6135411027fa6"
+  integrity sha512-hXBrvsR1rdjmB2kQmUjf1rEIa+TqHBGMge8pwi++C+Si1ad7EjZrJcpgwym+QGK/pqTx+K7keFAtLlVNdLRJOg==
+  dependencies:
+    acorn "^7.4.1"
+    eslint-utils "^2.1.0"
+    eslint-visitor-keys "^1.3.0"
+    espree "^6.0.0"
+    semver "^6.3.0"
+
 jsonfile@^6.0.1:
   version "6.1.0"
   resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
@@ -6239,7 +6333,7 @@ lodash.uniq@^4.5.0:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
 
-lodash@4.17.21, lodash@^4.17.21:
+lodash@4.17.21, lodash@^4.17.20, lodash@^4.17.21:
   version "4.17.21"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
   integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -10203,6 +10297,20 @@ yallist@^4.0.0:
   resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
   integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
 
+yaml-eslint-parser@^0.3.2:
+  version "0.3.2"
+  resolved "https://registry.yarnpkg.com/yaml-eslint-parser/-/yaml-eslint-parser-0.3.2.tgz#c7f5f3904f1c06ad55dc7131a731b018426b4898"
+  integrity sha512-32kYO6kJUuZzqte82t4M/gB6/+11WAuHiEnK7FreMo20xsCKPeFH5tDBU7iWxR7zeJpNnMXfJyXwne48D0hGrg==
+  dependencies:
+    eslint-visitor-keys "^1.3.0"
+    lodash "^4.17.20"
+    yaml "^1.10.0"
+
+yaml@^1.10.0:
+  version "1.10.2"
+  resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
+  integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
+
 yaml@^1.7.2:
   version "1.10.0"
   resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e"

From 78817e37f77d72a36f8ba33ad00e440992e47435 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 6 Apr 2022 11:30:42 +0300
Subject: [PATCH 02/18] force runtime build of i18n

---
 build/webpack.base.conf.js |  3 +-
 package.json               |  2 +-
 yarn.lock                  | 94 ++++++++++++++------------------------
 3 files changed, 37 insertions(+), 62 deletions(-)

diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
index 8d530ecc..f8bd9902 100644
--- a/build/webpack.base.conf.js
+++ b/build/webpack.base.conf.js
@@ -38,7 +38,8 @@ module.exports = {
       'static': path.resolve(__dirname, '../static'),
       'src': path.resolve(__dirname, '../src'),
       'assets': path.resolve(__dirname, '../src/assets'),
-      'components': path.resolve(__dirname, '../src/components')
+      'components': path.resolve(__dirname, '../src/components'),
+      'vue-i18n': 'vue-i18n/dist/vue-i18n.runtime.esm-bundler.js'
     }
   },
   module: {
diff --git a/package.json b/package.json
index b50e7cfc..e9a246b3 100644
--- a/package.json
+++ b/package.json
@@ -38,7 +38,7 @@
     "qrcode": "1",
     "ruffle-mirror": "2021.12.31",
     "vue": "^3.2.31",
-    "vue-i18n": "9.1.9",
+    "vue-i18n": "^9.2.0-beta.34",
     "vue-router": "4.0.14",
     "vue-template-compiler": "2.6.11",
     "vuex": "4.0.2"
diff --git a/yarn.lock b/yarn.lock
index ed5c18c8..042d87ac 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1217,35 +1217,24 @@
     source-map "^0.6.1"
     yaml-eslint-parser "^0.3.2"
 
-"@intlify/core-base@9.1.9":
-  version "9.1.9"
-  resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.1.9.tgz#e4e8c951010728e4af3a0d13d74cf3f9e7add7f6"
-  integrity sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==
+"@intlify/core-base@9.2.0-beta.34":
+  version "9.2.0-beta.34"
+  resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.2.0-beta.34.tgz#39d0dc41679510b39540da718c76022fd026a1e0"
+  integrity sha512-MwWvL7GMpFeYBfFOU2fDj8V+kodtoGv3ZjK0qxnQtJ6oWtmv2ldqRuIu1NxPSmykYYg4iljrG174EzZnQkIcqA==
   dependencies:
-    "@intlify/devtools-if" "9.1.9"
-    "@intlify/message-compiler" "9.1.9"
-    "@intlify/message-resolver" "9.1.9"
-    "@intlify/runtime" "9.1.9"
-    "@intlify/shared" "9.1.9"
-    "@intlify/vue-devtools" "9.1.9"
+    "@intlify/devtools-if" "9.2.0-beta.34"
+    "@intlify/message-compiler" "9.2.0-beta.34"
+    "@intlify/shared" "9.2.0-beta.34"
+    "@intlify/vue-devtools" "9.2.0-beta.34"
 
-"@intlify/devtools-if@9.1.9":
-  version "9.1.9"
-  resolved "https://registry.yarnpkg.com/@intlify/devtools-if/-/devtools-if-9.1.9.tgz#a30e1dd1256ff2c5c98d8d75d075384fba898e5d"
-  integrity sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==
+"@intlify/devtools-if@9.2.0-beta.34":
+  version "9.2.0-beta.34"
+  resolved "https://registry.yarnpkg.com/@intlify/devtools-if/-/devtools-if-9.2.0-beta.34.tgz#9a318026c104af43de9df937647b746e38303de6"
+  integrity sha512-Q/MNzslMLKpVygLJDE2poOwzQFed3KTpAn6hPsN10pgBPNHwJGVi6LgBYsO/6TVszN0w4GA1cv+6nT3iIyW7+A==
   dependencies:
-    "@intlify/shared" "9.1.9"
+    "@intlify/shared" "9.2.0-beta.34"
 
-"@intlify/message-compiler@9.1.9":
-  version "9.1.9"
-  resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.1.9.tgz#1193cbd224a71c2fb981455b8534a3c766d2948d"
-  integrity sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==
-  dependencies:
-    "@intlify/message-resolver" "9.1.9"
-    "@intlify/shared" "9.1.9"
-    source-map "0.6.1"
-
-"@intlify/message-compiler@next":
+"@intlify/message-compiler@9.2.0-beta.34", "@intlify/message-compiler@next":
   version "9.2.0-beta.34"
   resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.2.0-beta.34.tgz#a1a85c43f578e8ab00d30774963291fe2fdbc0b9"
   integrity sha512-l7JjkXJBW2l6cFZqPvI6oWU6QZn/i70agU6QB02W1O+6quFCFNpsiPswgYyQrmfHt4F4qYhLJUMZltIW/cqcbw==
@@ -1253,38 +1242,18 @@
     "@intlify/shared" "9.2.0-beta.34"
     source-map "0.6.1"
 
-"@intlify/message-resolver@9.1.9":
-  version "9.1.9"
-  resolved "https://registry.yarnpkg.com/@intlify/message-resolver/-/message-resolver-9.1.9.tgz#3155ccd2f5e6d0dc16cad8b7f1d8e97fcda05bfc"
-  integrity sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==
-
-"@intlify/runtime@9.1.9":
-  version "9.1.9"
-  resolved "https://registry.yarnpkg.com/@intlify/runtime/-/runtime-9.1.9.tgz#2c12ce29518a075629efed0a8ed293ee740cb285"
-  integrity sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==
-  dependencies:
-    "@intlify/message-compiler" "9.1.9"
-    "@intlify/message-resolver" "9.1.9"
-    "@intlify/shared" "9.1.9"
-
-"@intlify/shared@9.1.9":
-  version "9.1.9"
-  resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.1.9.tgz#0baaf96128b85560666bec784ffb01f6623cc17a"
-  integrity sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==
-
 "@intlify/shared@9.2.0-beta.34", "@intlify/shared@next":
   version "9.2.0-beta.34"
   resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.2.0-beta.34.tgz#e8e9a93455eadcc9785fe2e2437fe037fc267f7d"
   integrity sha512-hbUKcVbTOkLVpnlSeZE1OPgEI7FpvhuZF/gb84xECTjXEImIa3u0fIcJKUUffv3dlAx8fMOE5xKgDzngidm0tw==
 
-"@intlify/vue-devtools@9.1.9":
-  version "9.1.9"
-  resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.1.9.tgz#2be8f4dbe7f7ed4115676eb32348141d411e426b"
-  integrity sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==
+"@intlify/vue-devtools@9.2.0-beta.34":
+  version "9.2.0-beta.34"
+  resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.2.0-beta.34.tgz#baa0260f09ec07497d12d9d83af2569172d981bb"
+  integrity sha512-0fEUqxZ2XibWNpWr1OTQrz0hBgqiWdXOvg5D6NjYBYIrSlJ13cPFfkfPBlnKUkrfBdw7RG6l+SlcUwIPj0ViGA==
   dependencies:
-    "@intlify/message-resolver" "9.1.9"
-    "@intlify/runtime" "9.1.9"
-    "@intlify/shared" "9.1.9"
+    "@intlify/core-base" "9.2.0-beta.34"
+    "@intlify/shared" "9.2.0-beta.34"
 
 "@intlify/vue-i18n-loader@^5.0.0":
   version "5.0.0"
@@ -1527,11 +1496,16 @@
     "@vue/compiler-dom" "3.2.31"
     "@vue/shared" "3.2.31"
 
-"@vue/devtools-api@^6.0.0", "@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.0.0-beta.7":
+"@vue/devtools-api@^6.0.0", "@vue/devtools-api@^6.0.0-beta.11":
   version "6.1.3"
   resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.1.3.tgz#a44c52e8fa6d22f84db3abdcdd0be5135b7dd7cf"
   integrity sha512-79InfO2xHv+WHIrH1bHXQUiQD/wMls9qBk6WVwGCbdwP7/3zINtvqPNMtmSHXsIKjvUAHc8L0ouOj6ZQQRmcXg==
 
+"@vue/devtools-api@^6.0.0-beta.13":
+  version "6.1.4"
+  resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.1.4.tgz#b4aec2f4b4599e11ba774a50c67fa378c9824e53"
+  integrity sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ==
+
 "@vue/reactivity-transform@3.2.31":
   version "3.2.31"
   resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.31.tgz#0f5b25c24e70edab2b613d5305c465b50fc00911"
@@ -10014,15 +9988,15 @@ vue-eslint-parser@^5.0.0:
     esquery "^1.0.1"
     lodash "^4.17.11"
 
-vue-i18n@9.1.9:
-  version "9.1.9"
-  resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.1.9.tgz#cb53e06ab5cc5b7eed59332f151caf48d47be9bb"
-  integrity sha512-JeRdNVxS2OGp1E+pye5XB6+M6BBkHwAv9C80Q7+kzoMdUDGRna06tjC0vCB/jDX9aWrl5swxOMFcyAr7or8XTA==
+vue-i18n@^9.2.0-beta.34:
+  version "9.2.0-beta.34"
+  resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.2.0-beta.34.tgz#ab092a4c3635782c49054995265e3e44e3533e8d"
+  integrity sha512-AKzOMn91OKBKHTPVWrDF+kBSbYYNGfBeeBhuihkxW2ZTXd1l8vp7WBqA6weV9kb9EDv7HO61Qhctqcr79TmHVw==
   dependencies:
-    "@intlify/core-base" "9.1.9"
-    "@intlify/shared" "9.1.9"
-    "@intlify/vue-devtools" "9.1.9"
-    "@vue/devtools-api" "^6.0.0-beta.7"
+    "@intlify/core-base" "9.2.0-beta.34"
+    "@intlify/shared" "9.2.0-beta.34"
+    "@intlify/vue-devtools" "9.2.0-beta.34"
+    "@vue/devtools-api" "^6.0.0-beta.13"
 
 vue-loader@^16.0.0:
   version "16.8.3"

From bd77f3a1a6b341612949cd28237a4efbd2ce2bb4 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 6 Apr 2022 15:45:44 +0300
Subject: [PATCH 03/18] fix i18n for good??

---
 build/webpack.base.conf.js | 17 +++++++++--------
 src/i18n/messages.js       |  6 +++---
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
index f8bd9902..f8c544d7 100644
--- a/build/webpack.base.conf.js
+++ b/build/webpack.base.conf.js
@@ -59,6 +59,15 @@ module.exports = {
           }
         }
       },
+      {
+        enforce: 'post',
+        test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
+        type: 'javascript/auto',
+        loader: '@intlify/vue-i18n-loader',
+        include: [ // Use `Rule.include` to specify the files of locale messages to be pre-compiled
+          path.resolve(__dirname, '../src/i18n')
+        ]
+      },
       {
         test: /\.vue$/,
         loader: 'vue-loader',
@@ -99,14 +108,6 @@ module.exports = {
           }
         }
       },
-      {
-        test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
-        type: 'javascript/auto',
-        loader: '@intlify/vue-i18n-loader',
-        include: [ // Use `Rule.include` to specify the files of locale messages to be pre-compiled
-          path.resolve(__dirname, 'src/i18n')
-        ]
-      },
     ]
   },
   plugins: [
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index 2a1161be..c5997230 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -32,7 +32,7 @@ const loaders = {
   pt: () => import('./pt.json'),
   ro: () => import('./ro.json'),
   ru: () => import('./ru.json'),
-  te: () => import('./te.json'),
+  //te: () => import('./te.json'), // buggy
   uk: () => import('./uk.json'),
   zh: () => import('./zh.json'),
   zh_Hant: () => import('./zh_Hant.json')
@@ -41,12 +41,12 @@ const loaders = {
 const messages = {
   languages: ['en', ...Object.keys(loaders)],
   default: {
-    en: require('./en.json')
+    en: require('./en.json').default
   },
   setLanguage: async (i18n, language) => {
     if (loaders[language]) {
       let messages = await loaders[language]()
-      i18n.setLocaleMessage(language, messages)
+      i18n.setLocaleMessage(language, messages.default)
     }
     i18n.locale = language
   }

From b213d25711efdbf275c5092fbc3983792476eec9 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 6 Apr 2022 15:47:52 +0300
Subject: [PATCH 04/18] heck

---
 src/i18n/messages.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index c5997230..869eaec4 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -32,7 +32,7 @@ const loaders = {
   pt: () => import('./pt.json'),
   ro: () => import('./ro.json'),
   ru: () => import('./ru.json'),
-  //te: () => import('./te.json'), // buggy
+  // te: () => import('./te.json'), // buggy
   uk: () => import('./uk.json'),
   zh: () => import('./zh.json'),
   zh_Hant: () => import('./zh_Hant.json')

From 853f5145be2296911862a845d45fbb0242a62ade Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 6 Apr 2022 18:43:47 +0300
Subject: [PATCH 05/18] fix tegulu

---
 src/i18n/messages.js | 2 +-
 src/i18n/te.json     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index 869eaec4..977b8eb3 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -32,7 +32,7 @@ const loaders = {
   pt: () => import('./pt.json'),
   ro: () => import('./ro.json'),
   ru: () => import('./ru.json'),
-  // te: () => import('./te.json'), // buggy
+  te: () => import('./te.json'),
   uk: () => import('./uk.json'),
   zh: () => import('./zh.json'),
   zh_Hant: () => import('./zh_Hant.json')
diff --git a/src/i18n/te.json b/src/i18n/te.json
index 1216de59..4f255505 100644
--- a/src/i18n/te.json
+++ b/src/i18n/te.json
@@ -49,7 +49,7 @@
   "notifications.repeated_you": "మీ స్థితిని పునరావృతం చేసారు",
   "notifications.no_more_notifications": "ఇక నోటిఫికేషన్లు లేవు",
   "post_status.new_status": "క్రొత్త స్థితిని పోస్ట్ చేయండి",
-  "post_status.account_not_locked_warning": "మీ ఖాతా {౦} కాదు. ఎవరైనా మిమ్మల్ని అనుసరించి అనుచరులకు మాత్రమే ఉద్దేశించిన పోస్టులను చూడవచ్చు.",
+  "post_status.account_not_locked_warning": "మీ ఖాతా {0} కాదు. ఎవరైనా మిమ్మల్ని అనుసరించి అనుచరులకు మాత్రమే ఉద్దేశించిన పోస్టులను చూడవచ్చు.",
   "post_status.account_not_locked_warning_link": "తాళం వేయబడినది",
   "post_status.attachments_sensitive": "జోడింపులను సున్నితమైనవిగా గుర్తించండి",
   "post_status.content_type.text/plain": "సాధారణ అక్షరాలు",

From 4ddb6189dc09e03aba5e3da1d2dd2e06e7020b24 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Wed, 6 Apr 2022 17:06:41 -0400
Subject: [PATCH 06/18] Fix no reactivity on vuex 4 values

---
 src/App.js                                |  2 +-
 src/components/side_drawer/side_drawer.js |  2 +-
 src/modules/shout.js                      | 15 ++++++++++++++-
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/App.js b/src/App.js
index c4360af5..294f6000 100644
--- a/src/App.js
+++ b/src/App.js
@@ -65,7 +65,7 @@ export default {
         }
       }
     },
-    shout () { return this.$store.state.shout.channel.state === 'joined' },
+    shout () { return this.$store.state.shout.joined },
     suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
     showInstanceSpecificPanel () {
       return this.$store.state.instance.showInstanceSpecificPanel &&
diff --git a/src/components/side_drawer/side_drawer.js b/src/components/side_drawer/side_drawer.js
index 89719df3..bad1806b 100644
--- a/src/components/side_drawer/side_drawer.js
+++ b/src/components/side_drawer/side_drawer.js
@@ -49,7 +49,7 @@ const SideDrawer = {
     currentUser () {
       return this.$store.state.users.currentUser
     },
-    shout () { return this.$store.state.shout.channel.state === 'joined' },
+    shout () { return this.$store.state.shout.joined },
     unseenNotifications () {
       return unseenNotificationsFromStore(this.$store)
     },
diff --git a/src/modules/shout.js b/src/modules/shout.js
index 507a4d83..88aefbfe 100644
--- a/src/modules/shout.js
+++ b/src/modules/shout.js
@@ -1,7 +1,8 @@
 const shout = {
   state: {
     messages: [],
-    channel: { state: '' }
+    channel: { state: '' },
+    joined: false
   },
   mutations: {
     setChannel (state, channel) {
@@ -13,11 +14,23 @@ const shout = {
     },
     setMessages (state, messages) {
       state.messages = messages.slice(-19, 20)
+    },
+    setJoined (state, joined) {
+      state.joined = joined
     }
   },
   actions: {
     initializeShout (store, socket) {
       const channel = socket.channel('chat:public')
+      channel.joinPush.receive('ok', () => {
+        store.commit('setJoined', true)
+      })
+      channel.onClose(() => {
+        store.commit('setJoined', false)
+      })
+      channel.onError(() => {
+        store.commit('setJoined', false)
+      })
       channel.on('new_msg', (msg) => {
         store.commit('addMessage', msg)
       })

From 741a59e0cc4047487aee03e292329ff9ac17bbd6 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Wed, 6 Apr 2022 18:50:33 -0400
Subject: [PATCH 07/18] Fix phoenix sockets in dev mode

phoenix requires the Origin header to be set to the actual address,
so "http://localhost:xxxx" will not work.
---
 config/index.js | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/config/index.js b/config/index.js
index 7cb87c3b..023d4c9b 100644
--- a/config/index.js
+++ b/config/index.js
@@ -52,7 +52,10 @@ module.exports = {
         target,
         changeOrigin: true,
         cookieDomainRewrite: 'localhost',
-        ws: true
+        ws: true,
+        headers: {
+          'Origin': target
+        }
       },
       '/oauth/revoke': {
         target,

From 041c72b07c7d0559bd5b97c49503e69707aa08b2 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Wed, 6 Apr 2022 20:04:36 -0400
Subject: [PATCH 08/18] Fix dropdown menu style inside panel header

---
 src/components/popover/popover.vue | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue
index 8588b351..1502c30c 100644
--- a/src/components/popover/popover.vue
+++ b/src/components/popover/popover.vue
@@ -149,5 +149,30 @@
     }
 
   }
+
+  .button-default.dropdown-item {
+    &,
+    i[class*=icon-] {
+      color: $fallback--text;
+      color: var(--btnText, $fallback--text);
+    }
+
+    &:active {
+      background-color: $fallback--fg;
+      background-color: var(--btnPressed, $fallback--fg);
+      color: $fallback--text;
+      color: var(--btnPressedText, $fallback--text);
+    }
+
+    &:disabled {
+      color: $fallback--text;
+      color: var(--btnDisabledText, $fallback--text);
+    }
+
+    &.toggled {
+      color: $fallback--text;
+      color: var(--btnToggledText, $fallback--text);
+    }
+  }
 }
 </style>

From 6de87e8b658a203a471af0210b6677d22aef9ebb Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Wed, 6 Apr 2022 20:26:37 -0400
Subject: [PATCH 09/18] Use panel text instead of text for shoutbox icon

---
 src/components/shout_panel/shout_panel.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/shout_panel/shout_panel.vue b/src/components/shout_panel/shout_panel.vue
index c88797d1..f3e9ff96 100644
--- a/src/components/shout_panel/shout_panel.vue
+++ b/src/components/shout_panel/shout_panel.vue
@@ -98,7 +98,7 @@
 
     .icon {
       color: $fallback--text;
-      color: var(--text, $fallback--text);
+      color: var(--panelText, $fallback--text);
       margin-right: 0.5em;
     }
 

From fce9c5eeb2092a3c66609afbed81f933b6bec069 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Wed, 6 Apr 2022 22:50:01 -0400
Subject: [PATCH 10/18] Fix active popover style

---
 src/components/popover/popover.vue | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue
index 1502c30c..332a0398 100644
--- a/src/components/popover/popover.vue
+++ b/src/components/popover/popover.vue
@@ -158,10 +158,10 @@
     }
 
     &:active {
-      background-color: $fallback--fg;
-      background-color: var(--btnPressed, $fallback--fg);
-      color: $fallback--text;
-      color: var(--btnPressedText, $fallback--text);
+      background-color: $fallback--lightBg;
+      background-color: var(--selectedMenuPopover, $fallback--lightBg);
+      color: $fallback--link;
+      color: var(--selectedMenuPopoverText, $fallback--link);
     }
 
     &:disabled {

From 22c70ae22a43bb1b11ace5a480df6587650bb6c3 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Thu, 7 Apr 2022 11:43:59 -0400
Subject: [PATCH 11/18] Fix shrug text in muted status

---
 src/components/thread_tree/thread_tree.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/thread_tree/thread_tree.vue b/src/components/thread_tree/thread_tree.vue
index 74577583..4eaf597d 100644
--- a/src/components/thread_tree/thread_tree.vue
+++ b/src/components/thread_tree/thread_tree.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="thread-tree panel-body">
+  <div class="thread-tree">
     <status
       :key="status.id"
       ref="statusComponent"

From 6951fda0d6ad277153457a44c73eedc4edc0a927 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Thu, 7 Apr 2022 15:56:05 -0400
Subject: [PATCH 12/18] Fix mobile nav link text colour

---
 src/components/mobile_nav/mobile_nav.vue | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue
index 0f0ea457..f5279b3e 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -99,6 +99,9 @@
     width: 100%;
     position: fixed;
     box-sizing: border-box;
+    a {
+      color: var(--topBarLink, $fallback--link);
+    }
   }
 
   .mobile-inner-nav {

From 3b02566e16d33956604815e4bd5190f8f8144253 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Sat, 9 Apr 2022 23:49:22 -0400
Subject: [PATCH 13/18] Fix tab switcher not working when some tabs hidden

---
 src/components/tab_switcher/tab_switcher.jsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/tab_switcher/tab_switcher.jsx b/src/components/tab_switcher/tab_switcher.jsx
index f5a1e603..c8d390bc 100644
--- a/src/components/tab_switcher/tab_switcher.jsx
+++ b/src/components/tab_switcher/tab_switcher.jsx
@@ -50,7 +50,7 @@ export default {
     activeIndex () {
       // In case of controlled component
       if (this.activeTab) {
-        return this.slots().findIndex(slot => this.activeTab === slot.props.key)
+        return this.slots().findIndex(slot => slot && slot.props && this.activeTab === slot.props.key)
       } else {
         return this.active
       }

From 169d13680a72029cab71067abffbb4581cdb6b41 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Sun, 10 Apr 2022 13:02:02 -0400
Subject: [PATCH 14/18] Fix image cropper not closing correctly

---
 src/components/image_cropper/image_cropper.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/image_cropper/image_cropper.js b/src/components/image_cropper/image_cropper.js
index e72ed0e8..05f6fd4c 100644
--- a/src/components/image_cropper/image_cropper.js
+++ b/src/components/image_cropper/image_cropper.js
@@ -66,7 +66,7 @@ const ImageCropper = {
     }
   },
   methods: {
-    unmounted () {
+    destroy () {
       if (this.cropper) {
         this.cropper.destroy()
       }

From d175e86901dda5b54f7caad744f78f347332f821 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 12 Apr 2022 18:10:19 +0300
Subject: [PATCH 15/18] fix hashtags by explicitly putting attributes

---
 src/components/rich_content/rich_content.jsx | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx
index 41e287e4..ca075270 100644
--- a/src/components/rich_content/rich_content.jsx
+++ b/src/components/rich_content/rich_content.jsx
@@ -28,6 +28,10 @@ import './rich_content.scss'
  */
 export default {
   name: 'RichContent',
+  components: {
+    MentionsLine,
+    HashtagLink
+  },
   props: {
     // Original html content
     html: {
@@ -86,7 +90,8 @@ export default {
       if (!encounteredTextReverse) {
         lastTags.push(linkData)
       }
-      return <HashtagLink { ...linkData }/>
+      const { url, tag, content } = linkData
+      return <HashtagLink url={url} tag={tag} content={content}/>
     }
 
     const renderMention = (attrs, children) => {

From 0bb69d7fe026181bb6367ced8a921d0c3a0dc6ba Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 12 Apr 2022 19:04:32 +0300
Subject: [PATCH 16/18] fix tests

---
 test/unit/specs/components/rich_content.spec.js | 2 --
 1 file changed, 2 deletions(-)

diff --git a/test/unit/specs/components/rich_content.spec.js b/test/unit/specs/components/rich_content.spec.js
index a4920867..958fb997 100644
--- a/test/unit/specs/components/rich_content.spec.js
+++ b/test/unit/specs/components/rich_content.spec.js
@@ -308,10 +308,8 @@ describe('RichContent', () => {
       '<a href="http://macrochan.org/images/N/H/NHCMDUXJPPZ6M3Z2CQ6D2EBRSWGE7MZY.jpg" target="_blank">',
       'NHCMDUXJPPZ6M3Z2CQ6D2EBRSWGE7MZY.jpg</a>',
       ' <hashtag-link-stub url="https://shitposter.club/tag/nou" content="#nou" tag="nou">',
-      '#nou',
       '</hashtag-link-stub>',
       ' <hashtag-link-stub url="https://shitposter.club/tag/screencap" content="#screencap" tag="screencap">',
-      '#screencap',
       '</hashtag-link-stub>',
       ' </p>'
     ].join('')

From a4ea0a30bf02893cea783824c4824a5d1d87ff6c Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Tue, 19 Apr 2022 20:20:18 -0400
Subject: [PATCH 17/18] Fix incorrect close of a status popover when clicking
 Expand inside it

basically Vue (3 in particular?) will make changes to DOM before this event
listener is called, and if the target is displayed using v-if, it will not
be part of the DOM at that time, and contains() will return false. so it
goes to call hidePopover() which caused this bug.
---
 src/components/status_body/status_body.vue | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue
index 24d842c2..976fe98c 100644
--- a/src/components/status_body/status_body.vue
+++ b/src/components/status_body/status_body.vue
@@ -15,14 +15,14 @@
           :emoji="status.emojis"
         />
         <button
-          v-if="longSubject && showingLongSubject"
+          v-show="longSubject && showingLongSubject"
           class="button-unstyled -link tall-subject-hider"
           @click.prevent="toggleShowingLongSubject"
         >
           {{ $t("status.hide_full_subject") }}
         </button>
         <button
-          v-else-if="longSubject"
+          v-show="longSubject && !showingLongSubject"
           class="button-unstyled -link tall-subject-hider"
           @click.prevent="toggleShowingLongSubject"
         >
@@ -34,7 +34,7 @@
         class="text-wrapper"
       >
         <button
-          v-if="hideTallStatus"
+          v-show="hideTallStatus"
           class="button-unstyled -link tall-status-hider"
           :class="{ '-focused': focused }"
           @click.prevent="toggleShowMore"
@@ -54,7 +54,7 @@
         />
 
         <button
-          v-if="hideSubjectStatus"
+          v-show="hideSubjectStatus"
           class="button-unstyled -link cw-status-hider"
           @click.prevent="toggleShowMore"
         >
@@ -85,7 +85,7 @@
           />
         </button>
         <button
-          v-if="showingMore && !fullContent"
+          v-show="showingMore && !fullContent"
           class="button-unstyled -link status-unhider"
           @click.prevent="toggleShowMore"
         >

From 895eda3714e9977d931a5e4a0f215c304df021af Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 20 Apr 2022 20:19:22 +0300
Subject: [PATCH 18/18] fix some chat errors/warnings that sometimes happen

---
 src/components/chat_title/chat_title.vue | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/components/chat_title/chat_title.vue b/src/components/chat_title/chat_title.vue
index a92028e8..f4706caf 100644
--- a/src/components/chat_title/chat_title.vue
+++ b/src/components/chat_title/chat_title.vue
@@ -14,10 +14,11 @@
       />
     </router-link>
     <RichContent
+      v-if="user"
       class="username"
       :title="'@'+user.screen_name_ui"
       :html="htmlTitle"
-      :emoji="user.emoji"
+      :emoji="user.emoji || []"
     />
   </div>
 </template>
