Merge pull request #16 from ElectricS01/main

Update vue-cli, ESLint, and Electron
This commit is contained in:
Troplo 2023-12-10 15:38:41 +11:00 committed by GitHub
commit 114674bc70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 3575 additions and 5040 deletions

View File

@ -4,12 +4,13 @@
"private": true,
"license": "GPL-3.0",
"scripts": {
"dev": "nodemon",
"start": "node .",
"serve": "nodemon . --ignore config"
},
"dependencies": {
"argon2": "^0.28.7",
"axios": "^0.27.2",
"axios": "^1.6.2",
"clean-css": "^4.1.11",
"constantinople": "3.1.1",
"cookie-parser": "^1.4.6",
@ -24,10 +25,9 @@
"input": "^1.0.1",
"jade": "~1.11.0",
"jw-paginate": "^1.0.4",
"local-cors-proxy": "^1.1.0",
"mailgen": "^2.0.27",
"mariadb": "^3.0.1",
"multer": "^1.4.4",
"multer": "^1.4.5-lts.1",
"node-xwhois": "^2.0.10",
"nodemailer": "^6.7.7",
"open-graph-scraper": "^5.0.5",

View File

@ -240,16 +240,6 @@ aggregate-error@^3.0.0:
clean-stack "^2.0.0"
indent-string "^4.0.0"
ajv@^6.12.3:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
@ -289,13 +279,6 @@ ansi-styles@^2.2.1:
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
dependencies:
color-convert "^1.9.0"
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
@ -350,11 +333,6 @@ argparse@~1.0.9:
dependencies:
sprintf-js "~1.0.2"
array-back@^3.0.1, array-back@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0"
integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@ -365,13 +343,6 @@ asap@~1.0.0:
resolved "https://registry.yarnpkg.com/asap/-/asap-1.0.0.tgz#b2a45da5fdfa20b0496fc3768cc27c12fa916a7d"
integrity sha512-Ej9qjcXY+8Tuy1cNqiwNMwFRXOy9UwgTeMA8LxreodygIPV48lx8PU1ecFxb5ZeU1DpMKxiq6vGLTxcitWZPbA==
asn1@~0.2.3:
version "0.2.6"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
dependencies:
safer-buffer "~2.1.0"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
@ -392,23 +363,14 @@ at-least-node@^1.0.0:
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==
aws4@^1.8.0:
version "1.12.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3"
integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==
axios@^0.27.2:
version "0.27.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
axios@^1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2"
integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==
dependencies:
follow-redirects "^1.14.9"
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
b4a@^1.6.4:
version "1.6.4"
@ -462,13 +424,6 @@ base64id@2.0.0, base64id@~2.0.0:
resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6"
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==
dependencies:
tweetnacl "^0.14.3"
bluebird@^3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
@ -529,13 +484,12 @@ buffer-writer@2.0.0:
resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04"
integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==
busboy@^0.2.11:
version "0.2.14"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453"
integrity sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==
busboy@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==
dependencies:
dicer "0.2.5"
readable-stream "1.1.x"
streamsearch "^1.1.0"
bytes@3.1.2:
version "3.1.2"
@ -603,11 +557,6 @@ camelcase@^5.0.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==
center-align@^0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
@ -627,15 +576,6 @@ chalk@^1.0.0, chalk@^1.1.1:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.3.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^4.0.2, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
@ -780,13 +720,6 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
dependencies:
color-name "1.1.3"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
@ -794,11 +727,6 @@ color-convert@^2.0.1:
dependencies:
color-name "~1.1.4"
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
@ -814,23 +742,13 @@ colors@~1.2.1:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.5.tgz#89c7ad9a374bc030df8013241f68136ed8835afc"
integrity sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
command-line-args@^5.0.2:
version "5.2.1"
resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e"
integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==
dependencies:
array-back "^3.1.0"
find-replace "^3.0.0"
lodash.camelcase "^4.3.0"
typical "^4.0.0"
commander@^10.0.0:
version "10.0.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
@ -949,7 +867,7 @@ core-util-is@~1.0.0:
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
cors@^2.8.4, cors@~2.8.5:
cors@~2.8.5:
version "2.8.5"
resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
@ -1044,13 +962,6 @@ d@1, d@^1.0.1:
es5-ext "^0.10.50"
type "^1.0.1"
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==
dependencies:
assert-plus "^1.0.0"
dayjs@^1.11.4:
version "1.11.10"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0"
@ -1131,14 +1042,6 @@ detect-libc@^2.0.0:
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d"
integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==
dicer@0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f"
integrity sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==
dependencies:
readable-stream "1.1.x"
streamsearch "0.1.2"
dom-serializer@^1.0.1, dom-serializer@^1.3.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30"
@ -1216,14 +1119,6 @@ eastasianwidth@^0.2.0:
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==
dependencies:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
editorconfig@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-1.0.4.tgz#040c9a8e9a6c5288388b87c2db07028aa89f53a3"
@ -1398,7 +1293,7 @@ express-rate-limit@^6.4.0:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-6.11.2.tgz#6c42035603d3b52e4e2fb59f6ebaa89e628ef980"
integrity sha512-a7uwwfNTh1U60ssiIkuLFWHt4hAC5yxlLGU2VP0X4YNlyEDZAqF4tK3GD3NSitVBrCQmQ0++0uOyFOgC2y4DDw==
express@^4.16.3, express@^4.17.1:
express@^4.17.1:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@ -1442,11 +1337,6 @@ ext@^1.1.2:
dependencies:
type "^2.7.2"
extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
@ -1457,21 +1347,11 @@ extsprintf@^1.2.0:
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07"
integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==
fast-deep-equal@^3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-fifo@^1.1.0, fast-fifo@^1.2.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c"
integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
figures@^1.3.5:
version "1.7.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
@ -1516,13 +1396,6 @@ finalhandler@1.2.0:
statuses "2.0.1"
unpipe "~1.0.0"
find-replace@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38"
integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==
dependencies:
array-back "^3.0.1"
find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
@ -1538,7 +1411,7 @@ find-yarn-workspace-root@^2.0.0:
dependencies:
micromatch "^4.0.2"
follow-redirects@^1.14.9:
follow-redirects@^1.15.0:
version "1.15.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
@ -1551,11 +1424,6 @@ foreground-child@^3.1.0:
cross-spawn "^7.0.0"
signal-exit "^4.0.1"
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
form-data-encoder@^2.1.2:
version "2.1.4"
resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5"
@ -1570,15 +1438,6 @@ form-data@^4.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
@ -1665,13 +1524,6 @@ get-stream@^6.0.1:
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==
dependencies:
assert-plus "^1.0.0"
glob@^10.3.3:
version "10.3.10"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b"
@ -1735,19 +1587,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==
har-validator@~5.1.3:
version "5.1.5"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
dependencies:
ajv "^6.12.3"
har-schema "^2.0.0"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
@ -1755,11 +1594,6 @@ has-ansi@^2.0.0:
dependencies:
ansi-regex "^2.0.0"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
has-flag@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
@ -1864,15 +1698,6 @@ http-proxy-agent@^4.0.1:
agent-base "6"
debug "4"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
http2-wrapper@^2.1.10:
version "2.2.1"
resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.1.tgz#310968153dcdedb160d8b72114363ef5fce1f64a"
@ -1948,7 +1773,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -2078,11 +1903,6 @@ is-promise@~1:
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-1.0.1.tgz#31573761c057e33c2e91aab9e96da08cefbe76e5"
integrity sha512-mjWH5XxnhMA8cFnDchr6qRP9S/kLntKuEfIYku+PaN1CnS8v+OG9O/BKpRCVRJvpIkgAZm0Pf5Is3iSSOILlcg==
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==
is-wsl@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
@ -2090,11 +1910,6 @@ is-wsl@^2.1.1:
dependencies:
is-docker "^2.0.0"
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
@ -2105,11 +1920,6 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
jackspeak@^2.3.5:
version "2.3.6"
resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8"
@ -2155,31 +1965,16 @@ js-beautify@^1.14.5:
glob "^10.3.3"
nopt "^7.2.0"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==
json-buffer@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
@ -2189,16 +1984,6 @@ jsonfile@^6.0.1:
optionalDependencies:
graceful-fs "^4.1.6"
jsprim@^1.2.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb"
integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.4.0"
verror "1.10.0"
jsprim@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d"
@ -2276,17 +2061,6 @@ lie@~3.3.0:
dependencies:
immediate "~3.0.5"
local-cors-proxy@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/local-cors-proxy/-/local-cors-proxy-1.1.0.tgz#570a0abb19ba102ddccd3113e92fbf44cb075756"
integrity sha512-1UVrdG10HAT58TNZBhYSeMPkwQANuJunFsWBgEYOd1RChLDHGhvNPjUT8JsOlcqoJyr0QOH9cLx9IOLATf4j5w==
dependencies:
chalk "^2.3.2"
command-line-args "^5.0.2"
cors "^2.8.4"
express "^4.16.3"
request "^2.85.0"
locate-path@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
@ -2294,11 +2068,6 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
lodash.clone@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6"
@ -2442,7 +2211,7 @@ mime-db@1.52.0:
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
@ -2610,17 +2379,16 @@ ms@2.1.3, ms@^2.0.0:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
multer@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.4.tgz#e2bc6cac0df57a8832b858d7418ccaa8ebaf7d8c"
integrity sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==
multer@^1.4.5-lts.1:
version "1.4.5-lts.1"
resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.5-lts.1.tgz#803e24ad1984f58edffbc79f56e305aec5cfd1ac"
integrity sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==
dependencies:
append-field "^1.0.0"
busboy "^0.2.11"
busboy "^1.0.0"
concat-stream "^1.5.2"
mkdirp "^0.5.4"
object-assign "^4.1.1"
on-finished "^2.3.0"
type-is "^1.6.4"
xtend "^4.0.0"
@ -2745,11 +2513,6 @@ number-is-nan@^1.0.0:
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==
oauth-sign@~0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@ -2760,7 +2523,7 @@ object-inspect@^1.9.0:
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==
on-finished@2.4.1, on-finished@^2.3.0:
on-finished@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
@ -2939,11 +2702,6 @@ peek-readable@^4.1.0:
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72"
integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==
pg-cloudflare@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98"
@ -3086,15 +2844,10 @@ proxy-addr@~2.0.7:
forwarded "0.2.0"
ipaddr.js "1.9.1"
psl@^1.1.28:
version "1.9.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
punycode@^2.1.0, punycode@^2.1.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
qs@6.11.0:
version "6.11.0"
@ -3103,11 +2856,6 @@ qs@6.11.0:
dependencies:
side-channel "^1.0.4"
qs@~6.5.2:
version "6.5.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
queue-tick@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142"
@ -3133,16 +2881,6 @@ raw-body@2.5.1:
iconv-lite "0.4.24"
unpipe "1.0.0"
readable-stream@1.1.x:
version "1.1.14"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "0.0.1"
string_decoder "~0.10.x"
readable-stream@^2.2.2, readable-stream@~2.3.6:
version "2.3.8"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
@ -3191,32 +2929,6 @@ repeat-string@^1.5.2:
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
request@^2.85.0:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.8.0"
caseless "~0.12.0"
combined-stream "~1.0.6"
extend "~3.0.2"
forever-agent "~0.6.1"
form-data "~2.3.2"
har-validator "~5.1.3"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.19"
oauth-sign "~0.9.0"
performance-now "^2.1.0"
qs "~6.5.2"
safe-buffer "^5.1.2"
tough-cookie "~2.5.0"
tunnel-agent "^0.6.0"
uuid "^3.3.2"
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
@ -3299,7 +3011,7 @@ rx-lite@^3.1.2:
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
integrity sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==
safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
safe-buffer@5.2.1, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@ -3309,7 +3021,7 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
@ -3571,21 +3283,6 @@ sqlite3@^5.0.10:
optionalDependencies:
node-gyp "8.x"
sshpk@^1.7.0:
version "1.18.0"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028"
integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
bcrypt-pbkdf "^1.0.0"
dashdash "^1.12.0"
ecc-jsbn "~0.1.1"
getpass "^0.1.1"
jsbn "~0.1.0"
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
ssri@^8.0.0, ssri@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af"
@ -3603,10 +3300,10 @@ statuses@2.0.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
streamsearch@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
integrity sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==
streamsearch@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
streamx@^2.15.0:
version "2.15.6"
@ -3655,11 +3352,6 @@ string_decoder@^1.1.1:
dependencies:
safe-buffer "~5.2.0"
string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
@ -3701,13 +3393,6 @@ supports-color@^2.0.0:
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
dependencies:
has-flag "^3.0.0"
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
@ -3796,14 +3481,6 @@ toposort-class@^1.0.1:
resolved "https://registry.yarnpkg.com/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988"
integrity sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==
tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
dependencies:
psl "^1.1.28"
punycode "^2.1.1"
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
@ -3823,18 +3500,6 @@ tslib@^2.2.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==
type-fest@^0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
@ -3868,11 +3533,6 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
typical@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4"
integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==
ua-parser-js@^1.0.2:
version "1.0.37"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.37.tgz#b5dc7b163a5c1f0c510b08446aed4da92c46373f"
@ -3945,13 +3605,6 @@ unpipe@1.0.0, unpipe@~1.0.0:
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
dependencies:
punycode "^2.1.0"
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
@ -3962,11 +3615,6 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
uuid@^3.3.2:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"

View File

@ -2,13 +2,13 @@
"name": "colubrina-cli",
"private": true,
"dependencies": {
"argon2": "^0.28.7",
"axios": "^0.27.2",
"argon2": "^0.31.2",
"axios": "^1.6.2",
"input": "^1.0.1",
"mariadb": "^3.0.1",
"pg": "^8.7.3",
"sequelize": "^6.21.3",
"sqlite3": "^5.0.10",
"umzug": "^3.1.1"
"mariadb": "^3.2.2",
"pg": "^8.11.3",
"sequelize": "^6.35.1",
"sqlite3": "^5.1.6",
"umzug": "^3.4.0"
}
}

View File

@ -7,10 +7,10 @@
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
"@mapbox/node-pre-gyp@^1.0.0", "@mapbox/node-pre-gyp@^1.0.9":
version "1.0.10"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c"
integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==
"@mapbox/node-pre-gyp@^1.0.0", "@mapbox/node-pre-gyp@^1.0.11":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa"
integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==
dependencies:
detect-libc "^2.0.0"
https-proxy-agent "^5.0.0"
@ -44,9 +44,9 @@
integrity sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==
"@rushstack/ts-command-line@^4.12.2":
version "4.14.0"
resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.14.0.tgz#1719595bffc61e7a03e1df29a0fd29319f2e4843"
integrity sha512-DWozCsKg+ALgrsul+6vJhyB7ZogqSycRlnqULjGsJ9dLRv+Pc0Wj6J7pX0xarmgX2kH3tTf0rXgBcl8QjJULIQ==
version "4.17.1"
resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.17.1.tgz#c78db928ce5b93f2e98fd9e14c24f3f3876e57f1"
integrity sha512-2jweO1O57BYP5qdBGl6apJLB+aRIn5ccIRTPDyULh0KMwVzFqWtw6IZWt1qtUoZD/pD2RNkIOosH6Cq45rIYeg==
dependencies:
"@types/argparse" "1.0.38"
argparse "~1.0.9"
@ -63,37 +63,39 @@
resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9"
integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==
"@types/debug@^4.1.7":
version "4.1.8"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.8.tgz#cef723a5d0a90990313faec2d1e22aee5eecb317"
integrity sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==
"@types/debug@^4.1.8":
version "4.1.12"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917"
integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==
dependencies:
"@types/ms" "*"
"@types/geojson@^7946.0.10":
version "7946.0.10"
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.10.tgz#6dfbf5ea17142f7f9a043809f1cd4c448cb68249"
integrity sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==
version "7946.0.13"
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.13.tgz#e6e77ea9ecf36564980a861e24e62a095988775e"
integrity sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==
"@types/ms@*":
version "0.7.31"
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
version "0.7.34"
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433"
integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
"@types/node@*":
version "20.3.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.0.tgz#719498898d5defab83c3560f45d8498f58d11938"
integrity sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ==
version "20.10.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.4.tgz#b246fd84d55d5b1b71bf51f964bd514409347198"
integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==
dependencies:
undici-types "~5.26.4"
"@types/node@^17.0.45":
version "17.0.45"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190"
integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==
"@types/validator@^13.7.1":
version "13.7.17"
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.7.17.tgz#0a6d1510395065171e3378a4afc587a3aefa7cc1"
integrity sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==
"@types/validator@^13.7.17":
version "13.11.7"
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.11.7.tgz#99e19760297667ae46b7069ec8b96cbfe0a08b98"
integrity sha512-q0JomTsJ2I5Mv7dhHhQLGjMvX0JJm5dyZ1DXQySIUzU1UlwzB8bt+R6+LODUbz0UDIOvEzGc28tk27gBJw2N8Q==
abbrev@1:
version "1.1.1"
@ -108,12 +110,10 @@ agent-base@6, agent-base@^6.0.2:
debug "4"
agentkeepalive@^4.1.3:
version "4.3.0"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.3.0.tgz#bb999ff07412653c1803b3ced35e50729830a255"
integrity sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==
version "4.5.0"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923"
integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==
dependencies:
debug "^4.1.0"
depd "^2.0.0"
humanize-ms "^1.2.1"
aggregate-error@^3.0.0:
@ -165,14 +165,14 @@ are-we-there-yet@^3.0.0:
delegates "^1.0.0"
readable-stream "^3.6.0"
argon2@^0.28.7:
version "0.28.7"
resolved "https://registry.yarnpkg.com/argon2/-/argon2-0.28.7.tgz#f6cc1f1c9e3ef5455d2186d4ec5b27cfeda41591"
integrity sha512-pvsScM3Fq7b+jolXkZHh8nRQx0uD/WeelnwYPMRpn4pAydoa1gqeL/KRdWAag4Hnu1TJNBTAfqyTjV+ZHwNnYA==
argon2@^0.31.2:
version "0.31.2"
resolved "https://registry.yarnpkg.com/argon2/-/argon2-0.31.2.tgz#bb6590a63b8ff71c4a3a1907572893ff8dd9ffff"
integrity sha512-QSnJ8By5Mth60IEte45w9Y7v6bWcQw3YhRtJKKN8oNCxnTLDiv/AXXkDPf2srTMfxFVn3QJdVv2nhXESsUa+Yg==
dependencies:
"@mapbox/node-pre-gyp" "^1.0.9"
"@mapbox/node-pre-gyp" "^1.0.11"
"@phc/format" "^1.0.0"
node-addon-api "^5.0.0"
node-addon-api "^7.0.0"
argparse@~1.0.9:
version "1.0.10"
@ -186,13 +186,14 @@ asynckit@^0.4.0:
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
axios@^0.27.2:
version "0.27.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
axios@^1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2"
integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==
dependencies:
follow-redirects "^1.14.9"
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
babel-runtime@^6.6.1:
version "6.26.0"
@ -321,7 +322,7 @@ core-js@^2.4.0:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
debug@4, debug@^4.1.0, debug@^4.3.3:
debug@4, debug@^4.3.3, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@ -343,25 +344,20 @@ denque@^2.1.0:
resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1"
integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==
depd@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
detect-libc@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==
version "2.0.2"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d"
integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==
dottie@^2.0.2:
version "2.0.4"
resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.4.tgz#9ce42965f45e577a6fa7d988d47852fac70c4e82"
integrity sha512-iz64WUOmp/ECQhWMJjTWFzJN/wQ7RJ5v/a6A2OiCwjaGCpNo66WGIjlSf+IULO9DQd0b4cFawLOTbiKSrpKodw==
dottie@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.6.tgz#34564ebfc6ec5e5772272d466424ad5b696484d4"
integrity sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==
emittery@^0.12.1:
version "0.12.1"
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.12.1.tgz#cb9a4a18745816f7a1fa03a8953e7eaededb45f2"
integrity sha512-pYyW59MIZo0HxPFf+Vb3+gacUu0gxVS3TZwB2ClwkEZywgF9f9OJDoVmNLojTn0vKX3tO9LC+pdQEcLP4Oz/bQ==
emittery@^0.13.0:
version "0.13.1"
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad"
integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==
emoji-regex@^8.0.0:
version "8.0.0"
@ -403,10 +399,10 @@ figures@^1.3.5:
escape-string-regexp "^1.0.5"
object-assign "^4.1.0"
follow-redirects@^1.14.9:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
follow-redirects@^1.15.0:
version "1.15.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
form-data@^4.0.0:
version "4.0.0"
@ -417,14 +413,6 @@ form-data@^4.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
fs-jetpack@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/fs-jetpack/-/fs-jetpack-4.3.1.tgz#cdfd4b64e6bfdec7c7dc55c76b39efaa7853bb20"
integrity sha512-dbeOK84F6BiQzk2yqqCVwCPWTxAvVGJ3fMQc6E2wuEohS28mR6yHngbrKuVCK1KHRx/ccByDylqu4H5PCP2urQ==
dependencies:
minimatch "^3.0.2"
rimraf "^2.6.3"
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
@ -557,7 +545,7 @@ infer-owner@^1.0.4:
resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"
integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==
inflection@^1.13.2:
inflection@^1.13.4:
version "1.13.4"
resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.13.4.tgz#65aa696c4e2da6225b148d7a154c449366633a32"
integrity sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==
@ -636,6 +624,11 @@ lodash@^4.17.21, lodash@^4.3.0, lodash@^4.6.1:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
lru-cache@^10.0.1:
version "10.1.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484"
integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@ -643,11 +636,6 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
lru-cache@^7.14.0:
version "7.18.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89"
integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==
make-dir@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
@ -677,16 +665,16 @@ make-fetch-happen@^9.1.0:
socks-proxy-agent "^6.0.0"
ssri "^8.0.0"
mariadb@^3.0.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/mariadb/-/mariadb-3.1.2.tgz#96f9f6c3f280a3a3c37b56ff7974400edbb88bda"
integrity sha512-ILlC54fkXkvizTJZC1uP7f/REBxuu1k+OWzpiIITIEdS+dGIjFe/Ob3EW9KrdtBa38l3z+odz6elva0RG/y5og==
mariadb@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/mariadb/-/mariadb-3.2.2.tgz#320a991c708c737e5ddeefa1852ddf925f2dcd8c"
integrity sha512-9ClJCFsLcK7WnPXVxuKGd7p0CBvNch3i5nwAf1HEqERj7RV60DG/0dJu4DfO33gpYQd9Cr4jq17O76/2VjSbkg==
dependencies:
"@types/geojson" "^7946.0.10"
"@types/node" "^17.0.45"
denque "^2.1.0"
iconv-lite "^0.6.3"
lru-cache "^7.14.0"
lru-cache "^10.0.1"
mime-db@1.52.0:
version "1.52.0"
@ -700,7 +688,7 @@ mime-types@^2.1.12:
dependencies:
mime-db "1.52.0"
minimatch@^3.0.2, minimatch@^3.1.1:
minimatch@^3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
@ -778,14 +766,14 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
moment-timezone@^0.5.35:
moment-timezone@^0.5.43:
version "0.5.43"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.43.tgz#3dd7f3d0c67f78c23cd1906b9b2137a09b3c4790"
integrity sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==
dependencies:
moment "^2.29.4"
moment@^2.29.1, moment@^2.29.4:
moment@^2.29.4:
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
@ -815,15 +803,15 @@ node-addon-api@^4.2.0:
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f"
integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==
node-addon-api@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762"
integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==
node-addon-api@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.0.0.tgz#8136add2f510997b3b94814f4af1cce0b0e3962e"
integrity sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==
node-fetch@^2.6.7:
version "2.6.11"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25"
integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==
version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
dependencies:
whatwg-url "^5.0.0"
@ -909,25 +897,25 @@ path-is-absolute@^1.0.0:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
pg-cloudflare@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.0.tgz#833d70870d610d14bf9df7afb40e1cba310c17a0"
integrity sha512-tGM8/s6frwuAIyRcJ6nWcIvd3+3NmUKIs6OjviIm1HPPFEt5MzQDOTBQyhPWg/m0kCl95M6gA1JaIXtS8KovOA==
pg-cloudflare@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98"
integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==
pg-connection-string@^2.5.0, pg-connection-string@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.0.tgz#12a36cc4627df19c25cc1b9b736cc39ee1f73ae8"
integrity sha512-x14ibktcwlHKoHxx9X3uTVW9zIGR41ZB6QNhHb21OPNdCCO3NaRnpJuwKIQSR4u+Yqjx4HCvy7Hh7VSy1U4dGg==
pg-connection-string@^2.6.1, pg-connection-string@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475"
integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==
pg-int8@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
pg-pool@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.0.tgz#3190df3e4747a0d23e5e9e8045bcd99bda0a712e"
integrity sha512-clFRf2ksqd+F497kWFyM21tMjeikn60oGDmqMT8UBrynEwVEX/5R5xd2sdvdo1cZCFlguORNpVuqxIj+aK4cfQ==
pg-pool@^3.6.1:
version "3.6.1"
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.1.tgz#5a902eda79a8d7e3c928b77abf776b3cb7d351f7"
integrity sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==
pg-protocol@^1.6.0:
version "1.6.0"
@ -945,20 +933,20 @@ pg-types@^2.1.0:
postgres-date "~1.0.4"
postgres-interval "^1.1.0"
pg@^8.7.3:
version "8.11.0"
resolved "https://registry.yarnpkg.com/pg/-/pg-8.11.0.tgz#a37e534e94b57a7ed811e926f23a7c56385f55d9"
integrity sha512-meLUVPn2TWgJyLmy7el3fQQVwft4gU5NGyvV0XbD41iU9Jbg8lCH4zexhIkihDzVHJStlt6r088G6/fWeNjhXA==
pg@^8.11.3:
version "8.11.3"
resolved "https://registry.yarnpkg.com/pg/-/pg-8.11.3.tgz#d7db6e3fe268fcedd65b8e4599cda0b8b4bf76cb"
integrity sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==
dependencies:
buffer-writer "2.0.0"
packet-reader "1.0.0"
pg-connection-string "^2.6.0"
pg-pool "^3.6.0"
pg-connection-string "^2.6.2"
pg-pool "^3.6.1"
pg-protocol "^1.6.0"
pg-types "^2.1.0"
pgpass "1.x"
optionalDependencies:
pg-cloudflare "^1.1.0"
pg-cloudflare "^1.1.1"
pgpass@1.x:
version "1.0.5"
@ -967,7 +955,7 @@ pgpass@1.x:
dependencies:
split2 "^4.1.0"
pony-cause@^2.1.2:
pony-cause@^2.1.4:
version "2.1.10"
resolved "https://registry.yarnpkg.com/pony-cause/-/pony-cause-2.1.10.tgz#828457ad6f13be401a075dbf14107a9057945174"
integrity sha512-3IKLNXclQgkU++2fSi93sQ6BznFuxSLB11HdvZQ6JW/spahf/P1pAHBQEahr20rs0htZW0UDkM1HmA+nZkXKsw==
@ -1007,6 +995,11 @@ promise-retry@^2.0.1:
err-code "^2.0.2"
retry "^0.12.0"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
readable-stream@^3.6.0:
version "3.6.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
@ -1038,7 +1031,7 @@ restore-cursor@^1.0.1:
exit-hook "^1.0.0"
onetime "^1.0.0"
retry-as-promised@^7.0.3:
retry-as-promised@^7.0.4:
version "7.0.4"
resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-7.0.4.tgz#9df73adaeea08cb2948b9d34990549dc13d800a2"
integrity sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==
@ -1048,13 +1041,6 @@ retry@^0.12.0:
resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==
rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
dependencies:
glob "^7.1.3"
rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
@ -1085,14 +1071,14 @@ safe-buffer@~5.2.0:
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
semver@^6.0.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
version "6.3.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
semver@^7.3.5:
version "7.5.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec"
integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==
semver@^7.3.5, semver@^7.5.4:
version "7.5.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"
@ -1101,26 +1087,26 @@ sequelize-pool@^7.1.0:
resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-7.1.0.tgz#210b391af4002762f823188fd6ecfc7413020768"
integrity sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==
sequelize@^6.21.3:
version "6.32.0"
resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.32.0.tgz#566488aa0fcf32c1baa2ff2344f462a4c9eb4a01"
integrity sha512-gMd1M6kPANyrCeU/vtgEP5gnse7sVsiKbJyz7p4huuW8zZcRopj47UlglvdrMuIoqksZmsUPfApmMo6ZlJpcvg==
sequelize@^6.35.1:
version "6.35.1"
resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.35.1.tgz#e640bc11a7a37f6fa23a92974b5e5ca20affd150"
integrity sha512-UlP5k33nJsN11wCDLaWZXw9bB8w4ESKc5QmG6D04qMimwBwKVNeqRJiaaBlEJdtg8cRK+OJh95dliP+uEi+g9Q==
dependencies:
"@types/debug" "^4.1.7"
"@types/validator" "^13.7.1"
debug "^4.3.3"
dottie "^2.0.2"
inflection "^1.13.2"
"@types/debug" "^4.1.8"
"@types/validator" "^13.7.17"
debug "^4.3.4"
dottie "^2.0.6"
inflection "^1.13.4"
lodash "^4.17.21"
moment "^2.29.1"
moment-timezone "^0.5.35"
pg-connection-string "^2.5.0"
retry-as-promised "^7.0.3"
semver "^7.3.5"
moment "^2.29.4"
moment-timezone "^0.5.43"
pg-connection-string "^2.6.1"
retry-as-promised "^7.0.4"
semver "^7.5.4"
sequelize-pool "^7.1.0"
toposort-class "^1.0.1"
uuid "^8.3.2"
validator "^13.7.0"
validator "^13.9.0"
wkx "^0.5.0"
set-blocking@^2.0.0:
@ -1165,7 +1151,7 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
sqlite3@^5.0.10:
sqlite3@^5.1.6:
version "5.1.6"
resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.1.6.tgz#1d4fbc90fe4fbd51e952e0a90fd8f6c2b9098e97"
integrity sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==
@ -1233,9 +1219,9 @@ supports-color@^2.0.0:
integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==
tar@^6.0.2, tar@^6.1.11, tar@^6.1.2:
version "6.1.15"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69"
integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==
version "6.2.0"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73"
integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==
dependencies:
chownr "^2.0.0"
fs-minipass "^2.0.0"
@ -1259,22 +1245,26 @@ tr46@~0.0.3:
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
type-fest@^2.18.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b"
integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==
type-fest@^3.0.0:
version "3.13.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706"
integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==
umzug@^3.1.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/umzug/-/umzug-3.2.1.tgz#01c3a109efb037a10a317d4191be22810c37b195"
integrity sha512-XyWQowvP9CKZycKc/Zg9SYWrAWX/gJCE799AUTFqk8yC3tp44K1xWr3LoFF0MNEjClKOo1suCr5ASnoy+KltdA==
umzug@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/umzug/-/umzug-3.4.0.tgz#97819a2d2288c8ce2c156c3be8b18b02f2208423"
integrity sha512-bTen9ElCBoWU1mhcaXqVZWXxB1PojsBQBs/4vW0YV8f5CfhuhkfRjQZj6SCb6IuHWPkccDzF+T+RGZCYUiXaKg==
dependencies:
"@rushstack/ts-command-line" "^4.12.2"
emittery "^0.12.1"
fs-jetpack "^4.3.1"
emittery "^0.13.0"
glob "^8.0.3"
pony-cause "^2.1.2"
type-fest "^2.18.0"
pony-cause "^2.1.4"
type-fest "^3.0.0"
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
unique-filename@^1.1.1:
version "1.1.1"
@ -1300,10 +1290,10 @@ uuid@^8.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
validator@^13.7.0:
version "13.9.0"
resolved "https://registry.yarnpkg.com/validator/-/validator-13.9.0.tgz#33e7b85b604f3bbce9bb1a05d5c3e22e1c2ff855"
integrity sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==
validator@^13.9.0:
version "13.11.0"
resolved "https://registry.yarnpkg.com/validator/-/validator-13.11.0.tgz#23ab3fd59290c61248364eabf4067f04955fbb1b"
integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==
webidl-conversions@^3.0.0:
version "3.0.1"

View File

@ -4,9 +4,9 @@ module.exports = {
es2020: true,
node: true
},
extends: ["plugin:vue/essential", "eslint:recommended"],
extends: ["plugin:vue/recommended", "eslint:recommended"],
parserOptions: {
parser: "babel-eslint"
parser: "@babel/eslint-parser"
},
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
@ -14,6 +14,10 @@ module.exports = {
"vue/no-parsing-error": [
"error",
{ "invalid-first-character-of-tag-name": false }
]
],
"vue/no-reserved-component-names": "off",
"vue/no-mutating-props": "off",
"vue/multi-word-component-names": "off",
"vue/no-v-text-v-html-on-component": "off"
}
}

View File

@ -5,6 +5,7 @@
"private": true,
"author": "Troplo <troplo@troplo.com>",
"scripts": {
"dev": "vue-cli-service serve",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build --no-clean",
"lint": "vue-cli-service lint",
@ -19,7 +20,7 @@
"@babel/preset-env": "^7.17.10",
"@mdi/font": "6.5.95",
"@mdi/js": "^6.6.95",
"axios": "^0.26.1",
"axios": "^1.6.2",
"brace": "^0.11.1",
"chart.js": "^3.7.1",
"core-js": "^3.6.5",
@ -31,17 +32,15 @@
"markdown-it": "^13.0.1",
"markdown-it-emoji": "git+https://github.com/Troplo/markdown-it-unicode-emoji",
"markdown-it-highlightjs": "^4.0.1",
"node-ipc": "git+https://git.troplo.com/Troplo/node-ipc",
"nth-check": "^2.0.1",
"patch-package": "^6.4.7",
"prettier": "^2.6.1",
"register-service-worker": "^1.7.1",
"request": "^2.88.2",
"selfsigned": "^2.0.1",
"socket.io-client": "^4.5.1",
"twemoji": "^14.0.2",
"vue": "^2.6.11",
"vue-axios": "^3.4.1",
"vue-axios": "^3.5.2",
"vue-chartjs": "^4.0.1",
"vue-final-modal": "^2.4.1",
"vue-native-notification": "^1.1.1",
@ -54,24 +53,25 @@
"vuex": "^3.4.0"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@babel/plugin-proposal-optional-chaining": "^7.16.7",
"@vue/cli-plugin-babel": "~4.5.15",
"@vue/cli-plugin-eslint": "~4.5.15",
"@vue/cli-plugin-pwa": "~4.5.15",
"@vue/cli-plugin-router": "~4.5.15",
"@vue/cli-plugin-vuex": "~4.5.15",
"@vue/cli-service": "~4.5.15",
"babel-eslint": "^10.1.0",
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-eslint": "~5.0.8",
"@vue/cli-plugin-pwa": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
"@vue/cli-plugin-vuex": "~5.0.8",
"@vue/cli-service": "~5.0.8",
"dotenv-webpack": "^7.1.0",
"electron": "^23.0.0",
"electron": "^28.0.0",
"electron-devtools-installer": "^3.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"eslint": "^8.55.0",
"eslint-plugin-vue": "^9.19.2",
"material-design-icons-iconfont": "^6.5.0",
"sass": "~1.32.0",
"sass-loader": "^10.0.0",
"vue-cli-plugin-electron-builder": "^2.1.1",
"vue-cli-plugin-vuetify": "~2.4.7",
"vue-cli-plugin-electron-builder": "https://github.com/nklayman/vue-cli-plugin-electron-builder.git#b51147f",
"vue-cli-plugin-vuetify": "~2.5.8",
"vue-template-babel-compiler": "^1.1.3",
"vue-template-compiler": "^2.6.11",
"vuetify-loader": "^1.7.0",
@ -80,7 +80,6 @@
},
"license": "GPL-3.0",
"resolutions": {
"node-ipc": "git+https://git.troplo.com/Troplo/node-ipc",
"selfsigned": "^2.0.1",
"nth-check": "^2.0.1",
"glob-parent": "^5.1.2",

View File

@ -6,11 +6,11 @@
"
>
<v-overlay :value="!$store.state.wsConnected" absolute style="z-index: 69">
<v-progress-circular indeterminate size="64"></v-progress-circular>
<v-progress-circular indeterminate size="64" />
</v-overlay>
<DevOverlay v-if="$store.state.site.release === 'dev'"></DevOverlay>
<DevOverlay v-if="$store.state.site.release === 'dev'" />
<v-overlay :value="$store.state.site.loading">
<v-progress-circular indeterminate size="64"></v-progress-circular>
<v-progress-circular indeterminate size="64" />
</v-overlay>
<!-- theme engine editors -->
<vue-final-modal
@ -39,8 +39,8 @@
$store.state.themeEngine.type === "create" ? "Creator" : "Editor"
}}
<v-tooltip top>
<template v-slot:activator="{ on, attrs }">
<span v-on="on" v-bind="attrs">
<template #activator="{ on, attrs }">
<span v-bind="attrs" v-on="on">
<v-btn
fab
small
@ -54,7 +54,7 @@
<span> Randomize theme </span>
</v-tooltip>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-spacer />
<v-btn icon @click="$store.state.themeEngine.editor = false">
<v-icon>mdi-close</v-icon>
</v-btn>
@ -72,27 +72,30 @@
$store.dispatch('saveTheme', { theme: null, type: null })
$store.state.themeEngine.editor = false
"
>{{
>
{{
$store.state.themeEngine.type === "create"
? "Create & Apply"
: "Save Edits"
}}</v-btn
>
}}
</v-btn>
<v-btn
v-if="$store.state.themeEngine.type === 'edit'"
color="primary"
text
@click="
$store.dispatch('saveTheme', { theme: null, type: 'copy' })
"
v-if="$store.state.themeEngine.type === 'edit'"
>Save a Copy</v-btn
>
Save a Copy
</v-btn>
<v-btn
color="error darken-1"
text
@click="$store.dispatch('discardTheme')"
>Discard</v-btn
>
Discard
</v-btn>
</v-card-actions>
<v-form>
<v-text-field
@ -100,28 +103,23 @@
class="mx-3"
label="Theme Name"
required
></v-text-field>
/>
<v-select
v-model="$store.state.themeEngine.theme.primaryType"
:items="intendedFor"
label="Intended for"
class="mx-3"
v-model="$store.state.themeEngine.theme.primaryType"
>
</v-select>
<v-text-field
v-model="creatorJSON"
label="JSON"
class="mx-3"
></v-text-field>
/>
<v-text-field v-model="creatorJSON" label="JSON" class="mx-3" />
<v-btn @click="$store.state.themeEngine.cssEditor = true">
Custom CSS
</v-btn>
<h2
class="ml-2 mt-2 mb-3"
v-if="
$store.state.themeEngine.theme.primaryType === 'dark' ||
$store.state.themeEngine.theme.primaryType === 'all'
"
class="ml-2 mt-2 mb-3"
>
Dark:
</h2>
@ -132,44 +130,44 @@
"
>
<v-col
sm="3"
v-for="(item, index) in $store.state.themeEngine.theme.dark"
:key="index + '-dark-card'"
sm="3"
>
<v-card color="card">
<h3 class="ml-2 mt-2 mb-2">
{{ friendlyName(index) }}
</h3>
<v-menu offset-y>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<v-card
class="mb-2 mx-2"
:color="$store.state.themeEngine.theme.dark[index]"
v-on="on"
>
<v-container></v-container>
<v-container />
</v-card>
</template>
<v-color-picker
v-model="$store.state.themeEngine.theme.dark[index]"
show-swatches
hide-inputs
></v-color-picker>
/>
</v-menu>
<v-text-field
v-model="$store.state.themeEngine.theme.dark[index]"
class="mx-2"
label="#HEX"
v-model="$store.state.themeEngine.theme.dark[index]"
></v-text-field>
/>
</v-card>
</v-col>
</v-row>
<h2
class="ml-2 mt-2 mb-3"
v-if="
$store.state.themeEngine.theme.primaryType === 'light' ||
$store.state.themeEngine.theme.primaryType === 'all'
"
class="ml-2 mt-2 mb-3"
>
Light:
</h2>
@ -180,35 +178,35 @@
"
>
<v-col
sm="3"
v-for="(item, index) in $store.state.themeEngine.theme.light"
:key="index + '-light-card'"
sm="3"
>
<v-card color="card">
<h3 class="ml-2 mt-2 mb-2">
{{ friendlyName(index) }}
</h3>
<v-menu offset-y>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<v-card
class="mb-2 mx-2"
:color="$store.state.themeEngine.theme.light[index]"
v-on="on"
>
<v-container></v-container>
<v-container />
</v-card>
</template>
<v-color-picker
v-model="$store.state.themeEngine.theme.light[index]"
show-swatches
hide-inputs
></v-color-picker>
/>
</v-menu>
<v-text-field
v-model="$store.state.themeEngine.theme.light[index]"
class="mx-2"
label="#HEX"
v-model="$store.state.themeEngine.theme.light[index]"
></v-text-field>
/>
</v-card>
</v-col>
</v-row>
@ -221,27 +219,30 @@
$store.dispatch('saveTheme', { theme: null, type: null })
$store.state.themeEngine.editor = false
"
>{{
>
{{
$store.state.themeEngine.type === "create"
? "Create & Apply"
: "Save Edits"
}}</v-btn
>
}}
</v-btn>
<v-btn
v-if="$store.state.themeEngine.type === 'edit'"
color="primary"
text
@click="
$store.dispatch('saveTheme', { theme: null, type: 'copy' })
"
v-if="$store.state.themeEngine.type === 'edit'"
>Save a Copy</v-btn
>
Save a Copy
</v-btn>
<v-btn
color="error darken-1"
text
@click="$store.dispatch('discardTheme')"
>Discard</v-btn
>
Discard
</v-btn>
</v-card-actions>
</v-container>
</v-card>
@ -271,7 +272,7 @@
>
<v-card-title color="toolbar" class="editor__toolbar v-toolbar">
<v-toolbar-title>CSS Editor</v-toolbar-title>
<v-spacer></v-spacer>
<v-spacer />
<v-btn icon @click="$store.state.themeEngine.cssEditor = false">
<v-icon>mdi-close</v-icon>
</v-btn>
@ -281,13 +282,13 @@
<v-col>
<v-alert type="info" text class="editor__toolbar">
CTRL + ALT + D / F9 will toggle all custom CSS styling, works
anywhere, even outside the editor.</v-alert
>
anywhere, even outside the editor.
</v-alert>
<v-switch
v-model="$store.state.themeEngine.autoCSS"
inset
label="Live update"
v-model="$store.state.themeEngine.autoCSS"
></v-switch>
/>
<v-btn
icon
class="mb-2"
@ -306,26 +307,26 @@
<v-icon>mdi-refresh</v-icon>
</v-btn>
<editor
class="editor"
v-model="$store.state.themeEngine.theme.css"
@init="editorInit"
class="editor"
lang="css"
:theme="$vuetify.theme.dark ? 'monokai' : 'chrome'"
height="350"
></editor>
@init="editorInit"
/>
</v-col>
<v-col v-if="cssTips">
<v-card-title>
Tips
<v-spacer></v-spacer>
<v-spacer />
<v-btn icon @click="cssTips = false">
<v-icon>mdi-close</v-icon>
</v-btn></v-card-title
>
</v-btn>
</v-card-title>
<v-alert type="error" text>
This is an alert.<br />
Try to style it with .v-alert</v-alert
>
Try to style it with .v-alert
</v-alert>
Here's an example:<br />
<code class="block"
>.v-alert {<br />
@ -334,15 +335,17 @@
<v-btn
class="mt-2 mr-2"
@click="$toast.success('I have been pressed.')"
>Here's a button</v-btn
>
Here's a button
</v-btn>
<v-btn
class="mt-2"
text
color="info"
@click="$toast.info('This is the second button\'s action.')"
>Here's another one</v-btn
>
Here's another one
</v-btn>
<v-card-title> Fonts </v-card-title>
<code
class="block"
@ -392,9 +395,8 @@
</v-toolbar>
<v-container v-if="$store.state.modals.search">
<v-autocomplete
@keydown.enter="handleEnter"
auto-select-first
v-model="search"
auto-select-first
:items="$store.state.quickSwitchCache"
item-text="subjectLongName"
label="Search"
@ -402,13 +404,13 @@
autofocus
return-object
:search-input.sync="searchInput"
>
</v-autocomplete>
@keydown.enter="handleEnter"
/>
</v-container>
</v-card>
</v-dialog>
<v-main>
<Header></Header>
<Header />
<v-container
v-if="
$store.state.site.latestVersion > $store.state.versioning.version &&
@ -453,7 +455,6 @@
</v-main>
</v-app>
</template>
<style></style>
<script>
import AjaxErrorHandler from "@/lib/errorHandler.js"
import { VueFinalModal } from "vue-final-modal"
@ -529,6 +530,123 @@ export default {
}
}
},
watch: {
"$store.state.userPanel"(val) {
localStorage.setItem("userPanel", val)
},
cssTips(val) {
localStorage.setItem("cssTipsDismissed", !val)
},
"$store.state.themeEngine.theme": {
handler() {
this.$vuetify.theme.themes.dark =
this.$store.state.themeEngine.theme.dark
this.$vuetify.theme.themes.light =
this.$store.state.themeEngine.theme.light
this.$vuetify.theme.themes.name = this.$store.state.themeEngine.theme.id
},
deep: true
},
"$store.state.themeEngine.theme.css"() {
if (this.$store.state.themeEngine.autoCSS) {
this.$store.dispatch("applyCSS", null)
}
},
"$store.state.user.theme": {
handler() {
if (this.$store.state.user?.theme) {
this.$vuetify.theme.dark = this.$store.state.user.theme === "dark"
}
},
deep: true
},
$route(to, from) {
document.title = to.name + " - " + this.$store.state.site.name
this.$store.state.lastRoute = from.path
},
search() {
if (this.search) {
if (this.search.id) {
this.$router.push("/communications/" + this.search.id)
this.$store.commit("setSearch", false)
this.search = null
this.$nextTick(() => {
this.searchInput = null
})
} else if (this.search.customType === 1) {
this.$router.push(this.search.route)
this.$store.commit("setSearch", false)
this.search = null
this.$nextTick(() => {
this.searchInput = null
})
}
}
}
},
async mounted() {
if (localStorage.getItem("forceEnableDevMode"))
this.$store.state.release = "dev"
await this.$store.dispatch("doInit")
if (this.$vuetify.breakpoint.mobile) {
this.$store.state.drawer = false
}
if (localStorage.getItem("cssTipsDismissed")) {
this.cssTips = false
}
if (localStorage.getItem("userPanel")) {
this.$store.state.userPanel = JSON.parse(
localStorage.getItem("userPanel")
)
} else {
this.$store.state.userPanel = true
}
if (this.$vuetify.breakpoint.mobile) {
this.$store.state.userPanel = false
}
window.addEventListener("offline", () => {
this.$store.commit("setOnline", false)
this.$store.dispatch("getState")
})
window.addEventListener("online", () => {
this.$store.commit("setOnline", true)
this.$store.dispatch("getState")
this.$store.dispatch("getUserInfo")
})
this.$socket.connect()
this.$socket.on("unauthorized", () => {
console.log("Reauth requested")
this.$socket.emit("token", localStorage.getItem("token"))
})
document.title = this.$route.name
? this.$route.name + " - " + this.$store.state.site.name
: this.$store.state.site.name || "Colubrina"
this.$store.commit("setLoading", true)
this.$vuetify.theme.dark = this.$store.state.user?.theme === "dark" || true
this.$store.dispatch("getState")
this.$store
.dispatch("getUserInfo")
.then(() => {
console.log(window.location.pathname)
if (
!window.location.pathname.includes("/email/confirm/") &&
!window.location.pathname.includes("/email/verify") &&
!this.$store.state.user.emailVerified &&
this.$store.state.site.emailVerification
) {
this.$router.push("/email/verify")
}
})
.catch(() => {
this.$store.dispatch("logout")
if (!window.location.pathname.includes("/reset")) {
this.$router.push("/login")
}
})
this.getThemes()
this.communicationsIdleCheck()
this.registerSocket()
},
methods: {
handleEnter() {
if (
@ -766,126 +884,10 @@ export default {
AjaxErrorHandler(this.$store)(e)
})
}
},
async mounted() {
if (localStorage.getItem("forceEnableDevMode"))
this.$store.state.release = "dev"
await this.$store.dispatch("doInit")
if (this.$vuetify.breakpoint.mobile) {
this.$store.state.drawer = false
}
if (localStorage.getItem("cssTipsDismissed")) {
this.cssTips = false
}
if (localStorage.getItem("userPanel")) {
this.$store.state.userPanel = JSON.parse(
localStorage.getItem("userPanel")
)
} else {
this.$store.state.userPanel = true
}
if (this.$vuetify.breakpoint.mobile) {
this.$store.state.userPanel = false
}
window.addEventListener("offline", () => {
this.$store.commit("setOnline", false)
this.$store.dispatch("getState")
})
window.addEventListener("online", () => {
this.$store.commit("setOnline", true)
this.$store.dispatch("getState")
this.$store.dispatch("getUserInfo")
})
this.$socket.connect()
this.$socket.on("unauthorized", () => {
console.log("Reauth requested")
this.$socket.emit("token", localStorage.getItem("token"))
})
document.title = this.$route.name
? this.$route.name + " - " + this.$store.state.site.name
: this.$store.state.site.name || "Colubrina"
this.$store.commit("setLoading", true)
this.$vuetify.theme.dark = this.$store.state.user?.theme === "dark" || true
this.$store.dispatch("getState")
this.$store
.dispatch("getUserInfo")
.then(() => {
console.log(window.location.pathname)
if (
!window.location.pathname.includes("/email/confirm/") &&
!window.location.pathname.includes("/email/verify") &&
!this.$store.state.user.emailVerified &&
this.$store.state.site.emailVerification
) {
this.$router.push("/email/verify")
}
})
.catch(() => {
this.$store.dispatch("logout")
if (!window.location.pathname.includes("/reset")) {
this.$router.push("/login")
}
})
this.getThemes()
this.communicationsIdleCheck()
this.registerSocket()
},
watch: {
"$store.state.userPanel"(val) {
localStorage.setItem("userPanel", val)
},
cssTips(val) {
localStorage.setItem("cssTipsDismissed", !val)
},
"$store.state.themeEngine.theme": {
handler() {
this.$vuetify.theme.themes.dark =
this.$store.state.themeEngine.theme.dark
this.$vuetify.theme.themes.light =
this.$store.state.themeEngine.theme.light
this.$vuetify.theme.themes.name = this.$store.state.themeEngine.theme.id
},
deep: true
},
"$store.state.themeEngine.theme.css"() {
if (this.$store.state.themeEngine.autoCSS) {
this.$store.dispatch("applyCSS", null)
}
},
"$store.state.user.theme": {
handler() {
if (this.$store.state.user?.theme) {
this.$vuetify.theme.dark = this.$store.state.user.theme === "dark"
}
},
deep: true
},
$route(to, from) {
document.title = to.name + " - " + this.$store.state.site.name
this.$store.state.lastRoute = from.path
},
search() {
if (this.search) {
if (this.search.id) {
this.$router.push("/communications/" + this.search.id)
this.$store.commit("setSearch", false)
this.search = null
this.$nextTick(() => {
this.searchInput = null
})
} else if (this.search.customType === 1) {
this.$router.push(this.search.route)
this.$store.commit("setSearch", false)
this.search = null
this.$nextTick(() => {
this.searchInput = null
})
}
}
}
}
}
</script>
<style></style>
<style scoped>
::v-deep .modal-container {

View File

@ -18,7 +18,7 @@
padding: 10px;
cursor: move;
z-index: 2001;
background-color: #2196F3;
background-color: #2196f3;
}
.chat-col {
@ -28,7 +28,7 @@
height: 100%;
}
>>>.max-v-list-height {
>>> .max-v-list-height {
max-height: 10px;
overflow-y: auto;
}
@ -89,8 +89,8 @@ img.emoji {
pointer-events: none;
}
@font-face {
font-family: 'JetBrains Mono';
src: url('./fonts/JetBrainsMono-Regular.ttf') format('truetype');
font-family: "JetBrains Mono";
src: url("./fonts/JetBrainsMono-Regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}

View File

@ -7,11 +7,8 @@
</v-toolbar>
<v-card-text>
<v-container fluid>
<v-text-field v-model="poll.title" label="Title"></v-text-field>
<v-textarea
v-model="poll.description"
label="Description"
></v-textarea>
<v-text-field v-model="poll.title" label="Title" />
<v-textarea v-model="poll.description" label="Description" />
<v-text-field
v-for="(value, index) in poll.options"
:key="index"
@ -20,19 +17,19 @@
:maxlength="30"
:append-outer-icon="poll.options.length > 2 ? 'mdi-close' : ''"
@click:append-outer="poll.options.splice(index, 1)"
></v-text-field>
/>
<v-btn
@click="poll.options.push('')"
v-if="poll.options.length <= 3"
text
block
@click="poll.options.push('')"
>
<v-icon> mdi-plus </v-icon>
</v-btn>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn color="red" text @click="poll.dialog = false"> Cancel </v-btn>
<v-btn
color="blue darken-1"
@ -48,27 +45,27 @@
</v-card>
</v-dialog>
<v-toolbar
v-for="(embed, index) in embeds"
:key="index"
elevation="0"
outlined
height="40"
color="card"
v-for="(embed, index) in embeds"
style="cursor: pointer; overflow: hidden"
class="mb-2"
:key="index"
>
<v-toolbar-title>
<v-icon> mdi-attachment </v-icon>
{{ embedName(embed.type) }}
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon @click="embeds.splice(index, 1)" small>
<v-spacer />
<v-btn icon small @click="embeds.splice(index, 1)">
<v-icon> mdi-close </v-icon>
</v-btn>
</v-toolbar>
<v-progress-linear
v-model="uploadPercentage"
v-if="uploading"
v-model="uploadPercentage"
height="15"
color="toolbar"
disabled
@ -77,11 +74,11 @@
<small>{{ uploadPercentage }}%</small>
</v-progress-linear>
<v-toolbar
v-if="file"
elevation="0"
outlined
height="40"
color="card"
v-if="file"
style="cursor: pointer; overflow: hidden"
class="mb-2"
>
@ -89,12 +86,14 @@
<v-icon> mdi-attachment </v-icon>
{{ file.name }}
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon @click="file = null" small>
<v-spacer />
<v-btn icon small @click="file = null">
<v-icon> mdi-close </v-icon>
</v-btn>
</v-toolbar>
<v-textarea
:id="edit ? 'edit-input' : 'message-input'"
ref="message-input"
:style="
!$vuetify.breakpoint.mobile
? 'margin-bottom: 5px'
@ -103,12 +102,15 @@
autofocus
label="Type a message"
placeholder="Keep it civil"
v-model="message"
type="text"
ref="message-input"
:id="edit ? 'edit-input' : 'message-input'"
outlined
append-outer-icon="mdi-send"
auto-grow
rows="1"
single-line
dense
hide-details
@keyup.up="handleEditMessage"
@keyup.esc="handleEsc"
@click:append-outer="handleMessage()"
@ -118,27 +120,22 @@
completions = []
completionWord = ''
"
v-model="message"
@paste="handlePaste"
rows="1"
single-line
dense
hide-details
@keydown.enter.shift.exact.prevent="newLine($event)"
>
<template v-slot:append-outer>
<template #append-outer>
<v-btn
v-if="!edit"
icon
small
@click="handleMessage()"
v-if="!edit"
:retain-focus-on-click="false"
class="no-focus"
@click="handleMessage()"
>
<v-icon> mdi-send </v-icon>
</v-btn>
</template>
<template v-slot:prepend-inner>
<template #prepend-inner>
<v-menu
:nudge-top="10"
:nudge-left="5"
@ -148,13 +145,13 @@
offset-y
top
>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<v-btn
v-on="on"
id="attachment-button"
icon
style="margin-top: -3px; margin-left: -4px"
small
v-on="on"
@dblclick.stop="openFileInput"
>
<v-icon>mdi-plus-circle</v-icon>
@ -168,21 +165,22 @@
</v-list-item>
<v-list-item @click="openFileInput">
<v-file-input
v-if="!edit"
ref="file-input"
v-model="file"
style="margin-top: -10px"
single-line
hide-input
v-model="file"
@change="getURLForImage"
v-if="!edit"
ref="file-input"
st
></v-file-input>
@change="getURLForImage"
/>
Upload a file
</v-list-item>
</v-list>
</div>
</v-menu>
<v-menu
v-if="false"
:nudge-top="10"
:nudge-left="5"
:close-delay="100"
@ -190,19 +188,18 @@
bottom
offset-y
top
v-if="false"
>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<v-btn
id="emoji-button"
icon
v-on="on"
style="
margin-top: -2px;
margin-left: 1px;
filter: grayscale(100%);
"
small
v-on="on"
@dblclick.stop="openFileInput"
>
<img
@ -230,11 +227,10 @@
v-for="emoji in emojisByCategory[category]"
:key="emoji.emoji"
sm="4"
v-html="twemoji(emoji.emoji)"
@click="addEmoji(emoji.emoji)"
style="cursor: pointer"
>
</v-col>
@click="addEmoji(emoji.emoji)"
v-html="twemoji(emoji.emoji)"
/>
</v-row>
</v-container>
</v-card>
@ -304,6 +300,16 @@ export default {
completionWord: ""
}
},
watch: {
message() {
this.handleChange()
}
},
mounted() {
if (this.edit) {
this.message = this.edit.content
}
},
/*
computed: {
emojis() {
@ -582,16 +588,6 @@ export default {
}
}
}
},
mounted() {
if (this.edit) {
this.message = this.edit.content
}
},
watch: {
message() {
this.handleChange()
}
}
}
</script>

View File

@ -1,15 +1,15 @@
<template>
<div class="dev-overlay" id="dev-overlay">
<div class="dev-header" id="dev-header">Colubrina DevTools</div>
<div id="dev-overlay" class="dev-overlay">
<div id="dev-header" class="dev-header">Colubrina DevTools</div>
<v-container>
<v-btn @click="benchmark"
>Benchmark
<template v-if="isBenchmarking">({{ multiplier }}x)</template></v-btn
<v-btn @click="benchmark">
Benchmark
<template v-if="isBenchmarking"> ({{ multiplier }}x) </template> </v-btn
><br />
<template v-if="isBenchmarking"
>Please restart the Colubrina server to stop the benchmark.</template
<template v-if="isBenchmarking">
Please restart the Colubrina server to stop the benchmark. </template
><br />
<v-btn @click="deleteBenchmark">Delete benchuser messages</v-btn>
<v-btn @click="deleteBenchmark"> Delete benchuser messages </v-btn>
</v-container>
</div>
</template>
@ -24,6 +24,9 @@ export default {
multiplier: 0
}
},
mounted() {
this.drag(document.getElementById("dev-overlay"))
},
methods: {
deleteBenchmark() {
this.axios.delete("/api/v1/debug/bench").catch((e) => {
@ -81,9 +84,6 @@ export default {
document.onmousemove = null
}
}
},
mounted() {
this.drag(document.getElementById("dev-overlay"))
}
}
</script>

View File

@ -1,32 +1,29 @@
<template>
<span>
<v-card
v-if="embed.type === 'image'"
:min-width="!$vuetify.breakpoint.mobile ? 400 : 0"
:max-width="500"
elevation="0"
color="card"
v-if="embed.type === 'image'"
>
<v-hover v-slot="{ hover }">
<div>
<v-img
@click="setImagePreview(embed)"
contain
:max-width="500"
:max-height="500"
:min-height="250"
:min-width="250"
:min-height="100"
:min-width="100"
:src="$store.state.baseURL + embed.mediaProxyLink"
@click="setImagePreview(embed)"
>
<template v-slot:placeholder>
<template #placeholder>
<v-row class="fill-height ma-0" align="center" justify="center">
<v-progress-circular
indeterminate
color="grey lighten-5"
></v-progress-circular>
<v-progress-circular indeterminate color="grey lighten-5" />
</v-row>
</template>
<template v-slot:default>
<template #default>
<v-fade-transition v-if="hover">
<v-overlay absolute>
<v-icon large>mdi-arrow-expand-all</v-icon>
@ -48,9 +45,9 @@
<v-container fluid>
<v-row v-if="embed.type === 'openGraph'">
<v-col
v-if="embed.openGraph.ogImage"
cols="12"
class="text-xs-center"
v-if="embed.openGraph.ogImage"
>
<v-img
:src="
@ -60,12 +57,9 @@
contain
:aspect-ratio="16 / 9"
>
<template v-slot:placeholder>
<template #placeholder>
<v-row class="fill-height ma-0" align="center" justify="center">
<v-progress-circular
indeterminate
color="grey lighten-5"
></v-progress-circular>
<v-progress-circular indeterminate color="grey lighten-5" />
</v-row>
</template>
</v-img>
@ -85,7 +79,7 @@
</v-col>
</v-row>
<v-row v-else-if="embed.type === 'embed-v1'">
<v-col cols="12" class="text-xs-center" v-if="embed.headerImage">
<v-col v-if="embed.headerImage" cols="12" class="text-xs-center">
<v-img
:src="
embed.openGraph.headerImage?.url ||
@ -95,12 +89,9 @@
contain
:aspect-ratio="16 / 9"
>
<template v-slot:placeholder>
<template #placeholder>
<v-row class="fill-height ma-0" align="center" justify="center">
<v-progress-circular
indeterminate
color="grey lighten-5"
></v-progress-circular>
<v-progress-circular indeterminate color="grey lighten-5" />
</v-row>
</template>
</v-img>
@ -121,17 +112,17 @@
{{ graph.name }}
</h3>
<Chart
:chart-data="graph.data"
v-if="graph.data"
:chart-data="graph.data"
:options="graphOptions"
></Chart>
/>
<p v-else>Chart data could not be loaded.</p>
</v-col>
</v-row>
<v-row
v-for="(field, index) in embed.fields"
:key="'field-' + index"
:id="'field-' + index"
:key="'field-' + index"
class="mt-1"
>
<v-col
@ -144,8 +135,8 @@
</v-col>
</v-row>
<a
:href="embed.link.url"
v-if="embed.link"
:href="embed.link.url"
target="_blank"
style="text-decoration: none"
>
@ -193,10 +184,10 @@ ChartJS.register(
export default {
name: "Embed",
props: ["embed", "setImagePreview"],
components: {
Chart
}
},
props: ["embed", "setImagePreview"]
}
</script>

View File

@ -10,7 +10,7 @@
class="rounded-l"
style="z-index: 20"
>
<v-list class="rounded-l" v-if="context.user.item">
<v-list v-if="context.user.item" class="rounded-l">
<v-menu
:nudge-right="10"
:close-delay="100"
@ -20,42 +20,43 @@
offset-x
open-on-hover
>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<v-list-item v-on="on">
<v-list-item-title>Notification Settings</v-list-item-title
><v-icon class="ml-2">mdi-arrow-right</v-icon>
><v-icon class="ml-2"> mdi-arrow-right </v-icon>
</v-list-item>
</template>
<div>
<v-list>
<v-list-item @click="setNotifications('all')">
<v-list-item-title>All messages</v-list-item-title>
<v-icon v-if="context.user.raw.notifications === 'all'"
>mdi-check</v-icon
>
<v-icon v-if="context.user.raw.notifications === 'all'">
mdi-check
</v-icon>
</v-list-item>
<v-list-item two-line @click="setNotifications('mentions')">
<v-list-item-content>
<v-list-item-title
>Mentions only
<v-list-item-title>
Mentions only
<v-icon
style="float: right"
v-if="context.user.raw.notifications === 'mentions'"
>mdi-check</v-icon
></v-list-item-title
>
style="float: right"
>
mdi-check
</v-icon>
</v-list-item-title>
<v-list-item-subtitle
>Mentions are performed when your username is sent in the
chat.</v-list-item-subtitle
>
<v-list-item-subtitle>
Mentions are performed when your username is sent in the
chat.
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item @click="setNotifications('none')">
<v-list-item-title>None</v-list-item-title>
<v-icon v-if="context.user.raw.notifications === 'none'"
>mdi-check</v-icon
>
<v-icon v-if="context.user.raw.notifications === 'none'">
mdi-check
</v-icon>
</v-list-item>
</v-list>
</div>
@ -72,22 +73,22 @@
<v-list-item @click="groupSettings(context.user.raw.id)">
<v-list-item-title>Group Settings</v-list-item-title>
</v-list-item>
<v-list-item @click="groupLeave(context.user.raw.id)" color="error">
<v-list-item color="error" @click="groupLeave(context.user.raw.id)">
<v-list-item-title>Leave Group</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<v-dialog
v-if="settings.item"
v-model="settings.addMembers.dialog"
max-width="400px"
v-if="settings.item"
>
<v-card color="card">
<v-toolbar color="toolbar">
<v-toolbar-title
>Add User to {{ settings.item.chat.name }}</v-toolbar-title
>
<v-spacer></v-spacer>
<v-toolbar-title>
Add User to {{ settings.item.chat.name }}
</v-toolbar-title>
<v-spacer />
<v-btn icon @click.native="settings.addMembers.dialog = false">
<v-icon>mdi-close</v-icon>
</v-btn>
@ -105,7 +106,7 @@
item-value="id"
multiple
>
<template v-slot:selection="data">
<template #selection="data">
<v-chip
v-bind="data.attrs"
:input-value="data.selected"
@ -113,25 +114,25 @@
@click="data.select"
@click:close="remove(data.item)"
>
<v-avatar left v-if="data.item.avatar">
<v-avatar v-if="data.item.avatar" left>
<v-img
:src="
$store.state.baseURL + '/usercontent/' + data.item.avatar
"
></v-img>
/>
</v-avatar>
@{{ data.item.username }}
</v-chip>
</template>
<template v-slot:item="data">
<v-avatar left v-if="data.item.avatar" class="mr-3 mb-2 mt-2">
<template #item="data">
<v-avatar v-if="data.item.avatar" left class="mr-3 mb-2 mt-2">
<v-img
:src="
$store.state.baseURL + '/usercontent/' + data.item.avatar
"
></v-img>
/>
</v-avatar>
<v-avatar left v-else class="mr-3 mb-2 mt-2">
<v-avatar v-else left class="mr-3 mb-2 mt-2">
<v-icon>mdi-account</v-icon>
</v-avatar>
<v-list-item-content>
@ -141,60 +142,60 @@
</v-autocomplete>
</v-container>
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn color="error" text @click="settings.addMembers.dialog = false">
Cancel
</v-btn>
<v-btn
color="primary"
text
@click="addMembersToGroup"
:disabled="!settings.addMembers.users.length"
@click="addMembersToGroup"
>
Add
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="settings.dialog" max-width="500px" v-if="settings.item">
<v-dialog v-if="settings.item" v-model="settings.dialog" max-width="500px">
<v-card color="card">
<v-toolbar color="toolbar">
<v-toolbar-title>Group Settings</v-toolbar-title>
<v-spacer></v-spacer>
<v-spacer />
<v-btn icon @click.native="settings.dialog = false">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-toolbar>
<v-container>
<v-alert text type="info" v-if="settings.item.rank !== 'admin'">
<v-alert v-if="settings.item.rank !== 'admin'" text type="info">
You need to be an administrator of this group to change settings.
</v-alert>
<v-card-title v-if="settings.item.rank === 'admin'"
>General</v-card-title
>
<v-card-title v-if="settings.item.rank === 'admin'">
General
</v-card-title>
<v-text-field
label="Group Name"
v-if="
settings.item.chat.type === 'group' &&
settings.item.rank === 'admin'
"
v-model="settings.item.chat.name"
></v-text-field>
label="Group Name"
/>
<v-file-input
ref="avatarUpload"
v-model="settings.avatar"
accept="image/png, image/jpeg, image/jpg, image/gif, image/webp"
placeholder="Avatar"
prepend-icon=""
label="Profile Picture"
v-model="settings.avatar"
@change="doUpload"
></v-file-input>
<v-card-title
>Members
/>
<v-card-title>
Members
<v-btn
v-if="settings.item.rank === 'admin'"
icon
@click.native="settings.addMembers.dialog = true"
v-if="settings.item.rank === 'admin'"
>
<v-icon>mdi-plus</v-icon>
</v-btn>
@ -206,25 +207,25 @@
>
<v-list-item-avatar :color="$vuetify.theme.themes.dark?.primary">
<v-img
v-if="user.user.avatar"
:src="
$store.state.baseURL + '/usercontent/' + user.user.avatar
"
v-if="user.user.avatar"
/>
<v-icon v-else> mdi-account </v-icon>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title
>{{ user.user.username }}
<v-btn text icon v-if="user.rank === 'admin'">
<v-list-item-title>
{{ user.user.username }}
<v-btn v-if="user.rank === 'admin'" text icon>
<v-icon> mdi-gavel </v-icon>
</v-btn>
</v-list-item-title>
</v-list-item-content>
<v-list-item-action v-if="settings.item.rank === 'admin'">
<v-tooltip top>
<template v-slot:activator="{ on, attrs }">
<div v-on="on" v-bind="attrs">
<template #activator="{ on, attrs }">
<div v-bind="attrs" v-on="on">
<v-btn icon @click="giveUserAdmin(user)">
<v-icon>mdi-account-arrow-up</v-icon>
</v-btn>
@ -258,7 +259,7 @@
<v-card color="card">
<v-toolbar color="toolbar">
<v-toolbar-title>Are you sure you want to leave?</v-toolbar-title>
<v-spacer></v-spacer>
<v-spacer />
<v-btn
icon
@click.native="
@ -276,7 +277,7 @@
</p>
</v-container>
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn color="primary" text @click.native="leave.dialog = false">
Cancel
</v-btn>
@ -288,7 +289,7 @@
<v-card color="card">
<v-toolbar color="toolbar">
<v-toolbar-title>New Communication</v-toolbar-title>
<v-spacer></v-spacer>
<v-spacer />
<v-btn icon @click.native="dialogs.new = false">
<v-icon>mdi-close</v-icon>
</v-btn>
@ -306,7 +307,7 @@
item-value="id"
multiple
>
<template v-slot:selection="data">
<template #selection="data">
<v-chip
v-bind="data.attrs"
:input-value="data.selected"
@ -314,25 +315,25 @@
@click="data.select"
@click:close="remove(data.item)"
>
<v-avatar left v-if="data.item.avatar">
<v-avatar v-if="data.item.avatar" left>
<v-img
:src="
$store.state.baseURL + '/usercontent/' + data.item.avatar
"
></v-img>
/>
</v-avatar>
@{{ data.item.username }}
</v-chip>
</template>
<template v-slot:item="data">
<v-avatar left v-if="data.item.avatar" class="mr-3 mb-2 mt-2">
<template #item="data">
<v-avatar v-if="data.item.avatar" left class="mr-3 mb-2 mt-2">
<v-img
:src="
$store.state.baseURL + '/usercontent/' + data.item.avatar
"
></v-img>
/>
</v-avatar>
<v-avatar left v-else class="mr-3 mb-2 mt-2">
<v-avatar v-else left class="mr-3 mb-2 mt-2">
<v-icon>mdi-account</v-icon>
</v-avatar>
<v-list-item-content>
@ -347,7 +348,7 @@
>
</v-container>
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn color="error" text @click="dialogs.new = false">
Cancel
</v-btn>
@ -355,8 +356,8 @@
color="primary"
:loading="newConversation.loading"
text
@click="createConversation"
:disabled="!newConversation.users.length"
@click="createConversation"
>
Create
</v-btn>
@ -423,17 +424,17 @@
color="yellow darken-3"
empty-icon="$ratingFull"
hover
></v-rating>
/>
</v-col>
<v-col cols="12">
<v-textarea
class="rounded-xl"
v-model="feedback.text"
class="rounded-xl"
label="Enter your Feedback"
required
autofocus
placeholder="Enter your Feedback"
></v-textarea>
/>
</v-col>
<small
>Your feedback will be used to make
@ -443,7 +444,7 @@
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn
class="rounded-xl"
color="blue darken-1"
@ -471,17 +472,17 @@
<v-card-text>
<v-container>
<v-text-field
class="rounded-xl"
v-model="route.value"
class="rounded-xl"
autofocus
@keyup.enter="goToRoute()"
label="Route"
required
></v-text-field>
@keyup.enter="goToRoute()"
/>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn class="rounded-xl" text @click="route.modal = false">
Close
</v-btn>
@ -498,54 +499,54 @@
</v-dialog>
<v-app-bar app color="dark" elevation="5" style="z-index: 15">
<v-app-bar-nav-icon
@click.stop="$store.state.drawer = !$store.state.drawer"
v-if="$vuetify.breakpoint.mobile || !$store.state.drawer"
></v-app-bar-nav-icon>
@click.stop="$store.state.drawer = !$store.state.drawer"
/>
<button
style="display: none"
v-shortkey="['ctrl', 'k']"
style="display: none"
@shortkey="$store.commit('setSearch', true)"
>
Debug
</button>
<button
style="display: none"
v-shortkey="['meta', 'k']"
style="display: none"
@shortkey="$store.commit('setSearch', true)"
>
Debug
</button>
<button
style="display: none"
v-shortkey="['ctrl', 'alt', 'd']"
style="display: none"
@shortkey="$store.dispatch('toggleCSS')"
>
Style Toggle
</button>
<button
style="display: none"
v-shortkey="['f9']"
style="display: none"
@shortkey="$store.dispatch('toggleCSS')"
>
Style Toggle
</button>
<button
style="display: none"
v-shortkey="['ctrl', 'f']"
style="display: none"
@shortkey="$store.state.searchPanel = true"
>
Debug
</button>
<button
style="display: none"
v-shortkey="['ctrl', 'b']"
style="display: none"
@shortkey="route.modal = true"
>
Debug
</button>
<button
style="display: none"
v-shortkey="['ctrl', '/']"
style="display: none"
@shortkey="shortcuts = true"
>
Debug
@ -558,22 +559,22 @@
: chat?.chat?.name
}}
</v-toolbar-title>
<v-spacer></v-spacer>
<v-spacer />
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn v-on="on" icon @click="feedback.modal = true">
<template #activator="{ on }">
<v-btn icon v-on="on" @click="feedback.modal = true">
<v-icon>mdi-bug</v-icon>
</v-btn>
</template>
<span>Provide Feedback</span>
</v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<v-btn
icon
v-model="$store.state.context.pins.value"
@click="show($event, 'pins', null, null, true)"
id="pin-button"
v-model="$store.state.context.pins.value"
icon
@click="show($event, 'pins', null, null, true)"
v-on="on"
>
<v-icon>mdi-pin-outline</v-icon>
@ -582,7 +583,7 @@
<span>Chat Pins</span>
</v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<v-btn
icon
@click="$store.state.searchPanel = !$store.state.searchPanel"
@ -594,10 +595,10 @@
<span>Search Messages</span>
</v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<v-btn
v-on="on"
icon
v-on="on"
@click="$store.state.userPanel = !$store.state.userPanel"
>
<v-icon>mdi-account-group-outline</v-icon>
@ -616,9 +617,10 @@
?.primary
"
class="troplo-title"
@click="$router.push('/')"
style="cursor: pointer"
>{{ $store.state.site.name }}</v-toolbar-title
@click="$router.push('/')"
>
{{ $store.state.site.name }} </v-toolbar-title
><v-app-bar-nav-icon
v-if="
!$vuetify.breakpoint.mobile &&
@ -626,12 +628,13 @@
"
style="z-index: 1000"
disabled
>{{ $store.state.site.release }}</v-app-bar-nav-icon
>
<v-spacer></v-spacer>
{{ $store.state.site.release }}
</v-app-bar-nav-icon>
<v-spacer />
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn v-on="on" icon @click="feedback.modal = true">
<template #activator="{ on }">
<v-btn icon v-on="on" @click="feedback.modal = true">
<v-icon>mdi-bug</v-icon>
</v-btn>
</template>
@ -640,16 +643,16 @@
</template>
</v-app-bar>
<v-navigation-drawer
v-model="$store.state.drawer"
color="dark"
app
floating
style="max-height: 100%; z-index: 15"
class="elevation-5"
v-model="$store.state.drawer"
:width="$vuetify.breakpoint.mobile ? 270 : 320"
>
<v-container>
<v-list dense nav id="comms-sidebar-list">
<v-list id="comms-sidebar-list" dense nav>
<template v-if="$vuetify.breakpoint.mobile">
<v-btn
color="toolbar"
@ -658,7 +661,7 @@
class="mb-3 mr-1 rounded-xl"
elevation="2"
>
<v-icon left>mdi-account-multiple</v-icon>
<v-icon left> mdi-account-multiple </v-icon>
Friends
</v-btn>
<v-btn
@ -668,7 +671,7 @@
elevation="2"
@click="dialogs.new = true"
>
<v-icon left>mdi-plus</v-icon>
<v-icon left> mdi-plus </v-icon>
New
</v-btn>
</template>
@ -680,10 +683,11 @@
class="mb-3 rounded-xl"
elevation="2"
>
<v-icon left>mdi-account-multiple</v-icon>
<v-icon left> mdi-account-multiple </v-icon>
Friends
</v-btn>
<v-text-field
v-model="search"
class="rounded-xl"
filled
solo
@ -692,19 +696,18 @@
background-color="sheet"
style="margin-bottom: -18px"
elevation="2"
v-model="search"
autocomplete="none"
></v-text-field>
/>
<v-toolbar color="sheet" class="rounded-xl mb-3" elevation="2">
<v-toolbar-title class="subtitle-1">
CHATS ({{ chats.length }})
</v-toolbar-title>
<v-spacer></v-spacer>
<v-spacer />
<v-btn icon @click="dialogs.new = true">
<v-icon>mdi-plus</v-icon>
</v-btn>
</v-toolbar></template
>
</v-toolbar>
</template>
<v-list v-for="item in chats" :key="item.id">
<template>
<v-list-item
@ -714,10 +717,10 @@
"
>
<v-badge
v-if="item.chat.type === 'direct'"
bordered
bottom
:color="getStatus(item)"
v-if="item.chat.type === 'direct'"
dot
offset-x="24"
offset-y="20"
@ -741,7 +744,7 @@
</v-icon>
</v-list-item-avatar>
</v-badge>
<v-badge dot color="none" v-else>
<v-badge v-else dot color="none">
<v-list-item-avatar
:color="$vuetify.theme.themes.dark?.primary"
>
@ -777,8 +780,7 @@
$route.params.id !== item.id.toString()
"
>
<v-badge color="red" inline :content="item.unread">
</v-badge>
<v-badge color="red" inline :content="item.unread" />
</v-list-item-action>
</template>
</v-list-item>
@ -786,12 +788,12 @@
</v-list>
</v-list>
</v-container>
<template v-slot:append>
<template #append>
<v-card tile color="bg" elevation="0">
<v-divider></v-divider>
<v-divider />
<v-list-item>
<v-menu top offset-y>
<template v-slot:activator="{ on, attrs }">
<template #activator="{ on, attrs }">
<v-badge
bordered
bottom
@ -799,13 +801,13 @@
dot
offset-x="26"
offset-y="19"
v-on="on"
v-bind="attrs"
v-on="on"
>
<v-list-item-avatar
:color="$vuetify.theme.themes.dark?.primary"
v-on="on"
v-bind="attrs"
v-on="on"
>
<v-img
v-if="$store.state.user.avatar"
@ -830,29 +832,28 @@
<v-list-item two-line @click="setStatus('busy')">
<v-list-item-content>
<v-list-item-title>Do not Disturb</v-list-item-title>
<v-list-item-subtitle class="text-wrap"
>You will not receive any
notifications.</v-list-item-subtitle
>
<v-list-item-subtitle class="text-wrap">
You will not receive any notifications.
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item two-line @click="setStatus('invisible')">
<v-list-item-content>
<v-list-item-title>Invisible</v-list-item-title>
<v-list-item-subtitle class="text-wrap"
>You will appear as offline, and the typing indicator will
be disabled.</v-list-item-subtitle
>
<v-list-item-subtitle class="text-wrap">
You will appear as offline, and the typing indicator will
be disabled.
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</v-menu>
<v-tooltip v-model="copyTooltip" top>
<template v-slot:activator="{ attrs }">
<template #activator="{ attrs }">
<v-list-item-content
@click="copyUsername"
v-bind="attrs"
style="cursor: pointer; min-width: 100px"
@click="copyUsername"
>
<v-list-item-title>
{{ $store.state.user.username }}
@ -864,12 +865,12 @@
</template>
<span>Copied!</span>
</v-tooltip>
<v-spacer></v-spacer>
<v-spacer />
<v-btn
v-if="$store.state.user.admin"
icon
text
to="/admin"
v-if="$store.state.user.admin"
style="margin-right: 0; padding-right: 0"
>
<v-icon>mdi-gavel</v-icon>
@ -989,6 +990,73 @@ export default {
})
}
},
watch: {
$route(to) {
this.feedback.route = to.path
}
},
mounted() {
this.feedback.route = this.$route.path
Vue.axios.defaults.headers.common["Authorization"] =
localStorage.getItem("token")
this.searchUsers()
this.searchUsersForGroupAdmin()
this.$store.dispatch("getChats")
this.$socket.on("friendUpdate", () => {
this.searchUsers()
this.searchUsersForGroupAdmin()
})
this.$socket.on("siteState", () => {
this.searchUsers()
this.searchUsersForGroupAdmin()
})
this.$socket.on("userSettings", () => {
this.$store.dispatch("getChats")
})
this.$socket.on("chatUpdated", () => {
this.$store.dispatch("getChats")
})
this.$socket.on("chatAdded", (chat) => {
this.$store.commit("addChat", chat)
})
this.$socket.on("userStatus", (event) => {
this.$store.state.chats.forEach((item) => {
item.chat.associations.forEach((a) => {
if (a.user.id === event.userId) {
a.user.status = event.status
}
})
item.chat.users.forEach((u) => {
if (u.id === event.userId) {
u.status = event.status
}
})
})
})
this.$socket.on("message", (message) => {
const chat = this.$store.state.chats.find(
(item) => item.chatId === message.chatId
)
if (chat) {
const index = this.$store.state.chats.indexOf(chat)
this.$store.state.chats.splice(index, 1)
this.$store.state.chats.unshift(chat)
}
})
this.$socket.on("readChat", (chat) => {
const item = this.$store.state.chats.find((item) => item.id === chat.id)
if (item) {
const index = this.$store.state.chats.indexOf(item)
console.log(this.$store.state.chats[index].lastRead)
this.$store.state.chats[index].lastRead = chat.lastRead
this.$store.state.communicationNotifications = 0
this.$store.state.chats.forEach((item) => {
this.$store.state.communicationNotifications +=
this.getLastRead(item).count
})
}
})
},
methods: {
goToRoute() {
if (this.route.value === "forceEnableDevMode") {
@ -1332,73 +1400,6 @@ export default {
})
.catch(() => {})
}
},
mounted() {
this.feedback.route = this.$route.path
Vue.axios.defaults.headers.common["Authorization"] =
localStorage.getItem("token")
this.searchUsers()
this.searchUsersForGroupAdmin()
this.$store.dispatch("getChats")
this.$socket.on("friendUpdate", () => {
this.searchUsers()
this.searchUsersForGroupAdmin()
})
this.$socket.on("siteState", () => {
this.searchUsers()
this.searchUsersForGroupAdmin()
})
this.$socket.on("userSettings", () => {
this.$store.dispatch("getChats")
})
this.$socket.on("chatUpdated", () => {
this.$store.dispatch("getChats")
})
this.$socket.on("chatAdded", (chat) => {
this.$store.commit("addChat", chat)
})
this.$socket.on("userStatus", (event) => {
this.$store.state.chats.forEach((item) => {
item.chat.associations.forEach((a) => {
if (a.user.id === event.userId) {
a.user.status = event.status
}
})
item.chat.users.forEach((u) => {
if (u.id === event.userId) {
u.status = event.status
}
})
})
})
this.$socket.on("message", (message) => {
const chat = this.$store.state.chats.find(
(item) => item.chatId === message.chatId
)
if (chat) {
const index = this.$store.state.chats.indexOf(chat)
this.$store.state.chats.splice(index, 1)
this.$store.state.chats.unshift(chat)
}
})
this.$socket.on("readChat", (chat) => {
const item = this.$store.state.chats.find((item) => item.id === chat.id)
if (item) {
const index = this.$store.state.chats.indexOf(item)
console.log(this.$store.state.chats[index].lastRead)
this.$store.state.chats[index].lastRead = chat.lastRead
this.$store.state.communicationNotifications = 0
this.$store.state.chats.forEach((item) => {
this.$store.state.communicationNotifications +=
this.getLastRead(item).count
})
}
})
},
watch: {
$route(to) {
this.feedback.route = to.path
}
}
}
</script>

View File

@ -2,27 +2,27 @@
<div>
<template>
<v-toolbar
@click="jumpToMessage(message.replyId)"
v-if="message.reply"
:key="message.keyId + '-reply-toolbar'"
elevation="0"
height="40"
color="card"
v-if="message.reply"
style="cursor: pointer"
@click="jumpToMessage(message.replyId)"
>
<v-icon class="mr-2">mdi-reply</v-icon>
<v-icon class="mr-2"> mdi-reply </v-icon>
<v-avatar size="24" class="mr-2">
<v-img
v-if="message.reply.user.avatar"
:src="
$store.state.baseURL + '/usercontent/' + message.reply.user.avatar
"
v-if="message.reply.user.avatar"
class="elevation-1"
/>
<v-icon v-else class="elevation-1"> mdi-account </v-icon>
</v-avatar>
<template v-if="message.reply.attachments.length">
<v-icon class="mr-2">mdi-file-image</v-icon>
<v-icon class="mr-2"> mdi-file-image </v-icon>
</template>
<template
v-if="!message.reply.content && message.reply.attachments.length"
@ -32,6 +32,7 @@
{{ message.reply.content.substring(0, 100) }}
</v-toolbar>
<v-list-item
:id="'message-' + index"
:key="message.keyId"
:class="{
'pa-0': $vuetify.breakpoint.mobile,
@ -39,22 +40,21 @@
}"
class="message"
:dense="lastMessage"
:id="'message-' + index"
@contextmenu="show($event, 'message', message)"
:style="lastMessage ? 'margin-bottom: -5px; margin-top: -5px;' : ''"
@contextmenu="show($event, 'message', message)"
>
<v-avatar
v-if="!lastMessage"
size="45"
class="mr-2"
v-if="!lastMessage"
:class="{ 'hide-on-hover': message.type }"
>
<v-img
:src="$store.state.baseURL + '/usercontent/' + message.user.avatar"
v-if="message.user.avatar && !message.type"
:src="$store.state.baseURL + '/usercontent/' + message.user.avatar"
class="elevation-1"
/>
<v-icon class="elevation-1" v-else-if="!message.type">
<v-icon v-else-if="!message.type" class="elevation-1">
mdi-account
</v-icon>
<v-icon
@ -86,12 +86,12 @@
</v-icon>
</v-avatar>
<v-tooltip top style="z-index: 15">
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<small
v-on="on"
v-if="lastMessage || message.type"
style="font-size: 9px; position: absolute"
class="grey--text message-date"
v-if="lastMessage || message.type"
v-on="on"
>
{{ $date(message.createdAt).format("hh:mm A") }}
</small>
@ -110,14 +110,14 @@
color="calendarNormalActivity"
small
>
<v-icon small>mdi-robot</v-icon>&nbsp;
<v-icon small> mdi-robot </v-icon>&nbsp;
</v-chip>
<small>
{{ $date(message.createdAt).format("hh:mm A, DD/MM/YYYY") }}
</small>
<v-tooltip top v-if="message.edited">
<template v-slot:activator="{ on, attrs }">
<span v-on="on" v-bind="attrs">
<v-tooltip v-if="message.edited" top>
<template #activator="{ on, attrs }">
<span v-bind="attrs" v-on="on">
<v-icon
color="grey"
small
@ -140,9 +140,9 @@
<span v-markdown>
{{ message.content }}
</span>
<v-tooltip top v-if="message.edited && lastMessage">
<template v-slot:activator="{ on }">
<v-icon color="grey" small v-on="on" style="">
<v-tooltip v-if="message.edited && lastMessage" top>
<template #activator="{ on }">
<v-icon color="grey" small style="" v-on="on">
mdi-pencil
</v-icon>
</template>
@ -155,37 +155,36 @@
<template v-if="edit.id !== message.id">
<Embed
v-for="(embed, index) in message.embeds"
:key="index"
:id="'embed-' + index"
:key="index"
:embed="embed"
:setImagePreview="setImagePreview"
></Embed>
:set-image-preview="setImagePreview"
/>
<v-row v-if="message.poll" no-gutters>
<Poll :message="message"></Poll>
<Poll :message="message" />
</v-row>
</template>
<template v-if="edit.id !== message.id">
<v-card
v-for="(attachment, index) in message.attachments"
:key="attachment.id"
:id="'attachment-' + index"
:key="attachment.id"
:max-width="500"
:min-width="!$vuetify.breakpoint.mobile ? 400 : 0"
elevation="0"
color="card"
>
<v-hover
v-slot="{ hover }"
v-if="
attachment.extension === 'jpg' ||
attachment.extension === 'png' ||
attachment.extension === 'jpeg' ||
attachment.extension === 'gif'
"
v-slot="{ hover }"
>
<div>
<v-img
@click="setImagePreview(attachment)"
contain
:max-width="500"
:max-height="500"
@ -196,8 +195,9 @@
"
:min-height="250"
:min-width="250"
@click="setImagePreview(attachment)"
>
<template v-slot:placeholder>
<template #placeholder>
<v-row
class="fill-height ma-0"
align="center"
@ -206,13 +206,13 @@
<v-progress-circular
indeterminate
color="grey lighten-5"
></v-progress-circular>
/>
</v-row>
</template>
<template v-slot:default>
<template #default>
<v-fade-transition v-if="hover">
<v-overlay absolute>
<v-icon large>mdi-arrow-expand-all</v-icon>
<v-icon large> mdi-arrow-expand-all </v-icon>
</v-overlay>
</v-fade-transition>
</template>
@ -254,29 +254,29 @@
</v-card>
</template>
<CommsInput
v-if="edit.id === message.id"
:edit="edit"
:chat="chat"
:auto-scroll="autoScroll"
:end-edit="endEdit"
v-if="edit.id === message.id"
></CommsInput>
/>
</v-list-item-content>
<v-card
v-if="!$vuetify.breakpoint.mobile"
elevation="8"
color="card"
class="message-action-card"
v-if="!$vuetify.breakpoint.mobile"
>
<v-tooltip top>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<span v-on="on">
<v-btn
icon
v-on="on"
v-if="
message.userId === $store.state.user.id ||
chat.rank === 'admin'
"
icon
v-on="on"
@click="deleteMessage(message)"
>
<v-icon> mdi-delete </v-icon>
@ -286,9 +286,13 @@
<span> Delete </span>
</v-tooltip>
<v-tooltip top>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<span v-on="on">
<v-btn
v-if="
message.userId === $store.state.user.id &&
edit.id !== message.id
"
icon
v-on="on"
@click="
@ -296,10 +300,6 @@
edit.editing = true
edit.id = message.id
"
v-if="
message.userId === $store.state.user.id &&
edit.id !== message.id
"
>
<v-icon> mdi-pencil </v-icon>
</v-btn>
@ -308,20 +308,20 @@
<span> Edit </span>
</v-tooltip>
<v-tooltip top>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<span v-on="on">
<v-btn
v-on="on"
v-if="
message.userId === $store.state.user.id &&
edit.id === message.id
"
icon
v-on="on"
@click="
edit.content = ''
edit.editing = false
edit.id = null
"
v-if="
message.userId === $store.state.user.id &&
edit.id === message.id
"
>
<v-icon> mdi-close </v-icon>
</v-btn>
@ -330,7 +330,7 @@
<span> Discard Edits </span>
</v-tooltip>
<v-tooltip top>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<span v-on="on">
<v-btn
icon
@ -347,12 +347,12 @@
<span> Reply </span>
</v-tooltip>
<v-tooltip top>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<span v-on="on">
<v-btn
v-on="on"
icon
v-if="chat.rank === 'admin' || chat.chat.type === 'direct'"
icon
v-on="on"
@click="
pinMessage()
focusInput()
@ -364,9 +364,9 @@
</template>
<span> Pin to Chat </span>
</v-tooltip>
<v-menu offset-y v-if="$store.state.site.release === 'dev'">
<template v-slot:activator="{ on, attrs }">
<v-btn v-on="on" icon v-bind="attrs">
<v-menu v-if="$store.state.site.release === 'dev'" offset-y>
<template #activator="{ on, attrs }">
<v-btn icon v-bind="attrs" v-on="on">
<v-icon> mdi-dots-horizontal </v-icon>
</v-btn>
</template>
@ -388,6 +388,11 @@ import Poll from "@/components/Poll"
export default {
name: "Message",
components: {
Poll,
CommsInput,
Embed
},
props: [
"message",
"edit",
@ -404,11 +409,6 @@ export default {
"deleteMessage",
"lastMessage"
],
components: {
Poll,
CommsInput,
Embed
},
data() {
return {
graphOptions: {

View File

@ -10,11 +10,11 @@
label="Nickname"
autofocus
@keyup.enter="setFriendNickname"
></v-text-field>
/>
<small>Friend nicknames only show to you.</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn
color="blue darken-1"
text

View File

@ -74,6 +74,16 @@ export default {
})
}
},
mounted() {
this.$socket.on(`pollAnswer-${this.message.id}`, (data) => {
this.message.poll.answers = this.message.poll.answers.filter(
(answer) => answer.id !== data.id
)
if (data.answer) {
this.message.poll.answers.push(data.answer)
}
})
},
methods: {
votePoll(option) {
this.axios
@ -84,16 +94,6 @@ export default {
AjaxErrorHandler(this.$store)(e)
})
}
},
mounted() {
this.$socket.on(`pollAnswer-${this.message.id}`, (data) => {
this.message.poll.answers = this.message.poll.answers.filter(
(answer) => answer.id !== data.id
)
if (data.answer) {
this.message.poll.answers.push(data.answer)
}
})
}
}
</script>

View File

@ -1,27 +1,27 @@
<template>
<div v-if="!message.type" class="rounded-l">
<v-toolbar
@click="jumpToMessage(message.replyId)"
v-if="message.reply"
:key="message.keyId + '-reply-toolbar'"
elevation="0"
height="40"
color="card"
v-if="message.reply"
style="cursor: pointer"
@click="jumpToMessage(message.replyId)"
>
<v-icon class="mr-2">mdi-reply</v-icon>
<v-icon class="mr-2"> mdi-reply </v-icon>
<v-avatar size="24" class="mr-2">
<v-img
v-if="message.reply.user.avatar"
:src="
$store.state.baseURL + '/usercontent/' + message.reply.user.avatar
"
v-if="message.reply.user.avatar"
class="elevation-1"
/>
<v-icon v-else class="elevation-1"> mdi-account </v-icon>
</v-avatar>
<template v-if="message.reply.attachments.length">
<v-icon class="mr-2">mdi-file-image</v-icon>
<v-icon class="mr-2"> mdi-file-image </v-icon>
</template>
<template
v-if="!message.reply.content && message.reply.attachments.length"
@ -31,17 +31,17 @@
{{ message.reply.content.substring(0, 100) }}
</v-toolbar>
<v-list-item
:id="'message-' + index"
:key="message.keyId"
:class="{
'text-xs-right': message.userId === $store.state.user.id,
'text-xs-left': message.userId !== $store.state.user.id
}"
:id="'message-' + index"
>
<v-avatar size="48" class="mr-2">
<v-img
:src="$store.state.baseURL + '/usercontent/' + message.user.avatar"
v-if="message.user.avatar"
:src="$store.state.baseURL + '/usercontent/' + message.user.avatar"
class="elevation-1"
/>
<v-icon v-else class="elevation-1"> mdi-account </v-icon>
@ -50,14 +50,14 @@
<v-list-item-subtitle>
{{ getName(message.user) }}
<v-chip v-if="message.user.bot" color="calendarNormalActivity" small>
<v-icon small>mdi-robot</v-icon>&nbsp;
<v-icon small> mdi-robot </v-icon>&nbsp;
</v-chip>
<small>
{{ $date(message.createdAt).format("hh:mm A, DD/MM/YYYY") }}
</small>
<v-tooltip top v-if="message.edited">
<template v-slot:activator="{ on, attrs }">
<span v-on="on" v-bind="attrs">
<v-tooltip v-if="message.edited" top>
<template #activator="{ on, attrs }">
<span v-bind="attrs" v-on="on">
<v-icon
color="grey"
small

View File

@ -4,42 +4,42 @@
<v-toolbar color="toolbar" height="100">
<v-avatar size="64" class="mr-3 mb-2 mt-2">
<v-img
:src="$store.state.baseURL + '/usercontent/' + user.item.avatar"
v-if="user.item.avatar"
:src="$store.state.baseURL + '/usercontent/' + user.item.avatar"
class="elevation-1"
/>
<v-icon v-else class="elevation-1"> mdi-account </v-icon>
</v-avatar>
<v-toolbar-title>
{{ getName(user.item) }}
<v-tooltip top v-if="user.item.admin">
<template v-slot:activator="{ on }">
<v-btn icon v-on="on" small>
<v-tooltip v-if="user.item.admin" top>
<template #activator="{ on }">
<v-btn icon small v-on="on">
<v-icon> mdi-crown </v-icon>
</v-btn>
</template>
<span>Colubrina Instance Administrator</span>
</v-tooltip>
<v-tooltip top v-if="user.item.id < 35">
<template v-slot:activator="{ on }">
<v-btn icon v-on="on" small>
<v-tooltip v-if="user.item.id < 35" top>
<template #activator="{ on }">
<v-btn icon small v-on="on">
<v-icon> mdi-alpha-a-circle </v-icon>
</v-btn>
</template>
<span>Early User</span>
</v-tooltip>
<v-tooltip top v-if="user.item.bot">
<template v-slot:activator="{ on }">
<v-btn icon v-on="on" small>
<v-tooltip v-if="user.item.bot" top>
<template #activator="{ on }">
<v-btn icon small v-on="on">
<v-icon> mdi-robot </v-icon>
</v-btn>
</template>
<span>Bot</span>
</v-tooltip>
<div class="subheading subtitle-1 text--lighten-2">
<template v-if="user.item.nickname">{{
user.item.username
}}</template>
<template v-if="user.item.nickname">
{{ user.item.username }}
</template>
</div>
</v-toolbar-title>
</v-toolbar>
@ -62,10 +62,7 @@
"
>
<v-overlay :value="loading.mutualFriends" absolute>
<v-progress-circular
indeterminate
size="64"
></v-progress-circular>
<v-progress-circular indeterminate size="64" />
</v-overlay>
<v-list-item
v-for="item in mutualFriends"
@ -75,8 +72,8 @@
<v-list-item-title>
<v-avatar size="24">
<v-img
:src="$store.state.baseURL + '/usercontent/' + item.avatar"
v-if="item.avatar"
:src="$store.state.baseURL + '/usercontent/' + item.avatar"
class="elevation-1"
/>
<v-icon v-else class="elevation-1"> mdi-account </v-icon>
@ -100,10 +97,7 @@
"
>
<v-overlay :value="loading.mutualFriends" absolute>
<v-progress-circular
indeterminate
size="64"
></v-progress-circular>
<v-progress-circular indeterminate size="64" />
</v-overlay>
<v-list-item
v-for="item in mutualGroups"
@ -126,7 +120,7 @@
$vuetify.theme.themes[$vuetify.theme.dark ? 'dark' : 'light'].card
"
>
<v-spacer></v-spacer>
<v-spacer />
<v-btn color="primary" text @click="user.value = false"> Close </v-btn>
</v-card-actions>
</v-card>
@ -149,6 +143,9 @@ export default {
}
}
},
mounted() {
this.onMounted()
},
methods: {
openUserPanel(user) {
this.user.item = user
@ -199,9 +196,6 @@ export default {
})
}
}
},
mounted() {
this.onMounted()
}
}
</script>

View File

@ -1,7 +1,7 @@
<template>
<div id="admin">
<v-overlay :value="loading" absolute>
<v-progress-circular indeterminate size="64"></v-progress-circular>
<v-progress-circular indeterminate size="64" />
</v-overlay>
<v-container v-if="admin">
<v-card color="card" class="rounded-xl">
@ -30,7 +30,7 @@
<span>Config</span>
</v-tab>
</v-tabs>
<router-view :admin="admin" :metrics="metrics"></router-view>
<router-view :admin="admin" :metrics="metrics" />
</v-card>
</v-container>
</div>
@ -48,6 +48,10 @@ export default {
loading: true
}
},
mounted() {
this.getAdminInfo()
this.getAdminMetrics()
},
methods: {
getAdminMetrics() {
this.axios
@ -73,10 +77,6 @@ export default {
this.$router.push("/")
})
}
},
mounted() {
this.getAdminInfo()
this.getAdminMetrics()
}
}
</script>

View File

@ -2,8 +2,8 @@
<div id="admin-feedback">
<v-toolbar color="toolbar">
<v-toolbar-title>Feedback ({{ feedback.count }})</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn @click="getFeedback" icon>
<v-spacer />
<v-btn icon @click="getFeedback">
<v-icon>mdi-refresh</v-icon>
</v-btn>
</v-toolbar>
@ -43,6 +43,9 @@ export default {
feedback: []
}
},
mounted() {
this.getFeedback()
},
methods: {
getFeedback() {
this.axios
@ -51,9 +54,6 @@ export default {
this.feedback = res.data
})
}
},
mounted() {
this.getFeedback()
}
}
</script>

View File

@ -109,10 +109,10 @@ ChartJS.register(
)
export default {
name: "AdminHome",
props: ["admin", "metrics"],
components: {
Chart
},
props: ["admin", "metrics"],
data() {
return {
options: {

View File

@ -12,6 +12,9 @@ export default {
logLines: []
}
},
mounted() {
this.getLogs()
},
methods: {
getLogs() {
this.axios
@ -23,9 +26,6 @@ export default {
AjaxErrorHandler(this.$store)(e)
})
}
},
mounted() {
this.getLogs()
}
}
</script>

View File

@ -3,46 +3,44 @@
<v-toolbar color="toolbar">
<v-toolbar-title>Site Config</v-toolbar-title>
</v-toolbar>
<v-text-field
class="mx-3"
label="Notification"
v-model="notification"
></v-text-field>
<v-text-field v-model="notification" class="mx-3" label="Notification" />
<v-select
v-model="notificationType"
:items="notificationTypes"
label="Notification Type"
class="mx-3"
v-model="notificationType"
text-text="text"
text-value="value"
>
</v-select>
/>
<v-select
v-model="broadcastType"
:items="broadcastTypes"
label="Broadcast Type"
class="mx-3"
v-model="broadcastType"
text-text="text"
text-value="value"
>
</v-select>
/>
<v-switch
v-model="allowRegistrations"
inset
class="mx-3"
label="Allow registrations"
v-model="allowRegistrations"
></v-switch>
<v-textarea ref="rules" label="Instance Rules" v-model="rules" class="mx-3">
</v-textarea>
/>
<v-textarea
ref="rules"
v-model="rules"
label="Instance Rules"
class="mx-3"
/>
<v-card-title>
<v-icon class="mr-1">mdi-language-markdown</v-icon>Rules Preview:
<v-icon class="mr-1"> mdi-language-markdown </v-icon>Rules Preview:
</v-card-title>
<v-card-text>
<span v-markdown class="mx-3" :key="rules">{{ rules }}</span>
<span :key="rules" v-markdown class="mx-3">{{ rules }}</span>
</v-card-text>
<v-btn text class="mx-3 mb-3" color="primary" @click="updateState"
>Save</v-btn
>
<v-btn text class="mx-3 mb-3" color="primary" @click="updateState">
Save
</v-btn>
</div>
</template>
@ -75,6 +73,12 @@ export default {
]
}
},
mounted() {
this.notification = this.$store.state.site.notification
this.notificationType = this.$store.state.site.notificationType
this.allowRegistrations = this.$store.state.site.allowRegistrations
this.rules = this.$store.state.site.rules
},
methods: {
updateState() {
this.axios
@ -92,12 +96,6 @@ export default {
AjaxErrorHandler(this.$store)(e)
})
}
},
mounted() {
this.notification = this.$store.state.site.notification
this.notificationType = this.$store.state.site.notificationType
this.allowRegistrations = this.$store.state.site.allowRegistrations
this.rules = this.$store.state.site.rules
}
}
</script>

View File

@ -2,8 +2,8 @@
<div id="admin-themes">
<v-toolbar color="toolbar">
<v-toolbar-title>Themes ({{ themes.count }})</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn @click="getThemes" icon>
<v-spacer />
<v-btn icon @click="getThemes">
<v-icon>mdi-refresh</v-icon>
</v-btn>
</v-toolbar>
@ -16,10 +16,10 @@
$vuetify.theme.themes[$vuetify.theme.dark ? 'dark' : 'light'].card
"
>
<template v-slot:item.actions="{ item }">
<template #[`item.actions`]="{ item }">
<v-btn text color="primary" @click="applyTheme(item)"> Apply </v-btn>
</template>
<template v-slot:item.theme.css="{ item }">
<template #[`item.theme.css`]="{ item }">
{{ item.theme.css ? "Yes" : "No" }}
</template>
</v-data-table>
@ -78,6 +78,9 @@ export default {
]
}
},
mounted() {
this.getThemes()
},
methods: {
applyTheme(theme) {
this.axios
@ -110,9 +113,6 @@ export default {
AjaxErrorHandler(this.$store)(e)
})
}
},
mounted() {
this.getThemes()
}
}
</script>

View File

@ -1,39 +1,36 @@
<template>
<div id="admin-users">
<v-dialog width="500" v-model="create.dialog">
<v-dialog v-model="create.dialog" width="500">
<v-card color="card">
<v-toolbar color="toolbar">
<v-toolbar-title>Create User</v-toolbar-title>
</v-toolbar>
<v-container>
<v-form @submit.prevent="createUser">
<v-text-field v-model="create.username" label="Username" />
<v-text-field v-model="create.email" label="Email" />
<v-text-field
label="Username"
v-model="create.username"
></v-text-field>
<v-text-field label="Email" v-model="create.email"></v-text-field>
<v-text-field
v-model="create.password"
label="Password"
type="password"
v-model="create.password"
></v-text-field>
/>
<v-switch
v-model="create.emailVerified"
inset
label="Email Verified?"
v-model="create.emailVerified"
></v-switch>
<v-btn text type="submit" color="primary">Create</v-btn>
/>
<v-btn text type="submit" color="primary"> Create </v-btn>
</v-form>
</v-container>
</v-card>
</v-dialog>
<v-toolbar color="toolbar">
<v-toolbar-title>Users ({{ users.count }})</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn @click="create.dialog = true" icon>
<v-spacer />
<v-btn icon @click="create.dialog = true">
<v-icon>mdi-plus</v-icon>
</v-btn>
<v-btn @click="getUsers" icon>
<v-btn icon @click="getUsers">
<v-icon>mdi-refresh</v-icon>
</v-btn>
</v-toolbar>
@ -46,17 +43,17 @@
$vuetify.theme.themes[$vuetify.theme.dark ? 'dark' : 'light'].card
"
>
<template v-slot:item.index="{ index }">
<template #[`item.index`]="{ index }">
{{ index }}
</template>
<template v-slot:item.actions="{ item }">
<template #[`item.actions`]="{ item }">
<v-tooltip top>
<template v-slot:activator="{ on }">
<template #activator="{ on }">
<v-btn
v-on="on"
icon
@click="banUser(item)"
:disabled="item.id === $store.state.user.id || item.admin"
v-on="on"
@click="banUser(item)"
>
<v-icon>mdi-gavel</v-icon>
</v-btn>
@ -141,6 +138,9 @@ export default {
]
}
},
mounted() {
this.getUsers()
},
methods: {
createUser() {
this.axios
@ -197,9 +197,6 @@ export default {
AjaxErrorHandler(this.$store)(e)
})
}
},
mounted() {
this.getUsers()
}
}
</script>

View File

@ -5,7 +5,7 @@
:chat="selectedChat"
:loading="false"
:items="$store.state.chats"
></router-view>
/>
</div>
</template>
@ -23,6 +23,11 @@ export default {
}
}
},
watch: {
selectedChat() {
this.$store.commit("setSelectedChat", this.selectedChat)
}
},
mounted() {
this.$socket.on("memberListUpdate", () => {
this.$store.dispatch("getChats")
@ -30,11 +35,6 @@ export default {
if (!this.$route.params.id) {
this.$router.push("/communications/friends")
}
},
watch: {
selectedChat() {
this.$store.commit("setSelectedChat", this.selectedChat)
}
}
}
</script>

View File

@ -1,9 +1,9 @@
<template>
<div id="communications-chat" @dragover.prevent @drop.prevent="handleDrag">
<v-menu
v-model="$store.state.context.pins.value"
:position-x="$store.state.context.pins.x"
:position-y="60"
v-model="$store.state.context.pins.value"
class="rounded-l elevation-7"
absolute
transition="scroll-y-transition"
@ -12,24 +12,24 @@
>
<v-card min-width="400" max-width="400" color="toolbar">
<v-toolbar color="toolbar lighten-1">
<v-spacer></v-spacer>
<v-spacer />
<v-toolbar-title> Pins </v-toolbar-title>
<v-spacer></v-spacer>
<v-spacer />
</v-toolbar>
<v-divider></v-divider>
<v-divider />
<v-container>
<v-list dense v-if="pins.length" :max-height="600">
<v-list v-if="pins.length" dense :max-height="600">
<v-list-item
@click="jumpToMessage(pin.message.id)"
v-for="(pin, index) in pins"
:key="index"
@click="jumpToMessage(pin.message.id)"
>
<SimpleMessage
:key="pin.message.keyId"
:message="pin.message"
:index="index"
:key="pin.message.keyId"
></SimpleMessage>
<v-spacer></v-spacer>
/>
<v-spacer />
<v-btn icon text @click.stop="removePin(pin.messageId)">
<v-icon> mdi-close </v-icon>
</v-btn>
@ -52,7 +52,7 @@
offset-y
class="rounded-l"
>
<v-list class="rounded-l" v-if="context.message.item">
<v-list v-if="context.message.item" class="rounded-l">
<v-list-item @click="copy(context.message.item.content)">
<v-list-item-title>Copy Message Content</v-list-item-title>
</v-list-item>
@ -60,15 +60,15 @@
<v-list-item-title>Reply to Message</v-list-item-title>
</v-list-item>
<v-list-item
v-if="
context.message.item.userId === $store.state.user.id &&
edit.id !== context.message.item.id
"
@click="
edit.content = context.message.item.content
edit.editing = true
edit.id = context.message.item.id
"
v-if="
context.message.item.userId === $store.state.user.id &&
edit.id !== context.message.item.id
"
>
<v-list-item-title>Edit Message</v-list-item-title>
</v-list-item>
@ -81,9 +81,9 @@
</v-list>
</v-menu>
<UserDialog
:user="context.userPopout"
:key="context.userPopout.item?.id || 0"
></UserDialog>
:user="context.userPopout"
/>
<NicknameDialog :nickname="nickname" />
<v-dialog
v-model="preview.dialog"
@ -100,7 +100,7 @@
:max-height="600"
:min-height="300"
contain
></v-img>
/>
<v-container>
<a :href="preview.src" style="text-decoration: none" target="_blank">
<small> Open Externally </small>
@ -115,10 +115,10 @@
</v-card>
</v-dialog>
<v-navigation-drawer
v-if="$vuetify.breakpoint.mobile"
v-model="$store.state.userPanel"
color="bg"
floating
v-if="$vuetify.breakpoint.mobile"
app
right
style="z-index: 100"
@ -127,10 +127,10 @@
<v-list-item-group class="rounded-xl">
<template v-for="item in associations">
<v-list-item
:id="'user-popout-' + item.userId"
:key="item.title"
@contextmenu="show($event, 'user', item.user)"
@click="openUserPanel(item.user)"
:id="'user-popout-' + item.userId"
>
<v-badge
bordered
@ -162,10 +162,10 @@
</v-list-item-group>
</v-list>
</v-navigation-drawer>
<v-row @drop="handleDrag" no-gutters style="overflow: hidden">
<v-row no-gutters style="overflow: hidden" @drop="handleDrag">
<v-col
class="flex-grow-1 flex-shrink-1 pb-0"
id="chat-col"
class="flex-grow-1 flex-shrink-1 pb-0"
style="overflow: hidden"
>
<v-card
@ -176,40 +176,41 @@
>
<v-card-text>
<v-toolbar
@click="jumpToMessage(replying?.id)"
v-if="replying"
elevation="0"
height="35"
color="card"
v-if="replying"
style="cursor: pointer; overflow: hidden"
@click="jumpToMessage(replying?.id)"
>
<v-icon class="mr-2">mdi-reply</v-icon>
<v-icon class="mr-2"> mdi-reply </v-icon>
<v-avatar size="24" class="mr-2">
<v-img
v-if="replying.user.avatar"
:src="
$store.state.baseURL +
'/usercontent/' +
replying.user.avatar
"
v-if="replying.user.avatar"
class="elevation-1"
/>
<v-icon v-else class="elevation-1"> mdi-account </v-icon>
</v-avatar>
<template v-if="replying.attachments.length">
<v-icon class="mr-2">mdi-file-image</v-icon>
<v-icon class="mr-2"> mdi-file-image </v-icon>
</template>
<template v-if="!replying.content && replying.attachments.length">
Click to view attachment
</template>
{{ replying.content.substring(0, 100) }}
<v-spacer></v-spacer>
<v-btn icon @click="replying = null" class="mr-2" small>
<v-spacer />
<v-btn icon class="mr-2" small @click="replying = null">
<v-icon> mdi-close </v-icon>
</v-btn>
</v-toolbar>
<v-fade-transition v-model="avoidAutoScroll">
<v-toolbar
v-if="avoidAutoScroll"
height="24"
color="toolbar"
elevation="0"
@ -223,7 +224,6 @@
"
width="100%"
@click="forceScroll"
v-if="avoidAutoScroll"
>
<div>
<v-icon size="16px"> mdi-arrow-down </v-icon>
@ -232,17 +232,17 @@
</v-toolbar>
</v-fade-transition>
<v-fade-transition
v-model="usersTyping.length"
v-if="$vuetify.breakpoint.mobile"
v-model="usersTyping.length"
>
<div
v-if="usersTyping.length"
style="
border-radius: 0 0 20px 20px;
position: relative;
top: -30px;
margin-bottom: -22px;
"
v-if="usersTyping.length"
>
{{ usersTyping.map((user) => getName(user)).join(", ") }}
{{ usersTyping.length > 1 ? " are" : " is" }} typing...
@ -251,29 +251,29 @@
<CommsInput
:chat="chat"
:replying="replying"
:editLastMessage="editLastMessage"
:autoScroll="autoScroll"
:endSend="endSend"
></CommsInput>
:edit-last-message="editLastMessage"
:auto-scroll="autoScroll"
:end-send="endSend"
/>
<v-fade-transition
v-model="usersTyping.length"
v-if="!$vuetify.breakpoint.mobile"
v-model="usersTyping.length"
>
<div
v-if="usersTyping.length"
style="
border-radius: 0 0 20px 20px;
position: absolute;
margin-top: -2px;
bottom: 1px;
"
v-if="usersTyping.length"
>
{{ usersTyping.map((user) => getName(user)).join(", ") }}
{{ usersTyping.length > 1 ? " are" : " is" }} typing...
</div>
</v-fade-transition>
</v-card-text>
<v-card-text class="flex-grow-1 overflow-y-auto" id="message-list">
<v-card-text id="message-list" class="flex-grow-1 overflow-y-auto">
<v-card-title
v-if="
reachedTop && $store.state.selectedChat?.chat?.type === 'group'
@ -299,11 +299,11 @@
indeterminate
size="64"
style="display: block; width: 100px; margin: 0 auto"
></v-progress-circular>
/>
<template v-for="(message, index) in messages">
<div
:key="'div2-' + message.keyId"
v-if="message.readReceipts.length"
:key="'div2-' + message.keyId"
>
<v-tooltip
v-for="association in message.readReceipts"
@ -311,8 +311,8 @@
top
>
<template
v-slot:activator="{ on }"
v-if="association.user.id !== $store.state.user.id"
#activator="{ on }"
>
<v-btn
icon
@ -324,7 +324,7 @@
style="float: right"
@click="openUserPanel(association.user)"
>
<v-avatar size="20" v-on="on" color="primary">
<v-avatar size="20" color="primary" v-on="on">
<img
v-if="association.user.avatar"
:src="
@ -371,16 +371,16 @@
!message.replyId &&
!message.type
"
></Message>
/>
</template>
</v-card-text>
</v-card>
</v-col>
<v-col
v-if="$store.state.searchPanel && !$vuetify.breakpoint.mobile"
id="search-col"
cols="3"
class=""
id="search-col"
v-if="$store.state.searchPanel && !$vuetify.breakpoint.mobile"
style="z-index: 15"
>
<v-card
@ -393,7 +393,7 @@
<v-toolbar-title>
Search ({{ search.pager.totalItems || 0 }})
</v-toolbar-title>
<v-spacer></v-spacer>
<v-spacer />
<v-btn icon @click="$store.state.searchPanel = false">
<v-icon>mdi-close</v-icon>
</v-btn>
@ -405,13 +405,13 @@
outlined
autofocus
@keydown.enter="doSearch"
></v-text-field>
<v-list two-line color="card" ref="message-list-search">
/>
<v-list ref="message-list-search" two-line color="card">
<template v-for="(message, index) in search.results">
<div
@click="jumpToMessage(message.id)"
:key="message.keyId"
style="cursor: pointer"
@click="jumpToMessage(message.id)"
>
<Message
:message="message"
@ -428,7 +428,7 @@
:set-image-preview="setImagePreview"
:delete-message="deleteMessage"
:last-message="false"
></Message>
/>
</div>
</template>
<v-pagination
@ -436,19 +436,19 @@
class="my-4"
:length="search.pager.totalPages"
@input="doSearch"
></v-pagination>
/>
</v-list>
</v-card-text>
</v-card>
</v-col>
<v-col
:cols="$vuetify.breakpoint.xl ? 2 : 3"
id="user-col"
v-if="
$store.state.userPanel &&
!$vuetify.breakpoint.mobile &&
!$store.state.searchPanel
"
id="user-col"
:cols="$vuetify.breakpoint.xl ? 2 : 3"
>
<v-card
class="d-flex flex-column fill-height rounded-0"
@ -464,17 +464,17 @@
offset-y
class="rounded-l"
>
<v-list class="rounded-l" v-if="context.user.item">
<v-list v-if="context.user.item" class="rounded-l">
<v-list-item
@click="
nickname.dialog = true
nickname.user = context.user.item
"
>
<v-list-item-title
>Change Friend Nickname for
{{ context.user.item.username }}</v-list-item-title
>
<v-list-item-title>
Change Friend Nickname for
{{ context.user.item.username }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
@ -482,10 +482,10 @@
<v-list-item-group class="rounded-xl">
<template v-for="item in associations">
<v-list-item
:id="'user-popout-' + item.userId"
:key="item.title"
@contextmenu="show($event, 'user', item.user)"
@click="openUserPanel(item.user)"
:id="'user-popout-' + item.userId"
>
<v-badge
bordered
@ -513,25 +513,25 @@
<v-list-item-content>
<v-list-item-title>
{{ getName(item.user) }}
<v-tooltip top v-if="item.user.admin">
<template v-slot:activator="{ on }">
<v-btn icon v-on="on" small>
<v-tooltip v-if="item.user.admin" top>
<template #activator="{ on }">
<v-btn icon small v-on="on">
<v-icon> mdi-crown </v-icon>
</v-btn>
</template>
<span>Colubrina Instance Administrator</span>
</v-tooltip>
<v-tooltip top v-if="item.user.bot">
<template v-slot:activator="{ on }">
<v-btn icon v-on="on" small>
<v-tooltip v-if="item.user.bot" top>
<template #activator="{ on }">
<v-btn icon small v-on="on">
<v-icon> mdi-robot </v-icon>
</v-btn>
</template>
<span>Bot</span>
</v-tooltip>
<v-tooltip top v-if="item.user.id < 35">
<template v-slot:activator="{ on }">
<v-btn icon v-on="on" small>
<v-tooltip v-if="item.user.id < 35" top>
<template #activator="{ on }">
<v-btn icon small v-on="on">
<v-icon> mdi-alpha-a-circle </v-icon>
</v-btn>
</template>
@ -709,6 +709,178 @@ export default {
}
}
},
watch: {
"$store.state.context.pins.value"(val) {
if (val) {
this.getPins()
}
},
userPanel() {
localStorage.setItem("userPanel", JSON.stringify(this.userPanel))
},
"$route.path"() {
const tryParse = this.$route.params.id
if (!tryParse) {
// remove event listeners
document.removeEventListener("keypress", this.focusKey)
document.removeEventListener("keydown", this.escPressed)
document
.getElementById("message-list")
.removeEventListener("scroll", this.scrollEvent)
clearInterval(this.interval)
}
},
"$route.params.id"(val, oldVal) {
this.focusInput()
let drafts = {}
if (localStorage.getItem("drafts")) {
drafts = JSON.parse(localStorage.getItem("drafts"))
}
if (this.message && drafts[oldVal]) {
drafts[oldVal] = this.message
localStorage.setItem("drafts", JSON.stringify(drafts))
} else if (!this.message && drafts[oldVal]) {
drafts[oldVal] = ""
}
this.message = drafts[val] || ""
this.usersTyping = []
this.replying = null
this.reachedTop = false
this.avoidAutoScroll = false
this.offset = null
this.pins = []
this.messages = []
this.getMessages()
}
},
mounted() {
this.$socket.on("memberListUpdate", () => {
this.$store.dispatch("getChats")
})
if (!this.$route.params.id) {
this.$router.push("/communications/friends")
return
}
document.addEventListener("keypress", this.focusKey)
document.addEventListener("keydown", this.escPressed)
document
.getElementById("message-list")
.addEventListener("scroll", this.scrollEvent)
this.interval = setInterval(() => {
this.typing()
if (
document.hasFocus() &&
this.messages[this.messages.length - 1]?.id !== this.lastRead
) {
this.markRead()
}
}, 1000)
this.getMessages()
if (localStorage.getItem("userPanel")) {
this.userPanel = JSON.parse(localStorage.getItem("userPanel"))
} else {
localStorage.setItem("userPanel", true)
}
let drafts = {}
if (localStorage.getItem("drafts")) {
drafts = JSON.parse(localStorage.getItem("drafts"))
}
if (drafts[this.$route.params.id]) {
this.message = drafts[this.$route.params.id]
}
this.$socket.on("readChat", (data) => {
if (!this.chat) return
if (data.id === this.chat?.id) {
this.lastRead = data.lastRead
}
})
this.$socket.on("readReceipt", (data) => {
if (!this.chat) return
try {
if (
data.messageId &&
data.chatId === this.chat.chatId &&
this.messages?.length
) {
this.messages.forEach((message) => {
message.readReceipts = message.readReceipts.filter(
(readReceipt) => readReceipt.id !== data.id
)
})
this.messages
.find((message) => message.id === data.messageId)
.readReceipts?.push(data)
this.autoScroll()
}
} catch (e) {
console.log("Read receipt error", e)
}
})
this.$socket.on("message", (message) => {
try {
if (!this.chat) return
if (message.chatId === this.chat.chatId) {
this.messages.push(message)
this.autoScroll()
if (document.hasFocus()) {
this.markRead()
}
if (this.messages.length > 50 && !this.avoidAutoScroll) {
this.messages.shift()
this.reachedTop = false
}
}
} catch (e) {
console.log("Message error", e)
}
})
this.$socket.on("editMessage", (message) => {
if (message.chatId === this.chat.chatId) {
const index = this.messages.findIndex((item) => item.id === message.id)
if (index !== -1) {
this.messages[index].content = message.content
this.messages[index].edited = message.edited
this.messages[index].editedAt = message.editedAt
this.messages[index].keyId = message.id + "-" + message.editedAt
}
}
})
this.$socket.on("messageEmbedResolved", (message) => {
if (message.chatId === this.chat.chatId) {
const index = this.messages.findIndex((item) => item.id === message.id)
if (index !== -1) {
this.messages[index].keyId = message.id + "-" + message.editedAt
this.messages[index].embeds = message.embeds
this.autoScroll()
}
}
})
this.$socket.on("typing", (event) => {
if (event.chatId === this.chat.chatId) {
const index = this.usersTyping.findIndex(
(item) => item.userId === event.userId
)
if (index > -1) {
this.usersTyping.splice(index, 1)
}
this.usersTyping.push(event)
}
})
this.$socket.on("deleteMessage", (message) => {
if (message.chatId === this.chat.chatId) {
const index = this.messages.findIndex((item) => item.id === message.id)
if (index !== -1) {
this.messages.splice(index, 1)
}
}
})
},
destroyed() {
document.removeEventListener("keypress", this.focusKey)
document.removeEventListener("keydown", this.escPressed)
document.removeEventListener("scroll", this.scrollEvent)
clearInterval(this.interval)
},
methods: {
copy(content) {
navigator.clipboard.writeText(content)
@ -1090,178 +1262,6 @@ export default {
this.$store.state.searchPanel = false
}
}
},
mounted() {
this.$socket.on("memberListUpdate", () => {
this.$store.dispatch("getChats")
})
if (!this.$route.params.id) {
this.$router.push("/communications/friends")
return
}
document.addEventListener("keypress", this.focusKey)
document.addEventListener("keydown", this.escPressed)
document
.getElementById("message-list")
.addEventListener("scroll", this.scrollEvent)
this.interval = setInterval(() => {
this.typing()
if (
document.hasFocus() &&
this.messages[this.messages.length - 1]?.id !== this.lastRead
) {
this.markRead()
}
}, 1000)
this.getMessages()
if (localStorage.getItem("userPanel")) {
this.userPanel = JSON.parse(localStorage.getItem("userPanel"))
} else {
localStorage.setItem("userPanel", true)
}
let drafts = {}
if (localStorage.getItem("drafts")) {
drafts = JSON.parse(localStorage.getItem("drafts"))
}
if (drafts[this.$route.params.id]) {
this.message = drafts[this.$route.params.id]
}
this.$socket.on("readChat", (data) => {
if (!this.chat) return
if (data.id === this.chat?.id) {
this.lastRead = data.lastRead
}
})
this.$socket.on("readReceipt", (data) => {
if (!this.chat) return
try {
if (
data.messageId &&
data.chatId === this.chat.chatId &&
this.messages?.length
) {
this.messages.forEach((message) => {
message.readReceipts = message.readReceipts.filter(
(readReceipt) => readReceipt.id !== data.id
)
})
this.messages
.find((message) => message.id === data.messageId)
.readReceipts?.push(data)
this.autoScroll()
}
} catch (e) {
console.log("Read receipt error", e)
}
})
this.$socket.on("message", (message) => {
try {
if (!this.chat) return
if (message.chatId === this.chat.chatId) {
this.messages.push(message)
this.autoScroll()
if (document.hasFocus()) {
this.markRead()
}
if (this.messages.length > 50 && !this.avoidAutoScroll) {
this.messages.shift()
this.reachedTop = false
}
}
} catch (e) {
console.log("Message error", e)
}
})
this.$socket.on("editMessage", (message) => {
if (message.chatId === this.chat.chatId) {
const index = this.messages.findIndex((item) => item.id === message.id)
if (index !== -1) {
this.messages[index].content = message.content
this.messages[index].edited = message.edited
this.messages[index].editedAt = message.editedAt
this.messages[index].keyId = message.id + "-" + message.editedAt
}
}
})
this.$socket.on("messageEmbedResolved", (message) => {
if (message.chatId === this.chat.chatId) {
const index = this.messages.findIndex((item) => item.id === message.id)
if (index !== -1) {
this.messages[index].keyId = message.id + "-" + message.editedAt
this.messages[index].embeds = message.embeds
this.autoScroll()
}
}
})
this.$socket.on("typing", (event) => {
if (event.chatId === this.chat.chatId) {
const index = this.usersTyping.findIndex(
(item) => item.userId === event.userId
)
if (index > -1) {
this.usersTyping.splice(index, 1)
}
this.usersTyping.push(event)
}
})
this.$socket.on("deleteMessage", (message) => {
if (message.chatId === this.chat.chatId) {
const index = this.messages.findIndex((item) => item.id === message.id)
if (index !== -1) {
this.messages.splice(index, 1)
}
}
})
},
watch: {
"$store.state.context.pins.value"(val) {
if (val) {
this.getPins()
}
},
userPanel() {
localStorage.setItem("userPanel", JSON.stringify(this.userPanel))
},
"$route.path"() {
const tryParse = this.$route.params.id
if (!tryParse) {
// remove event listeners
document.removeEventListener("keypress", this.focusKey)
document.removeEventListener("keydown", this.escPressed)
document
.getElementById("message-list")
.removeEventListener("scroll", this.scrollEvent)
clearInterval(this.interval)
}
},
"$route.params.id"(val, oldVal) {
this.focusInput()
let drafts = {}
if (localStorage.getItem("drafts")) {
drafts = JSON.parse(localStorage.getItem("drafts"))
}
if (this.message || drafts[oldVal]) {
drafts[oldVal] = this.message
localStorage.setItem("drafts", JSON.stringify(drafts))
} else if (!this.message && drafts[oldVal]) {
drafts[oldVal] = ""
}
this.message = drafts[val] || ""
this.usersTyping = []
this.replying = null
this.reachedTop = false
this.avoidAutoScroll = false
this.offset = null
this.pins = []
this.messages = []
this.getMessages()
}
},
destroyed() {
document.removeEventListener("keypress", this.focusKey)
document.removeEventListener("keydown", this.escPressed)
document.removeEventListener("scroll", this.scrollEvent)
clearInterval(this.interval)
}
}
</script>

View File

@ -1,8 +1,8 @@
<template>
<div id="communications-friends">
<v-card color="card" class="rounded-0" :height="viewport()" elevation="0">
<v-tabs centered background-color="card" v-model="tab">
<v-tab :key="0">Users</v-tab>
<v-tabs v-model="tab" centered background-color="card">
<v-tab :key="0"> Users </v-tab>
<v-tab :key="1"> Friends </v-tab>
<v-tab :key="2"> Add new friend </v-tab>
<v-tab-item
@ -16,31 +16,31 @@
<v-toolbar-title> Users </v-toolbar-title>
</v-toolbar>
<v-card color="card" elevation="0">
<v-list color="card" v-if="$store.state.site.publicUsers">
<v-list v-if="$store.state.site.publicUsers" color="card">
<v-list-item v-for="user in users" :key="user.id">
<v-list-item-avatar
@click="userProfile(user)"
style="cursor: pointer"
:color="$vuetify.theme.themes.dark?.primary"
@click="userProfile(user)"
>
<v-img
v-if="user.avatar"
:src="
$store.state.baseURL + '/usercontent//' + user.avatar
"
v-if="user.avatar"
/>
<v-icon v-else> mdi-account </v-icon>
</v-list-item-avatar>
<v-list-item-content
@click="userProfile(user)"
style="cursor: pointer"
@click="userProfile(user)"
>
<v-list-item-title>
{{ user.username }}
<v-tooltip top v-if="user.admin">
<template v-slot:activator="{ on }">
<v-btn icon v-on="on" class="ml-1">
<v-tooltip v-if="user.admin" top>
<template #activator="{ on }">
<v-btn icon class="ml-1" v-on="on">
<v-icon> mdi-crown </v-icon>
</v-btn>
</template>
@ -55,7 +55,9 @@
"
>
<v-btn icon>
<v-icon @click="addFriend(user)">mdi-account-plus</v-icon>
<v-icon @click="addFriend(user)">
mdi-account-plus
</v-icon>
</v-btn>
</v-list-item-action>
<v-list-item-action
@ -70,9 +72,9 @@
</v-list-item-action>
</v-list-item>
</v-list>
<v-card-title v-else
>Public users are not enabled on this instance.</v-card-title
>
<v-card-title v-else>
Public users are not enabled on this instance.
</v-card-title>
</v-card>
</v-card>
</v-tab-item>
@ -100,16 +102,16 @@
:key="friend.id"
>
<v-list-item-avatar
@click="userProfile(friend.user2)"
:color="$vuetify.theme.themes.dark?.primary"
@click="userProfile(friend.user2)"
>
<v-img
v-if="friend.user2.avatar"
:src="
$store.state.baseURL +
'/usercontent//' +
friend.user2.avatar
"
v-if="friend.user2.avatar"
/>
<v-icon v-else> mdi-account </v-icon>
</v-list-item-avatar>
@ -121,16 +123,16 @@
</v-list-item-content>
<v-list-item-action>
<v-btn icon>
<v-icon color="error" @click="removeFriend(friend)"
>mdi-close</v-icon
>
<v-icon color="error" @click="removeFriend(friend)">
mdi-close
</v-icon>
</v-btn>
</v-list-item-action>
<v-list-item-action>
<v-btn icon>
<v-icon color="success" @click="acceptFriend(friend)">
mdi-check</v-icon
>
mdi-check
</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
@ -153,24 +155,24 @@
:key="friend.id"
>
<v-list-item-avatar
@click="userProfile(friend.user2)"
style="cursor: pointer"
:color="$vuetify.theme.themes.dark?.primary"
@click="userProfile(friend.user2)"
>
<v-img
v-if="friend.user2.avatar"
:src="
$store.state.baseURL +
'/usercontent//' +
friend.user2.avatar
"
v-if="friend.user2.avatar"
/>
<v-icon v-else> mdi-account </v-icon>
</v-list-item-avatar>
<v-list-item-content
@click="userProfile(friend.user2)"
style="cursor: pointer"
@click="userProfile(friend.user2)"
>
<v-list-item-title>
{{ friend.user2.username }}
@ -178,9 +180,9 @@
</v-list-item-content>
<v-list-item-action>
<v-btn icon>
<v-icon color="error" @click="removeFriend(friend)"
>mdi-close</v-icon
>
<v-icon color="error" @click="removeFriend(friend)">
mdi-close
</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
@ -200,17 +202,17 @@
</v-list-item>
<v-list-item v-for="friend in computeAccepted" :key="friend.id">
<v-list-item-avatar
@click="userProfile(friend.user2)"
style="cursor: pointer"
:color="$vuetify.theme.themes.dark?.primary"
@click="userProfile(friend.user2)"
>
<v-img
v-if="friend.user2.avatar"
:src="
$store.state.baseURL +
'/usercontent//' +
friend.user2.avatar
"
v-if="friend.user2.avatar"
/>
<v-icon v-else> mdi-account </v-icon>
</v-list-item-avatar>
@ -222,9 +224,9 @@
</v-list-item-content>
<v-list-item-action>
<v-btn icon>
<v-icon color="error" @click="removeFriend(friend)"
>mdi-close</v-icon
>
<v-icon color="error" @click="removeFriend(friend)">
mdi-close
</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
@ -246,15 +248,14 @@
friends with them. You can add them here.
</p>
<v-text-field
@keyup.enter="addFriend(null)"
v-model="friend"
label="Friend username"
:placeholder="'BTR0001'"
v-model="friend"
>
</v-text-field>
@keyup.enter="addFriend(null)"
/>
</v-container>
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn color="primary" text @click="addFriend(null)">
Send Request
</v-btn>
@ -292,6 +293,19 @@ export default {
)
}
},
async mounted() {
this.getFriends()
this.getUsers()
this.$socket.on("friendRequest", () => {
this.getFriends()
})
this.$socket.on("friendUpdate", () => {
this.getFriends()
})
this.$socket.on("friendAccepted", () => {
this.getFriends()
})
},
methods: {
userProfile() {
// todo
@ -372,19 +386,6 @@ export default {
this.friends = res.data
})
}
},
async mounted() {
this.getFriends()
this.getUsers()
this.$socket.on("friendRequest", () => {
this.getFriends()
})
this.$socket.on("friendUpdate", () => {
this.getFriends()
})
this.$socket.on("friendAccepted", () => {
this.getFriends()
})
}
}
</script>

View File

@ -6,11 +6,7 @@
<v-toolbar-title> Email Confirmation </v-toolbar-title>
</v-toolbar>
<v-container v-if="loading" class="text-center justify-center">
<v-progress-circular
size="64"
:indeterminate="true"
class="mb-3"
></v-progress-circular>
<v-progress-circular size="64" :indeterminate="true" class="mb-3" />
<h3>We're currently confirming your email address. Please wait.</h3>
</v-container>
<v-container v-else-if="failed" class="text-center justify-center">

View File

@ -11,9 +11,9 @@
follow the instructions provided.
</h3>
<p class="mt-2">Haven't received it?</p>
<v-btn color="primary" text @click="resend" :loading="loading"
>Resend</v-btn
>
<v-btn color="primary" text :loading="loading" @click="resend">
Resend
</v-btn>
</v-container>
</v-card>
</v-container>
@ -30,6 +30,9 @@ export default {
loading: true
}
},
mounted() {
this.resend()
},
methods: {
resend() {
this.loading = true
@ -44,9 +47,6 @@ export default {
AjaxErrorHandler(this.$store)(e)
})
}
},
mounted() {
this.resend()
}
}
</script>

View File

@ -1,24 +1,24 @@
<template>
<div id="login" v-if="!$store.state.user?.bcUser?.id">
<div v-if="!$store.state.user?.bcUser?.id" id="login">
<v-dialog v-model="totpDialog" max-width="500px">
<v-card color="card">
<v-toolbar color="toolbar">
<v-toolbar-title> Two-Factor Authentication </v-toolbar-title>
</v-toolbar>
<v-container>
<v-card-text
>You are seeing this because you have enabled Two-Factor
<v-card-text>
You are seeing this because you have enabled Two-Factor
Authentication on {{ $store.state.site.name }}.<br />
Please check your phone, or authenticator app to obtain the 6 digit
code and enter it here.</v-card-text
>
code and enter it here.
</v-card-text>
<v-otp-input
v-model="totp"
length="6"
:disabled="loading"
@keyup.enter="doLogin()"
@finish="doLogin()"
v-model="totp"
:disabled="loading"
></v-otp-input>
/>
</v-container>
</v-card>
</v-dialog>
@ -33,64 +33,60 @@
<span class="troplo-title">{{ $store.state.site.name }}</span>
</p>
<v-text-field
@keyup.enter="doLogin()"
class="rounded-xl"
v-model="instance"
v-if="isElectron()"
v-model="instance"
class="rounded-xl"
label="Instance URL"
placeholder="https://colubrina.troplo.com"
type="email"
></v-text-field>
<small style="float: right" v-if="isElectron()">{{
@keyup.enter="doLogin()"
/>
<small v-if="isElectron()" style="float: right">{{
instanceString
}}</small
><br v-if="isElectron()" />
<v-text-field
@keyup.enter="doLogin()"
class="rounded-xl"
v-model="customHeaders[header.name]"
v-for="header in $store.state.site.customHeaders"
:key="header.name"
v-model="customHeaders[header.name]"
class="rounded-xl"
:label="header.friendlyName"
:placeholder="header.placeholder"
type="email"
></v-text-field>
<v-text-field
@keyup.enter="doLogin()"
class="rounded-xl"
/>
<v-text-field
v-model="username"
class="rounded-xl"
label="Username"
placeholder="FOO1000"
type="email"
></v-text-field>
<v-text-field
@keyup.enter="doLogin()"
class="rounded-xl"
/>
<v-text-field
v-model="password"
class="rounded-xl"
color="blue accent-7"
label="Password"
type="password"
></v-text-field>
@keyup.enter="doLogin()"
/>
<p
style="float: right; color: #2196f3; cursor: pointer"
@click="doPasswordReset()"
>
Reset your Password
</p>
<v-switch
inset
label="Remember Me"
v-model="rememberMe"
></v-switch>
<v-switch v-model="rememberMe" inset label="Remember Me" />
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn
v-if="$store.state.site.allowRegistrations"
class="rounded-xl"
:loading="loading"
color="primary"
text
@click="$router.push('/register')"
v-if="$store.state.site.allowRegistrations"
>
Register
</v-btn>
@ -133,18 +129,40 @@ export default {
customHeaders: {}
}
},
watch: {
instance() {
this.testInstance()
}
},
mounted() {
this.$store
.dispatch("getUserInfo")
.then(() => {
this.$router.push("/")
})
.catch(() => {
this.$store.state.user = {
bcUser: null,
loggedIn: false
}
})
this.testInstance()
},
methods: {
doPasswordReset() {
this.loading = true
this.axios.post("/api/v1/user/reset/send", {
email: this.username
}).then(() => {
this.loading = false
this.$toast.success("Password reset sent, check your email!")
}).catch((e) => {
this.loading = false
AjaxErrorHandler(this.$store)(e)
})
this.axios
.post("/api/v1/user/reset/send", {
email: this.username
})
.then(() => {
this.loading = false
this.$toast.success("Password reset sent, check your email!")
})
.catch((e) => {
this.loading = false
AjaxErrorHandler(this.$store)(e)
})
},
isElectron() {
return process.env.IS_ELECTRON
@ -223,25 +241,6 @@ export default {
})
}
}
},
mounted() {
this.$store
.dispatch("getUserInfo")
.then(() => {
this.$router.push("/")
})
.catch(() => {
this.$store.state.user = {
bcUser: null,
loggedIn: false
}
})
this.testInstance()
},
watch: {
instance() {
this.testInstance()
}
}
}
</script>

View File

@ -3,13 +3,13 @@
<v-container>
<v-card color="card" class="rounded-xl">
<v-toolbar color="toolbar">
<v-spacer></v-spacer>
<v-spacer />
<v-toolbar-title> Not Found </v-toolbar-title>
<v-spacer></v-spacer>
<v-spacer />
</v-toolbar>
<v-container class="text-center justify-center">
<h1>The page you were looking for couldn't be found.</h1>
<v-btn color="primary" text to="/">Home</v-btn>
<v-btn color="primary" text to="/"> Home </v-btn>
</v-container>
</v-card>
</v-container>

View File

@ -8,23 +8,23 @@
<v-card-text>
<v-form>
<v-text-field
@keyup.enter="doPasswordReset()"
class="rounded-xl"
v-model="password"
class="rounded-xl"
label="Password"
type="password"
></v-text-field>
<v-text-field
@keyup.enter="doPasswordReset()"
class="rounded-xl"
/>
<v-text-field
v-model="confirmPassword"
class="rounded-xl"
label="Confirm Password"
type="password"
></v-text-field>
@keyup.enter="doPasswordReset()"
/>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn
class="rounded-xl"
:loading="loading"

View File

@ -1,5 +1,5 @@
<template>
<div id="login" v-if="!$store.state.user?.id">
<div v-if="!$store.state.user?.id" id="login">
<v-dialog v-model="rulesDialog" max-width="700px">
<v-card color="card">
<v-toolbar color="toolbar">
@ -8,7 +8,7 @@
</v-toolbar-title>
</v-toolbar>
<v-card-text class="mt-3" style="color: unset">
<span v-markdown :key="$store.state.site.rules">{{
<span :key="$store.state.site.rules" v-markdown>{{
$store.state.site.rules
}}</span>
</v-card-text>
@ -25,80 +25,80 @@
<span class="troplo-title">{{ $store.state.site.name }}</span>
</p>
<v-text-field
@keyup.enter="doRegister()"
class="rounded-xl"
v-model="instance"
v-if="isElectron()"
v-model="instance"
class="rounded-xl"
label="Instance URL"
placeholder="https://colubrina.troplo.com"
type="email"
></v-text-field>
<small style="float: right" v-if="isElectron()">{{
@keyup.enter="doRegister()"
/>
<small v-if="isElectron()" style="float: right">{{
instanceString
}}</small
><br v-if="isElectron()" />
<v-text-field
@keyup.enter="doRegister()"
class="rounded-xl"
v-model="username"
class="rounded-xl"
label="Username"
placeholder="FOO1000"
type="email"
></v-text-field>
<v-text-field
@keyup.enter="doRegister()"
class="rounded-xl"
/>
<v-text-field
v-model="email"
class="rounded-xl"
label="Email"
placeholder="troplo@troplo.com"
type="email"
></v-text-field>
<v-text-field
@keyup.enter="doRegister()"
class="rounded-xl"
/>
<v-text-field
v-model="password"
class="rounded-xl"
color="blue accent-7"
label="Password"
type="password"
></v-text-field>
@keyup.enter="doRegister()"
/>
<small v-if="$store.state.site.emailVerification"
>This instance has email verification enforced, ensure your
email is correct.</small
>
<v-row align="center">
<v-tooltip top v-if="!rulesOpenedOnce">
<template v-slot:activator="{ on }">
<v-tooltip v-if="!rulesOpenedOnce" top>
<template #activator="{ on }">
<div v-on="on">
<v-switch
v-model="rules"
class="ml-4 mt-5"
inset
v-model="rules"
:disabled="!rulesOpenedOnce"
></v-switch>
/>
</div>
</template>
<span>You need to view the rules first.</span>
</v-tooltip>
<v-switch
v-else
v-model="rules"
class="ml-4 mt-5"
inset
v-model="rules"
v-else
:disabled="!rulesOpenedOnce"
></v-switch>
/>
I have read and agree to the&nbsp;
<a
target="_blank"
@click="
rulesDialog = true
rulesOpenedOnce = true
"
target="_blank"
>
instance rules </a
>.
</v-row>
<v-card-actions>
<v-spacer></v-spacer>
<v-spacer />
<v-btn
class="rounded-xl"
:loading="loading"
@ -149,6 +149,25 @@ export default {
instanceString: ""
}
},
watch: {
instance() {
this.testInstance()
}
},
mounted() {
this.$store
.dispatch("getUserInfo")
.then(() => {
this.$router.push("/")
})
.catch(() => {
this.$store.state.user = {
bcUser: null,
loggedIn: false
}
})
this.testInstance()
},
methods: {
isElectron() {
return process.env.IS_ELECTRON
@ -229,25 +248,6 @@ export default {
}
})
}
},
mounted() {
this.$store
.dispatch("getUserInfo")
.then(() => {
this.$router.push("/")
})
.catch(() => {
this.$store.state.user = {
bcUser: null,
loggedIn: false
}
})
this.testInstance()
},
watch: {
instance() {
this.testInstance()
}
}
}
</script>

View File

@ -12,7 +12,7 @@
<v-tab to="/settings/security"> Security </v-tab>
<v-tab to="/settings/sessions"> Sessions </v-tab>
</v-tabs>
<router-view> </router-view>
<router-view />
<div class="mx-4">
<small
>Troplo/Colubrina version {{ $store.state.versioning.version }},

View File

@ -5,10 +5,10 @@
v-model="$store.state.user.theme"
true-value="dark"
false-value="light"
@change="saveSettings"
inset
label="Dark theme"
></v-switch>
@change="saveSettings"
/>
</v-card-text>
<v-alert
v-if="
@ -23,41 +23,41 @@
You currently have a theme enabled that is not designed for your selected
base theme.
</v-alert>
<v-card-text
><v-switch
inset
<v-card-text>
<v-switch
v-model="defineAccent"
inset
label="Use a custom accent color (overrides theme's primary attribute)."
></v-switch>
/>
<v-color-picker
v-if="defineAccent"
v-model="accent"
hide-canvas
value="hex"
hide-inputs
show-swatches
swatches-max-height="132"
v-model="accent"
></v-color-picker>
/>
</v-card-text>
<v-col sm="4">
<v-select
v-model="$store.state.user.font"
:items="fonts"
@change="setFont"
label="Font"
item-text="name"
item-value="name"
></v-select>
@change="setFont"
/>
</v-col>
<v-card-text>
<v-card
class="my-2"
@click="setTheme(theme)"
hover
outlined
v-for="(theme, index) in computeThemes"
:key="index"
class="my-2"
hover
outlined
color="card"
@click="setTheme(theme)"
>
<v-list-item>
<v-list-item-content>
@ -67,20 +67,20 @@
<v-icon>mdi-download</v-icon>
</v-btn>
<v-btn
v-if="theme.userId === $store.state.user.id"
text
fab
small
@click="initEditTheme(theme)"
v-if="theme.userId === $store.state.user.id"
>
<v-icon>mdi-pencil</v-icon>
</v-btn>
<v-btn
v-if="theme.userId === $store.state.user.id"
text
fab
small
@click="doDeleteTheme(theme)"
v-if="theme.userId === $store.state.user.id"
>
<v-icon>mdi-delete</v-icon>
</v-btn>
@ -95,44 +95,44 @@
</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-avatar color="success" size="30" v-if="name === theme.id">
<v-avatar v-if="name === theme.id" color="success" size="30">
<v-icon>mdi-check</v-icon>
</v-avatar>
</v-list-item-action>
</v-list-item>
<div class="my-2" v-if="$vuetify.theme.dark">
<div v-if="$vuetify.theme.dark" class="my-2">
<v-chip-group>
<v-chip
v-for="(key, index) in Object.keys(theme.dark)"
:key="index"
disabled
style="opacity: 1"
class="mx-1"
label
:color="theme.dark[key]"
v-for="(key, index) in Object.keys(theme.dark)"
:key="index"
>
{{ friendlyName(key) }}</v-chip
>
{{ friendlyName(key) }}
</v-chip>
</v-chip-group>
</div>
<div class="my-2" v-if="!$vuetify.theme.dark">
<div v-if="!$vuetify.theme.dark" class="my-2">
<v-chip-group column>
<v-chip
v-for="(key, index) in Object.keys(theme.light)"
:key="index"
class="mx-1"
label
:color="theme.light[key]"
v-for="(key, index) in Object.keys(theme.light)"
:key="index"
>
{{ key }}</v-chip
>
{{ key }}
</v-chip>
</v-chip-group>
</div>
</v-card>
<v-container class="text-center justify-center">
<v-chip @click="initThemeCreator" x-large outlined fab
><v-icon x-large>mdi-plus</v-icon></v-chip
>
<v-chip x-large outlined fab @click="initThemeCreator">
<v-icon x-large> mdi-plus </v-icon>
</v-chip>
</v-container>
</v-card-text>
</div>
@ -229,6 +229,52 @@ export default {
}
}
},
watch: {
"$store.state.themeEngine.editor"() {
this.getThemes()
},
"$store.state.themeEngine.cssEditor"() {
this.getThemes()
},
"creator.css"() {
if (this.autoCSS) {
this.applyCSS(null)
}
},
creator() {
this.$vuetify.theme.themes.dark = this.creator.dark
this.$vuetify.theme.themes.light = this.creator.light
this.$vuetify.theme.themes.name = this.creator.id
},
accent() {
this.setTheme(
this.themes.find(
(theme) => theme.id === this.$vuetify.theme.themes.name
)
)
},
defineAccent() {
if (!this.defineAccent) {
this.accent = null
this.$store.state.user.accentColor = null
this.getThemes()
} else {
this.accent = this.$store.state.user.accentColor || "#0190ea"
}
},
"$store.state.user.theme": {
handler() {
this.$vuetify.theme.dark = this.$store.state.user.theme === "dark"
},
deep: true
}
},
mounted() {
this.defineAccent = this.$store.state.user.accentColor !== null
this.accent = this.$store.state.user.accentColor
this.name = this.$vuetify.theme.themes.name
this.getThemes()
},
methods: {
setFont() {
const element = document.getElementById("user-font")
@ -461,52 +507,6 @@ div {
AjaxErrorHandler(this.$store)(e)
})
}
},
mounted() {
this.defineAccent = this.$store.state.user.accentColor !== null
this.accent = this.$store.state.user.accentColor
this.name = this.$vuetify.theme.themes.name
this.getThemes()
},
watch: {
"$store.state.themeEngine.editor"() {
this.getThemes()
},
"$store.state.themeEngine.cssEditor"() {
this.getThemes()
},
"creator.css"() {
if (this.autoCSS) {
this.applyCSS(null)
}
},
creator() {
this.$vuetify.theme.themes.dark = this.creator.dark
this.$vuetify.theme.themes.light = this.creator.light
this.$vuetify.theme.themes.name = this.creator.id
},
accent() {
this.setTheme(
this.themes.find(
(theme) => theme.id === this.$vuetify.theme.themes.name
)
)
},
defineAccent() {
if (!this.defineAccent) {
this.accent = null
this.$store.state.user.accentColor = null
this.getThemes()
} else {
this.accent = this.$store.state.user.accentColor || "#0190ea"
}
},
"$store.state.user.theme": {
handler() {
this.$vuetify.theme.dark = this.$store.state.user.theme === "dark"
},
deep: true
}
}
}
</script>

View File

@ -2,18 +2,16 @@
<div>
<v-card-text>
<v-switch
inset
v-model="messageAudio"
label="Play sound effect on new message"
>
</v-switch>
<v-switch
inset
label="Play sound effect on new message"
/>
<v-switch
v-model="nativeNotifications"
inset
label="Desktop notifications"
@change="setNativeNotifications"
>
</v-switch>
/>
<v-btn v-if="nativeNotifications" @click="testNativeNotification">
Test desktop notifications
</v-btn>
@ -30,6 +28,24 @@ export default {
nativeNotifications: false
}
},
watch: {
nativeNotifications(val) {
localStorage.setItem("nativeNotifications", val)
},
messageAudio(val) {
localStorage.setItem("messageAudio", val)
}
},
mounted() {
if (localStorage.getItem("messageAudio")) {
this.messageAudio = JSON.parse(localStorage.getItem("messageAudio"))
}
if (localStorage.getItem("nativeNotifications")) {
this.nativeNotifications = JSON.parse(
localStorage.getItem("nativeNotifications")
)
}
},
methods: {
setNativeNotifications() {
if (this.nativeNotifications) {
@ -68,24 +84,6 @@ export default {
"A desktop notification has been sent, if you don't see it, check your site permissions."
)
}
},
mounted() {
if (localStorage.getItem("messageAudio")) {
this.messageAudio = JSON.parse(localStorage.getItem("messageAudio"))
}
if (localStorage.getItem("nativeNotifications")) {
this.nativeNotifications = JSON.parse(
localStorage.getItem("nativeNotifications")
)
}
},
watch: {
nativeNotifications(val) {
localStorage.setItem("nativeNotifications", val)
},
messageAudio(val) {
localStorage.setItem("messageAudio", val)
}
}
}
</script>

View File

@ -13,15 +13,14 @@
accessed by anyone else, and that you don't loose it.
</p>
<v-text-field
v-model="totp.password"
type="password"
label="Password"
v-model="totp.password"
color="white"
@keydown.enter="totpEnable"
autocomplete="false"
>
</v-text-field>
<v-btn @click="totpEnable" text>Proceed</v-btn>
@keydown.enter="totpEnable"
/>
<v-btn text @click="totpEnable"> Proceed </v-btn>
</template>
<template v-else-if="totp.stage === 2">
<p class="text-h6">Enable 2 Factor Authentication</p>
@ -29,27 +28,25 @@
<code>{{ totp.secret }}</code>
<p>Please enter the 6 digit code from your authenticator app.</p>
<v-text-field
v-model="totp.code"
type="number"
label="Code"
v-model="totp.code"
@keydown.enter="totpConfirm"
color="white"
>
</v-text-field>
<v-btn @click="totpConfirm" text>Enable</v-btn>
@keydown.enter="totpConfirm"
/>
<v-btn text @click="totpConfirm"> Enable </v-btn>
</template>
<template v-else-if="totp.stage === 3">
<p class="text-h6">2 Factor Authentication Enabled</p>
<p>You have successfully enabled 2 Factor Authentication.</p>
<v-text-field
v-model="totp.code"
type="password"
label="2FA Code"
v-model="totp.code"
color="white"
@keydown.enter="totpDisable"
>
</v-text-field>
<v-btn @click="totpDisable" text>Disable</v-btn>
/>
<v-btn text @click="totpDisable"> Disable </v-btn>
</template>
</v-alert>
<v-alert>
@ -58,15 +55,15 @@
<p class="text-h6">Change Password</p>
<p>You may set a custom password here.</p>
<v-text-field
label="Current Password"
v-model="password.current"
label="Current Password"
type="password"
color="white"
@keydown.enter="passwordChange"
></v-text-field>
/>
<v-text-field
label="New Password"
v-model="password.new"
label="New Password"
type="password"
color="white"
:rules="[
@ -75,10 +72,10 @@
v.length >= 8 || 'Password must be at least 8 characters.'
]"
@keydown.enter="passwordChange"
></v-text-field>
/>
<v-text-field
label="Confirm New Password"
v-model="password.confirm"
label="Confirm New Password"
type="password"
color="white"
:rules="[
@ -87,8 +84,8 @@
v.length >= 8 || 'Password must be at least 8 characters.'
]"
@keydown.enter="passwordChange"
></v-text-field>
<v-btn @click="passwordChange" text>Change</v-btn>
/>
<v-btn text @click="passwordChange"> Change </v-btn>
</v-col>
</v-row>
</v-alert>
@ -121,6 +118,11 @@ export default {
}
}
},
mounted() {
this.$store.state.user.totpEnabled
? (this.totp.stage = 3)
: (this.totp.stage = 1)
},
methods: {
passwordChange() {
if (this.password.new === this.password.confirm) {
@ -188,11 +190,6 @@ export default {
AjaxErrorHandler(this.$store)(e)
})
}
},
mounted() {
this.$store.state.user.totpEnabled
? (this.totp.stage = 3)
: (this.totp.stage = 1)
}
}
</script>

View File

@ -2,22 +2,22 @@
<div id="settings-sessions">
<v-container fluid>
<v-row>
<v-col md="3" v-for="session in sessions" :key="session.id">
<v-col v-for="session in sessions" :key="session.id" md="3">
<v-card class="mb-2 rounded-xl" color="card">
<v-toolbar color="toolbar">
<v-toolbar-title>{{
session.other.osString || "Unknown Session"
}}</v-toolbar-title>
<v-toolbar-title>
{{ session.other.osString || "Unknown Session" }}
</v-toolbar-title>
</v-toolbar>
<v-container>
<v-card-text>
Browser: {{ session.other.browserString }}
</v-card-text>
<v-card-text
>Login IP address: {{ session.other.ip }}
<v-card-text>
Login IP address: {{ session.other.ip }}
</v-card-text>
<v-card-text
>Operating System: {{ session.other.osString }}
<v-card-text>
Operating System: {{ session.other.osString }}
</v-card-text>
<v-card-text>
Time of login:
@ -30,7 +30,7 @@
<v-card-text> Country: {{ session.other.location }} </v-card-text>
<v-card-text> ISP: {{ session.other.isp }} </v-card-text>
<v-card-actions>
<v-btn @click="deleteSession(session.id)" color="error" text>
<v-btn color="error" text @click="deleteSession(session.id)">
Invalidate
</v-btn>
</v-card-actions>
@ -52,6 +52,9 @@ export default {
sessions: []
}
},
mounted() {
this.getSessions()
},
methods: {
deleteSession(id) {
this.axios
@ -74,9 +77,6 @@ export default {
AjaxErrorHandler(this.$store)(e)
})
}
},
mounted() {
this.getSessions()
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<div id="settings-site" v-if="$store.state.user?.id">
<div v-if="$store.state.user?.id" id="settings-site">
<v-card-text>
<div class="d-flex">
<v-btn
@ -22,16 +22,16 @@
>
<v-fade-transition v-if="hover">
<v-overlay absolute>
<v-icon large>mdi-upload</v-icon>
<v-icon large> mdi-upload </v-icon>
</v-overlay>
</v-fade-transition>
<v-img
v-if="$store.state.user.avatar"
:src="
$store.state.baseURL +
'/usercontent/' +
$store.state.user.avatar
"
v-if="$store.state.user.avatar"
class="elevation-1"
/>
<v-icon v-else-if="!hover" class="elevation-1">
@ -40,15 +40,15 @@
</v-avatar>
</v-hover>
<v-file-input
class="ml-3"
ref="avatarUpload"
v-model="avatar.file"
class="ml-3"
accept="image/png, image/jpeg, image/jpg, image/gif, image/webp"
placeholder="Avatar"
prepend-icon=""
label="Profile Picture"
v-model="avatar.file"
@change="doUpload"
></v-file-input>
/>
</div>
<v-text-field
v-model="$store.state.user.email"
@ -57,7 +57,7 @@
(v) => !!v || 'Email is required',
(v) => /^.+@.+\..+$/.test(v) || 'Email must be valid'
]"
></v-text-field>
/>
<v-text-field
v-model="$store.state.user.username"
label="Username"
@ -67,17 +67,17 @@
(v) => /^[a-zA-Z0-9]+$/.test(v) || 'Username must be alphanumeric',
(v) => v.length >= 2 || 'Username must be at least 2 characters'
]"
></v-text-field>
/>
</v-card-text>
<v-card-actions>
<v-btn
text
color="primary"
:disabled="!$store.state.user.email || !$store.state.user.username"
@click="
$store.dispatch('saveOnlineSettings')
$toast.success('Updated successfully.')
"
:disabled="!$store.state.user.email || !$store.state.user.username"
>
Save
</v-btn>
@ -88,8 +88,9 @@
$store.dispatch('logout')
$router.push('/login')
"
>Logout</v-btn
>
Logout
</v-btn>
</v-card-actions>
</div>
</template>

File diff suppressed because it is too large Load Diff