Compare commits

...

169 Commits

Author SHA1 Message Date
3fb0e92ddc Updated default values 2023-07-22 18:02:20 -07:00
tusooa
510392e4ca Merge branch 'weblate' into 'develop'
Translations update from Pleroma Weblate

See merge request pleroma/pleroma-fe!1842
2023-07-18 22:02:35 +00:00
Kian-ting Tan
7aac8cd2ee Translated using Weblate (Chinese (Min Nan) (nan_TW))
Currently translated at 58.7% (619 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/nan_TW/
2023-07-18 18:23:25 +00:00
Kian-ting Tan
80ceff95e9 Translated using Weblate (Chinese (Min Nan) (nan_TW))
Currently translated at 56.9% (600 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/nan_TW/
2023-07-17 10:00:37 +00:00
Kian-ting Tan
1ec9487714 Translated using Weblate (Chinese (Min Nan) (nan_TW))
Currently translated at 55.8% (589 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/nan_TW/
2023-07-14 11:00:36 +00:00
baloo toumi
4bdc4bc5a9 Translated using Weblate (Arabic)
Currently translated at 75.5% (796 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-07-13 08:00:35 +00:00
Kian-ting Tan
d234000fdf Translated using Weblate (Chinese (Min Nan) (nan_TW))
Currently translated at 54.8% (578 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/nan_TW/
2023-07-11 13:00:42 +00:00
Kian-ting Tan
837dd81d21 Translated using Weblate (Chinese (Traditional))
Currently translated at 68.0% (717 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/zh_Hant/
2023-07-11 13:00:40 +00:00
baloo toumi
6413aef1b4 Translated using Weblate (Arabic)
Currently translated at 75.5% (796 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-07-11 13:00:40 +00:00
baloo toumi
fc2aca4ddc Translated using Weblate (Arabic)
Currently translated at 65.5% (691 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-07-07 19:00:33 +00:00
@t12
a417867ec7 Translated using Weblate (Indonesian)
Currently translated at 49.4% (521 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/id/
2023-07-06 12:00:36 +00:00
baloo toumi
8173a46030 Translated using Weblate (Arabic)
Currently translated at 63.7% (672 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-07-06 12:00:33 +00:00
Kian-ting Tan
6e93fbb96a Translated using Weblate (Chinese (Min Nan) (nan_TW))
Currently translated at 52.1% (550 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/nan_TW/
2023-07-04 16:00:40 +00:00
Poesty Li
273aeea05e Translated using Weblate (Chinese (Simplified))
Currently translated at 99.8% (1052 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/zh_Hans/
2023-07-04 16:00:36 +00:00
baloo toumi
d6734a1942 Translated using Weblate (Arabic)
Currently translated at 61.8% (652 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-07-04 16:00:33 +00:00
Kian-ting Tan
e47328f170 Translated using Weblate (Chinese (Min Nan) (nan_TW))
Currently translated at 45.4% (479 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/nan_TW/
2023-06-29 16:09:57 +00:00
Kian-ting Tan
75fcf486dc Translated using Weblate (Chinese (Min Nan) (nan_TW))
Currently translated at 43.4% (458 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/nan_TW/
2023-06-29 16:09:57 +00:00
Kian-ting Tan
927729f128 Translated using Weblate (Chinese (Min Nan) (nan_TW))
Currently translated at 42.5% (448 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/nan_TW/
2023-06-29 16:09:57 +00:00
Kian-ting Tan
91bddb7218 Translated using Weblate (Chinese (Min Nan) (nan_TW))
Currently translated at 33.0% (348 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/nan_TW/
2023-06-29 16:09:57 +00:00
tusooa
e57a186b23 Translated using Weblate (Chinese (Simplified))
Currently translated at 93.3% (984 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/zh_Hans/
2023-06-29 16:09:57 +00:00
HJ
c9d07c6202 Merge branch 'tusooa/scroll-emoji-selector-safari' into 'develop'
Fix scrolling emoji selector in modal in safari ios

Closes #1264

See merge request pleroma/pleroma-fe!1844
2023-06-29 16:09:51 +00:00
HJ
586705ec02 Merge branch 'tusooa/react-button-safari' into 'develop'
Fix react button misalignment on safari ios

See merge request pleroma/pleroma-fe!1843
2023-06-29 16:09:31 +00:00
tusooa
9fa0c05b35
Fix lint 2023-06-29 11:43:49 -04:00
tusooa
bf5bd4235d
Comment the v-body-scroll-lock usage in code 2023-06-29 11:40:33 -04:00
tusooa
09402e2537
Fix scrolling emoji selector in modal in safari ios 2023-06-29 11:31:25 -04:00
tusooa
8cc6b213fb
Fix react button misalignment on safari ios 2023-06-29 10:28:05 -04:00
tusooa
d5e9a28c84 Merge branch 'develop' into 'develop'
Add nan support

See merge request pleroma/pleroma-fe!1841
2023-06-22 17:32:05 +00:00
Kian-ting Tan
7ce71d8f82 Update nan-TW.json 2023-06-22 15:35:04 +00:00
Kian-ting Tan
e1fff8e064 Update file locale.service.js 2023-06-21 17:51:06 +00:00
Kian-ting Tan
b4cf20e7bc fix the error of unquoting 2023-06-21 17:45:05 +00:00
Kian-ting Tan
ee01393b5f Update 2 files
- /src/i18n/languages.js
- /src/services/locale/locale.service.js
2023-06-21 17:06:01 +00:00
Kian-ting Tan
cf0d8c9257 according to https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1841#note_101513 by tusooa 2023-06-21 17:02:26 +00:00
Kian-ting Tan
8897ac5c9b Update locale.service.js 2023-06-21 14:20:37 +00:00
Kian-ting Tan
d722dc165e unify the indention 2023-06-20 14:52:41 +00:00
Kian-ting Tan
d98650e21d add changelog 2023-06-20 14:47:51 +00:00
Kian-ting Tan
a7aafd0775 Merge branch 'main' into 'develop'
Main

See merge request yoxem/pleroma-fe!1
2023-06-20 14:10:51 +00:00
Kian-ting Tan
21093e573c Main 2023-06-20 14:10:51 +00:00
tusooa
018f83b997 Merge branch 'weblate' into 'develop'
Translations update from Pleroma Weblate

See merge request pleroma/pleroma-fe!1833
2023-06-18 23:31:42 +00:00
baloo toumi
a7705ade88 Translated using Weblate (Arabic)
Currently translated at 58.3% (615 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-06-13 19:12:24 +00:00
baloo toumi
148e8a7170 Translated using Weblate (Arabic)
Currently translated at 57.8% (610 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-06-13 19:12:24 +00:00
baloo toumi
6ff477e124 Translated using Weblate (Arabic)
Currently translated at 55.3% (583 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-06-13 19:12:24 +00:00
baloo toumi
20621c71dc Translated using Weblate (Arabic)
Currently translated at 46.0% (485 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-06-13 19:12:24 +00:00
baloo toumi
5d63833c99 Translated using Weblate (Arabic)
Currently translated at 45.9% (484 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-06-13 19:12:24 +00:00
baloo toumi
66a881db4f Translated using Weblate (Arabic)
Currently translated at 41.8% (441 of 1054 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-06-13 19:12:24 +00:00
HJ
336a966a52 Merge branch 'tusooa/custom-emoji-notif-width' into 'develop'
Keep aspect ratio of custom emoji reaction in notification

See merge request pleroma/pleroma-fe!1839
2023-06-13 19:12:19 +00:00
tusooa
db1643b94e
Keep aspect ratio of custom emoji reaction in notification 2023-06-13 15:06:46 -04:00
HJ
7ab5ee9cba Merge branch 'tusooa/1262-edit-profile-button' into 'develop'
Fix openSettingsModalTab

Closes #1262

See merge request pleroma/pleroma-fe!1838
2023-06-13 18:47:51 +00:00
tusooa
4e6af5bd23
Fix openSettingsModalTab 2023-06-13 14:01:26 -04:00
HJ
5b93e4a0de Merge branch 'tusooa/react-button-fix' into 'develop'
Fix react button not working if reaction accounts are not loaded

See merge request pleroma/pleroma-fe!1837
2023-06-10 23:19:14 +00:00
tusooa
8ba22a2481
Fix react button not working if reaction accounts are not loaded 2023-06-09 16:13:43 -04:00
HJ
624af7ed00 Merge branch 'harden-parser' into 'develop'
fix regex misinterpreting tag name in badly formed HTML

See merge request pleroma/pleroma-fe!1835
2023-06-05 19:04:30 +00:00
Henry Jameson
0109724a5f case insensititvy 2023-06-05 21:57:36 +03:00
Henry Jameson
10e28f6c1d changelog 2023-06-05 21:54:17 +03:00
Henry Jameson
5e656cc0b4 Merge remote-tracking branch 'origin/develop' into harden-parser 2023-06-05 21:53:14 +03:00
Henry Jameson
00b47e1673 fix regex misinterpreting tag name in badly formed HTML, prevent rich
content from ever using dangerous tags
2023-06-05 21:49:47 +03:00
tusooa
ae5181d21e Merge branch 'weblate' into 'develop'
Translations update from Pleroma Weblate

See merge request pleroma/pleroma-fe!1832
2023-05-26 03:54:43 +00:00
baloo toumi
8e9f0aabba Translated using Weblate (Arabic)
Currently translated at 39.7% (394 of 990 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-05-24 18:55:30 +00:00
HJ
c730c9b6d0 Merge branch 'improve_settings_reusability' into 'develop'
AdminFE functionality in PleromaFE

See merge request pleroma/pleroma-fe!1800
2023-05-24 18:55:20 +00:00
Henry Jameson
cbd22d52b8 make admin settings modal available on mobile 2023-05-24 12:00:16 +03:00
Henry Jameson
b3d0360699 fix and cleanup reset button 2023-05-24 11:44:41 +03:00
Henry Jameson
ed34b07b3f fix transition when resetting to indeterminate state 2023-05-24 11:44:26 +03:00
Henry Jameson
d223683b2e make detailed access restriction an expert section 2023-05-24 11:32:16 +03:00
Henry Jameson
9f77f910b8 fix animation when ideterminate is the initial state 2023-05-24 11:29:59 +03:00
Henry Jameson
3ead21bcc6 changelog 2023-05-23 22:30:24 +03:00
Henry Jameson
b72af7d6ae Merge remote-tracking branch 'origin/develop' into improve_settings_reusability 2023-05-23 22:24:04 +03:00
Henry Jameson
99f85069b8 fix indeterminate state animation 2023-05-23 22:23:58 +03:00
HJ
4bf085b8fe Merge branch 'renovate/vue-virtual-scroller-2.x-lockfile' into 'develop'
Update dependency vue-virtual-scroller to v2.0.0-beta.8

See merge request pleroma/pleroma-fe!1824
2023-05-23 08:36:56 +00:00
HJ
8692453ffd Merge branch 'renovate/vuelidate-core-2.x' into 'develop'
Update dependency @vuelidate/core to v2.0.2

See merge request pleroma/pleroma-fe!1804
2023-05-23 08:34:10 +00:00
HJ
8d32f305fd Merge branch 'renovate/font-awesome' into 'develop'
Update Font Awesome to v6.4.0

See merge request pleroma/pleroma-fe!1825
2023-05-23 08:33:00 +00:00
HJ
0101f67639 Merge branch 'weblate' into 'develop'
Translations update from Pleroma Weblate

See merge request pleroma/pleroma-fe!1828
2023-05-23 08:31:58 +00:00
baloo toumi
f4d3575804 Translated using Weblate (Arabic)
Currently translated at 37.4% (370 of 989 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-05-23 08:27:34 +00:00
HJ
63ee9088b6 Merge branch 'tusooa/changelog' into 'develop'
Add changelog checker

See merge request pleroma/pleroma-fe!1816
2023-05-23 08:27:29 +00:00
HJ
b6cef856f9 Merge branch 'tusooa/reaction-accessibility' into 'develop'
Reaction accessibility

See merge request pleroma/pleroma-fe!1827
2023-05-23 08:24:56 +00:00
tusooa
b82f2a3543
Use button text in reaction counter 2023-05-22 23:09:28 -04:00
tusooa
dc2ff9b2d2
Add text label for custom emoji reactions 2023-05-22 22:37:18 -04:00
tusooa
c675130024
Make reaction counter accessible 2023-05-22 22:30:54 -04:00
tusooa
d3e251665f
Lint 2023-05-22 22:20:09 -04:00
tusooa
48ee11fea3
Add aria for react button 2023-05-22 22:18:42 -04:00
tusooa
0b2f676e50
Fix focus (unvisible) style 2023-05-22 22:14:44 -04:00
tusooa
8a1074336c
Make emoji reactions clickable when not logged in 2023-05-22 22:09:04 -04:00
tusooa
ed23f51838
Make reaction button accessible 2023-05-22 22:02:22 -04:00
tusooa
6b0d72937e Apply 1 suggestion(s) to 1 file(s) 2023-05-21 18:31:25 +00:00
tusooa
1e597d8b1a Merge branch 'weblate' into 'develop'
Translations update from Pleroma Weblate

See merge request pleroma/pleroma-fe!1826
2023-05-20 19:19:53 +00:00
baloo toumi
b171d831f2 Translated using Weblate (Arabic)
Currently translated at 14.2% (141 of 989 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ar/
2023-05-18 12:22:20 +00:00
Pleroma Renovate Bot
b275c9afa6 Update Font Awesome to v6.4.0 2023-05-16 09:06:29 +00:00
tusooa
fc1fda50df Merge branch 'weblate' into 'develop'
Translations update from Pleroma Weblate

See merge request pleroma/pleroma-fe!1812
2023-05-16 02:05:33 +00:00
Tirifto
762cdc738f Translated using Weblate (Esperanto)
Currently translated at 98.1% (971 of 989 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/eo/
2023-05-16 02:01:29 +00:00
Xnuk Shuman
811adc5b1f Translated using Weblate (Korean)
Currently translated at 96.6% (955 of 988 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ko/
2023-05-16 02:01:29 +00:00
Tirifto
1dd5fa8bb7 Translated using Weblate (Esperanto)
Currently translated at 98.2% (971 of 988 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/eo/
2023-05-16 02:01:29 +00:00
Tirifto
2e5412fbd8 Translated using Weblate (Esperanto)
Currently translated at 98.0% (969 of 988 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/eo/
2023-05-16 02:01:29 +00:00
tusooa
d4ea180a39 Merge branch 'renovate/nightwatch-2.x' into 'develop'
Update dependency nightwatch to v2.6.20

See merge request pleroma/pleroma-fe!1820
2023-05-16 02:01:23 +00:00
Pleroma Renovate Bot
ac21bba90c Update dependency vue-virtual-scroller to v2.0.0-beta.8 2023-05-13 09:06:36 +00:00
HJ
fca1e0abae Merge branch 'tusooa/custom-emoji-selective' into 'develop'
Fix custom emojis shown in selector if backend does not support it

See merge request pleroma/pleroma-fe!1823
2023-05-12 14:07:33 +00:00
tusooa
f5891e950e Merge branch 'renovate/sinon-15.x' into 'develop'
Update dependency sinon to v15.0.4

See merge request pleroma/pleroma-fe!1822
2023-05-12 13:58:48 +00:00
tusooa
4b38fc5ffc
Fix custom emojis shown in selector if backend does not support it 2023-05-12 09:57:22 -04:00
Henry Jameson
4664d99af2 lint 2023-05-09 23:29:30 +03:00
Henry Jameson
ad3916027a lint 2023-05-08 22:14:49 +03:00
Henry Jameson
b79f297692 fix double pushbuttons in the draft buttons 2023-05-08 22:04:05 +03:00
Henry Jameson
039b6c61a2 lint 2023-05-08 21:37:29 +03:00
Henry Jameson
09e3735e37 semantics + description for instance access section 2023-05-08 21:36:18 +03:00
Henry Jameson
2322646442 reintroduce width limit on number input but only for sizesetting 2023-05-08 21:13:07 +03:00
Henry Jameson
0f81239451 remove restriction on number input's width 2023-05-08 21:11:48 +03:00
Henry Jameson
05a7e612aa show warning for developer for missing labels 2023-05-08 21:10:06 +03:00
Henry Jameson
b9c69a2272 improve the semantics 2023-05-08 21:01:29 +03:00
Henry Jameson
1935bf6bd4 fix media upload bug 2023-05-08 21:01:20 +03:00
Pleroma Renovate Bot
586cdadcec Update dependency sinon to v15.0.4 2023-05-05 09:04:48 +00:00
Henry Jameson
6816bc8bad remove unused stuff 2023-05-05 01:50:41 +03:00
tusooa
0f730a8524 Merge branch 'renovate/karma-6.x' into 'develop'
Update dependency karma to v6.4.2

See merge request pleroma/pleroma-fe!1819
2023-05-04 12:24:37 +00:00
Pleroma Renovate Bot
4d75a58bb9 Update dependency nightwatch to v2.6.20 2023-05-04 09:05:44 +00:00
Pleroma Renovate Bot
8531149f43 Update dependency karma to v6.4.2 2023-05-04 09:05:33 +00:00
tusooa
2504929da2 Merge branch 'renovate/babel-monorepo' into 'develop'
Update babel monorepo

See merge request pleroma/pleroma-fe!1817
2023-05-04 01:19:30 +00:00
Pleroma Renovate Bot
2f632b95cc Update babel monorepo 2023-05-03 09:06:26 +00:00
tusooa
7c7385b1de
Do not count renames when checking changelog 2023-05-02 22:17:02 -04:00
tusooa
670ff6e940 Merge branch 'renovate/postcss-8.x' into 'develop'
Update dependency postcss to v8.4.23

See merge request pleroma/pleroma-fe!1750
2023-05-02 12:22:05 +00:00
tusooa
1364e56437 Merge branch 'renovate/sass-loader-13.x' into 'develop'
Update dependency sass-loader to v13.2.2

See merge request pleroma/pleroma-fe!1811
2023-05-02 12:19:50 +00:00
tusooa
ebad6a17d2 Merge branch 'renovate/mini-css-extract-plugin-2.x' into 'develop'
Update dependency mini-css-extract-plugin to v2.7.5

See merge request pleroma/pleroma-fe!1810
2023-05-02 12:18:32 +00:00
tusooa
2d9ee02c12 Merge branch 'renovate/html-webpack-plugin-5.x' into 'develop'
Update dependency html-webpack-plugin to v5.5.1

See merge request pleroma/pleroma-fe!1815
2023-05-02 12:17:18 +00:00
tusooa
5f8a34c51d
Run merge request pipelines instead of two different ones 2023-04-28 18:20:44 -04:00
tusooa
cd5d0a8b64
Skip changelog 2023-04-28 18:15:44 -04:00
tusooa
ca7b5b7deb
Add changelog checker 2023-04-28 18:14:23 -04:00
Henry Jameson
1492937a7e lint 2023-04-24 23:01:29 +03:00
Henry Jameson
e0fbeee88e finish up attachment setting (right now only for admin section only) 2023-04-24 21:57:31 +03:00
Pleroma Renovate Bot
17e7df9da3 Update dependency html-webpack-plugin to v5.5.1 2023-04-21 09:05:46 +00:00
Pleroma Renovate Bot
e1d5add046 Update dependency postcss to v8.4.23 2023-04-20 09:07:46 +00:00
Henry Jameson
9aaa8a86f5 initial implementation of attachmentsetting 2023-04-13 01:11:20 +03:00
Henry Jameson
d8ed541d12 reordered registrations section to be above access since it's more
likely to be used more often
2023-04-13 00:02:35 +03:00
Henry Jameson
4c158e636b more i18n stuff, added missing labels and such 2023-04-13 00:02:31 +03:00
Henry Jameson
3e1aeb6d2c Merge remote-tracking branch 'origin/develop' into improve_settings_reusability 2023-04-12 23:31:11 +03:00
HJ
80eddb1099 Merge branch 'develop' into 'develop'
Fix i18n

See merge request pleroma/pleroma-fe!1814
2023-04-12 20:04:46 +00:00
XYenon
01758a28ea Fix i18n 2023-04-13 00:06:32 +08:00
HJ
bc830cd033 Merge branch 'renovate/autoprefixer-10.x' into 'develop'
Update dependency autoprefixer to v10.4.14

See merge request pleroma/pleroma-fe!1808
2023-04-11 21:29:57 +00:00
HJ
a814520709 Merge branch 'tusooa/pin-announcement' into 'develop'
Fix bug where announcements cannot be pinned

See merge request pleroma/pleroma-fe!1809
2023-04-11 21:28:02 +00:00
HJ
9a8f52a38d Merge branch 'tusooa/chat-user' into 'develop'
Populate user card on receiving chats

See merge request pleroma/pleroma-fe!1766
2023-04-11 21:26:39 +00:00
HJ
9c376b3511 Merge branch 'tusooa/1244-report-delete-fail' into 'develop'
Display delete status errors

Closes #1244

See merge request pleroma/pleroma-fe!1769
2023-04-11 21:26:16 +00:00
HJ
ad5bd09204 Merge branch 'tusooa/blocklist-loadmore' into 'develop'
Make block & mute lists able to load more

Closes #1150, #1071, #1226, and #1041

See merge request pleroma/pleroma-fe!1790
2023-04-11 21:25:39 +00:00
Pleroma Renovate Bot
034ed86312 Update dependency sass-loader to v13.2.2 2023-04-07 09:08:33 +00:00
Pleroma Renovate Bot
0bcfde4c2e Update dependency mini-css-extract-plugin to v2.7.5 2023-04-07 09:08:13 +00:00
tusooa
5c0deb1e6f
Fix bug where announcements cannot be pinned 2023-04-06 18:14:49 -04:00
Pleroma Renovate Bot
6deb6d45c6 Update dependency autoprefixer to v10.4.14 2023-04-06 09:10:40 +00:00
Pleroma Renovate Bot
251787ed07 Update dependency @vuelidate/core to v2.0.2 2023-03-30 09:08:23 +00:00
Henry Jameson
9e5c7313c6 use draft state instead of live state in that one place 2023-03-29 23:34:30 +03:00
Henry Jameson
ac75d051b7 better frontends tab, now you can set default frontend 2023-03-29 23:26:57 +03:00
Henry Jameson
7bb28bb23c frontends tab initial implementation, now you can (re)install frontends! yay! 2023-03-29 00:58:07 +03:00
Henry Jameson
3ac67ab727 fix 2023-03-27 23:00:52 +03:00
Henry Jameson
4c3af5c362 handle db config disabled case 2023-03-27 22:57:50 +03:00
Henry Jameson
df9fe6d261 localization strings 2023-03-22 19:23:36 +02:00
Henry Jameson
ece69f01b7 added mass-draft-push and mass-draft-reset, small stylistic fixes 2023-03-22 18:57:23 +02:00
Henry Jameson
9153417202 localization strings 2023-03-22 12:48:21 +02:00
Henry Jameson
c7a16bdfe2 grouped settings/managed drafts support added 2023-03-22 12:43:53 +02:00
Henry Jameson
6992439c92 fixes for diabled state, tri-state boolean and access control 2023-03-22 00:00:52 +02:00
Henry Jameson
2bf224e214 made draft-mode and source inject-able 2023-03-21 22:46:40 +02:00
Henry Jameson
6b40fc9895 fixes 2023-03-21 22:26:11 +02:00
Henry Jameson
9a97e0d196 modal update, initial localization 2023-03-21 10:26:25 +02:00
Henry Jameson
0b5e536b4c ChoiceSetting support added, added captcha settings 2023-03-20 23:36:47 +02:00
Henry Jameson
819cd41cf0 Merge remote-tracking branch 'origin/develop' into improve_settings_reusability
* origin/develop:
  Translated using Weblate (Chinese (Simplified))
  Generalize IntegerSetting into NumberSetting, add Integer/Float wrappers
  Allow custom emoji reactions: add option to scale reaction buttons
  Fix user-profile route crash on pinned favorites route
  Hide custom emoji in reaction picker when BE does not advertise pleroma_custom_emoji_reactions
  Allow custom emoji reactions
2023-03-20 22:48:38 +02:00
Henry Jameson
332ad77e35 limits tab, backend descriptions 2023-03-19 21:27:07 +02:00
Henry Jameson
ab5408d36e remove obsolete files 2023-03-17 00:10:37 +02:00
Henry Jameson
27f63d5e50 lint 2023-03-17 00:06:31 +02:00
Henry Jameson
bfd802ad04 setting admin settings works now. also now we have draftable settings 2023-03-16 23:18:55 +02:00
Henry Jameson
4d23d31fec initial admin settings prototype (WIP) 2023-03-14 21:50:43 +02:00
Henry Jameson
9632b77786 initial implementation of an admin settings module 2023-03-13 00:09:47 +02:00
Henry Jameson
55ea6df40b lint 2023-03-12 17:28:14 +02:00
Henry Jameson
6a7b182af1 fixes for stuff i missed 2023-03-12 17:11:20 +02:00
Henry Jameson
947b73f870 minimize the rest of the sharedcomputedobject 2023-03-12 16:55:39 +02:00
Henry Jameson
ac32997f8b move websocket connection logic into module 2023-03-12 16:51:50 +02:00
Henry Jameson
af0cd54223 serverSideConfig renamed into profileSettingConfig to avoid confusion
with serverSideStorage, reduced overall need for SharedComputedObject in
settings tabs, moved copypaste code of "setting" type of helpers into a
separate file.
2023-03-12 14:36:49 +02:00
tusooa
e516eee479
Make block & mute lists able to load more 2023-02-21 00:39:16 -05:00
tusooa
d1876503bc
Display delete status errors 2023-01-20 12:34:15 -05:00
tusooa
5b56b6b9fd
Populate user card on receiving chats 2023-01-17 19:55:16 -05:00
98 changed files with 4973 additions and 817 deletions

View File

@ -4,11 +4,36 @@
image: node:16
stages:
- check-changelog
- lint
- build
- test
- deploy
# https://git.pleroma.social/help/ci/yaml/workflow.md#switch-between-branch-pipelines-and-merge-request-pipelines
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
check-changelog:
stage: check-changelog
image: alpine
rules:
- if: $CI_MERGE_REQUEST_SOURCE_PROJECT_PATH == 'pleroma/pleroma-fe' && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^renovate/
when: never
- if: $CI_MERGE_REQUEST_SOURCE_PROJECT_PATH == 'pleroma/pleroma-fe' && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == 'weblate'
when: never
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"
before_script: ''
after_script: ''
cache: {}
script:
- apk add git
- sh ./tools/check-changelog
lint:
stage: lint
script:

View File

@ -0,0 +1 @@
add the initial i18n translation file for Taiwanese (Hokkien), and modify some related files.

1
changelog.d/adminfe.add Normal file
View File

@ -0,0 +1 @@
Implemented a very basic instance administration screen

View File

View File

@ -0,0 +1 @@
Keep aspect ratio of custom emoji reaction in notification

View File

@ -0,0 +1 @@
Fix openSettingsModalTab so that it correctly opens Settings modal instead of Admin modal

1
changelog.d/parser.fix Normal file
View File

@ -0,0 +1 @@
fix regex issue in HTML parser/renderer

View File

@ -0,0 +1 @@
Fix react button misalignment on safari ios

View File

@ -0,0 +1 @@
Fix react button not working if reaction accounts are not loaded

View File

@ -0,0 +1 @@
Fix scrolling emoji selector in modal in safari ios

View File

@ -16,16 +16,16 @@
"lint-fix": "eslint --fix --ext .js,.vue src test/unit/specs test/e2e/specs"
},
"dependencies": {
"@babel/runtime": "7.21.0",
"@babel/runtime": "7.21.5",
"@chenfengyuan/vue-qrcode": "2.0.0",
"@fortawesome/fontawesome-svg-core": "6.3.0",
"@fortawesome/free-regular-svg-icons": "6.3.0",
"@fortawesome/free-solid-svg-icons": "6.3.0",
"@fortawesome/fontawesome-svg-core": "6.4.0",
"@fortawesome/free-regular-svg-icons": "6.4.0",
"@fortawesome/free-solid-svg-icons": "6.4.0",
"@fortawesome/vue-fontawesome": "3.0.3",
"@kazvmoe-infra/pinch-zoom-element": "1.2.0",
"@kazvmoe-infra/unicode-emoji-json": "0.4.0",
"@ruffle-rs/ruffle": "0.1.0-nightly.2022.7.12",
"@vuelidate/core": "2.0.0",
"@vuelidate/core": "2.0.2",
"@vuelidate/validators": "2.0.0",
"body-scroll-lock": "3.1.5",
"chromatism": "3.0.0",
@ -49,10 +49,10 @@
"vuex": "4.1.0"
},
"devDependencies": {
"@babel/core": "7.21.4",
"@babel/eslint-parser": "7.21.3",
"@babel/core": "7.21.8",
"@babel/eslint-parser": "7.21.8",
"@babel/plugin-transform-runtime": "7.21.4",
"@babel/preset-env": "7.21.4",
"@babel/preset-env": "7.21.5",
"@babel/register": "7.21.0",
"@intlify/vue-i18n-loader": "5.0.1",
"@ungap/event-target": "0.2.3",
@ -60,7 +60,7 @@
"@vue/babel-plugin-jsx": "1.1.1",
"@vue/compiler-sfc": "3.2.45",
"@vue/test-utils": "2.2.8",
"autoprefixer": "10.4.13",
"autoprefixer": "10.4.14",
"babel-loader": "9.1.2",
"babel-plugin-lodash": "3.3.4",
"chai": "4.3.7",
@ -83,11 +83,11 @@
"eventsource-polyfill": "0.9.6",
"express": "4.18.2",
"function-bind": "1.1.1",
"html-webpack-plugin": "5.5.0",
"html-webpack-plugin": "5.5.1",
"http-proxy-middleware": "2.0.6",
"iso-639-1": "2.1.15",
"json-loader": "0.5.7",
"karma": "6.4.1",
"karma": "6.4.2",
"karma-coverage": "2.2.0",
"karma-firefox-launcher": "2.1.2",
"karma-mocha": "2.0.1",
@ -97,22 +97,22 @@
"karma-spec-reporter": "0.0.36",
"karma-webpack": "5.0.0",
"lodash": "4.17.21",
"mini-css-extract-plugin": "2.7.2",
"mini-css-extract-plugin": "2.7.5",
"mocha": "10.2.0",
"nightwatch": "2.6.19",
"nightwatch": "2.6.20",
"opn": "5.5.0",
"ora": "0.4.1",
"postcss": "8.4.20",
"postcss": "8.4.23",
"postcss-html": "^1.5.0",
"postcss-loader": "7.0.2",
"postcss-scss": "^4.0.6",
"sass": "1.60.0",
"sass-loader": "13.2.0",
"sass-loader": "13.2.2",
"selenium-server": "2.53.1",
"semver": "7.3.8",
"serviceworker-webpack5-plugin": "2.0.0",
"shelljs": "0.8.5",
"sinon": "15.0.1",
"sinon": "15.0.4",
"sinon-chai": "3.7.0",
"stylelint": "14.16.1",
"stylelint-config-html": "^1.1.0",

View File

@ -645,6 +645,20 @@ option {
}
}
.cards-list {
list-style: none;
display: grid;
grid-auto-flow: row dense;
grid-template-columns: 1fr 1fr;
li {
border: 1px solid var(--border);
border-radius: var(--inputRadius);
padding: 0.5em;
margin: 0.25em;
}
}
.btn-block {
display: block;
width: 100%;
@ -655,16 +669,19 @@ option {
display: inline-flex;
vertical-align: middle;
button {
button,
.button-dropdown {
position: relative;
flex: 1 1 auto;
&:not(:last-child) {
&:not(:last-child),
&:not(:last-child) .button-default {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
&:not(:first-child) {
&:not(:first-child),
&:not(:first-child) .button-default {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}

View File

@ -1,7 +1,7 @@
<template>
<label
class="checkbox"
:class="{ disabled, indeterminate }"
:class="{ disabled, indeterminate, 'indeterminate-fix': indeterminateTransitionFix }"
>
<input
type="checkbox"
@ -14,6 +14,7 @@
<i
class="checkbox-indicator"
:aria-hidden="true"
@transitionend.capture="onTransitionEnd"
/>
<span
v-if="!!$slots.default"
@ -31,7 +32,24 @@ export default {
'indeterminate',
'disabled'
],
emits: ['update:modelValue']
emits: ['update:modelValue'],
data: (vm) => ({
indeterminateTransitionFix: vm.indeterminate
}),
watch: {
indeterminate (e) {
if (e) {
this.indeterminateTransitionFix = true
}
}
},
methods: {
onTransitionEnd (e) {
if (!this.indeterminate) {
this.indeterminateTransitionFix = false
}
}
}
}
</script>
@ -98,6 +116,12 @@ export default {
}
}
&.indeterminate-fix {
input[type="checkbox"] + .checkbox-indicator::before {
content: "";
}
}
& > span {
margin-left: 0.5em;
}

View File

@ -107,7 +107,10 @@ export default {
this.searchBarHidden = hidden
},
openSettingsModal () {
this.$store.dispatch('openSettingsModal')
this.$store.dispatch('openSettingsModal', 'user')
},
openAdminModal () {
this.$store.dispatch('openSettingsModal', 'admin')
}
}
}

View File

@ -48,20 +48,19 @@
icon="cog"
/>
</button>
<a
<button
v-if="currentUser && currentUser.role === 'admin'"
href="/pleroma/admin/#/login-pleroma"
class="nav-icon"
class="button-unstyled nav-icon"
target="_blank"
:title="$t('nav.administration')"
@click.stop
@click.stop="openAdminModal"
>
<FAIcon
fixed-width
class="fa-scale-110 fa-old-padding"
icon="tachometer-alt"
/>
</a>
</button>
<span class="spacer" />
<button
v-if="currentUser"

View File

@ -105,6 +105,7 @@ const EmojiPicker = {
default: false
}
},
inject: ['popoversZLayer'],
data () {
return {
keyword: '',
@ -350,6 +351,9 @@ const EmojiPicker = {
return emoji.displayText
}
},
isInModal () {
return this.popoversZLayer === 'modals'
}
}
}

View File

@ -9,8 +9,14 @@
>
<template #content>
<div class="heading">
<!--
Body scroll lock needs to be on every scrollable element on safari iOS.
Here we tell it to enable scrolling for this element.
See https://github.com/willmcpo/body-scroll-lock#vanilla-js
-->
<span
ref="header"
v-body-scroll-lock="isInModal"
class="emoji-tabs"
>
<span
@ -75,8 +81,10 @@
@input="$event.target.composing = false"
>
</div>
<!-- Enables scrolling for this element on safari iOS. See comments for header. -->
<DynamicScroller
ref="emoji-groups"
v-body-scroll-lock="isInModal"
class="emoji-groups"
:class="groupsScrolledClass"
:min-item-size="minItemSize"

View File

@ -1,5 +1,17 @@
import UserAvatar from '../user_avatar/user_avatar.vue'
import UserListPopover from '../user_list_popover/user_list_popover.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faPlus,
faMinus,
faCheck
} from '@fortawesome/free-solid-svg-icons'
library.add(
faPlus,
faMinus,
faCheck
)
const EMOJI_REACTION_COUNT_CUTOFF = 12
@ -33,6 +45,9 @@ const EmojiReactions = {
},
loggedIn () {
return !!this.$store.state.users.currentUser
},
remoteInteractionLink () {
return this.$store.getters.remoteInteractionLink({ statusId: this.status.id })
}
},
methods: {
@ -42,10 +57,10 @@ const EmojiReactions = {
reactedWith (emoji) {
return this.status.emoji_reactions.find(r => r.name === emoji).me
},
fetchEmojiReactionsByIfMissing () {
async fetchEmojiReactionsByIfMissing () {
const hasNoAccounts = this.status.emoji_reactions.find(r => !r.accounts)
if (hasNoAccounts) {
this.$store.dispatch('fetchEmojiReactionsBy', this.status.id)
return await this.$store.dispatch('fetchEmojiReactionsBy', this.status.id)
}
},
reactWith (emoji) {
@ -54,14 +69,26 @@ const EmojiReactions = {
unreact (emoji) {
this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })
},
emojiOnClick (emoji, event) {
async emojiOnClick (emoji, event) {
if (!this.loggedIn) return
await this.fetchEmojiReactionsByIfMissing()
if (this.reactedWith(emoji)) {
this.unreact(emoji)
} else {
this.reactWith(emoji)
}
},
counterTriggerAttrs (reaction) {
return {
class: [
'btn',
'button-default',
'emoji-reaction-count-button',
{ '-picked-reaction': this.reactedWith(reaction.name) }
],
'aria-label': this.$tc('status.reaction_count_label', reaction.count, { num: reaction.count })
}
}
}
}

View File

@ -1,15 +1,19 @@
<template>
<div class="EmojiReactions">
<UserListPopover
<span
v-for="(reaction) in emojiReactions"
:key="reaction.url || reaction.name"
:users="accountsForEmoji[reaction.name]"
class="emoji-reaction-container btn-group"
>
<button
<component
:is="loggedIn ? 'button' : 'a'"
v-bind="!loggedIn ? { href: remoteInteractionLink } : {}"
role="button"
class="emoji-reaction btn button-default"
:class="{ '-picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }"
:class="{ '-picked-reaction': reactedWith(reaction.name) }"
:title="reaction.url ? reaction.name : undefined"
:aria-pressed="reactedWith(reaction.name)"
@click="emojiOnClick(reaction.name, $event)"
@mouseenter="fetchEmojiReactionsByIfMissing()"
>
<span
class="reaction-emoji"
@ -17,7 +21,6 @@
<img
v-if="reaction.url"
:src="reaction.url"
:title="reaction.name"
class="reaction-emoji-content"
width="1em"
>
@ -26,9 +29,36 @@
class="reaction-emoji reaction-emoji-content"
>{{ reaction.name }}</span>
</span>
<span>{{ reaction.count }}</span>
</button>
<FALayers>
<FAIcon
v-if="reactedWith(reaction.name)"
class="active-marker"
transform="shrink-6 up-9"
icon="check"
/>
<FAIcon
v-if="!reactedWith(reaction.name)"
class="focus-marker"
transform="shrink-6 up-9"
icon="plus"
/>
<FAIcon
v-else
class="focus-marker"
transform="shrink-6 up-9"
icon="minus"
/>
</FALayers>
</component>
<UserListPopover
:users="accountsForEmoji[reaction.name]"
class="emoji-reaction-popover"
:trigger-attrs="counterTriggerAttrs(reaction)"
@show="fetchEmojiReactionsByIfMissing()"
>
<span class="emoji-reaction-counts">{{ reaction.count }}</span>
</UserListPopover>
</span>
<a
v-if="tooManyReactions"
class="emoji-reaction-expand faint"
@ -43,6 +73,7 @@
<script src="./emoji_reactions.js"></script>
<style lang="scss">
@import "../../variables";
@import "../../mixins";
.EmojiReactions {
display: flex;
@ -51,14 +82,46 @@
--emoji-size: calc(1.25em * var(--emojiReactionsScale, 1));
.emoji-reaction {
padding: 0 0.5em;
margin-right: 0.5em;
.emoji-reaction-container {
display: flex;
align-items: stretch;
margin-top: 0.5em;
margin-right: 0.5em;
.emoji-reaction-popover {
padding: 0;
.emoji-reaction-count-button {
background-color: var(--btn);
margin: 0;
height: 100%;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
box-sizing: border-box;
min-width: 2em;
display: inline-flex;
justify-content: center;
align-items: center;
color: $fallback--text;
color: var(--btnText, $fallback--text);
&.-picked-reaction {
border: 1px solid var(--accent, $fallback--link);
margin-right: -1px;
}
}
}
}
.emoji-reaction {
padding-left: 0.5em;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
margin: 0;
.reaction-emoji {
width: var(--emoji-size);
@ -85,19 +148,45 @@
outline: none;
}
&.not-clickable {
cursor: default;
&:hover {
box-shadow: $fallback--buttonShadow;
box-shadow: var(--buttonShadow);
}
.svg-inline--fa {
color: $fallback--text;
color: var(--btnText, $fallback--text);
}
&.-picked-reaction {
border: 1px solid var(--accent, $fallback--link);
margin-left: -1px; // offset the border, can't use inset shadows either
margin-right: calc(0.5em - 1px);
margin-right: -1px;
.svg-inline--fa {
color: $fallback--link;
color: var(--accent, $fallback--link);
}
}
@include unfocused-style {
.focus-marker {
visibility: hidden;
}
.active-marker {
visibility: visible;
}
}
@include focused-style {
.svg-inline--fa {
color: $fallback--link;
color: var(--accent, $fallback--link);
}
.focus-marker {
visibility: visible;
}
.active-marker {
visibility: hidden;
}
}
}

View File

@ -36,7 +36,9 @@
<button
class="button-default btn"
@click="addLanguage"
>{{ $t('settings.add_language') }}</button>
>
{{ $t('settings.add_language') }}
</button>
</li>
</ul>
</div>

View File

@ -1,9 +1,13 @@
<template>
<div class="list">
<div
class="list"
role="list"
>
<div
v-for="item in items"
:key="getKey(item)"
class="list-item"
role="listitem"
>
<slot
name="item"

View File

@ -23,6 +23,11 @@ const mediaUpload = {
}
},
methods: {
onClick () {
if (this.uploadReady) {
this.$refs.input.click()
}
},
uploadFile (file) {
const self = this
const store = this.$store
@ -69,10 +74,15 @@ const mediaUpload = {
this.multiUpload(target.files)
}
},
props: [
'dropFiles',
'disabled'
],
props: {
dropFiles: Object,
disabled: Boolean,
normalButton: Boolean,
acceptTypes: {
type: String,
default: '*/*'
}
},
watch: {
dropFiles: function (fileInfos) {
if (!this.uploading) {

View File

@ -1,8 +1,9 @@
<template>
<label
<button
class="media-upload"
:class="{ disabled: disabled }"
:class="[normalButton ? 'button-default btn' : 'button-unstyled', { disabled }]"
:title="$t('tool_tip.media_upload')"
@click="onClick"
>
<FAIcon
v-if="uploading"
@ -15,15 +16,21 @@
class="new-icon"
icon="upload"
/>
<template v-if="normalButton">
{{ ' ' }}
{{ uploading ? $t('general.loading') : $t('tool_tip.media_upload') }}
</template>
<input
v-if="uploadReady"
ref="input"
class="hidden-input-file"
:disabled="disabled"
type="file"
multiple="true"
:accept="acceptTypes"
@change="change"
>
</label>
</button>
</template>
<script src="./media_upload.js"></script>
@ -32,10 +39,12 @@
@import "../../variables";
.media-upload {
cursor: pointer; // We use <label> for interactivity... i wonder if it's fine
.hidden-input-file {
display: none;
}
}
</style>
label.media-upload {
cursor: pointer; // We use <label> for interactivity... i wonder if it's fine
}
</style>

View File

@ -45,6 +45,7 @@ const NavPanel = {
privateMode: state => state.instance.private,
federating: state => state.instance.federating,
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable,
supportsAnnouncements: state => state.announcements.supportsAnnouncements,
pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems)
}),
pinnedList () {
@ -56,6 +57,7 @@ const NavPanel = {
],
{
hasChats: this.pleromaChatMessagesAvailable,
hasAnnouncements: this.supportsAnnouncements,
isFederating: this.federating,
isPrivate: this.privateMode,
currentUser: this.currentUser
@ -75,6 +77,7 @@ const NavPanel = {
],
{
hasChats: this.pleromaChatMessagesAvailable,
hasAnnouncements: this.supportsAnnouncements,
isFederating: this.federating,
isPrivate: this.privateMode,
currentUser: this.currentUser

View File

@ -125,7 +125,8 @@
v-if="notification.emoji_url"
class="emoji-reaction-emoji emoji-reaction-emoji-image"
:src="notification.emoji_url"
:name="notification.emoji"
:alt="notification.emoji"
:title="notification.emoji"
>
<span
v-else
@ -162,8 +163,8 @@
</router-link>
<button
class="button-unstyled expand-icon"
:aria-expanded="statusExpanded"
:title="$t('tool_tip.toggle_expand')"
:aria-expanded="statusExpanded"
@click.prevent="toggleStatusExpanded"
>
<FAIcon

View File

@ -136,6 +136,7 @@
.emoji-reaction-emoji-image {
vertical-align: middle;
object-fit: contain;
}
.notification-details {

View File

@ -45,6 +45,9 @@ const Popover = {
// Lets hover popover stay when clicking inside of it
stayOnClick: Boolean,
// Use styled button (to avoid nested buttons)
normalButton: Boolean,
triggerAttrs: {
type: Object,
default: {}

View File

@ -5,7 +5,8 @@
>
<button
ref="trigger"
class="button-unstyled popover-trigger-button"
class="popover-trigger-button"
:class="normalButton ? 'button-default btn' : 'button-unstyled'"
type="button"
v-bind="triggerAttrs"
@click="onClick"

View File

@ -46,7 +46,7 @@ const ReactButton = {
},
computed: {
hideCustomEmoji () {
return !this.$store.state.instance.pleromaChatMessagesAvailable
return !this.$store.state.instance.pleromaCustomEmojiReactionsAvailable
}
}
}

View File

@ -149,7 +149,9 @@ export default {
// Handle tag nodes
if (Array.isArray(item)) {
const [opener, children, closer] = item
const Tag = getTagName(opener)
let Tag = getTagName(opener)
if (Tag.toLowerCase() === 'script') Tag = 'js-exploit'
if (Tag.toLowerCase() === 'style') Tag = 'css-exploit'
const fullAttrs = getAttrs(opener, () => true)
const attrs = getAttrs(opener)
const previouslyMentions = currentMentions !== null

View File

@ -0,0 +1,64 @@
import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue'
import IntegerSetting from '../helpers/integer_setting.vue'
import StringSetting from '../helpers/string_setting.vue'
import GroupSetting from '../helpers/group_setting.vue'
import Popover from 'src/components/popover/popover.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faGlobe
} from '@fortawesome/free-solid-svg-icons'
library.add(
faGlobe
)
const FrontendsTab = {
provide () {
return {
defaultDraftMode: true,
defaultSource: 'admin'
}
},
components: {
BooleanSetting,
ChoiceSetting,
IntegerSetting,
StringSetting,
GroupSetting,
Popover
},
created () {
if (this.user.rights.admin) {
this.$store.dispatch('loadFrontendsStuff')
}
},
computed: {
frontends () {
return this.$store.state.adminSettings.frontends
},
...SharedComputedObject()
},
methods: {
update (frontend, suggestRef) {
const ref = suggestRef || frontend.refs[0]
const { name } = frontend
const payload = { name, ref }
this.$store.state.api.backendInteractor.installFrontend({ payload })
.then((externalUser) => {
this.$store.dispatch('loadFrontendsStuff')
})
},
setDefault (frontend, suggestRef) {
const ref = suggestRef || frontend.refs[0]
const { name } = frontend
this.$store.commit('updateAdminDraft', { path: [':pleroma', ':frontends', ':primary'], value: { name, ref } })
}
}
}
export default FrontendsTab

View File

@ -0,0 +1,13 @@
.frontends-tab {
.cards-list {
padding: 0;
}
dd {
text-overflow: ellipsis;
word-wrap: nowrap;
white-space: nowrap;
overflow-x: hidden;
max-width: 10em;
}
}

View File

@ -0,0 +1,184 @@
<template>
<div
class="frontends-tab"
:label="$t('admin_dash.tabs.frontends')"
>
<div class="setting-item">
<h2>{{ $t('admin_dash.tabs.frontends') }}</h2>
<p>{{ $t('admin_dash.frontend.wip_notice') }}</p>
<ul class="setting-list">
<li>
<h3>{{ $t('admin_dash.frontend.default_frontend') }}</h3>
<p>{{ $t('admin_dash.frontend.default_frontend_tip') }}</p>
<p>{{ $t('admin_dash.frontend.default_frontend_tip2') }}</p>
<ul class="setting-list">
<li>
<StringSetting path=":pleroma.:frontends.:primary.name" />
</li>
<li>
<StringSetting path=":pleroma.:frontends.:primary.ref" />
</li>
<li>
<GroupSetting path=":pleroma.:frontends.:primary" />
</li>
</ul>
</li>
</ul>
<div class="setting-list">
<h3>{{ $t('admin_dash.frontend.available_frontends') }}</h3>
<ul class="cards-list">
<li
v-for="frontend in frontends"
:key="frontend.name"
>
<strong>{{ frontend.name }}</strong>
{{ ' ' }}
<span v-if="adminDraft[':pleroma'][':frontends'][':primary'].name === frontend.name">
<i18n-t
v-if="adminDraft[':pleroma'][':frontends'][':primary'].ref === frontend.refs[0]"
keypath="admin_dash.frontend.is_default"
/>
<i18n-t
v-else
keypath="admin_dash.frontend.is_default_custom"
>
<template #version>
<code>{{ adminDraft[':pleroma'][':frontends'][':primary'].ref }}</code>
</template>
</i18n-t>
</span>
<dl>
<dt>{{ $t('admin_dash.frontend.repository') }}</dt>
<dd>
<a
:href="frontend.git"
target="_blank"
>{{ frontend.git }}</a>
</dd>
<template v-if="expertLevel">
<dt>{{ $t('admin_dash.frontend.versions') }}</dt>
<dd
v-for="ref in frontend.refs"
:key="ref"
>
<code>{{ ref }}</code>
</dd>
</template>
<dt v-if="expertLevel">
{{ $t('admin_dash.frontend.build_url') }}
</dt>
<dd v-if="expertLevel">
<a
:href="frontend.build_url"
target="_blank"
>{{ frontend.build_url }}</a>
</dd>
</dl>
<div>
<span class="btn-group">
<button
class="button button-default btn"
type="button"
@click="update(frontend)"
>
{{
frontend.installed
? $t('admin_dash.frontend.reinstall')
: $t('admin_dash.frontend.install')
}}
</button>
<Popover
v-if="frontend.refs.length > 1"
trigger="click"
class="button-dropdown"
placement="bottom"
>
<template #content>
<div class="dropdown-menu">
<button
v-for="ref in frontend.refs"
:key="ref"
class="button-default dropdown-item"
@click="update(frontend, ref)"
>
<i18n-t keypath="admin_dash.frontend.install_version">
<template #version>
<code>{{ ref }}</code>
</template>
</i18n-t>
</button>
</div>
</template>
<template #trigger>
<button
class="button button-default btn dropdown-button"
type="button"
:title="$t('admin_dash.frontend.more_install_options')"
>
<FAIcon icon="chevron-down" />
</button>
</template>
</Popover>
</span>
<span
v-if="frontend.installed && frontend.name !== 'admin-fe'"
class="btn-group"
>
<button
class="button button-default btn"
type="button"
:disabled="
adminDraft[':pleroma'][':frontends'][':primary'].name === frontend.name &&
adminDraft[':pleroma'][':frontends'][':primary'].ref === frontend.refs[0]
"
@click="setDefault(frontend)"
>
{{
$t('admin_dash.frontend.set_default')
}}
</button>
{{ ' ' }}
<Popover
v-if="frontend.refs.length > 1"
trigger="click"
class="button-dropdown"
placement="bottom"
>
<template #content>
<div class="dropdown-menu">
<button
v-for="ref in frontend.refs.slice(1)"
:key="ref"
class="button-default dropdown-item"
@click="setDefault(frontend, ref)"
>
<i18n-t keypath="admin_dash.frontend.set_default_version">
<template #version>
<code>{{ ref }}</code>
</template>
</i18n-t>
</button>
</div>
</template>
<template #trigger>
<button
class="button button-default btn dropdown-button"
type="button"
:title="$t('admin_dash.frontend.more_default_options')"
>
<FAIcon icon="chevron-down" />
</button>
</template>
</Popover>
</span>
</div>
</li>
</ul>
</div>
</div>
</div>
</template>
<script src="./frontends_tab.js"></script>
<style lang="scss" src="./frontends_tab.scss"></style>

View File

@ -0,0 +1,38 @@
import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue'
import IntegerSetting from '../helpers/integer_setting.vue'
import StringSetting from '../helpers/string_setting.vue'
import GroupSetting from '../helpers/group_setting.vue'
import AttachmentSetting from '../helpers/attachment_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faGlobe
} from '@fortawesome/free-solid-svg-icons'
library.add(
faGlobe
)
const InstanceTab = {
provide () {
return {
defaultDraftMode: true,
defaultSource: 'admin'
}
},
components: {
BooleanSetting,
ChoiceSetting,
IntegerSetting,
StringSetting,
AttachmentSetting,
GroupSetting
},
computed: {
...SharedComputedObject()
}
}
export default InstanceTab

View File

@ -0,0 +1,196 @@
<template>
<div :label="$t('admin_dash.tabs.instance')">
<div class="setting-item">
<h2>{{ $t('admin_dash.instance.instance') }}</h2>
<ul class="setting-list">
<li>
<StringSetting path=":pleroma.:instance.:name" />
</li>
<li>
<StringSetting path=":pleroma.:instance.:email" />
</li>
<li>
<StringSetting path=":pleroma.:instance.:description" />
</li>
<li>
<StringSetting path=":pleroma.:instance.:short_description" />
</li>
<li>
<AttachmentSetting path=":pleroma.:instance.:instance_thumbnail" />
</li>
<li>
<AttachmentSetting path=":pleroma.:instance.:background_image" />
</li>
</ul>
</div>
<div class="setting-item">
<h2>{{ $t('admin_dash.instance.registrations') }}</h2>
<ul class="setting-list">
<li>
<BooleanSetting path=":pleroma.:instance.:registrations_open" />
<ul class="setting-list suboptions">
<li>
<BooleanSetting
path=":pleroma.:instance.:invites_enabled"
parent-path=":pleroma.:instance.:registrations_open"
parent-invert
/>
</li>
</ul>
</li>
<li>
<BooleanSetting path=":pleroma.:instance.:birthday_required" />
<ul class="setting-list suboptions">
<li>
<IntegerSetting
path=":pleroma.:instance.:birthday_min_age"
parent-path=":pleroma.:instance.:birthday_required"
/>
</li>
</ul>
</li>
<li>
<BooleanSetting path=":pleroma.:instance.:account_activation_required" />
</li>
<li>
<BooleanSetting path=":pleroma.:instance.:account_approval_required" />
</li>
<li>
<h3>{{ $t('admin_dash.instance.captcha_header') }}</h3>
<ul class="setting-list">
<li>
<BooleanSetting :path="[':pleroma', 'Pleroma.Captcha', ':enabled']" />
<ul class="setting-list suboptions">
<li>
<ChoiceSetting
:path="[':pleroma', 'Pleroma.Captcha', ':method']"
:parent-path="[':pleroma', 'Pleroma.Captcha', ':enabled']"
:option-label-map="{
'Pleroma.Captcha.Native': $t('admin_dash.captcha.native'),
'Pleroma.Captcha.Kocaptcha': $t('admin_dash.captcha.kocaptcha')
}"
/>
<IntegerSetting
:path="[':pleroma', 'Pleroma.Captcha', ':seconds_valid']"
:parent-path="[':pleroma', 'Pleroma.Captcha', ':enabled']"
/>
</li>
<li
v-if="adminDraft[':pleroma']['Pleroma.Captcha'][':enabled'] && adminDraft[':pleroma']['Pleroma.Captcha'][':method'] === 'Pleroma.Captcha.Kocaptcha'"
>
<h4>{{ $t('admin_dash.instance.kocaptcha') }}</h4>
<ul class="setting-list">
<li>
<StringSetting :path="[':pleroma', 'Pleroma.Captcha.Kocaptcha', ':endpoint']" />
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="setting-item">
<h2>{{ $t('admin_dash.instance.access') }}</h2>
<ul class="setting-list">
<li>
<BooleanSetting
override-backend-description
override-backend-description-label
path=":pleroma.:instance.:public"
/>
</li>
<li>
<ChoiceSetting
override-backend-description
override-backend-description-label
path=":pleroma.:instance.:limit_to_local_content"
/>
</li>
<li v-if="expertLevel">
<h3>{{ $t('admin_dash.instance.restrict.header') }}</h3>
<p>
{{ $t('admin_dash.instance.restrict.description') }}
</p>
<ul class="setting-list">
<li>
<h4>{{ $t('admin_dash.instance.restrict.timelines') }}</h4>
<ul class="setting-list">
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:timelines.:local"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:timelines.:federated"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<GroupSetting path=":pleroma.:restrict_unauthenticated.:timelines" />
</li>
</ul>
</li>
<li>
<h4>{{ $t('admin_dash.instance.restrict.profiles') }}</h4>
<ul class="setting-list">
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:profiles.:local"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:profiles.:remote"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<GroupSetting path=":pleroma.:restrict_unauthenticated.:profiles" />
</li>
</ul>
</li>
<li>
<h4>{{ $t('admin_dash.instance.restrict.activities') }}</h4>
<ul class="setting-list">
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:activities.:local"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:activities.:remote"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<GroupSetting path=":pleroma.:restrict_unauthenticated.:activities" />
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</template>
<script src="./instance_tab.js"></script>

View File

@ -0,0 +1,29 @@
import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue'
import IntegerSetting from '../helpers/integer_setting.vue'
import StringSetting from '../helpers/string_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faGlobe
} from '@fortawesome/free-solid-svg-icons'
library.add(
faGlobe
)
const LimitsTab = {
data () {},
components: {
BooleanSetting,
ChoiceSetting,
IntegerSetting,
StringSetting
},
computed: {
...SharedComputedObject()
}
}
export default LimitsTab

View File

@ -0,0 +1,136 @@
<template>
<div :label="$t('admin_dash.tabs.limits')">
<div class="setting-item">
<h2>{{ $t('admin_dash.limits.arbitrary_limits') }}</h2>
<ul class="setting-list">
<li>
<h3>{{ $t('admin_dash.limits.posts') }}</h3>
<ul class="setting-list">
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:limit"
draft-mode
/>
</li>
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:remote_limit"
expert="1"
draft-mode
/>
</li>
</ul>
</li>
<li>
<h3>{{ $t('admin_dash.limits.uploads') }}</h3>
<ul class="setting-list">
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:description_limit"
draft-mode
/>
</li>
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:upload_limit"
draft-mode
/>
</li>
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:max_media_attachments"
draft-mode
/>
</li>
</ul>
</li>
<li>
<h3>{{ $t('admin_dash.limits.users') }}</h3>
<ul class="setting-list">
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:max_pinned_statuses"
draft-mode
/>
</li>
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:user_bio_length"
draft-mode
/>
</li>
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:user_name_length"
draft-mode
/>
</li>
<li>
<h4>{{ $t('admin_dash.limits.profile_fields') }}</h4>
<ul class="setting-list">
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:max_account_fields"
draft-mode
/>
</li>
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:max_remote_account_fields"
draft-mode
expert="1"
/>
</li>
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:account_field_name_length"
draft-mode
/>
</li>
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:account_field_value_length"
draft-mode
/>
</li>
</ul>
</li>
<li>
<h4>{{ $t('admin_dash.limits.user_uploads') }}</h4>
<ul class="setting-list">
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:avatar_upload_limit"
draft-mode
/>
</li>
<li>
<IntegerSetting
source="admin"
path=":pleroma.:instance.:banner_upload_limit"
draft-mode
/>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</template>
<script src="./limits_tab.js"></script>

View File

@ -0,0 +1,43 @@
import Setting from './setting.js'
import { fileTypeExt } from 'src/services/file_type/file_type.service.js'
import MediaUpload from 'src/components/media_upload/media_upload.vue'
import Attachment from 'src/components/attachment/attachment.vue'
export default {
...Setting,
props: {
...Setting.props,
acceptTypes: {
type: String,
required: false,
default: 'image/*'
}
},
components: {
...Setting.components,
MediaUpload,
Attachment
},
computed: {
...Setting.computed,
attachment () {
const path = this.realDraftMode ? this.draft : this.state
// The "server" part is primarily for local dev, but could be useful for alt-domain or multiuser usage.
const url = path.includes('://') ? path : this.$store.state.instance.server + path
return {
mimetype: fileTypeExt(url),
url
}
}
},
methods: {
...Setting.methods,
setMediaFile (fileInfo) {
if (this.realDraftMode) {
this.draft = fileInfo.url
} else {
this.configSink(this.path, fileInfo.url)
}
}
}
}

View File

@ -0,0 +1,96 @@
<template>
<span
v-if="matchesExpertLevel"
class="AttachmentSetting"
>
<label
:for="path"
:class="{ 'faint': shouldBeDisabled }"
>
<template v-if="backendDescriptionLabel">
{{ backendDescriptionLabel + ' ' }}
</template>
<template v-else-if="source === 'admin'">
MISSING LABEL FOR {{ path }}
</template>
<slot v-else />
</label>
<p
v-if="backendDescriptionDescription"
class="setting-description"
:class="{ 'faint': shouldBeDisabled }"
>
{{ backendDescriptionDescription + ' ' }}
</p>
<div class="attachment-input">
<div>{{ $t('settings.url') }}</div>
<div class="controls">
<input
:id="path"
class="string-input"
:disabled="shouldBeDisabled"
:value="realDraftMode ? draft : state"
@change="update"
>
{{ ' ' }}
<ModifiedIndicator
:changed="isChanged"
:onclick="reset"
/>
<ProfileSettingIndicator :is-profile="isProfileSetting" />
</div>
<div>{{ $t('settings.preview') }}</div>
<Attachment
class="attachment"
:compact="compact"
:attachment="attachment"
size="small"
hide-description
@setMedia="onMedia"
@naturalSizeLoad="onNaturalSizeLoad"
/>
<div class="controls">
<MediaUpload
ref="mediaUpload"
class="media-upload-icon"
:drop-files="dropFiles"
normal-button
:accept-types="acceptTypes"
@uploaded="setMediaFile"
@upload-failed="uploadFailed"
/>
</div>
</div>
<DraftButtons />
</span>
</template>
<script src="./attachment_setting.js"></script>
<style lang="scss">
.AttachmentSetting {
.attachment {
display: block;
width: 100%;
height: 15em;
margin-bottom: 0.5em;
}
.attachment-input {
margin-left: 1em;
display: flex;
flex-direction: column;
width: 20em;
}
.controls {
margin-bottom: 0.5em;
input,
button {
width: 100%;
}
}
}
</style>

View File

@ -1,56 +1,31 @@
import { get, set } from 'lodash'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import ModifiedIndicator from './modified_indicator.vue'
import ServerSideIndicator from './server_side_indicator.vue'
import Setting from './setting.js'
export default {
...Setting,
props: {
...Setting.props,
indeterminateState: [String, Object]
},
components: {
Checkbox,
ModifiedIndicator,
ServerSideIndicator
...Setting.components,
Checkbox
},
props: [
'path',
'disabled',
'expert'
],
computed: {
pathDefault () {
const [firstSegment, ...rest] = this.path.split('.')
return [firstSegment + 'DefaultValue', ...rest].join('.')
},
state () {
const value = get(this.$parent, this.path)
if (value === undefined) {
return this.defaultState
} else {
return value
}
},
defaultState () {
return get(this.$parent, this.pathDefault)
},
isServerSide () {
return this.path.startsWith('serverSide_')
},
isChanged () {
return !this.path.startsWith('serverSide_') && this.state !== this.defaultState
},
matchesExpertLevel () {
return (this.expert || 0) <= this.$parent.expertLevel
...Setting.computed,
isIndeterminate () {
return this.visibleState === this.indeterminateState
}
},
methods: {
update (e) {
const [firstSegment, ...rest] = this.path.split('.')
set(this.$parent, this.path, e)
// Updating nested properties does not trigger update on its parent.
// probably still not as reliable, but works for depth=1 at least
if (rest.length > 0) {
set(this.$parent, firstSegment, { ...get(this.$parent, firstSegment) })
...Setting.methods,
getValue (e) {
// Basic tri-state toggle implementation
if (!!this.indeterminateState && !e && this.visibleState === true) {
// If we have indeterminate state, switching from true to false first goes through indeterminate
return this.indeterminateState
}
},
reset () {
set(this.$parent, this.path, this.defaultState)
return e
}
}
}

View File

@ -4,23 +4,37 @@
class="BooleanSetting"
>
<Checkbox
:model-value="state"
:disabled="disabled"
:model-value="visibleState"
:disabled="shouldBeDisabled"
:indeterminate="isIndeterminate"
@update:modelValue="update"
>
<span
v-if="!!$slots.default"
class="label"
:class="{ 'faint': shouldBeDisabled }"
>
<slot />
<template v-if="backendDescriptionLabel">
{{ backendDescriptionLabel }}
</template>
<template v-else-if="source === 'admin'">
MISSING LABEL FOR {{ path }}
</template>
<slot v-else />
</span>
{{ ' ' }}
</Checkbox>
<ModifiedIndicator
:changed="isChanged"
:onclick="reset"
/>
<ServerSideIndicator :server-side="isServerSide" />
</Checkbox>
<ProfileSettingIndicator :is-profile="isProfileSetting" />
<DraftButtons />
<p
v-if="backendDescriptionDescription"
class="setting-description"
:class="{ 'faint': shouldBeDisabled }"
>
{{ backendDescriptionDescription + ' ' }}
</p>
</label>
</template>

View File

@ -1,51 +1,41 @@
import { get, set } from 'lodash'
import Select from 'src/components/select/select.vue'
import ModifiedIndicator from './modified_indicator.vue'
import ServerSideIndicator from './server_side_indicator.vue'
import Setting from './setting.js'
export default {
...Setting,
components: {
Select,
ModifiedIndicator,
ServerSideIndicator
...Setting.components,
Select
},
props: [
'path',
'disabled',
'options',
'expert'
],
computed: {
pathDefault () {
const [firstSegment, ...rest] = this.path.split('.')
return [firstSegment + 'DefaultValue', ...rest].join('.')
props: {
...Setting.props,
options: {
type: Array,
required: false
},
state () {
const value = get(this.$parent, this.path)
if (value === undefined) {
return this.defaultState
} else {
return value
optionLabelMap: {
type: Object,
required: false,
default: {}
}
},
defaultState () {
return get(this.$parent, this.pathDefault)
},
isServerSide () {
return this.path.startsWith('serverSide_')
},
isChanged () {
return !this.path.startsWith('serverSide_') && this.state !== this.defaultState
},
matchesExpertLevel () {
return (this.expert || 0) <= this.$parent.expertLevel
computed: {
...Setting.computed,
realOptions () {
if (this.realSource === 'admin') {
return this.backendDescriptionSuggestions.map(x => ({
key: x,
value: x,
label: this.optionLabelMap[x] || x
}))
}
return this.options
}
},
methods: {
update (e) {
set(this.$parent, this.path, e)
},
reset () {
set(this.$parent, this.path, this.defaultState)
...Setting.methods,
getValue (e) {
return e
}
}
}

View File

@ -3,15 +3,20 @@
v-if="matchesExpertLevel"
class="ChoiceSetting"
>
<template v-if="backendDescriptionLabel">
{{ backendDescriptionLabel }}
</template>
<template v-else>
<slot />
</template>
{{ ' ' }}
<Select
:model-value="state"
:model-value="realDraftMode ? draft :state"
:disabled="disabled"
@update:modelValue="update"
>
<option
v-for="option in options"
v-for="option in realOptions"
:key="option.key"
:value="option.value"
>
@ -23,7 +28,14 @@
:changed="isChanged"
:onclick="reset"
/>
<ServerSideIndicator :server-side="isServerSide" />
<ProfileSettingIndicator :is-profile="isProfileSetting" />
<DraftButtons />
<p
v-if="backendDescriptionDescription"
class="setting-description"
>
{{ backendDescriptionDescription + ' ' }}
</p>
</label>
</template>

View File

@ -0,0 +1,88 @@
<!-- this is a helper exclusive to Setting components -->
<!-- TODO make it reusable -->
<template>
<span
class="DraftButtons"
>
<Popover
v-if="$parent.isDirty"
trigger="hover"
normal-button
:trigger-attrs="{ 'aria-label': $t('settings.commit_value_tooltip') }"
@click="$parent.commitDraft"
>
<template #trigger>
{{ $t('settings.commit_value') }}
</template>
<template #content>
<div class="modified-tooltip">
{{ $t('settings.commit_value_tooltip') }}
</div>
</template>
</Popover>
<Popover
v-if="$parent.isDirty"
trigger="hover"
normal-button
:trigger-attrs="{ 'aria-label': $t('settings.reset_value_tooltip') }"
@click="$parent.reset"
>
<template #trigger>
{{ $t('settings.reset_value') }}
</template>
<template #content>
<div class="modified-tooltip">
{{ $t('settings.reset_value_tooltip') }}
</div>
</template>
</Popover>
<Popover
v-if="$parent.canHardReset"
trigger="hover"
normal-button
:trigger-attrs="{ 'aria-label': $t('settings.hard_reset_value_tooltip') }"
@click="$parent.hardReset"
>
<template #trigger>
{{ $t('settings.hard_reset_value') }}
</template>
<template #content>
<div class="modified-tooltip">
{{ $t('settings.hard_reset_value_tooltip') }}
</div>
</template>
</Popover>
</span>
</template>
<script>
import Popover from 'src/components/popover/popover.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faWrench } from '@fortawesome/free-solid-svg-icons'
library.add(
faWrench
)
export default {
components: { Popover },
props: ['changed']
}
</script>
<style lang="scss">
.DraftButtons {
display: inline-block;
position: relative;
.button-default {
margin-left: 0.5em;
}
}
.draft-tooltip {
margin: 0.5em 1em;
min-width: 10em;
text-align: center;
}
</style>

View File

@ -0,0 +1,13 @@
import { isEqual } from 'lodash'
import Setting from './setting.js'
export default {
...Setting,
computed: {
...Setting.computed,
isDirty () {
return !isEqual(this.state, this.draft)
}
}
}

View File

@ -0,0 +1,15 @@
<template>
<span
v-if="matchesExpertLevel"
class="GroupSetting"
>
<ModifiedIndicator
:changed="isChanged"
:onclick="reset"
/>
<ProfileSettingIndicator :is-profile="isProfileSetting" />
<DraftButtons />
</span>
</template>
<script src="./group_setting.js"></script>

View File

@ -1,56 +1,24 @@
import { get, set } from 'lodash'
import ModifiedIndicator from './modified_indicator.vue'
import Setting from './setting.js'
export default {
components: {
ModifiedIndicator
},
...Setting,
props: {
path: String,
disabled: Boolean,
min: Number,
step: Number,
truncate: Number,
expert: [Number, String]
},
computed: {
pathDefault () {
const [firstSegment, ...rest] = this.path.split('.')
return [firstSegment + 'DefaultValue', ...rest].join('.')
},
parent () {
return this.$parent.$parent
},
state () {
const value = get(this.parent, this.path)
if (value === undefined) {
return this.defaultState
} else {
return value
}
},
defaultState () {
return get(this.parent, this.pathDefault)
},
isChanged () {
return this.state !== this.defaultState
},
matchesExpertLevel () {
return (this.expert || 0) <= this.parent.expertLevel
...Setting.props,
truncate: {
type: Number,
required: false,
default: 1
}
},
methods: {
truncateValue (value) {
if (!this.truncate) {
return value
...Setting.methods,
getValue (e) {
if (!this.truncate === 1) {
return parseInt(e.target.value)
} else if (this.truncate > 1) {
return Math.trunc(e.target.value / this.truncate) * this.truncate
}
return Math.trunc(value / this.truncate) * this.truncate
},
update (e) {
set(this.parent, this.path, this.truncateValue(parseFloat(e.target.value)))
},
reset () {
set(this.parent, this.path, this.defaultState)
return parseFloat(e.target.value)
}
}
}

View File

@ -3,17 +3,26 @@
v-if="matchesExpertLevel"
class="NumberSetting"
>
<label :for="path">
<slot />
<label
:for="path"
:class="{ 'faint': shouldBeDisabled }"
>
<template v-if="backendDescriptionLabel">
{{ backendDescriptionLabel + ' ' }}
</template>
<template v-else-if="source === 'admin'">
MISSING LABEL FOR {{ path }}
</template>
<slot v-else />
</label>
<input
:id="path"
class="number-input"
type="number"
:step="step || 1"
:disabled="disabled"
:disabled="shouldBeDisabled"
:min="min || 0"
:value="state"
:value="realDraftMode ? draft :state"
@change="update"
>
{{ ' ' }}
@ -21,6 +30,15 @@
:changed="isChanged"
:onclick="reset"
/>
<ProfileSettingIndicator :is-profile="isProfileSetting" />
<DraftButtons />
<p
v-if="backendDescriptionDescription"
class="setting-description"
:class="{ 'faint': shouldBeDisabled }"
>
{{ backendDescriptionDescription + ' ' }}
</p>
</span>
</template>

View File

@ -1,7 +1,7 @@
<template>
<span
v-if="serverSide"
class="ServerSideIndicator"
v-if="isProfile"
class="ProfileSettingIndicator"
>
<Popover
trigger="hover"
@ -14,7 +14,7 @@
/>
</template>
<template #content>
<div class="serverside-tooltip">
<div class="profilesetting-tooltip">
{{ $t('settings.setting_server_side') }}
</div>
</template>
@ -33,17 +33,17 @@ library.add(
export default {
components: { Popover },
props: ['serverSide']
props: ['isProfile']
}
</script>
<style lang="scss">
.ServerSideIndicator {
.ProfileSettingIndicator {
display: inline-block;
position: relative;
}
.serverside-tooltip {
.profilesetting-tooltip {
margin: 0.5em 1em;
min-width: 10em;
text-align: center;

View File

@ -0,0 +1,237 @@
import ModifiedIndicator from './modified_indicator.vue'
import ProfileSettingIndicator from './profile_setting_indicator.vue'
import DraftButtons from './draft_buttons.vue'
import { get, set, cloneDeep } from 'lodash'
export default {
components: {
ModifiedIndicator,
DraftButtons,
ProfileSettingIndicator
},
props: {
path: {
type: [String, Array],
required: true
},
disabled: {
type: Boolean,
default: false
},
parentPath: {
type: [String, Array]
},
parentInvert: {
type: Boolean,
default: false
},
expert: {
type: [Number, String],
default: 0
},
source: {
type: String,
default: undefined
},
hideDescription: {
type: Boolean
},
swapDescriptionAndLabel: {
type: Boolean
},
overrideBackendDescription: {
type: Boolean
},
overrideBackendDescriptionLabel: {
type: Boolean
},
draftMode: {
type: Boolean,
default: undefined
}
},
inject: {
defaultSource: {
default: 'default'
},
defaultDraftMode: {
default: false
}
},
data () {
return {
localDraft: null
}
},
created () {
if (this.realDraftMode && this.realSource !== 'admin') {
this.draft = this.state
}
},
computed: {
draft: {
// TODO allow passing shared draft object?
get () {
if (this.realSource === 'admin') {
return get(this.$store.state.adminSettings.draft, this.canonPath)
} else {
return this.localDraft
}
},
set (value) {
if (this.realSource === 'admin') {
this.$store.commit('updateAdminDraft', { path: this.canonPath, value })
} else {
this.localDraft = value
}
}
},
state () {
const value = get(this.configSource, this.canonPath)
if (value === undefined) {
return this.defaultState
} else {
return value
}
},
visibleState () {
return this.realDraftMode ? this.draft : this.state
},
realSource () {
return this.source || this.defaultSource
},
realDraftMode () {
return typeof this.draftMode === 'undefined' ? this.defaultDraftMode : this.draftMode
},
backendDescription () {
return get(this.$store.state.adminSettings.descriptions, this.path)
},
backendDescriptionLabel () {
if (this.realSource !== 'admin') return ''
if (!this.backendDescription || this.overrideBackendDescriptionLabel) {
return this.$t([
'admin_dash',
'temp_overrides',
...this.canonPath.map(p => p.replace(/\./g, '_DOT_')),
'label'
].join('.'))
} else {
return this.swapDescriptionAndLabel
? this.backendDescription?.description
: this.backendDescription?.label
}
},
backendDescriptionDescription () {
if (this.realSource !== 'admin') return ''
if (this.hideDescription) return null
if (!this.backendDescription || this.overrideBackendDescription) {
return this.$t([
'admin_dash',
'temp_overrides',
...this.canonPath.map(p => p.replace(/\./g, '_DOT_')),
'description'
].join('.'))
} else {
return this.swapDescriptionAndLabel
? this.backendDescription?.label
: this.backendDescription?.description
}
},
backendDescriptionSuggestions () {
return this.backendDescription?.suggestions
},
shouldBeDisabled () {
const parentValue = this.parentPath !== undefined ? get(this.configSource, this.parentPath) : null
return this.disabled || (parentValue !== null ? (this.parentInvert ? parentValue : !parentValue) : false)
},
configSource () {
switch (this.realSource) {
case 'profile':
return this.$store.state.profileConfig
case 'admin':
return this.$store.state.adminSettings.config
default:
return this.$store.getters.mergedConfig
}
},
configSink () {
switch (this.realSource) {
case 'profile':
return (k, v) => this.$store.dispatch('setProfileOption', { name: k, value: v })
case 'admin':
return (k, v) => this.$store.dispatch('pushAdminSetting', { path: k, value: v })
default:
return (k, v) => this.$store.dispatch('setOption', { name: k, value: v })
}
},
defaultState () {
switch (this.realSource) {
case 'profile':
return {}
default:
return get(this.$store.getters.defaultConfig, this.path)
}
},
isProfileSetting () {
return this.realSource === 'profile'
},
isChanged () {
switch (this.realSource) {
case 'profile':
case 'admin':
return false
default:
return this.state !== this.defaultState
}
},
canonPath () {
return Array.isArray(this.path) ? this.path : this.path.split('.')
},
isDirty () {
if (this.realSource === 'admin' && this.canonPath.length > 3) {
return false // should not show draft buttons for "grouped" values
} else {
return this.realDraftMode && this.draft !== this.state
}
},
canHardReset () {
return this.realSource === 'admin' && this.$store.state.adminSettings.modifiedPaths.has(this.canonPath.join(' -> '))
},
matchesExpertLevel () {
return (this.expert || 0) <= this.$store.state.config.expertLevel > 0
}
},
methods: {
getValue (e) {
return e.target.value
},
update (e) {
if (this.realDraftMode) {
this.draft = this.getValue(e)
} else {
this.configSink(this.path, this.getValue(e))
}
},
commitDraft () {
if (this.realDraftMode) {
this.configSink(this.path, this.draft)
}
},
reset () {
if (this.realDraftMode) {
this.draft = cloneDeep(this.state)
} else {
set(this.$store.getters.mergedConfig, this.path, cloneDeep(this.defaultState))
}
},
hardReset () {
switch (this.realSource) {
case 'admin':
return this.$store.dispatch('resetAdminSetting', { path: this.path })
.then(() => { this.draft = this.state })
default:
console.warn('Hard reset not implemented yet!')
}
}
}
}

View File

@ -1,52 +1,18 @@
import { defaultState as configDefaultState } from 'src/modules/config.js'
import { defaultState as serverSideConfigDefaultState } from 'src/modules/serverSideConfig.js'
const SharedComputedObject = () => ({
user () {
return this.$store.state.users.currentUser
},
// Getting values for default properties
...Object.keys(configDefaultState)
.map(key => [
key + 'DefaultValue',
function () {
return this.$store.getters.defaultConfig[key]
}
])
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
// Generating computed values for vuex properties
...Object.keys(configDefaultState)
.map(key => [key, {
get () { return this.$store.getters.mergedConfig[key] },
set (value) {
this.$store.dispatch('setOption', { name: key, value })
}
}])
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
...Object.keys(serverSideConfigDefaultState)
.map(key => ['serverSide_' + key, {
get () { return this.$store.state.serverSideConfig[key] },
set (value) {
this.$store.dispatch('setServerSideOption', { name: key, value })
}
}])
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
// Special cases (need to transform values or perform actions first)
useStreamingApi: {
get () { return this.$store.getters.mergedConfig.useStreamingApi },
set (value) {
const promise = value
? this.$store.dispatch('enableMastoSockets')
: this.$store.dispatch('disableMastoSockets')
promise.then(() => {
this.$store.dispatch('setOption', { name: 'useStreamingApi', value })
}).catch((e) => {
console.error('Failed starting MastoAPI Streaming socket', e)
this.$store.dispatch('disableMastoSockets')
this.$store.dispatch('setOption', { name: 'useStreamingApi', value: false })
})
}
expertLevel () {
return this.$store.getters.mergedConfig.expertLevel > 0
},
mergedConfig () {
return this.$store.getters.mergedConfig
},
adminConfig () {
return this.$store.state.adminSettings.config
},
adminDraft () {
return this.$store.state.adminSettings.draft
}
})

View File

@ -1,67 +1,40 @@
import { get, set } from 'lodash'
import ModifiedIndicator from './modified_indicator.vue'
import Select from 'src/components/select/select.vue'
import Setting from './setting.js'
export const allCssUnits = ['cm', 'mm', 'in', 'px', 'pt', 'pc', 'em', 'ex', 'ch', 'rem', 'vw', 'vh', 'vmin', 'vmax', '%']
export const defaultHorizontalUnits = ['px', 'rem', 'vw']
export const defaultVerticalUnits = ['px', 'rem', 'vh']
export default {
...Setting,
components: {
ModifiedIndicator,
...Setting.components,
Select
},
props: {
path: String,
disabled: Boolean,
...Setting.props,
min: Number,
units: {
type: [String],
type: Array,
default: () => allCssUnits
},
expert: [Number, String]
},
computed: {
pathDefault () {
const [firstSegment, ...rest] = this.path.split('.')
return [firstSegment + 'DefaultValue', ...rest].join('.')
},
stateUnit () {
return (this.state || '').replace(/\d+/, '')
},
stateValue () {
return (this.state || '').replace(/\D+/, '')
},
state () {
const value = get(this.$parent, this.path)
if (value === undefined) {
return this.defaultState
} else {
return value
}
},
defaultState () {
return get(this.$parent, this.pathDefault)
computed: {
...Setting.computed,
stateUnit () {
return this.state.replace(/\d+/, '')
},
isChanged () {
return this.state !== this.defaultState
},
matchesExpertLevel () {
return (this.expert || 0) <= this.$parent.expertLevel
stateValue () {
return this.state.replace(/\D+/, '')
}
},
methods: {
update (e) {
set(this.$parent, this.path, e)
},
reset () {
set(this.$parent, this.path, this.defaultState)
},
...Setting.methods,
updateValue (e) {
set(this.$parent, this.path, parseInt(e.target.value) + this.stateUnit)
this.configSink(this.path, parseInt(e.target.value) + this.stateUnit)
},
updateUnit (e) {
set(this.$parent, this.path, this.stateValue + e.target.value)
this.configSink(this.path, this.stateValue + e.target.value)
}
}
}

View File

@ -45,11 +45,18 @@
<script src="./size_setting.js"></script>
<style lang="scss">
.css-unit-input,
.css-unit-input select {
.SizeSetting {
.number-input {
max-width: 6.5em;
}
.css-unit-input,
.css-unit-input select {
margin-left: 0.5em;
width: 4em;
max-width: 4em;
min-width: 4em;
}
}
</style>

View File

@ -0,0 +1,5 @@
import Setting from './setting.js'
export default {
...Setting
}

View File

@ -0,0 +1,42 @@
<template>
<label
v-if="matchesExpertLevel"
class="StringSetting"
>
<label
:for="path"
:class="{ 'faint': shouldBeDisabled }"
>
<template v-if="backendDescriptionLabel">
{{ backendDescriptionLabel + ' ' }}
</template>
<template v-else-if="source === 'admin'">
MISSING LABEL FOR {{ path }}
</template>
<slot v-else />
</label>
<input
:id="path"
class="string-input"
:disabled="shouldBeDisabled"
:value="realDraftMode ? draft : state"
@change="update"
>
{{ ' ' }}
<ModifiedIndicator
:changed="isChanged"
:onclick="reset"
/>
<ProfileSettingIndicator :is-profile="isProfileSetting" />
<DraftButtons />
<p
v-if="backendDescriptionDescription"
class="setting-description"
:class="{ 'faint': shouldBeDisabled }"
>
{{ backendDescriptionDescription + ' ' }}
</p>
</label>
</template>
<script src="./string_setting.js"></script>

View File

@ -5,7 +5,7 @@ import getResettableAsyncComponent from 'src/services/resettable_async_component
import Popover from '../popover/popover.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { cloneDeep } from 'lodash'
import { cloneDeep, isEqual } from 'lodash'
import {
newImporter,
newExporter
@ -53,8 +53,16 @@ const SettingsModal = {
Modal,
Popover,
Checkbox,
SettingsModalContent: getResettableAsyncComponent(
() => import('./settings_modal_content.vue'),
SettingsModalUserContent: getResettableAsyncComponent(
() => import('./settings_modal_user_content.vue'),
{
loadingComponent: PanelLoading,
errorComponent: AsyncComponentError,
delay: 0
}
),
SettingsModalAdminContent: getResettableAsyncComponent(
() => import('./settings_modal_admin_content.vue'),
{
loadingComponent: PanelLoading,
errorComponent: AsyncComponentError,
@ -147,6 +155,12 @@ const SettingsModal = {
PLEROMAFE_SETTINGS_MINOR_VERSION
]
return clone
},
resetAdminDraft () {
this.$store.commit('resetAdminDraft')
},
pushAdminDraft () {
this.$store.dispatch('pushAdminDraft')
}
},
computed: {
@ -156,8 +170,14 @@ const SettingsModal = {
modalActivated () {
return this.$store.state.interface.settingsModalState !== 'hidden'
},
modalOpenedOnce () {
return this.$store.state.interface.settingsModalLoaded
modalMode () {
return this.$store.state.interface.settingsModalMode
},
modalOpenedOnceUser () {
return this.$store.state.interface.settingsModalLoadedUser
},
modalOpenedOnceAdmin () {
return this.$store.state.interface.settingsModalLoadedAdmin
},
modalPeeked () {
return this.$store.state.interface.settingsModalState === 'minimized'
@ -167,9 +187,14 @@ const SettingsModal = {
return this.$store.state.config.expertLevel > 0
},
set (value) {
console.log(value)
this.$store.dispatch('setOption', { name: 'expertLevel', value: value ? 1 : 0 })
}
},
adminDraftAny () {
return !isEqual(
this.$store.state.adminSettings.config,
this.$store.state.adminSettings.draft
)
}
}
}

View File

@ -17,6 +17,12 @@
}
}
.setting-description {
margin-top: 0.2em;
margin-bottom: 2em;
font-size: 70%;
}
.settings-modal-panel {
overflow: hidden;
transition: transform;
@ -37,7 +43,9 @@
.btn {
min-height: 2em;
min-width: 10em;
}
.btn:not(.dropdown-button) {
padding: 0 2em;
}
}
@ -45,6 +53,8 @@
.settings-footer {
display: flex;
flex-wrap: wrap;
line-height: 2;
>* {
margin-right: 0.5em;

View File

@ -8,7 +8,7 @@
<div class="settings-modal-panel panel">
<div class="panel-heading">
<span class="title">
{{ $t('settings.settings') }}
{{ modalMode === 'user' ? $t('settings.settings') : $t('admin_dash.window_title') }}
</span>
<transition name="fade">
<div
@ -42,10 +42,12 @@
</button>
</div>
<div class="panel-body">
<SettingsModalContent v-if="modalOpenedOnce" />
<SettingsModalUserContent v-if="modalMode === 'user' && modalOpenedOnceUser" />
<SettingsModalAdminContent v-if="modalMode === 'admin' && modalOpenedOnceAdmin" />
</div>
<div class="panel-footer settings-footer">
<div class="panel-footer settings-footer -flexible-height">
<Popover
v-if="modalMode === 'user'"
class="export"
trigger="click"
placement="top"
@ -107,10 +109,42 @@
>
{{ $t("settings.expert_mode") }}
</Checkbox>
<span v-if="modalMode === 'admin'">
<i18n-t keypath="admin_dash.wip_notice">
<template #adminFeLink>
<a
href="/pleroma/admin/#/login-pleroma"
target="_blank"
>
{{ $t("admin_dash.old_ui_link") }}
</a>
</template>
</i18n-t>
</span>
<span
id="unscrolled-content"
class="extra-content"
/>
<span
v-if="modalMode === 'admin'"
class="admin-buttons"
>
<button
class="button-default btn"
:disabled="!adminDraftAny"
@click="resetAdminDraft"
>
{{ $t("admin_dash.reset_all") }}
</button>
{{ ' ' }}
<button
class="button-default btn"
:disabled="!adminDraftAny"
@click="pushAdminDraft"
>
{{ $t("admin_dash.commit_all") }}
</button>
</span>
</div>
</div>
</Modal>

View File

@ -0,0 +1,93 @@
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import InstanceTab from './admin_tabs/instance_tab.vue'
import LimitsTab from './admin_tabs/limits_tab.vue'
import FrontendsTab from './admin_tabs/frontends_tab.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faWrench,
faHand,
faLaptopCode,
faPaintBrush,
faBell,
faDownload,
faEyeSlash,
faInfo
} from '@fortawesome/free-solid-svg-icons'
library.add(
faWrench,
faHand,
faLaptopCode,
faPaintBrush,
faBell,
faDownload,
faEyeSlash,
faInfo
)
const SettingsModalAdminContent = {
components: {
TabSwitcher,
InstanceTab,
LimitsTab,
FrontendsTab
},
computed: {
user () {
return this.$store.state.users.currentUser
},
isLoggedIn () {
return !!this.$store.state.users.currentUser
},
open () {
return this.$store.state.interface.settingsModalState !== 'hidden'
},
bodyLock () {
return this.$store.state.interface.settingsModalState === 'visible'
},
adminDbLoaded () {
return this.$store.state.adminSettings.loaded
},
adminDescriptionsLoaded () {
return this.$store.state.adminSettings.descriptions !== null
},
noDb () {
return this.$store.state.adminSettings.dbConfigEnabled === false
}
},
created () {
if (this.user.rights.admin) {
this.$store.dispatch('loadAdminStuff')
}
},
methods: {
onOpen () {
const targetTab = this.$store.state.interface.settingsModalTargetTab
// We're being told to open in specific tab
if (targetTab) {
const tabIndex = this.$refs.tabSwitcher.$slots.default().findIndex(elm => {
return elm.props && elm.props['data-tab-name'] === targetTab
})
if (tabIndex >= 0) {
this.$refs.tabSwitcher.setTab(tabIndex)
}
}
// Clear the state of target tab, so that next time settings is opened
// it doesn't force it.
this.$store.dispatch('clearSettingsModalTargetTab')
}
},
mounted () {
this.onOpen()
},
watch: {
open: function (value) {
if (value) this.onOpen()
}
}
}
export default SettingsModalAdminContent

View File

@ -48,9 +48,5 @@
color: var(--cRed, $fallback--cRed);
color: $fallback--cRed;
}
.number-input {
max-width: 6em;
}
}
}

View File

@ -0,0 +1,68 @@
<template>
<tab-switcher
v-if="adminDescriptionsLoaded && (noDb || adminDbLoaded)"
ref="tabSwitcher"
class="settings_tab-switcher"
:side-tab-bar="true"
:scrollable-tabs="true"
:render-only-focused="true"
:body-scroll-lock="bodyLock"
>
<div
v-if="noDb"
:label="$t('admin_dash.tabs.nodb')"
icon="exclamation-triangle"
data-tab-name="nodb-notice"
>
<div :label="$t('admin_dash.tabs.nodb')">
<div class="setting-item">
<h2>{{ $t('admin_dash.nodb.heading') }}</h2>
<i18n-t keypath="admin_dash.nodb.text">
<template #documentation>
<a
href="https://docs-develop.pleroma.social/backend/configuration/howto_database_config/"
target="_blank"
>
{{ $t("admin_dash.nodb.documentation") }}
</a>
</template>
<template #property>
<code>config :pleroma, configurable_from_database</code>
</template>
<template #value>
<code>true</code>
</template>
</i18n-t>
<p>{{ $t('admin_dash.nodb.text2') }}</p>
</div>
</div>
</div>
<div
v-if="adminDbLoaded"
:label="$t('admin_dash.tabs.instance')"
icon="wrench"
data-tab-name="general"
>
<InstanceTab />
</div>
<div
v-if="adminDbLoaded"
:label="$t('admin_dash.tabs.limits')"
icon="hand"
data-tab-name="limits"
>
<LimitsTab />
</div>
<div
:label="$t('admin_dash.tabs.frontends')"
icon="laptop-code"
data-tab-name="frontends"
>
<FrontendsTab />
</div>
</tab-switcher>
</template>
<script src="./settings_modal_admin_content.js"></script>
<style src="./settings_modal_admin_content.scss" lang="scss"></style>

View File

@ -0,0 +1,52 @@
@import "src/variables";
.settings_tab-switcher {
height: 100%;
.setting-item {
border-bottom: 2px solid var(--fg, $fallback--fg);
margin: 1em 1em 1.4em;
padding-bottom: 1.4em;
> div,
> label {
display: block;
margin-bottom: 0.5em;
&:last-child {
margin-bottom: 0;
}
}
.select-multiple {
display: flex;
.option-list {
margin: 0;
padding-left: 0.5em;
}
}
&:last-child {
border-bottom: none;
padding-bottom: 0;
margin-bottom: 1em;
}
select {
min-width: 10em;
}
textarea {
width: 100%;
max-width: 100%;
height: 100px;
}
.unavailable,
.unavailable svg {
color: var(--cRed, $fallback--cRed);
color: $fallback--cRed;
}
}
}

View File

@ -78,6 +78,6 @@
</tab-switcher>
</template>
<script src="./settings_modal_content.js"></script>
<script src="./settings_modal_user_content.js"></script>
<style src="./settings_modal_content.scss" lang="scss"></style>
<style src="./settings_modal_user_content.scss" lang="scss"></style>

View File

@ -7,13 +7,11 @@
<BooleanSetting path="hideFilteredStatuses">
{{ $t('settings.hide_filtered_statuses') }}
</BooleanSetting>
<ul
class="setting-list suboptions"
:class="[{disabled: !streaming}]"
>
<ul class="setting-list suboptions">
<li>
<BooleanSetting
:disabled="hideFilteredStatuses"
parent-path="hideFilteredStatuses"
:parent-invert="true"
path="hideWordFilteredPosts"
>
{{ $t('settings.hide_wordfiltered_statuses') }}
@ -22,7 +20,8 @@
<li>
<BooleanSetting
v-if="user"
:disabled="hideFilteredStatuses"
parent-path="hideFilteredStatuses"
:parent-invert="true"
path="hideMutedThreads"
>
{{ $t('settings.hide_muted_threads') }}
@ -31,7 +30,8 @@
<li>
<BooleanSetting
v-if="user"
:disabled="hideFilteredStatuses"
parent-path="hideFilteredStatuses"
:parent-invert="true"
path="hideMutedPosts"
>
{{ $t('settings.hide_muted_posts') }}

View File

@ -7,7 +7,7 @@ import SizeSetting, { defaultHorizontalUnits } from '../helpers/size_setting.vue
import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import ServerSideIndicator from '../helpers/server_side_indicator.vue'
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faGlobe
@ -67,7 +67,7 @@ const GeneralTab = {
SizeSetting,
InterfaceLanguageSwitcher,
ScopeSelector,
ServerSideIndicator
ProfileSettingIndicator
},
computed: {
horizontalUnits () {
@ -110,7 +110,7 @@ const GeneralTab = {
},
methods: {
changeDefaultScope (value) {
this.$store.dispatch('setServerSideOption', { name: 'defaultScope', value })
this.$store.dispatch('setProfileOption', { name: 'defaultScope', value })
}
}
}

View File

@ -29,14 +29,11 @@
<BooleanSetting path="streaming">
{{ $t('settings.streaming') }}
</BooleanSetting>
<ul
class="setting-list suboptions"
:class="[{disabled: !streaming}]"
>
<ul class="setting-list suboptions">
<li>
<BooleanSetting
path="pauseOnUnfocused"
:disabled="!streaming"
parent-path="streaming"
>
{{ $t('settings.pause_on_unfocused') }}
</BooleanSetting>
@ -213,7 +210,7 @@
</ChoiceSetting>
</li>
<ul
v-if="conversationDisplay !== 'linear'"
v-if="mergedConfig.conversationDisplay !== 'linear'"
class="setting-list suboptions"
>
<li>
@ -265,7 +262,8 @@
<li>
<BooleanSetting
v-if="user"
path="serverSide_stripRichContent"
source="profile"
path="stripRichContent"
expert="1"
>
{{ $t('settings.no_rich_text_description') }}
@ -299,7 +297,7 @@
<BooleanSetting
path="preloadImage"
expert="1"
:disabled="!hideNsfw"
parent-path="hideNsfw"
>
{{ $t('settings.preload_images') }}
</BooleanSetting>
@ -308,7 +306,7 @@
<BooleanSetting
path="useOneClickNsfw"
expert="1"
:disabled="!hideNsfw"
parent-path="hideNsfw"
>
{{ $t('settings.use_one_click_nsfw') }}
</BooleanSetting>
@ -321,15 +319,13 @@
>
{{ $t('settings.loop_video') }}
</BooleanSetting>
<ul
class="setting-list suboptions"
:class="[{disabled: !streaming}]"
>
<ul class="setting-list suboptions">
<li>
<BooleanSetting
path="loopVideoSilentOnly"
expert="1"
:disabled="!loopVideo || !loopSilentAvailable"
parent-path="loopVideo"
:disabled="!loopSilentAvailable"
>
{{ $t('settings.loop_video_silent_only') }}
</BooleanSetting>
@ -427,18 +423,18 @@
<ul class="setting-list">
<li>
<label for="default-vis">
{{ $t('settings.default_vis') }} <ServerSideIndicator :server-side="true" />
{{ $t('settings.default_vis') }} <ProfileSettingIndicator :is-profile="true" />
<ScopeSelector
class="scope-selector"
:show-all="true"
:user-default="serverSide_defaultScope"
:initial-scope="serverSide_defaultScope"
:user-default="$store.state.profileConfig.defaultScope"
:initial-scope="$store.state.profileConfig.defaultScope"
:on-scope-change="changeDefaultScope"
/>
</label>
</li>
<li>
<!-- <BooleanSetting path="serverSide_defaultNSFW"> -->
<!-- <BooleanSetting source="profile" path="defaultNSFW"> -->
<BooleanSetting path="sensitiveByDefault">
{{ $t('settings.sensitive_by_default') }}
</BooleanSetting>

View File

@ -9,17 +9,20 @@ import DomainMuteCard from 'src/components/domain_mute_card/domain_mute_card.vue
import SelectableList from 'src/components/selectable_list/selectable_list.vue'
import ProgressButton from 'src/components/progress_button/progress_button.vue'
import withSubscription from 'src/components/../hocs/with_subscription/with_subscription'
import withLoadMore from 'src/components/../hocs/with_load_more/with_load_more'
import Checkbox from 'src/components/checkbox/checkbox.vue'
const BlockList = withSubscription({
const BlockList = withLoadMore({
fetch: (props, $store) => $store.dispatch('fetchBlocks'),
select: (props, $store) => get($store.state.users.currentUser, 'blockIds', []),
destroy: () => {},
childPropName: 'items'
})(SelectableList)
const MuteList = withSubscription({
const MuteList = withLoadMore({
fetch: (props, $store) => $store.dispatch('fetchMutes'),
select: (props, $store) => get($store.state.users.currentUser, 'muteIds', []),
destroy: () => {},
childPropName: 'items'
})(SelectableList)

View File

@ -4,7 +4,10 @@
<h2>{{ $t('settings.notification_setting_filters') }}</h2>
<ul class="setting-list">
<li>
<BooleanSetting path="serverSide_blockNotificationsFromStrangers">
<BooleanSetting
source="profile"
path="blockNotificationsFromStrangers"
>
{{ $t('settings.notification_setting_block_from_strangers') }}
</BooleanSetting>
</li>
@ -67,7 +70,8 @@
</li>
<li>
<BooleanSetting
path="serverSide_webPushHideContents"
source="profile"
path="webPushHideContents"
expert="1"
>
{{ $t('settings.notification_setting_hide_notification_contents') }}

View File

@ -254,37 +254,50 @@
<h2>{{ $t('settings.account_privacy') }}</h2>
<ul class="setting-list">
<li>
<BooleanSetting path="serverSide_locked">
<BooleanSetting
source="profile"
path="locked"
>
{{ $t('settings.lock_account_description') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="serverSide_discoverable">
<BooleanSetting
source="profile"
path="discoverable"
>
{{ $t('settings.discoverable') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="serverSide_allowFollowingMove">
<BooleanSetting
source="profile"
path="allowFollowingMove"
>
{{ $t('settings.allow_following_move') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="serverSide_hideFavorites">
<BooleanSetting
source="profile"
path="hideFavorites"
>
{{ $t('settings.hide_favorites_description') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="serverSide_hideFollowers">
<BooleanSetting
source="profile"
path="hideFollowers"
>
{{ $t('settings.hide_followers_description') }}
</BooleanSetting>
<ul
class="setting-list suboptions"
:class="[{disabled: !serverSide_hideFollowers}]"
>
<ul class="setting-list suboptions">
<li>
<BooleanSetting
path="serverSide_hideFollowersCount"
:disabled="!serverSide_hideFollowers"
source="profile"
path="hideFollowersCount"
parent-path="hideFollowers"
>
{{ $t('settings.hide_followers_count_description') }}
</BooleanSetting>
@ -292,17 +305,18 @@
</ul>
</li>
<li>
<BooleanSetting path="serverSide_hideFollows">
<BooleanSetting
source="profile"
path="hideFollows"
>
{{ $t('settings.hide_follows_description') }}
</BooleanSetting>
<ul
class="setting-list suboptions"
:class="[{disabled: !serverSide_hideFollows}]"
>
<ul class="setting-list suboptions">
<li>
<BooleanSetting
path="serverSide_hideFollowsCount"
:disabled="!serverSide_hideFollows"
source="profile"
path="hideFollowsCount"
parent-path="hideFollows"
>
{{ $t('settings.hide_follows_count_description') }}
</BooleanSetting>

View File

@ -143,8 +143,8 @@
/>
</div>
<div>
<i18n
path="settings.new_alias_target"
<i18n-t
keypath="settings.new_alias_target"
tag="p"
>
<code
@ -152,7 +152,7 @@
>
foo@example.org
</code>
</i18n>
</i18n-t>
<input
v-model="addAliasTarget"
>
@ -175,16 +175,16 @@
<h2>{{ $t('settings.move_account') }}</h2>
<p>{{ $t('settings.move_account_notes') }}</p>
<div>
<i18n
path="settings.move_account_target"
<i18n-t
keypath="settings.move_account_target"
tag="p"
>
<code
place="example"
>
<template #example>
<code>
foo@example.org
</code>
</i18n>
</template>
</i18n-t>
<input
v-model="moveAccountTarget"
>

View File

@ -115,7 +115,10 @@ const SideDrawer = {
GestureService.updateSwipe(e, this.closeGesture)
},
openSettingsModal () {
this.$store.dispatch('openSettingsModal')
this.$store.dispatch('openSettingsModal', 'user')
},
openAdminModal () {
this.$store.dispatch('openSettingsModal', 'admin')
}
}
}

View File

@ -180,16 +180,16 @@
v-if="currentUser && currentUser.role === 'admin'"
@click="toggleDrawer"
>
<a
href="/pleroma/admin/#/login-pleroma"
target="_blank"
<button
class="button-unstyled -link -fullwidth"
@click.stop="openAdminModal"
>
<FAIcon
fixed-width
class="fa-scale-110 fa-old-padding"
icon="tachometer-alt"
/> {{ $t("nav.administration") }}
</a>
</button>
</li>
<li
v-if="currentUser && supportsAnnouncements"

View File

@ -60,13 +60,7 @@ export default {
const isWanted = slot => slot.props && slot.props['data-tab-name'] === tabName
return this.$slots.default().findIndex(isWanted) === this.activeIndex
}
},
settingsModalVisible () {
return this.settingsModalState === 'visible'
},
...mapState({
settingsModalState: state => state.interface.settingsModalState
})
}
},
beforeUpdate () {
const currentSlot = this.slots()[this.active]

View File

@ -98,7 +98,7 @@ const withLoadMore = ({
</button>
}
{!this.error && this.loading && <FAIcon spin icon="circle-notch"/>}
{!this.error && !this.loading && !this.bottomedOut && <a onClick={this.fetchEntries}>{this.$t('general.more')}</a>}
{!this.error && !this.loading && !this.bottomedOut && <a onClick={this.fetchEntries} role="button" tabindex="0">{this.$t('general.more')}</a>}
</div>
</div>
)

File diff suppressed because it is too large Load Diff

View File

@ -519,6 +519,8 @@
"loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")",
"mutes_tab": "Mutes",
"play_videos_in_modal": "Play videos in a popup frame",
"url": "URL",
"preview": "Preview",
"file_export_import": {
"backup_restore": "Settings backup",
"backup_settings": "Backup settings to file",
@ -830,6 +832,98 @@
"title": "Version",
"backend_version": "Backend version",
"frontend_version": "Frontend version"
},
"commit_value": "Save",
"commit_value_tooltip": "Value is not saved, press this button to commit your changes",
"reset_value": "Reset",
"reset_value_tooltip": "Reset draft",
"hard_reset_value": "Hard reset",
"hard_reset_value_tooltip": "Remove setting from storage, forcing use of default value"
},
"admin_dash": {
"window_title": "Administration",
"wip_notice": "This admin dashboard is experimental and WIP, {adminFeLink}.",
"old_ui_link": "old admin UI available here",
"reset_all": "Reset all",
"commit_all": "Save all",
"tabs": {
"nodb": "No DB Config",
"instance": "Instance",
"limits": "Limits",
"frontends": "Front-ends"
},
"nodb": {
"heading": "Database config is disabled",
"text": "You need to change backend config files so that {property} is set to {value}, see more in {documentation}.",
"documentation": "documentation",
"text2": "Most configuration options will be unavailable."
},
"captcha": {
"native": "Native",
"kocaptcha": "KoCaptcha"
},
"instance": {
"instance": "Instance information",
"registrations": "User sign-ups",
"captcha_header": "CAPTCHA",
"kocaptcha": "KoCaptcha settings",
"access": "Instance access",
"restrict": {
"header": "Restrict access for anonymous visitors",
"description": "Detailed setting for allowing/disallowing access to certain aspects of API. By default (indeterminate state) it will disallow if instance is not public, ticked checkbox means disallow access even if instance is public, unticked means allow access even if instance is private. Please note that unexpected behavior might happen if some settings are set, i.e. if profile access is disabled posts will show without profile information.",
"timelines": "Timelines access",
"profiles": "User profiles access",
"activities": "Statues/activities access"
}
},
"limits": {
"arbitrary_limits": "Arbitrary limits",
"posts": "Post limits",
"uploads": "Attachments limits",
"users": "User profile limits",
"profile_fields": "Profile fields limits",
"user_uploads": "Profile media limits"
},
"frontend": {
"repository": "Repository link",
"versions": "Available versions",
"build_url": "Build URL",
"reinstall": "Reinstall",
"is_default": "(Default)",
"is_default_custom": "(Default, version: {version})",
"install": "Install",
"install_version": "Install version {version}",
"more_install_options": "More install options",
"more_default_options": "More default setting options",
"set_default": "Set default",
"set_default_version": "Set version {version} as default",
"wip_notice": "Please note that this section is a WIP and lacks certain features as backend implementation of front-end management is incomplete.",
"default_frontend": "Default front-end",
"default_frontend_tip": "Default front-end will be shown to all users. Currently there's no way to for a user to select personal front-end. If you switch away from PleromaFE you'll most likely have to use old and buggy AdminFE to do instance configuration until we replace it.",
"default_frontend_tip2": "WIP: Since Pleroma backend doesn't properly list all installed frontends you'll have to enter name and reference manually. List below provides shortcuts to fill the values.",
"available_frontends": "Available for install"
},
"temp_overrides": {
":pleroma": {
":instance": {
":public": {
"label": "Instance is public",
"description": "Disabling this will make all API accessible only for logged-in users, this will make Public and Federated timelines inaccessible to anonymous visitors."
},
":limit_to_local_content": {
"label": "Limit search to local content",
"description": "Disables global network search for unauthenticated (default), all users or none"
},
":description_limit": {
"label": "Limit",
"description": "Character limit for attachment descriptions"
},
":background_image": {
"label": "Background image",
"description": "Background image (primarily used by PleromaFE)"
}
}
}
}
},
"time": {
@ -879,6 +973,7 @@
"repeat_confirm_accept_button": "Repeat",
"repeat_confirm_cancel_button": "Do not repeat",
"delete": "Delete status",
"delete_error": "Error deleting status: {0}",
"edit": "Edit status",
"edited_at": "(last edited {time})",
"pin": "Pin on profile",
@ -932,7 +1027,8 @@
"show_all_conversation_with_icon": "{icon} {text}",
"show_all_conversation": "Show full conversation ({numStatus} other status) | Show full conversation ({numStatus} other statuses)",
"show_only_conversation_under_this": "Only show replies to this status",
"status_history": "Status history"
"status_history": "Status history",
"reaction_count_label": "{num} person reacted | {num} people reacted"
},
"user_card": {
"approve": "Approve",

View File

@ -55,8 +55,8 @@
"undo": "Malfari",
"yes": "Jes",
"no": "Ne",
"unpin": "Malfiksi eron",
"pin": "Fiksi eron",
"unpin": "Malfiksi",
"pin": "Fiksi",
"scroll_to_top": "Rulumi supren"
},
"image_cropper": {
@ -81,7 +81,11 @@
"recovery_code": "Rehava kodo",
"enter_two_factor_code": "Enigu kodon de duobla aŭtentikigo",
"enter_recovery_code": "Enigu rehavan kodon",
"authentication_code": "Aŭtentikiga kodo"
"authentication_code": "Aŭtentikiga kodo",
"logout_confirm_title": "Konfirmo de adiaŭo",
"logout_confirm": "Ĉu vi certe volas adiaŭi?",
"logout_confirm_accept_button": "Adiaŭi",
"logout_confirm_cancel_button": "Ne adiaŭi"
},
"media_modal": {
"previous": "Antaŭa",
@ -90,7 +94,7 @@
"hide": "Fermi vidilon de vidaŭdaĵoj"
},
"nav": {
"about": "Pri",
"about": "Prio",
"back": "Reen",
"chat": "Loka babilejo",
"friend_requests": "Petoj pri abono",
@ -115,7 +119,9 @@
"edit_finish": "Fini redakton",
"mobile_notifications": "Malfermi sciigojn (estas nelegitaj)",
"mobile_notifications_close": "Fermi sciigojn",
"announcements": "Anoncoj"
"announcements": "Anoncoj",
"search_close": "Fermi serĉujon",
"mobile_sidebar": "(Mal)ŝalti flankan breton por telefonoj"
},
"notifications": {
"broken_favorite": "Nekonata afiŝo, serĉante ĝin…",
@ -169,7 +175,9 @@
"post": "Afiŝo",
"edit_remote_warning": "Aliaj foraj nodoj eble ne subtenas redaktadon, kaj ne povos ricevi pli novan version de via afiŝo.",
"edit_unsupported_warning": "Pleroma ne subtenas redaktadon de mencioj aŭ enketoj.",
"edit_status": "Redakti afiŝon"
"edit_status": "Redakti afiŝon",
"content_type_selection": "Formo de afiŝo",
"scope_notice_dismiss": "Fermi ĉi tiun avizon"
},
"registration": {
"bio": "Priskribo",
@ -189,14 +197,18 @@
"email_required": "ne povas resti malplena",
"password_required": "ne povas resti malplena",
"password_confirmation_required": "ne povas resti malplena",
"password_confirmation_match": "samu la pasvorton"
"password_confirmation_match": "samu la pasvorton",
"birthday_min_age": "ne povas esti post {date}",
"birthday_required": "ne povas resti malplena"
},
"reason_placeholder": "Ĉi-node oni aprobas registriĝojn permane.\nSciigu la administrantojn kial vi volas registriĝi.",
"reason": "Kialo registriĝi",
"register": "Registriĝi",
"bio_optional": "Prio (malnepra)",
"email_optional": "Retpoŝtadreso (malnepra)",
"email_language": "En kiu lingvo vi volus ricevi retleterojn de la servilo?"
"email_language": "En kiu lingvo vi volus ricevi retleterojn de la servilo?",
"birthday": "Naskiĝtago:",
"birthday_optional": "Naskiĝtago (malnepra):"
},
"settings": {
"app_name": "Nomo de aplikaĵo",
@ -666,7 +678,28 @@
"user_popover_avatar_overlay": "Aperigi ŝprucaĵon pri uzanto sur profilbildo",
"show_yous": "Montri la markon «(Vi)»",
"user_popover_avatar_action_zoom": "Zomi la profilbildon",
"third_column_mode": "Kun sufiĉo da spaco, montri trian kolumnon kun"
"third_column_mode": "Kun sufiĉo da spaco, montri trian kolumnon kun",
"birthday": {
"show_birthday": "Montri mian naskiĝtagon",
"label": "Naskiĝtago"
},
"confirm_dialogs_delete": "forigo de afiŝo",
"backup_running": "Ĉi tiu savkopiado progresas, traktis {number} datumon. | Ĉi tiu savkopiado progresas, traktis {number} datumojn.",
"backup_failed": "Ĉi tiu savkopiado malsukcesis.",
"autocomplete_select_first": "Memage elekti unuan kandidaton kiam rezultoj de memaga konjektado disponeblas",
"confirm_dialogs_logout": "adiaŭo",
"user_popover_avatar_action": "Post klako sur profilbildon en ŝprucaĵo",
"remove_language": "Forigi",
"primary_language": "Ĉefa lingvo:",
"confirm_dialogs": "Peti konfirmon je",
"confirm_dialogs_repeat": "ripeto de afiŝo",
"confirm_dialogs_unfollow": "malabono de uzanto",
"confirm_dialogs_block": "blokado de uzanto",
"confirm_dialogs_mute": "silentigo de uzanto",
"confirm_dialogs_approve_follow": "aprobo de abonanto",
"confirm_dialogs_deny_follow": "malaprobo de abonanto",
"confirm_dialogs_remove_follower": "forigo de abonanto",
"tree_fade_ancestors": "Montri responditojn de la nuna afiŝo per teksto malvigla"
},
"timeline": {
"collapse": "Maletendi",
@ -753,7 +786,33 @@
"note_blank": "(Neniu)",
"edit_note_apply": "Apliki",
"edit_note_cancel": "Nuligi",
"edit_note": "Redakti noton"
"edit_note": "Redakti noton",
"block_confirm": "Ĉu vi certe volas bloki uzanton {user}?",
"block_confirm_accept_button": "Bloki",
"remove_follower_confirm": "Ĉu vi certe volas forigi uzanton {user} de viaj abonantoj?",
"approve_confirm_accept_button": "Aprobi",
"approve_confirm_cancel_button": "Ne aprobi",
"approve_confirm": "Ĉu vi certe volas aprobi abonan peton de {user}?",
"block_confirm_title": "Konfirmo de blokado",
"approve_confirm_title": "Konfirmo de aprobo",
"block_confirm_cancel_button": "Ne bloki",
"deny_confirm_accept_button": "Malaprobi",
"deny_confirm_cancel_button": "Ne malaprobi",
"mute_confirm_title": "Silentigi konfirmon",
"deny_confirm_title": "Konfirmo de malaprobo",
"mute_confirm": "Ĉu vi certe volas silentigi uzanton {user}?",
"mute_confirm_accept_button": "Silentigi",
"mute_confirm_cancel_button": "Ne silentigi",
"mute_duration_prompt": "Silentigi ĉi tiun uzanton por (0 signifas senliman silentigon):",
"remove_follower_confirm_accept_button": "Forigi",
"remove_follower_confirm_title": "Konfirmo de forigo de abonanto",
"birthday": "Naskita je {birthday}",
"deny_confirm": "Ĉu vi certe volas malaprobi abonan peton de {user}?",
"unfollow_confirm_cancel_button": "Ne malaboni",
"unfollow_confirm_title": "Konfirmo de malabono",
"unfollow_confirm": "Ĉu vi certe volas malaboni uzanton {user}?",
"unfollow_confirm_accept_button": "Malaboni",
"remove_follower_confirm_cancel_button": "Ne forigi"
},
"user_profile": {
"timeline_title": "Historio de uzanto",
@ -775,7 +834,8 @@
"accept_follow_request": "Akcepti abonpeton",
"add_reaction": "Aldoni reagon",
"toggle_expand": "Etendi aŭ maletendi sciigon por montri plenan afiŝon",
"toggle_mute": "Etendi aŭ maletendi afiŝon por montri silentigitan enhavon"
"toggle_mute": "Etendi aŭ maletendi afiŝon por montri silentigitan enhavon",
"autocomplete_available": "{number} rezulto disponeblas. Uzu la sagajn klavojn supren kaj suben por foliumi ilin. | {number} rezulto disponeblas. Uzu la sagajn klavojn supren kaj suben por foliumi ilin."
},
"upload": {
"error": {
@ -951,7 +1011,14 @@
"show_all_conversation_with_icon": "{icon} {text}",
"show_only_conversation_under_this": "Montri nur respondojn al ĉi tiu afiŝo",
"status_history": "Historio de afiŝo",
"open_gallery": "Malfermi galerion"
"open_gallery": "Malfermi galerion",
"delete_confirm_title": "Konfirmo de forigo",
"delete_confirm_accept_button": "Forigi",
"repeat_confirm": "Ĉu vi certe volas ripeti ĉi tiun afiŝon?",
"repeat_confirm_title": "Konfirmo de ripeto",
"repeat_confirm_accept_button": "Ripeti",
"repeat_confirm_cancel_button": "Ne ripeti",
"delete_confirm_cancel_button": "Ne forigi"
},
"time": {
"years_short": "{0}j",
@ -1119,6 +1186,7 @@
"edit_action": "Redakti",
"submit_edit_action": "Afiŝi",
"cancel_edit_action": "Nuligi",
"inactive_message": "Ĉi tiu anonco estas neaktiva"
"inactive_message": "Ĉi tiu anonco estas neaktiva",
"post_form_header": "Afiŝi anoncon"
}
}

View File

@ -214,7 +214,8 @@
"domain_mutes": "Domain",
"composing": "Menulis",
"no_blocks": "Tidak ada yang diblokir",
"no_mutes": "Tidak ada yang dibisukan"
"no_mutes": "Tidak ada yang dibisukan",
"remove_language": "Hapus"
},
"about": {
"mrf": {
@ -230,7 +231,9 @@
"accept_desc": "Instansi ini hanya menerima pesan dari instansi-instansi berikut:",
"accept": "Terima",
"media_removal": "Penghapusan Media",
"media_removal_desc": "Instansi ini menghapus media dari postingan yang berasal dari instansi-instansi berikut:"
"media_removal_desc": "Instansi ini menghapus media dari postingan yang berasal dari instansi-instansi berikut:",
"instance": "Instance",
"reason": "Alasan"
},
"federation": "Federasi",
"mrf_policies": "Kebijakan MRF yang diaktifkan"
@ -437,7 +440,10 @@
"password_required": "tidak boleh kosong",
"email_required": "tidak boleh kosong",
"fullname_required": "tidak boleh kosong",
"username_required": "tidak boleh kosong"
"username_required": "tidak boleh kosong",
"password_confirmation_match": "wajib sama dengan sandi",
"birthday_required": "tidak boleh kosong",
"birthday_min_age": "wajib sama dengan atau sebelum {date}"
},
"register": "Daftar",
"fullname_placeholder": "contoh. Lain Iwakura",
@ -450,7 +456,12 @@
"bio": "Bio",
"reason_placeholder": "Instansi ini menerima pendaftaran secara manual.\nBeritahu administrasinya mengapa Anda ingin mendaftar.",
"reason": "Alasan mendaftar",
"registration": "Pendaftaran"
"registration": "Pendaftaran",
"email_language": "Dalam bahasa apa kamu ingin menerima surel dari server ini?",
"email_optional": "Surel (opsional)",
"birthday": "Ulang tahun:",
"birthday_optional": "Ulang tahun (opsional):",
"bio_optional": "Bio (opsional)"
},
"post_status": {
"preview_empty": "Kosong",
@ -482,7 +493,8 @@
"empty_status_error": "Tidak dapat memposting status kosong tanpa berkas",
"account_not_locked_warning_link": "terkunci",
"account_not_locked_warning": "Akun Anda tidak {0}. Siapapun dapat mengikuti Anda untuk melihat postingan hanya-pengikut Anda.",
"new_status": "Posting status baru"
"new_status": "Posting status baru",
"edit_status": "Sunting status"
},
"general": {
"apply": "Terapkan",
@ -508,7 +520,15 @@
"generic_error": "Terjadi kesalahan",
"loading": "Memuat…",
"more": "Lebih banyak",
"submit": "Kirim"
"submit": "Kirim",
"yes": "Ya",
"no": "Tidak",
"scope_in_timeline": {
"direct": "Langsung",
"private": "Hanya pengikut",
"public": "Publik"
},
"generic_error_message": "Terjadi kesalahan: {0}"
},
"remote_user_resolver": {
"error": "Tidak ditemukan."
@ -522,7 +542,18 @@
"emoji": "Emoji",
"stickers": "Stiker",
"keep_open": "Tetap buka pemilih",
"custom": "Emoji kustom"
"custom": "Emoji kustom",
"unicode_groups": {
"activities": "Aktivitas",
"animals-and-nature": "Hewan & Alam",
"flags": "Bendera",
"food-and-drink": "Makanan & Minuman",
"objects": "Objek",
"people-and-body": "Orang & Tubuh",
"smileys-and-emotion": "Emosi",
"symbols": "Simbol",
"travel-and-places": "Perjalanan & Tempat-tempat"
}
},
"polls": {
"expired": "Japat berakhir {0} yang lalu",
@ -553,11 +584,17 @@
"timelines": "Linimasa",
"chats": "Obrolan",
"dms": "Pesan langsung",
"friend_requests": "Ingin mengikuti"
"friend_requests": "Ingin mengikuti",
"twkn": "Jaringan Dikenal",
"mobile_notifications_close": "Tutup notifikasi",
"announcements": "Pengumuman",
"mobile_notifications": "Buka notifikasi (ada yang belum dibaca)"
},
"media_modal": {
"next": "Selanjutnya",
"previous": "Sebelum"
"previous": "Sebelum",
"counter": "{current} / {total}",
"hide": "Tutup penampil media"
},
"login": {
"recovery_code": "Kode pemulihan",
@ -574,7 +611,10 @@
"heading": {
"totp": "Otentikasi dua-faktor"
},
"enter_two_factor_code": "Masukkan kode dua-faktor"
"enter_two_factor_code": "Masukkan kode dua-faktor",
"logout_confirm": "Apa kamu yakin ingin keluar?",
"logout_confirm_accept_button": "Keluar",
"logout_confirm_cancel_button": "Jangan keluar"
},
"importer": {
"error": "Terjadi kesalahan ketika mnengimpor berkas ini.",
@ -597,7 +637,8 @@
"gopher": "Gopher",
"pleroma_chat_messages": "Pleroma Obrolan",
"chat": "Obrolan",
"upload_limit": "Batas unggahan"
"upload_limit": "Batas unggahan",
"media_proxy": "Proxy media"
},
"exporter": {
"processing": "Memproses, Anda akan segera diminta untuk mengunduh berkas Anda",
@ -619,12 +660,41 @@
"moves": "Pengguna yang bermigrasi",
"follows": "Pengikut baru",
"favs_repeats": "Ulangan dan favorit",
"load_older": "Muat interaksi yang lebih tua"
"load_older": "Muat interaksi yang lebih tua",
"emoji_reactions": "Reaksi Emoji",
"reports": "Laporan"
},
"errors": {
"storage_unavailable": "Pleroma tidak dapat mengakses penyimpanan browser. Login Anda atau pengaturan lokal Anda tidak akan tersimpan dan masalah yang tidak terduga dapat terjadi. Coba mengaktifkan kuki."
},
"shoutbox": {
"title": "Kotak Suara"
},
"report": {
"state_closed": "Ditutup",
"reporter": "Pelapor:",
"reported_statuses": "Status yang dilaporkan:",
"reported_user": "Pengguna yang dilaporkan:",
"notes": "Catatan:",
"state": "Status:",
"state_open": "Terbuka",
"state_resolved": "Selesai"
},
"announcements": {
"end_time_prompt": "Waktu berakhir: ",
"published_time_display": "Diterbitkan pada {time}",
"page_header": "Pengumuman",
"title": "Pengumuman",
"mark_as_read_action": "Tandai telah dibaca",
"post_placeholder": "Ketik isi pengumumanmu di sini...",
"close_error": "Tutup",
"delete_action": "Hapus",
"start_time_prompt": "Waktu mulai: ",
"post_error": "Kesalahan: {error}",
"start_time_display": "Dimulai pada {time}",
"end_time_display": "Berakhir pada {time}",
"edit_action": "Sunting",
"submit_edit_action": "Kirim",
"cancel_edit_action": "Batal"
}
}

View File

@ -75,7 +75,11 @@
"enter_two_factor_code": "2단계인증 코드를 입력하십시오",
"enter_recovery_code": "복구 코드를 입력하십시오",
"authentication_code": "인증 코드",
"hint": "로그인해서 대화에 참여"
"hint": "로그인해서 대화에 참여",
"logout_confirm_title": "로그아웃 확인",
"logout_confirm": "정말 로그아웃 하시겠습니까?",
"logout_confirm_accept_button": "로그아웃",
"logout_confirm_cancel_button": "로그아웃 안 함"
},
"nav": {
"about": "인스턴스 소개",
@ -104,7 +108,8 @@
"edit_finish": "편집 종료",
"mobile_notifications_close": "알림 닫기",
"mobile_sidebar": "모바일 사이드바 토글",
"announcements": "공지사항"
"announcements": "공지사항",
"search_close": "검색 바 닫기"
},
"notifications": {
"broken_favorite": "알 수 없는 게시물입니다, 검색합니다…",
@ -158,7 +163,9 @@
"edit_status": "수정",
"edit_remote_warning": "수정 기능이 없는 다른 인스턴스에서는 수정한 사항이 반영되지 않을 수 있습니다.",
"post": "게시",
"direct_warning_to_first_only": "맨 앞에 멘션한 사용자들에게만 보여집니다."
"direct_warning_to_first_only": "맨 앞에 멘션한 사용자들에게만 보여집니다.",
"content_type_selection": "게시물 형태",
"scope_notice_dismiss": "알림 닫기"
},
"registration": {
"bio": "소개",
@ -175,7 +182,9 @@
"email_required": "공백으로 둘 수 없습니다",
"password_required": "공백으로 둘 수 없습니다",
"password_confirmation_required": "공백으로 둘 수 없습니다",
"password_confirmation_match": "패스워드와 일치해야 합니다"
"password_confirmation_match": "패스워드와 일치해야 합니다",
"birthday_required": "공백으로 둘 수 없습니다",
"birthday_min_age": "{date} 또는 그 이전 출생만 가능합니다"
},
"fullname_placeholder": "예: 김례인",
"username_placeholder": "예: lain",
@ -185,7 +194,9 @@
"reason": "가입하려는 이유",
"reason_placeholder": "이 인스턴스는 수동으로 가입을 승인하고 있습니다.\n왜 가입하고 싶은지 관리자에게 알려주세요.",
"register": "가입",
"email_language": "무슨 언어로 이메일을 받길 원하시나요?"
"email_language": "무슨 언어로 이메일을 받길 원하시나요?",
"birthday": "생일:",
"birthday_optional": "생일 (선택):"
},
"settings": {
"attachmentRadius": "첨부물",
@ -383,7 +394,8 @@
"highlight": "강조 요소",
"pressed": "눌렸을 때",
"toggled": "토글됨",
"tabs": "탭"
"tabs": "탭",
"underlay": "밑배경"
},
"radii": {
"_tab_label": "둥글기"
@ -652,7 +664,29 @@
"post_status_content_type": "게시물 내용 형식",
"list_aliases_error": "별칭을 가져오는 중 에러 발생: {error}",
"add_alias_error": "별칭을 추가하는 중 에러 발생: {error}",
"mention_link_show_avatar_quick": "멘션 옆에 유저 프로필 사진을 보임"
"mention_link_show_avatar_quick": "멘션 옆에 유저 프로필 사진을 보임",
"backup_running": "백업 중입니다, {number}개 처리 완료. | 백업 중입니다, {number}개 처리 완료.",
"confirm_dialogs": "하기 전에 다시 물어보기",
"autocomplete_select_first": "자동완성이 가능하면 자동으로 첫 번째 후보를 선택",
"backup_failed": "백업에 실패했습니다.",
"emoji_reactions_scale": "리액션 크기",
"birthday": {
"label": "생일",
"show_birthday": "내 생일 보여주기"
},
"add_language": "보조 언어 추가",
"confirm_dialogs_repeat": "리핏",
"confirm_dialogs_unfollow": "언팔로우",
"confirm_dialogs_block": "차단",
"confirm_dialogs_mute": "뮤트",
"confirm_dialogs_delete": "게시물 삭제",
"confirm_dialogs_approve_follow": "팔로워 승인",
"confirm_dialogs_deny_follow": "팔로워 거절",
"confirm_dialogs_remove_follower": "팔로워 제거",
"remove_language": "삭제",
"primary_language": "주 언어:",
"fallback_language": "보조 언어 {index}:",
"confirm_dialogs_logout": "로그아웃"
},
"timeline": {
"collapse": "접기",
@ -735,7 +769,12 @@
"striped": "줄무늬 배경",
"solid": "단색 배경",
"side": "옆트임"
}
},
"approve_confirm_title": "승인 확인",
"approve_confirm_accept_button": "승인",
"approve_confirm_cancel_button": "승인 안 함",
"approve_confirm": "{user}의 팔로우 요청을 승인할까요?",
"block_confirm_title": "차단 확인"
},
"user_profile": {
"timeline_title": "사용자 타임라인",
@ -1069,7 +1108,14 @@
"ancestor_follow_with_icon": "{icon} {text}",
"show_all_conversation_with_icon": "{icon} {text}",
"ancestor_follow": "이 게시물 아래 {numReplies}개 답글 더 보기 | 이 게시물 아래 {numReplies}개 답글 더 보기",
"show_only_conversation_under_this": "이 게시물의 답글만 보기"
"show_only_conversation_under_this": "이 게시물의 답글만 보기",
"repeat_confirm": "리핏할까요?",
"repeat_confirm_title": "리핏 확인",
"repeat_confirm_accept_button": "리핏",
"repeat_confirm_cancel_button": "리핏 안 함",
"delete_confirm_title": "삭제 확인",
"delete_confirm_accept_button": "삭제",
"delete_confirm_cancel_button": "냅두기"
},
"errors": {
"storage_unavailable": "Pleroma가 브라우저 저장소에 접근할 수 없습니다. 로그인이 풀리거나 로컬 설정이 초기화 되는 등 예상치 못한 문제를 겪을 수 있습니다. 쿠키를 활성화 해보세요."

View File

@ -1,4 +1,3 @@
const languages = [
'ar',
'ca',
@ -18,6 +17,7 @@ const languages = [
'ja',
'ja_easy',
'ko',
'nan-TW',
'nb',
'nl',
'oc',

806
src/i18n/nan-TW.json Normal file
View File

@ -0,0 +1,806 @@
{
"about": {
"mrf": {
"federation": "聯邦",
"keyword": {
"keyword_policies": "關鍵字政策",
"ftl_removal": "Tuì「知影 ê 網路」時間線除掉",
"reject": "拒絕",
"replace": "取代",
"is_replaced_by": "→"
},
"mrf_policies": "啟用 ê MRF 政策",
"mrf_policies_desc": "MRF 政策操作本站 ê 對外通信行為。以下ê政策啟用 ah",
"simple": {
"simple_policies": "站臺特有 ê 政策",
"instance": "站",
"reason": "理由",
"accept": "接受",
"accept_desc": "本站干焦接受下跤 ê 站 ê 短 phue",
"reject": "拒絕",
"reject_desc": "本站 buē 接受 tuì 以下 ê 站 ê 短 phue",
"quarantine": "隔離",
"quarantine_desc": "針對下跤 ê 站,本站干焦送出公開ê PO文",
"ftl_removal": "Tuì「知影 ê 網路」時間線thâi掉",
"ftl_removal_desc": "本站buē 佇「知影 ê 網路」刊下跤 ê 站 ê PO文",
"media_removal": "Thâi除媒體",
"media_removal_desc": "本站 kā 下跤 ê 站臺送 ê PO文 ê 媒體 lóng thâi 除:",
"media_nsfw": "媒體 lóng 標做「敏感內容」",
"media_nsfw_desc": "本站 kā 下跤 ê 站 ê 媒體lóng 標做敏感內容:",
"not_applicable": "N/A"
}
},
"staff": "工作人員"
},
"announcements": {
"page_header": "公告",
"title": "公告",
"mark_as_read_action": "標做讀過",
"post_form_header": "貼公告",
"post_placeholder": "佇 tsia 拍你 ê 公告……",
"post_action": "貼",
"post_error": "錯誤:{error}",
"close_error": "關",
"start_time_prompt": "開始時間: ",
"end_time_prompt": "結束時間: ",
"all_day_prompt": "Tse 是 kui 工 ê 事件",
"published_time_display": "公告佇 {time}",
"start_time_display": "有效 tuì{time}",
"end_time_display": "中止佇:{time}",
"edit_action": "編輯",
"submit_edit_action": "送出",
"cancel_edit_action": "取消",
"inactive_message": "這个公告 tsit-má 無效力",
"delete_action": "Thâi掉"
},
"shoutbox": {
"title": "留話枋"
},
"domain_mute_card": {
"mute": "消音",
"mute_progress": "Teh 消音……",
"unmute": "予有聲",
"unmute_progress": "Teh 予有聲……"
},
"exporter": {
"export": "匯出",
"processing": "Teh 處理,較停仔指示你下載檔案"
},
"features_panel": {
"shout": "留話枋",
"pleroma_chat_messages": "Pleroma 開講",
"media_proxy": "媒體代理伺侯器",
"scope_options": "公開範圍選項",
"text_limit": "字數限制",
"title": "有效 ê 功能",
"who_to_follow": "啥儂通綴",
"upload_limit": "檔案 sài-suh 限制",
"gopher": "Gopher"
},
"finder": {
"error_fetching_user": "Tshuē 用者 ê 時起錯誤",
"find_user": "Tshuē 用者"
},
"general": {
"apply": "應用",
"submit": "送出",
"more": "Koh 較 tsē",
"loading": "Leh 載入……",
"generic_error": "起錯誤 ah",
"generic_error_message": "起錯誤:{0}",
"error_retry": "請 koh 試一 kái",
"retry": "Koh 試",
"optional": "非必要",
"show_more": "展示較 tsē",
"show_less": "展示較少",
"never_show_again": "Mài koh 展示",
"dismiss": "無視",
"cancel": "取消",
"disable": "無愛用",
"enable": "啟用",
"confirm": "確認",
"verify": "驗證",
"close": "關掉",
"undo": "復原",
"yes": "是",
"no": "毋是",
"peek": "先看 māi",
"scroll_to_top": "捲 kàu 頂懸",
"role": {
"admin": "行政員",
"moderator": "管理員"
},
"unpin": "無愛 kā 釘",
"pin": "Kā釘起來",
"flash_content": "Ji̍h tsia用 Ruffleiáu teh 試驗,可能 buē 紡)看 Flash ê 內容。",
"flash_sepcurity": "注意 tse 可能有危險,因為 Flash 內容猶原是任意 ê 程式碼。",
"flash_fail": "載入 flash 內容失敗,詳細ē當看控制臺。",
"scope_in_timeline": {
"direct": "私人 phue",
"private": "干焦 hōo 綴 lí ê 看",
"public": "公開佇公共時間線",
"unlisted": "無愛公開佇公共時間線"
},
"flash_security": "Flash內容通藏任何ê指令所以可能有危險。"
},
"image_cropper": {
"crop_picture": "裁相片",
"save": "儲存",
"save_without_cropping": "無裁就儲存",
"cancel": "取消"
},
"importer": {
"submit": "送出",
"success": "匯入成功。",
"error": "佇匯入 ê 時起錯誤。"
},
"login": {
"login": "登入",
"description": "用 OAuth 登入",
"logout": "登出",
"logout_confirm_title": "登出確認",
"logout_confirm": "Lí 敢真正 beh 登出",
"logout_confirm_accept_button": "登出",
"logout_confirm_cancel_button": "mài 登出",
"password": "密碼",
"placeholder": "例lain",
"register": "註冊",
"username": "用者 ê 名",
"hint": "登入,參與討論",
"authentication_code": "認證碼",
"enter_recovery_code": "輸入恢復碼",
"enter_two_factor_code": "輸入兩階段認證碼",
"recovery_code": "恢復碼",
"heading": {
"totp": "兩階段認證",
"recovery": "兩階段恢復"
}
},
"media_modal": {
"previous": "頂一 ê",
"next": "後一个",
"counter": "{current} / {total}",
"hide": "關掉媒體瀏覽"
},
"nav": {
"about": "關係本站",
"administration": "管理",
"back": "轉去",
"friend_requests": "跟綴請求",
"mentions": "The̍h起",
"interactions": "互動",
"dms": "私人 phue",
"public_tl": "公共時間線",
"timeline": "時間線",
"home_timeline": "Tshù ê 時間線",
"twkn": "知影 ê 網路",
"bookmarks": "冊籤",
"user_search": "Tshuē 用者",
"search_close": "關掉 tshiau-tshuē liâu",
"who_to_follow": "Siáng ē當綴",
"preferences": "個人 ê 設定",
"timelines": "時間線",
"chats": "開講",
"lists": "列單",
"edit_nav_mobile": "自訂導覽條",
"edit_pinned": "編輯釘起來 ê 項目",
"edit_finish": "編輯 suah",
"mobile_sidebar": "切換行動版 ê 邊 á liâu",
"mobile_notifications": "拍開通知(有無讀ê)",
"mobile_notifications_close": "關掉通知",
"announcements": "公告",
"search": "Tshuē"
},
"notifications": {
"broken_favorite": "狀態毋知影leh tshiau-tshuē……",
"error": "佇取得通知 ê 時起錯誤:{0}",
"favorited_you": "kah 意 lí ê 狀態",
"followed_you": "綴 lí",
"follow_request": "想 beh 綴 lí",
"load_older": "載入 khah 早 ê 通知",
"notifications": "通知",
"read": "有讀ah",
"repeated_you": "轉送 lí ê 狀態",
"no_more_notifications": "無別 ê 通知",
"migrated_to": "移民到",
"reacted_with": "顯出{0} ê 反應",
"submitted_report": "送出檢舉",
"poll_ended": "投票結束"
},
"polls": {
"add_poll": "開投票",
"add_option": "加選項",
"option": "選項",
"votes": "票",
"people_voted_count": "{count} 位有投",
"votes_count": "{count} 票",
"vote": "投票",
"type": "投票 ê 形式",
"single_choice": "孤選",
"multiple_choices": "Tsē 選",
"expiry": "投票期限",
"expires_in": "投票 tī {0} 以後結束",
"expired": "投票佇 {0} 以前結束",
"not_enough_options": "投票 ê 選項傷少"
},
"emoji": {
"stickers": "貼圖",
"emoji": "繪文字",
"keep_open": "Hōo 揀選仔開 leh",
"search_emoji": "Tshuē 繪文字",
"add_emoji": "插繪文字",
"custom": "定製 ê 繪文字",
"unpacked": "拍開 ê 繪文字",
"unicode": "Unicode 繪文字",
"unicode_groups": {
"activities": "活動",
"animals-and-nature": "動物 kap 自然",
"flags": "旗 á",
"food-and-drink": "食物 kap 飲料",
"objects": "物體",
"people-and-body": "Lâng kap 身軀",
"smileys-and-emotion": "笑面 kap 情緒",
"symbols": "符號",
"travel-and-places": "旅遊 kap 所在"
},
"load_all_hint": "載入頭前 {saneAmount} ê 繪文字,規个攏載入效能可能 ē khah 食力。",
"load_all": "Kā {emojiAmount} ê 繪文字攏載入",
"regional_indicator": "地區指引 {letter}"
},
"errors": {
"storage_unavailable": "Pleroma buē-tàng the̍h 著瀏覽器儲存 ê。Lí ê 登入狀態抑是局部設定 buē 儲存mā 凡勢 tú 著意料外 ê 問題。拍開 cookie 看覓。"
},
"interactions": {
"favs_repeats": "轉送 kap kah 意",
"follows": "最近綴 lí ê",
"emoji_reactions": "繪文字 ê 回應",
"reports": "檢舉",
"moves": "用者 ê 移民",
"load_older": "載入 koh khah 早 ê 互動"
},
"post_status": {
"edit_status": "編輯狀態",
"new_status": "PO 新 ê 狀態",
"account_not_locked_warning": "Lín 口座毋是 {0} ê。見 nā 有 lâng 綴--líē-tàng 看著 lí ê 限定跟綴者 ê PO 文。.",
"account_not_locked_warning_link": "鎖起來 ê 口座",
"attachments_sensitive": "Kā 附件標做敏感內容",
"media_description": "媒體說明",
"content_type": {
"text/plain": "純 ê 文字",
"text/html": "HTML",
"text/markdown": "Markdown",
"text/bbcode": "BBCode"
},
"content_type_selection": "貼 ê 形式",
"content_warning": "主旨(毋是必要)",
"default": "Tú 正 kàu 高雄 ah。",
"direct_warning_to_all": "Tsit ê PO 文通 hōo 逐 ê 提起 ê 用者看見。",
"direct_warning_to_first_only": "Tsit ê PO 文kan-ta 短信 tú 開始提起 ê 用者tsiah 通看見。",
"edit_remote_warning": "別 ê 站臺可能無支援編輯,無法度收著 PO 文上新 ê 版本。",
"edit_unsupported_warning": "Pleroma 無支持編輯 the̍h 起 hām 投票。",
"posting": "PO 文",
"preview": "Sing 看覓",
"preview_empty": "空 ê",
"empty_status_error": "無法度 PO 無檔案 koh 空 ê 狀態",
"media_description_error": "更新媒體失敗,請 koh 試一 kái",
"scope_notice": {
"public": "Tsit ê PO 文通予逐 ê 儂看著",
"private": "Tsit ê PO 文 kan-ta 予綴 lí ê 看著",
"unlisted": "Tsit ê PO 文 buē 公開 tī 公共時間線 kap 知影 ê 網路"
},
"scope_notice_dismiss": "關掉 tsit ê 通知",
"scope": {
"direct": "私人 phue - PO 文干焦予提起 ê 用者看著",
"private": "限定綴 ê 儂 - PO 文干焦予綴 lí ê 儂看著",
"public": "公開 - PO kàu 公開時間線",
"unlisted": "Mài 列出來 - Mài PO tī 公開時間線"
},
"post": "PO 上去"
},
"registration": {
"bio_optional": "介紹(毋是必要)",
"email_optional": "Email毋是必要",
"fullname": "顯示 ê 名",
"password_confirm": "確認密碼",
"registration": "註冊",
"token": "邀請碼",
"captcha": "驗證碼",
"new_captcha": "Ji̍h 圖片the̍h 新 ê 驗證碼",
"fullname_placeholder": "e.g. 岩倉 Lain",
"bio_placeholder": "e.g.\nLí 好,我是 Lain。\n我是日本動畫 ê 角色tuà tī 日本 ê 郊區。Lí 凡勢 bat tī Wired 知影我。",
"reason": "註冊 ê 理由",
"reason_placeholder": "本站靠人工審核註冊。\n介紹管理者 lí beh tī tsia 註冊 ê 理由。",
"register": "註冊",
"validations": {
"username_required": "著愛添",
"fullname_required": "著愛添",
"email_required": "著愛添",
"password_required": "著愛添",
"password_confirmation_required": "著愛添",
"password_confirmation_match": "密碼著相 kâng",
"birthday_required": "著愛添",
"birthday_min_age": "Buē-tàng tī {date} 以後"
},
"email_language": "Lí想 beh 服侍器用 siánn 物語言寄批 hōo lí",
"birthday": "生日:",
"birthday_optional": "生日(毋是必要):",
"email": "電子 phue 箱",
"username_placeholder": "比如lain"
},
"remote_user_resolver": {
"remote_user_resolver": "別站用者 ê 解析器",
"error": "Tshuē無。",
"searching_for": "Tshuē"
},
"report": {
"reporter": "檢舉人:",
"reported_user": "Beh 檢舉 ê 用者:",
"reported_statuses": "Beh 檢舉 ê 狀態:",
"state_open": "開 ê",
"state_closed": "關 ê",
"state_resolved": "解決了 ê",
"notes": "註:",
"state": "狀態:"
},
"selectable_list": {
"select_all": "攏總揀"
},
"settings": {
"add_language": "加一 ê 備用 ê 語言",
"remove_language": "Ni 掉",
"primary_language": "主要語言:",
"fallback_language": "備用語言 {index}",
"app_name": "App ê 名",
"expert_mode": "進階模式",
"save": "保存改變",
"security": "安全",
"setting_changed": "設定 kap 預先 ê 有 tsing 差",
"style": {
"common": {
"color": "色彩",
"opacity": "無透明度",
"contrast": {
"hint": "色彩ê對比率:{ratio}。{level}、 {context}"
}
},
"switcher": {
"keep_shadows": "保持陰影",
"keep_color": "保持色彩",
"keep_opacity": "保持無透明度",
"keep_roundness": "保留邊á角ê khà-buh",
"keep_fonts": "保持字型",
"reset": "重頭設定",
"clear_all": "攏清掉",
"clear_opacity": "清掉無透明度",
"load_theme": "載入主題",
"keep_as_is": "Mài振動",
"use_snapshot": "舊ê版本",
"use_source": "新ê版本",
"help": {
"upgraded_from_v2": "PleromaFE升級ah主題huân-sè kap lí知影ê無kâng。",
"v2_imported": "Lí輸入ê檔案是舊版本ê前端用ê。Guán盡量予版本相通毋過可能有所在buē-tàng。",
"older_version_imported": "Lí輸入ê檔案是予舊ê前端用ê。",
"future_version_imported": "Lí輸入ê檔案是新ê前端所用ê。"
}
}
},
"upload": {
"error": {
"base": "上傳 ê 時失敗。",
"message": "傳 buē 起去:{0}",
"file_too_big": "檔案 sài-suh 傷大 [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
"default": "Koh 試一 kái。"
}
},
"search": {
"people": "用戶",
"hashtags": "主題標籤",
"person_talking": "{count} ê leh 論",
"people_talking": "{count} ê leh 論",
"no_results": "無半 ê 結果",
"no_more_results": "無其他 ê 結果",
"load_more": "載入 koh 較 tsē 結果"
},
"password_reset": {
"forgot_password": "Buē 記得密碼?",
"password_reset": "重頭設密碼",
"instruction": "拍 lí ê email 地址 iah 是用者 ê 名。Guán 會送 lí 連結,重頭設定密碼。",
"placeholder": "Lí ê email 地址 iah 是用者 ê 名。",
"check_email": "檢查電子 phue 箱,看有重頭設密碼 ê 連結無。",
"return_home": "轉來頭頁",
"too_many_requests": "Lí kā 請求 ê khòo-tah 用了 ah。等一時仔閣試一 pái。",
"password_reset_disabled": "密碼重頭設定無開放。請聯絡本站 ê 行政員。",
"password_reset_required": "Beh 登入,著重頭設 lí ê 密碼。",
"password_reset_required_but_mailer_is_disabled": "Lí 需要重頭設密碼,毋 koh tsia 無開放密碼 koh 再設定。請聯絡本站 ê 行政員。"
},
"chats": {
"message_user": "傳私人 phue{nickname}",
"delete": "Thâi 掉",
"chats": "開講",
"new": "發起開講",
"empty_message_error": "無法度 PO 空 ê phue",
"more": "Koh較濟……",
"delete_confirm": "Lí 敢真 ê beh thâi tsit 張 phue",
"error_loading_chat": "載入開講 ê 時,出箠 ah。",
"error_sending_message": "送 phue ê 時,出箠 ah。",
"empty_chat_list_placeholder": "Lí 猶無佇 tsia 開講過,來開講 lah"
},
"lists": {
"lists": "列單",
"new": "新 ê 列單",
"title": "列單標題",
"search": "Tshuē 用者",
"create": "開新 ê",
"save": "保存改變",
"delete": "刣列單",
"following_only": "限定 lí 所關注 ê",
"manage_lists": "管理列單",
"manage_members": "管理列單成員",
"add_members": "Tshiau 閣較 tsē ê 用者",
"remove_from_list": "對列單刣掉",
"add_to_list": "加入去列單",
"is_in_list": "列單已經有 ah ",
"editing_list": "編輯列單 {listTitle}",
"creating_list": "開新 ê 列單",
"update_title": "保存標題",
"really_delete": "敢真正 beh 刣掉列單?",
"error": "操作列單 ê 時陣出重耽:{0}"
},
"file_type": {
"audio": "音訊",
"video": "影片",
"image": "影像",
"file": "檔案"
},
"display_date": {
"today": "今 á 日"
},
"update": {
"big_update_title": "敬請體諒",
"big_update_content": "因為 guán 有一站 á 無發行新版本,所以這个版本會 kap lí 以早慣 sì ê 無仝。",
"update_bugs": "請佇 {pleromaGitlab} 報告任何問題 kap bug因為 Pleroma 改變真 tsē。雖罔 guán 徹底 leh 試mā 家 kī 用開發版伊凡勢有一寡重耽。Guán 歡迎 lín 提供關係所拄著 ê 問題 ê 意見、建議,或者是改進 Pleroma kap Pleroma-FE ê 法度。",
"update_changelog": "Nā beh 知影改變 ê 詳細,請看:{theFullChangelog}.",
"update_changelog_here": "Kui ê 改變日誌",
"art_by": "美編:{linkToArtist}"
},
"unicode_domain_indicator": {
"tooltip": "這 ê 域名包含毋是 ascii ê 字元。"
},
"setting_server_side": "Tsit-ê設定縛佇lí ê個人資料mā 影響逐ê連線階段kap用者端",
"post_look_feel": "PO 文ê外貌kap感受",
"mention_links": "提起 ê 連結",
"mfa": {
"otp": "OTP",
"setup_otp": "設 OTP",
"wait_pre_setup_otp": "kā OTP 預設",
"title": "兩階段認證",
"generate_new_recovery_codes": "產生新ê恢復碼",
"warning_of_generate_new_codes": "產生新 ê 恢復碼ê時,舊 ê tio̍h 變無效。",
"recovery_codes": "恢復碼。",
"waiting_a_recovery_codes": "當leh收備份碼……",
"authentication_methods": "認證方法",
"scan": {
"title": "掃一 ē",
"secret_code": "鎖匙",
"desc": "The̍h lí个兩階段app掃 tsit ê QR code抑是拍文字鎖匙"
},
"verify": {
"desc": "Nā beh開兩階段認證請拍兩階段認證app內底ê碼"
},
"confirm_and_enable": "確定,拍開 OTP",
"recovery_codes_warning": "著 kā tsiah ê 號碼抄落來,抑是儲存佇安全ê所在,因為號碼 buē koh 再出現。若是 lí 袂當用 lí 个兩階段認證app而且恢復碼拍 ka-la̍uhlí就永永buē當登入lí个口座。"
},
"lists_navigation": "佇導覽中顯示列單",
"allow_following_move": "若是綴ê口座徙位ê時,允准自動綴新ê",
"attachmentRadius": "附件",
"avatar": "標頭",
"avatarAltRadius": "標頭(通知)",
"avatarRadius": "標頭",
"background": "背景",
"bio": "紹介",
"block_export": "輸出封鎖名單",
"block_export_button": "封鎖名單輸出kàu csv檔",
"block_import_error": "佇輸入封鎖名單ê時出tshê",
"block_import": "輸入封鎖名單",
"mute_export": "輸出消音名單",
"mute_export_button": "輸出消音名單kàu csv檔",
"mute_import": "輸入消音名單",
"blocks_imported": "成功輸入封鎖名單較停仔tsiah ē處理suah。",
"mutes_imported": "成功輸入消音名單較停仔tsiah ē處理suah。",
"import_mutes_from_a_csv_file": "輸入封鎖名單ê csv檔",
"account_backup": "備份口座",
"mutes_and_blocks": "消音kap封鎖",
"delete_account": "Thâi口座",
"delete_account_error": "佇刣掉lí ê 口座ê時出問題。若是問題一直佇leh請聯絡 lín 站臺 ê 行政員。",
"account_alias": "口座 ê 別名",
"account_alias_table_head": "別名",
"list_aliases_error": "佇the̍h別名ê時出tshê{error}",
"hide_list_aliases_error_action": "關掉",
"remove_alias": "Thâi 掉tsit ê別名",
"new_alias_target": "加新ê別名(比如: {example})",
"added_alias": "別名加入去ah。",
"add_alias_error": "佇加別名ê時出tshê{error}",
"move_account": "徙口座",
"move_account_target": "目標口座(比如:{example}",
"moved_account": "口座徙過去ah。",
"move_account_error": "佇徙口座ê時出tshê{error}",
"attachments": "附件",
"email_language": "服侍器送ê email 所用 ê 語言",
"enter_current_password_to_confirm": "輸入lí tsit-má ê 密碼確認lí ê身份",
"mute_import_error": "佇輸入消音名單ê時出tshê",
"delete_account_description": "Ē 永永刣掉lí个資料hōo lí 个口座bē當用。",
"delete_account_instructions": "佇佇下跤拍lí个密碼確認 kā 口座 thâi掉。",
"move_account_notes": "若是欲徙tsit ê口座著去lí ê目標口座hia加一ê指tsia ê別名。",
"account_backup_table_head": "備份",
"download_backup": "下載",
"backup_not_ready": "備份猶 buē tshuân 予好勢。",
"backup_running": "備份leh處理其中 {number} 筆記錄處理 suah--ah。",
"backup_failed": "備份失敗。",
"remove_backup": "Thâi 掉",
"list_backups_error": "佇 the̍h 備份列單ê時出tshê {error}",
"add_backup": "開新ê備份",
"added_backup": "新ê備份開好 ah。",
"add_backup_error": "佇開新ê備份ê時出tshê{error}",
"blocks_tab": "封鎖",
"bot": "Tse 是機器 lâng ê 口座",
"btnRadius": "鈕仔",
"cBlue": "藍色(回應,跟綴)",
"cGreen": "綠色(轉送)",
"cOrange": "柑仔色kah 意)",
"cRed": "紅色(取消)",
"change_email": "換電子 phue 箱",
"changed_email": "電子 phue 箱變換成功!",
"change_password": "改密碼",
"change_password_error": "佇改密碼ê時出問題。",
"changed_password": "改密碼成功!",
"chatMessageRadius": "開講ê訊息",
"composing": "編寫ê設定",
"confirm_new_password": "確認新ê密碼",
"current_password": "Tann ê 密碼",
"confirm_dialogs": "問確認佇",
"confirm_dialogs_repeat": "轉送狀態",
"confirm_dialogs_unfollow": "無愛綴用者",
"confirm_dialogs_block": "封鎖用者",
"confirm_dialogs_mute": "kā用者消音",
"confirm_dialogs_delete": "thâi掉狀態",
"confirm_dialogs_logout": "登出",
"confirm_dialogs_approve_follow": "允准跟綴",
"confirm_dialogs_deny_follow": "無允准跟綴",
"confirm_dialogs_remove_follower": "徙走綴 lí ê",
"data_import_export_tab": "資料輸入/出",
"default_vis": "預設ê公開範圍",
"discoverable": "允准用tshiau-tshuē kap 其他ê服務tshuē著 tsit ê口座",
"domain_mutes": "域名",
"avatar_size_instruction": "建議ê標頭影像sài-suh 是150x150畫素。",
"pad_emoji": "Tuì 揀選器揀繪文字以後,佇繪文字雙 pîng 邊加空白",
"emoji_reactions_on_timeline": "佇時間線頂,顯示繪文字ê反應",
"emoji_reactions_scale": "反應ê規模係數",
"export_theme": "保存主題",
"filtering": "過濾",
"wordfilter": "詞語過濾器",
"word_filter_and_more": "詞語過濾器 kap 其他……",
"follow_export": "輸出 lí 所綴ê",
"follow_export_button": "輸出lí所綴ê kàu csv 檔",
"follow_import": "輸入lí所綴ê",
"follow_import_error": "佇輸入跟綴 ê 資料 ê 時出tshê",
"accent": "強調",
"foreground": "前景",
"general": "一般",
"hide_attachments_in_convo": "佇對話ê時khàm附件",
"hide_attachments_in_tl": "Khàm掉時間線內ê附件",
"hide_media_previews": "Khàm掉媒體ê預展",
"hide_muted_posts": "Khàm掉消音ê用者ê PO文",
"hide_bot_indication": "Khàm 掉PO文內底ê機器lâng ê指示",
"hide_all_muted_posts": "Khàm掉消音êPO文",
"max_thumbnails": "PO文ê縮小圖ê khòo-tah無寫=無限制)",
"hide_isp": "Khàm 站臺特有ê面 pang",
"right_sidebar": "Kā 邊á liâu徙kah正手pîng",
"navbar_column_stretch": "伸導覽liâukah 欄平闊",
"always_show_post_button": "一直顯示「新ê PO文」ê鈕仔",
"hide_wallpaper": "Khàm站臺ê壁紙",
"use_one_click_nsfw": "Tshi̍h 一ê就會當拍開敏感內容",
"hide_post_stats": "Khàm PO文ê統計數據比如kah 意ê額數)",
"hide_filtered_statuses": "Khàm 逐ê過濾掉êPO文",
"hide_wordfiltered_statuses": "Khàm詞語過濾掉ê狀態",
"hide_muted_threads": "Khàm消音ê討論線",
"import_blocks_from_a_csv_file": "Tuì csv 檔輸入封鎖名單",
"import_followers_from_a_csv_file": "Uì csv 檔輸入跟綴ê資料",
"import_theme": "載入主題",
"inputRadius": "輸入ê格仔",
"checkboxRadius": "選擇框仔",
"instance_default": "(預設:{value}",
"instance_default_simple": "(預設)",
"interface": "界面",
"column_sizes_sidebar": "邊 á liâu",
"auto_update": "自動顯示新ê PO文",
"user_mutes": "用者",
"useStreamingApi": "連鞭收著PO文kap通知",
"use_websockets": "用websockets實ê時間ê更新",
"text": "文字",
"theme": "主題",
"theme_help": "用16進位ê碼(#rrggbb)來訂做家己ê色彩主題。",
"change_email_error": "佇換電子phue箱ê時出問題。",
"collapse_subject": "Kā 有主旨ê PO 文 khàm 起來",
"autocomplete_select_first": "若是有自動完成ê結果,自動揀頭一ê侯選ê",
"filtering_explanation": "見若有下跤ê詞語ê狀態會hőng消音。一tsuā寫一ê",
"follows_imported": "Lí所綴ê輸入去ah較停仔tsiah ē處理suah。",
"mute_bot_posts": "Kā 機器lâng ê PO文消音",
"hide_shoutbox": "Khàm 站臺ê留話pang",
"account_backup_description": "Tse 予 lí ē當 kā lín 口座 ê 資訊 kap PO 文載落來,毋過 in 猶無法度輸入kàu Pleroma口座 ê 內底。",
"theme_help_v2_1": "拍開選擇框á就 ē 當改掉一寡組件ê色彩kap無透明度。Ji̍h「清掉所有ê」ē 恢復原來ê款。",
"preload_images": "Kā 圖片先載入",
"hide_user_stats": "Khàm 掉用者ê統計數據(比如:綴ê lâng額",
"interfaceLanguage": "界面ê語言",
"invalid_theme_imported": "Lí 所揀ê主題檔案Pleroma 無支援,所以主題無改。",
"limited_availability": "你ê瀏覽器內底buē當用",
"links": "連結",
"lock_account_description": "Kan-ta lí 同意別儂tsiah通綴lí",
"loop_video": "循環播出ê影片",
"loop_video_silent_only": "Kan-ta無聲ê影片tsiah通循環播出比如Mastodon ê \"gif\"",
"mutes_tab": "消音",
"play_videos_in_modal": "佇跳出來ê框仔播出影片",
"url": "URL",
"preview": "預展",
"file_export_import": {
"backup_restore": "備份設定",
"backup_settings": "Kā 設定備份kàu檔案",
"backup_settings_theme": "Kā設定kap主題備份kàu檔案",
"restore_settings": "對檔案回復設定",
"errors": {
"file_too_old": "無接受ê主要版本:{fileMajor}檔案ê版本siūnn舊buē當處理{feMajor} 版以後ê tsiah支援",
"file_slightly_new": "檔案ê次版本無仝一寡設定可能buē當載入去",
"invalid_file": "選擇ê檔案毋是Pleroma支援ê設定備份設定無振動。",
"file_too_new": "無接受ê主要版本:{fileMajor},本 PleromaFE設定版本 {feMajor}siūnn舊buē當處理"
}
},
"profile_fields": {
"label": "個人資料ê meta資料",
"add_field": "加格仔",
"name": "標簽",
"value": "內容"
},
"birthday": {
"label": "生日",
"show_birthday": "顯示我ê生日"
},
"account_privacy": "隱私",
"use_contain_fit": "Mài裁附件ê縮小圖",
"name_bio": "名kah介紹",
"new_password": "新ê密碼",
"posts": "PO文",
"name": "名",
"new_email": "新ê電子phue箱",
"notification_visibility_likes": "收藏",
"hide_favorites_description": "Mài 顯示阮收藏ê列單別儂uân-á ē收著通知)",
"user_profiles": "用者ê資料",
"notification_visibility": "Beh顯示啥款ê通知",
"notification_visibility_follows": "綴ê儂",
"notification_visibility_mentions": "提起",
"notification_visibility_repeats": "轉送",
"notification_visibility_moves": "用者suá位",
"notification_visibility_emoji_reactions": "回應",
"notification_visibility_polls": "Lí參與ê選舉辦suah佇",
"no_rich_text_description": "Po文mài用RTF格式",
"no_blocks": "無封鎖",
"no_mutes": "無消音",
"hide_follows_description": "Mài顯示我綴ê儂",
"hide_followers_description": "Mài顯示綴我ê儂",
"hide_follows_count_description": "Mài顯示我跟綴ê儂額",
"hide_followers_count_description": "Mài顯示綴我ê儂額",
"show_moderator_badge": "佇我ê個人資料顯示「管理員」證章",
"nsfw_clickthrough": "Khàm掉敏感ê媒體內容",
"oauth_tokens": "OAuth token",
"refresh_token": "對頭the̍h token",
"valid_until": "到期佇",
"revoke_token": "撤回",
"panelRadius": "面pang",
"presets": "代先ê設定",
"profile_background": "個人資料ê背景",
"profile_banner": "個人資料ê條á",
"profile_tab": "個人資料",
"radii_help": "設定界面邊á ê khà-buh (curve) ê 半徑(單位:畫素)",
"replies_in_timeline": "佇時間線內底ê回應",
"reply_visibility_all": "顯示所有ê回應",
"reply_visibility_following": "Kan-ta顯示送予我抑是我綴ê儂ê回應",
"reply_visibility_self": "Kan-ta顯示送予我ê回應",
"reply_visibility_following_short": "顯示予我所綴ê儂ê回應",
"reply_visibility_self_short": "Kan-ta顯示予我ka-kī ê回應",
"autohide_floating_post_button": "自動khàm掉「新êPO文」ê鈕仔行動版",
"saving_err": "佇保存設定ê時出tshê",
"saving_ok": "設定保存好ah",
"search_user_to_block": "Tshuē lí beh封鎖ê",
"search_user_to_mute": "Tshuē lí beh 消音ê",
"security_tab": "安全",
"scope_copy": "回應ê時ē khóo-pih ê範圍私人phue 定著ē hőng khóo-pih",
"minimal_scopes_mode": "Kā PO文ê公開範圍ê選項kiu kah上細",
"set_new_avatar": "設定新ê標頭",
"set_new_profile_background": "設定新ê個人資料ê背景",
"set_new_profile_banner": "設定新ê個人資料ê條á",
"reset_avatar": "Tuì頭設定標頭",
"reset_profile_background": "Tuì頭設個人資料ê背景",
"reset_profile_banner": "Tuì頭設個人資料ê條á",
"reset_avatar_confirm": "Lí敢確實beh tuì頭設定標頭",
"reset_banner_confirm": "Lí敢確實beh tuì頭設定條á",
"reset_background_confirm": "Lí敢確實beh tuì頭設定背景",
"settings": "設定",
"subject_input_always_show": "一直顯示主旨ê格á",
"subject_line_behavior": "回應ê時khóo-pih主旨",
"subject_line_email": "電子phue風格「re: 主旨」",
"subject_line_mastodon": "Mastodon風格主旨無變",
"subject_line_noop": "Mài khóo-pih",
"conversation_display": "顯示對話ê風格",
"conversation_display_tree": "樹á ê形",
"disable_sticky_headers": "Mài 予欄位ê頭牢佇螢幕頂懸",
"show_scrollbars": "展示邊á liâu ê giú-á",
"third_column_mode": "空間夠額ê時,展示第三ê欄位",
"third_column_mode_none": "不管時mài顯示第三ê欄位",
"third_column_mode_notifications": "通知ê欄位",
"third_column_mode_postform": "主要êPO文表kah導覽",
"show_admin_badge": "佇我ê個人資料顯示「行政員」證章",
"pause_on_unfocused": "若是 Pleroma ê分頁無點開tiō 暫停更新",
"conversation_display_tree_quick": "樹á形ê展示",
"columns": "欄位",
"column_sizes": "欄位sài-suh",
"column_sizes_content": "內容",
"column_sizes_notifs": "通知",
"tree_advanced": "允准用較活動ê方式導覽佇樹á形ê展示",
"tree_fade_ancestors": "用較淺ê色水顯示目前狀態ê前文",
"conversation_display_linear": "線á形ê風格",
"conversation_display_linear_quick": "線á形ê展示",
"conversation_other_replies_button": "顯示「其他ê回應」鈕仔",
"conversation_other_replies_button_below": "佇狀態下kha",
"conversation_other_replies_button_inside": "佇狀態內底",
"max_depth_in_thread": "預設ê討論線顯示層數ê上限",
"post_status_content_type": "Po文狀態ê內容類型",
"sensitive_by_default": "預設內kā po文標做敏感內容",
"stop_gifs": "Kā滑鼠ê指標khǹg佇面頂ê時動畫圖片tsiah振動",
"streaming": "Giú kàu頂懸ê時自動展示新ê po文",
"theme_help_v2_2": "一寡圖片下kha ê標á是背景圖片ê對比指示滑鼠指標khǹg佇面頂ê時ē當看詳細。請記lit若是用透明ê對比指示顯示上bái ê情況。",
"tooltipRadius": "提醒",
"type_domains_to_mute": "揣beh愛消音ê域名",
"upload_a_photo": "Kā相片傳上去",
"user_settings": "用者ê設定",
"values": {
"false": "無",
"true": "是"
},
"mention_link_display_short": "一直顯示短ê名(比如: {'@'}foo",
"mention_link_display_full": "一直用全名顯示(比如:{'@'}foo{'@'}example.org",
"virtual_scrolling": "Kā時間線ê算畫最佳化",
"mention_link_display_full_for_remote": "Kan-ta kā其他域名ê用者用全名顯示比如{'@'}foo{'@'}example.org",
"token": "Token",
"use_at_icon": "用標á顯示 {'@'} 符號mài用文字",
"mention_link_display": "顯示提起ê連結",
"mention_link_use_tooltip": "佇tshi̍h提起ê連結ê時顯示用者ê卡片",
"mention_link_show_avatar": "佇連結邊á顯示用者ê標頭",
"mention_link_show_avatar_quick": "佇提起ê隔壁,顯示用者ê標頭",
"mention_link_fade_domain": "用較淺ê色水顯示域名(比如:{'@'}foo{'@'}example.org ê {'@'}example.org",
"mention_link_bolden_you": "佇lí hőng提起ê時強調對lí ê提起文字",
"user_popover_avatar_action": "Tshi̍h跳出來ê標頭ê動作",
"user_popover_avatar_action_zoom": "放大/縮小標頭",
"user_popover_avatar_action_close": "關掉跳出來ê框á",
"user_popover_avatar_action_open": "拍開個人資料",
"user_popover_avatar_overlay": "佇用者ê跳出來ê框仔面頂,顯示用者ê標頭",
"fun": "趣味ê",
"greentext": "Meme ê箭頭",
"show_yous": "顯示",
"notifications": "通知",
"notification_setting_filters": "過濾ê",
"notification_setting_block_from_strangers": "關lí bô綴ê lâng 送ê通知",
"notification_setting_privacy": "隱私",
"notification_setting_hide_notification_contents": "Kā sak通知ê lâng kap伊ê內容khàm掉",
"notification_mutes": "若tsún無愛收tuì指定用者來ê通知著用消音。",
"notification_blocks": "封鎖用者ē停止所有i hia來ê通知mā取消訂伊。",
"enable_web_push_notifications": "拍開網頁sak通知ê功能",
"more_settings": "Koh較tsē ê設定"
},
"status": {
"favorites": "收藏"
},
"user_card": {
"favorites": "收藏"
},
"tool_tip": {
"favorite": "收藏"
}
}

View File

@ -699,7 +699,7 @@
"hide_muted_threads": "不显示已隐藏的同主题帖子",
"notification_visibility_polls": "你所投的投票的结束于",
"tree_advanced": "允许在树状视图中进行更灵活的导航",
"tree_fade_ancestors": "以模糊的文字显示当前状态的原型",
"tree_fade_ancestors": "以模糊的文字显示当前状态的上级",
"conversation_display_linear": "线性样式",
"mention_link_fade_domain": "淡化域名(例如:{'@'}example.org 中的 {'@'}foo{'@'}example.org",
"mention_link_bolden_you": "当你被提及时突出显示提及你",
@ -738,7 +738,16 @@
"mention_link_show_avatar": "在链接旁边显示用户头像",
"mention_link_show_avatar_quick": "在提及内容旁边显示用户头像",
"user_popover_avatar_action_open": "打开个人资料",
"autocomplete_select_first": "当有自动完成的结果时,自动选择第一个候选项"
"autocomplete_select_first": "当有自动完成的结果时,自动选择第一个候选项",
"url": "URL",
"preview": "预览",
"commit_value": "保存",
"commit_value_tooltip": "当前值未保存,请按此按钮以提交你的修改",
"reset_value": "重置",
"reset_value_tooltip": "重置草稿",
"hard_reset_value": "硬重置",
"hard_reset_value_tooltip": "从存储中移除设置,强制使用默认值",
"emoji_reactions_scale": "表情回应比例系数"
},
"time": {
"day": "{0} 天",
@ -869,7 +878,9 @@
"delete_confirm_accept_button": "删除",
"delete_confirm_cancel_button": "保留",
"show_attachment_in_modal": "在媒体模式中显示",
"status_history": "状态历史"
"status_history": "状态历史",
"delete_error": "删除状态时出错:{0}",
"reaction_count_label": "{num} 人作出了表情回应"
},
"user_card": {
"approve": "核准",
@ -1063,7 +1074,7 @@
"smileys-and-emotion": "表情与情感"
},
"regional_indicator": "地区指示符 {letter}",
"unpacked": "拆分的表情符号"
"unpacked": "未分组的表情符号"
},
"about": {
"mrf": {
@ -1195,5 +1206,91 @@
"lists": "列表",
"new": "新的列表",
"title": "列表标题"
},
"admin_dash": {
"window_title": "管理员",
"old_ui_link": "旧的管理界面在此处",
"reset_all": "重置全部",
"commit_all": "保存全部",
"tabs": {
"nodb": "无数据库配置",
"instance": "实例",
"limits": "限制",
"frontends": "前端"
},
"nodb": {
"heading": "数据库配置已禁用",
"documentation": "文档",
"text2": "大多数配置选项将不可用。",
"text": "你需要修改后端配置文件,以便将 {property} 设置为 {value},更多内容请参见 {documentation}。"
},
"captcha": {
"native": "本地",
"kocaptcha": "KoCaptcha"
},
"instance": {
"instance": "实例信息",
"registrations": "用户注册",
"captcha_header": "验证码",
"kocaptcha": "KoCaptcha 设置",
"access": "实例访问",
"restrict": {
"header": "限制匿名访客的访问",
"timelines": "时间线访问",
"profiles": "用户个人资料访问",
"activities": "状态/活动访问",
"description": "允许/不允许访问特定 API 的详细设置。默认情况下(不确定状态),如果实例不是公开的,它将拒绝访问;勾选复选框意味着即使实例是公开的,也拒绝访问;不勾选意味着即使实例是私有的,也允许访问。请注意,如果某些设置被设定,可能会发生意想不到的行为,例如,如果个人资料访问被禁用,显示的帖文将不包含个人资料信息。"
}
},
"limits": {
"arbitrary_limits": "任意限制",
"posts": "帖文限制",
"uploads": "附件限制",
"users": "用户个人资料限制",
"profile_fields": "个人资料字段限制",
"user_uploads": "个人资料媒体限制"
},
"frontend": {
"repository": "存储库链接",
"versions": "可用版本",
"build_url": "构建产物 URL",
"reinstall": "重新安装",
"is_default": "(默认)",
"is_default_custom": "(默认,版本:{version}",
"install": "安装",
"install_version": "安装版本 {version}",
"more_install_options": "更多安装选项",
"more_default_options": "更多默认设置选项",
"set_default": "设为默认",
"set_default_version": "将版本 {version} 设为默认",
"wip_notice": "请注意此部分是一个WIP缺乏某些功能因为前端管理的后台实现并不完整。",
"default_frontend": "默认前端",
"default_frontend_tip": "默认的前端将显示给所有用户。目前还没有办法让用户选择个人的前端。如果你不使用 PleromaFE你很可能不得不使用旧的和有问题的 AdminFE 来进行实例配置,直到我们替换它。",
"default_frontend_tip2": "WIP: 由于 Pleroma 后端没有正确列出所有已安装的前端,你必须手动输入名称和引用。下面的列表提供了填写这些值的快捷方式。",
"available_frontends": "可供安装"
},
"temp_overrides": {
":pleroma": {
":instance": {
":public": {
"label": "实例是公开的",
"description": "禁用此功能将使所有的 API 只能被已登录用户访问,这将使公共和联邦时间线无法被匿名访客访问。"
},
":limit_to_local_content": {
"label": "将搜索限于本地内容",
"description": "禁用未认证用户(默认)、所有用户或无人的全局网络搜索"
},
":description_limit": {
"label": "限制",
"description": "附件描述的字数限制"
},
":background_image": {
"label": "背景图片",
"description": "背景图片(主要使用于 PleromaFE"
}
}
}
},
"wip_notice": "此管理仪表板是实验性和 WIP 的,{adminFeLink}。"
}
}

View File

@ -546,7 +546,7 @@
"backend_version": "後端版本",
"frontend_version": "前端版本"
},
"virtual_scrolling": "優化時間線渲染",
"virtual_scrolling": "最佳化時間軸算繪",
"import_mutes_from_a_csv_file": "從CSV文件導入靜音",
"mutes_imported": "靜音導入了!處理它們將需要一段時間。",
"mute_import": "靜音導入",
@ -576,7 +576,10 @@
},
"sensitive_by_default": "默認標記發文為敏感內容",
"right_sidebar": "在右側顯示側邊欄",
"hide_shoutbox": "隱藏實例留言框"
"hide_shoutbox": "隱藏實例留言框",
"mention_link_display_short": "總是使用短名(如: {'@'}foo",
"mention_link_display": "顯式提及連結",
"use_at_icon": "將{'@'}改用圖標顯示,不用文字"
},
"chats": {
"more": "更多",

View File

@ -10,8 +10,9 @@ import listsModule from './modules/lists.js'
import usersModule from './modules/users.js'
import apiModule from './modules/api.js'
import configModule from './modules/config.js'
import serverSideConfigModule from './modules/serverSideConfig.js'
import profileConfigModule from './modules/profileConfig.js'
import serverSideStorageModule from './modules/serverSideStorage.js'
import adminSettingsModule from './modules/adminSettings.js'
import shoutModule from './modules/shout.js'
import oauthModule from './modules/oauth.js'
import authFlowModule from './modules/auth_flow.js'
@ -44,7 +45,7 @@ const i18n = createI18n({
messages: messages.default
})
messages.setLanguage(i18n, currentLocale)
messages.setLanguage(i18n.global, currentLocale)
const persistedStateOptions = {
paths: [
@ -80,8 +81,9 @@ const persistedStateOptions = {
lists: listsModule,
api: apiModule,
config: configModule,
serverSideConfig: serverSideConfigModule,
profileConfig: profileConfigModule,
serverSideStorage: serverSideStorageModule,
adminSettings: adminSettingsModule,
shout: shoutModule,
oauth: oauthModule,
authFlow: authFlowModule,

View File

@ -0,0 +1,230 @@
import { set, get, cloneDeep, differenceWith, isEqual, flatten } from 'lodash'
export const defaultState = {
frontends: [],
loaded: false,
needsReboot: null,
config: null,
modifiedPaths: null,
descriptions: null,
draft: null,
dbConfigEnabled: null
}
export const newUserFlags = {
...defaultState.flagStorage
}
const adminSettingsStorage = {
state: {
...cloneDeep(defaultState)
},
mutations: {
setInstanceAdminNoDbConfig (state) {
state.loaded = false
state.dbConfigEnabled = false
},
setAvailableFrontends (state, { frontends }) {
state.frontends = frontends.map(f => {
if (f.name === 'pleroma-fe') {
f.refs = ['master', 'develop']
} else {
f.refs = [f.ref]
}
return f
})
},
updateAdminSettings (state, { config, modifiedPaths }) {
state.loaded = true
state.dbConfigEnabled = true
state.config = config
state.modifiedPaths = modifiedPaths
},
updateAdminDescriptions (state, { descriptions }) {
state.descriptions = descriptions
},
updateAdminDraft (state, { path, value }) {
const [group, key, subkey] = path
const parent = [group, key, subkey]
set(state.draft, path, value)
// force-updating grouped draft to trigger refresh of group settings
if (path.length > parent.length) {
set(state.draft, parent, cloneDeep(get(state.draft, parent)))
}
},
resetAdminDraft (state) {
state.draft = cloneDeep(state.config)
}
},
actions: {
loadFrontendsStuff ({ state, rootState, dispatch, commit }) {
rootState.api.backendInteractor.fetchAvailableFrontends()
.then(frontends => commit('setAvailableFrontends', { frontends }))
},
loadAdminStuff ({ state, rootState, dispatch, commit }) {
rootState.api.backendInteractor.fetchInstanceDBConfig()
.then(backendDbConfig => {
if (backendDbConfig.error) {
if (backendDbConfig.error.status === 400) {
backendDbConfig.error.json().then(errorJson => {
if (/configurable_from_database/.test(errorJson.error)) {
commit('setInstanceAdminNoDbConfig')
}
})
}
} else {
dispatch('setInstanceAdminSettings', { backendDbConfig })
}
})
if (state.descriptions === null) {
rootState.api.backendInteractor.fetchInstanceConfigDescriptions()
.then(backendDescriptions => dispatch('setInstanceAdminDescriptions', { backendDescriptions }))
}
},
setInstanceAdminSettings ({ state, commit, dispatch }, { backendDbConfig }) {
const config = state.config || {}
const modifiedPaths = new Set()
backendDbConfig.configs.forEach(c => {
const path = [c.group, c.key]
if (c.db) {
// Path elements can contain dot, therefore we use ' -> ' as a separator instead
// Using strings for modified paths for easier searching
c.db.forEach(x => modifiedPaths.add([...path, x].join(' -> ')))
}
const convert = (value) => {
if (Array.isArray(value) && value.length > 0 && value[0].tuple) {
return value.reduce((acc, c) => {
return { ...acc, [c.tuple[0]]: convert(c.tuple[1]) }
}, {})
} else {
return value
}
}
set(config, path, convert(c.value))
})
console.log(config[':pleroma'])
commit('updateAdminSettings', { config, modifiedPaths })
commit('resetAdminDraft')
},
setInstanceAdminDescriptions ({ state, commit, dispatch }, { backendDescriptions }) {
const convert = ({ children, description, label, key = '<ROOT>', group, suggestions }, path, acc) => {
const newPath = group ? [group, key] : [key]
const obj = { description, label, suggestions }
if (Array.isArray(children)) {
children.forEach(c => {
convert(c, newPath, obj)
})
}
set(acc, newPath, obj)
}
const descriptions = {}
backendDescriptions.forEach(d => convert(d, '', descriptions))
console.log(descriptions[':pleroma']['Pleroma.Captcha'])
commit('updateAdminDescriptions', { descriptions })
},
// This action takes draft state, diffs it with live config state and then pushes
// only differences between the two. Difference detection only work up to subkey (third) level.
pushAdminDraft ({ rootState, state, commit, dispatch }) {
// TODO cleanup paths in modifiedPaths
const convert = (value) => {
if (typeof value !== 'object') {
return value
} else if (Array.isArray(value)) {
return value.map(convert)
} else {
return Object.entries(value).map(([k, v]) => ({ tuple: [k, v] }))
}
}
// Getting all group-keys used in config
const allGroupKeys = flatten(
Object
.entries(state.config)
.map(
([group, lv1data]) => Object
.keys(lv1data)
.map((key) => ({ group, key }))
)
)
// Only using group-keys where there are changes detected
const changedGroupKeys = allGroupKeys.filter(({ group, key }) => {
return !isEqual(state.config[group][key], state.draft[group][key])
})
// Here we take all changed group-keys and get all changed subkeys
const changed = changedGroupKeys.map(({ group, key }) => {
const config = state.config[group][key]
const draft = state.draft[group][key]
// We convert group-key value into entries arrays
const eConfig = Object.entries(config)
const eDraft = Object.entries(draft)
// Then those entries array we diff so only changed subkey entries remain
// We use the diffed array to reconstruct the object and then shove it into convert()
return ({ group, key, value: convert(Object.fromEntries(differenceWith(eDraft, eConfig, isEqual))) })
})
rootState.api.backendInteractor.pushInstanceDBConfig({
payload: {
configs: changed
}
})
.then(() => rootState.api.backendInteractor.fetchInstanceDBConfig())
.then(backendDbConfig => dispatch('setInstanceAdminSettings', { backendDbConfig }))
},
pushAdminSetting ({ rootState, state, commit, dispatch }, { path, value }) {
const [group, key, ...rest] = Array.isArray(path) ? path : path.split(/\./g)
const clone = {} // not actually cloning the entire thing to avoid excessive writes
set(clone, rest, value)
// TODO cleanup paths in modifiedPaths
const convert = (value) => {
if (typeof value !== 'object') {
return value
} else if (Array.isArray(value)) {
return value.map(convert)
} else {
return Object.entries(value).map(([k, v]) => ({ tuple: [k, v] }))
}
}
rootState.api.backendInteractor.pushInstanceDBConfig({
payload: {
configs: [{
group,
key,
value: convert(clone)
}]
}
})
.then(() => rootState.api.backendInteractor.fetchInstanceDBConfig())
.then(backendDbConfig => dispatch('setInstanceAdminSettings', { backendDbConfig }))
},
resetAdminSetting ({ rootState, state, commit, dispatch }, { path }) {
const [group, key, subkey] = path.split(/\./g)
state.modifiedPaths.delete(path)
return rootState.api.backendInteractor.pushInstanceDBConfig({
payload: {
configs: [{
group,
key,
delete: true,
subkeys: [subkey]
}]
}
})
.then(() => rootState.api.backendInteractor.fetchInstanceDBConfig())
.then(backendDbConfig => dispatch('setInstanceAdminSettings', { backendDbConfig }))
}
}
}
export default adminSettingsStorage

View File

@ -65,6 +65,7 @@ const chats = {
const newChatMessageSideEffects = (chat) => {
maybeShowChatNotification(store, chat)
}
commit('addNewUsers', chats.map(k => k.account).filter(k => k))
commit('addNewChats', { dispatch, chats, rootGetters, newChatMessageSideEffects })
},
updateChat ({ commit }, { chat }) {

View File

@ -1,6 +1,7 @@
import Cookies from 'js-cookie'
import { setPreset, applyTheme, applyConfig } from '../services/style_setter/style_setter.js'
import messages from '../i18n/messages'
import { set } from 'lodash'
import localeService from '../services/locale/locale.service.js'
const BACKEND_LANGUAGE_COOKIE_NAME = 'userLanguage'
@ -49,7 +50,7 @@ export const defaultState = {
alwaysShowNewPostButton: false,
autohideFloatingPostButton: false,
pauseOnUnfocused: true,
stopGifs: true,
stopGifs: false,
replyVisibility: 'all',
thirdColumnMode: 'notifications',
notificationVisibility: {
@ -89,7 +90,7 @@ export const defaultState = {
modalOnRemoveUserFromFollowers: undefined, // instance default
playVideosInModal: false,
useOneClickNsfw: false,
useContainFit: true,
useContainFit: false,
disableStickyHeaders: false,
showScrollbars: false,
userPopoverAvatarAction: 'open',
@ -148,7 +149,7 @@ const config = {
},
mutations: {
setOption (state, { name, value }) {
state[name] = value
set(state, name, value)
},
setHighlight (state, { user, color, type }) {
const data = this.state.config.highlight[user]
@ -178,6 +179,25 @@ const config = {
commit('setHighlight', { user, color, type })
},
setOption ({ commit, dispatch, state }, { name, value }) {
const exceptions = new Set([
'useStreamingApi'
])
if (exceptions.has(name)) {
switch (name) {
case 'useStreamingApi': {
const action = value ? 'enableMastoSockets' : 'disableMastoSockets'
dispatch(action).then(() => {
commit('setOption', { name: 'useStreamingApi', value })
}).catch((e) => {
console.error('Failed starting MastoAPI Streaming socket', e)
dispatch('disableMastoSockets')
dispatch('setOption', { name: 'useStreamingApi', value: false })
})
}
}
} else {
commit('setOption', { name, value })
switch (name) {
case 'theme':
@ -207,6 +227,7 @@ const config = {
}
}
}
}
}
export default config

View File

@ -1,7 +1,9 @@
const defaultState = {
settingsModalState: 'hidden',
settingsModalLoaded: false,
settingsModalLoadedUser: false,
settingsModalLoadedAdmin: false,
settingsModalTargetTab: null,
settingsModalMode: 'user',
settings: {
currentSaveStateNotice: null,
noticeClearTimeout: null,
@ -54,10 +56,17 @@ const interfaceMod = {
throw new Error('Illegal minimization state of settings modal')
}
},
openSettingsModal (state) {
openSettingsModal (state, value) {
state.settingsModalMode = value
state.settingsModalState = 'visible'
if (!state.settingsModalLoaded) {
state.settingsModalLoaded = true
if (value === 'user') {
if (!state.settingsModalLoadedUser) {
state.settingsModalLoadedUser = true
}
} else if (value === 'admin') {
if (!state.settingsModalLoadedAdmin) {
state.settingsModalLoadedAdmin = true
}
}
},
setSettingsModalTargetTab (state, value) {
@ -92,8 +101,8 @@ const interfaceMod = {
closeSettingsModal ({ commit }) {
commit('closeSettingsModal')
},
openSettingsModal ({ commit }) {
commit('openSettingsModal')
openSettingsModal ({ commit }, value = 'user') {
commit('openSettingsModal', value)
},
togglePeekSettingsModal ({ commit }) {
commit('togglePeekSettingsModal')
@ -103,7 +112,7 @@ const interfaceMod = {
},
openSettingsModalTab ({ commit }, value) {
commit('setSettingsModalTargetTab', value)
commit('openSettingsModal')
commit('openSettingsModal', 'user')
},
pushGlobalNotice (
{ commit, dispatch, state },

View File

@ -22,9 +22,9 @@ const notificationsApi = ({ rootState, commit }, { path, value, oldValue }) => {
.updateNotificationSettings({ settings })
.then(result => {
if (result.status === 'success') {
commit('confirmServerSideOption', { name, value })
commit('confirmProfileOption', { name, value })
} else {
commit('confirmServerSideOption', { name, value: oldValue })
commit('confirmProfileOption', { name, value: oldValue })
}
})
}
@ -94,16 +94,16 @@ export const settingsMap = {
export const defaultState = Object.fromEntries(Object.keys(settingsMap).map(key => [key, null]))
const serverSideConfig = {
const profileConfig = {
state: { ...defaultState },
mutations: {
confirmServerSideOption (state, { name, value }) {
confirmProfileOption (state, { name, value }) {
set(state, name, value)
},
wipeServerSideOption (state, { name }) {
wipeProfileOption (state, { name }) {
set(state, name, null)
},
wipeAllServerSideOptions (state) {
wipeAllProfileOptions (state) {
Object.keys(settingsMap).forEach(key => {
set(state, key, null)
})
@ -118,23 +118,23 @@ const serverSideConfig = {
}
},
actions: {
setServerSideOption ({ rootState, state, commit, dispatch }, { name, value }) {
setProfileOption ({ rootState, state, commit, dispatch }, { name, value }) {
const oldValue = get(state, name)
const map = settingsMap[name]
if (!map) throw new Error('Invalid server-side setting')
const { set: path = map, api = defaultApi } = map
commit('wipeServerSideOption', { name })
commit('wipeProfileOption', { name })
api({ rootState, commit }, { path, value, oldValue })
.catch((e) => {
console.warn('Error setting server-side option:', e)
commit('confirmServerSideOption', { name, value: oldValue })
commit('confirmProfileOption', { name, value: oldValue })
})
},
logout ({ commit }) {
commit('wipeAllServerSideOptions')
commit('wipeAllProfileOptions')
}
}
}
export default serverSideConfig
export default profileConfig

View File

@ -615,9 +615,19 @@ const statuses = {
fetchStatusHistory ({ rootState, dispatch }, status) {
return apiService.fetchStatusHistory({ status })
},
deleteStatus ({ rootState, commit }, status) {
commit('setDeleted', { status })
deleteStatus ({ rootState, commit, dispatch }, status) {
apiService.deleteStatus({ id: status.id, credentials: rootState.users.currentUser.credentials })
.then((_) => {
commit('setDeleted', { status })
})
.catch((e) => {
dispatch('pushGlobalNotice', {
level: 'error',
messageKey: 'status.delete_error',
messageArgs: [e.message],
timeout: 5000
})
})
},
deleteStatusById ({ rootState, commit }, id) {
const status = rootState.statuses.allStatusesObject[id]
@ -747,7 +757,7 @@ const statuses = {
)
},
fetchEmojiReactionsBy ({ rootState, commit }, id) {
rootState.api.backendInteractor.fetchEmojiReactions({ id }).then(
return rootState.api.backendInteractor.fetchEmojiReactions({ id }).then(
emojiReactions => {
commit('addEmojiReactionsBy', { id, emojiReactions, currentUser: rootState.users.currentUser })
}

View File

@ -195,9 +195,15 @@ export const mutations = {
state.currentUser.blockIds.push(blockId)
}
},
setBlockIdsMaxId (state, blockIdsMaxId) {
state.currentUser.blockIdsMaxId = blockIdsMaxId
},
saveMuteIds (state, muteIds) {
state.currentUser.muteIds = muteIds
},
setMuteIdsMaxId (state, muteIdsMaxId) {
state.currentUser.muteIdsMaxId = muteIdsMaxId
},
addMuteId (state, muteId) {
if (state.currentUser.muteIds.indexOf(muteId) === -1) {
state.currentUser.muteIds.push(muteId)
@ -320,10 +326,20 @@ const users = {
.then((inLists) => store.commit('updateUserInLists', { id, inLists }))
}
},
fetchBlocks (store) {
return store.rootState.api.backendInteractor.fetchBlocks()
fetchBlocks (store, args) {
const { reset } = args || {}
const maxId = store.state.currentUser.blockIdsMaxId
return store.rootState.api.backendInteractor.fetchBlocks({ maxId })
.then((blocks) => {
if (reset) {
store.commit('saveBlockIds', map(blocks, 'id'))
} else {
map(blocks, 'id').map(id => store.commit('addBlockId', id))
}
if (blocks.length) {
store.commit('setBlockIdsMaxId', last(blocks).id)
}
store.commit('addNewUsers', blocks)
return blocks
})
@ -346,10 +362,20 @@ const users = {
editUserNote (store, args) {
return editUserNote(store, args)
},
fetchMutes (store) {
return store.rootState.api.backendInteractor.fetchMutes()
fetchMutes (store, args) {
const { reset } = args || {}
const maxId = store.state.currentUser.muteIdsMaxId
return store.rootState.api.backendInteractor.fetchMutes({ maxId })
.then((mutes) => {
if (reset) {
store.commit('saveMuteIds', map(mutes, 'id'))
} else {
map(mutes, 'id').map(id => store.commit('addMuteId', id))
}
if (mutes.length) {
store.commit('setMuteIdsMaxId', last(mutes).id)
}
store.commit('addNewUsers', mutes)
return mutes
})
@ -551,6 +577,7 @@ const users = {
loginUser (store, accessToken) {
return new Promise((resolve, reject) => {
const commit = store.commit
const dispatch = store.dispatch
commit('beginLogin')
store.rootState.api.backendInteractor.verifyCredentials(accessToken)
.then((data) => {
@ -565,57 +592,57 @@ const users = {
commit('setServerSideStorage', user)
commit('addNewUsers', [user])
store.dispatch('fetchEmoji')
dispatch('fetchEmoji')
getNotificationPermission()
.then(permission => commit('setNotificationPermission', permission))
// Set our new backend interactor
commit('setBackendInteractor', backendInteractorService(accessToken))
store.dispatch('pushServerSideStorage')
dispatch('pushServerSideStorage')
if (user.token) {
store.dispatch('setWsToken', user.token)
dispatch('setWsToken', user.token)
// Initialize the shout socket.
store.dispatch('initializeSocket')
dispatch('initializeSocket')
}
const startPolling = () => {
// Start getting fresh posts.
store.dispatch('startFetchingTimeline', { timeline: 'friends' })
dispatch('startFetchingTimeline', { timeline: 'friends' })
// Start fetching notifications
store.dispatch('startFetchingNotifications')
dispatch('startFetchingNotifications')
// Start fetching chats
store.dispatch('startFetchingChats')
dispatch('startFetchingChats')
}
store.dispatch('startFetchingLists')
dispatch('startFetchingLists')
if (user.locked) {
store.dispatch('startFetchingFollowRequests')
dispatch('startFetchingFollowRequests')
}
if (store.getters.mergedConfig.useStreamingApi) {
store.dispatch('fetchTimeline', { timeline: 'friends', since: null })
store.dispatch('fetchNotifications', { since: null })
store.dispatch('enableMastoSockets', true).catch((error) => {
dispatch('fetchTimeline', { timeline: 'friends', since: null })
dispatch('fetchNotifications', { since: null })
dispatch('enableMastoSockets', true).catch((error) => {
console.error('Failed initializing MastoAPI Streaming socket', error)
}).then(() => {
store.dispatch('fetchChats', { latest: true })
setTimeout(() => store.dispatch('setNotificationsSilence', false), 10000)
dispatch('fetchChats', { latest: true })
setTimeout(() => dispatch('setNotificationsSilence', false), 10000)
})
} else {
startPolling()
}
// Get user mutes
store.dispatch('fetchMutes')
dispatch('fetchMutes')
store.dispatch('setLayoutWidth', windowWidth())
store.dispatch('setLayoutHeight', windowHeight())
dispatch('setLayoutWidth', windowWidth())
dispatch('setLayoutHeight', windowHeight())
// Fetch our friends
store.rootState.api.backendInteractor.fetchFriends({ id: user.id })

View File

@ -108,6 +108,11 @@ const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements'
const PLEROMA_EDIT_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}`
const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}`
const PLEROMA_ADMIN_CONFIG_URL = '/api/pleroma/admin/config'
const PLEROMA_ADMIN_DESCRIPTIONS_URL = '/api/pleroma/admin/config/descriptions'
const PLEROMA_ADMIN_FRONTENDS_URL = '/api/pleroma/admin/frontends'
const PLEROMA_ADMIN_FRONTENDS_INSTALL_URL = '/api/pleroma/admin/frontends/install'
const oldfetch = window.fetch
const fetch = (url, options) => {
@ -923,8 +928,9 @@ const editStatus = ({
}
const deleteStatus = ({ id, credentials }) => {
return fetch(MASTODON_DELETE_URL(id), {
headers: authHeaders(credentials),
return promisedRequest({
url: MASTODON_DELETE_URL(id),
credentials,
method: 'DELETE'
})
}
@ -1113,8 +1119,12 @@ const generateMfaBackupCodes = ({ credentials }) => {
}).then((data) => data.json())
}
const fetchMutes = ({ credentials }) => {
return promisedRequest({ url: MASTODON_USER_MUTES_URL, credentials })
const fetchMutes = ({ maxId, credentials }) => {
const query = new URLSearchParams({ with_relationships: true })
if (maxId) {
query.append('max_id', maxId)
}
return promisedRequest({ url: `${MASTODON_USER_MUTES_URL}?${query.toString()}`, credentials })
.then((users) => users.map(parseUser))
}
@ -1138,8 +1148,12 @@ const unsubscribeUser = ({ id, credentials }) => {
return promisedRequest({ url: MASTODON_UNSUBSCRIBE_USER(id), credentials, method: 'POST' })
}
const fetchBlocks = ({ credentials }) => {
return promisedRequest({ url: MASTODON_USER_BLOCKS_URL, credentials })
const fetchBlocks = ({ maxId, credentials }) => {
const query = new URLSearchParams({ with_relationships: true })
if (maxId) {
query.append('max_id', maxId)
}
return promisedRequest({ url: `${MASTODON_USER_BLOCKS_URL}?${query.toString()}`, credentials })
.then((users) => users.map(parseUser))
}
@ -1659,6 +1673,94 @@ const setReportState = ({ id, state, credentials }) => {
})
}
// ADMIN STUFF // EXPERIMENTAL
const fetchInstanceDBConfig = ({ credentials }) => {
return fetch(PLEROMA_ADMIN_CONFIG_URL, {
headers: authHeaders(credentials)
})
.then((response) => {
if (response.ok) {
return response.json()
} else {
return {
error: response
}
}
})
}
const fetchInstanceConfigDescriptions = ({ credentials }) => {
return fetch(PLEROMA_ADMIN_DESCRIPTIONS_URL, {
headers: authHeaders(credentials)
})
.then((response) => {
if (response.ok) {
return response.json()
} else {
return {
error: response
}
}
})
}
const fetchAvailableFrontends = ({ credentials }) => {
return fetch(PLEROMA_ADMIN_FRONTENDS_URL, {
headers: authHeaders(credentials)
})
.then((response) => {
if (response.ok) {
return response.json()
} else {
return {
error: response
}
}
})
}
const pushInstanceDBConfig = ({ credentials, payload }) => {
return fetch(PLEROMA_ADMIN_CONFIG_URL, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...authHeaders(credentials)
},
method: 'POST',
body: JSON.stringify(payload)
})
.then((response) => {
if (response.ok) {
return response.json()
} else {
return {
error: response
}
}
})
}
const installFrontend = ({ credentials, payload }) => {
return fetch(PLEROMA_ADMIN_FRONTENDS_INSTALL_URL, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...authHeaders(credentials)
},
method: 'POST',
body: JSON.stringify(payload)
})
.then((response) => {
if (response.ok) {
return response.json()
} else {
return {
error: response
}
}
})
}
const apiService = {
verifyCredentials,
fetchTimeline,
@ -1772,7 +1874,12 @@ const apiService = {
postAnnouncement,
editAnnouncement,
deleteAnnouncement,
adminFetchAnnouncements
adminFetchAnnouncements,
fetchInstanceDBConfig,
fetchInstanceConfigDescriptions,
fetchAvailableFrontends,
pushInstanceDBConfig,
installFrontend
}
export default apiService

View File

@ -1,7 +1,7 @@
// TODO this func might as well take the entire file and use its mimetype
// or the entire service could be just mimetype service that only operates
// on mimetypes and not files. Currently the naming is confusing.
const fileType = mimetype => {
export const fileType = mimetype => {
if (mimetype.match(/flash/)) {
return 'flash'
}
@ -25,11 +25,25 @@ const fileType = mimetype => {
return 'unknown'
}
const fileMatchesSomeType = (types, file) =>
export const fileTypeExt = url => {
if (url.match(/\.(png|jpe?g|gif|webp|avif)$/)) {
return 'image'
}
if (url.match(/\.(ogv|mp4|webm|mov)$/)) {
return 'video'
}
if (url.match(/\.(it|s3m|mod|umx|mp3|aac|m4a|flac|alac|ogg|oga|opus|wav|ape|midi?)$/)) {
return 'audio'
}
return 'unknown'
}
export const fileMatchesSomeType = (types, file) =>
types.some(type => fileType(file.mimetype) === type)
const fileTypeService = {
fileType,
fileTypeExt,
fileMatchesSomeType
}

View File

@ -5,7 +5,7 @@
* @return {String} - tagname, i.e. "div"
*/
export const getTagName = (tag) => {
const result = /(?:<\/(\w+)>|<(\w+)\s?.*?\/?>)/gi.exec(tag)
const result = /(?:<\/(\w+)>|<(\w+)\s?.*?\/?>)/gis.exec(tag)
return result && (result[1] || result[2])
}

View File

@ -19,6 +19,7 @@ const internalToBackendLocaleMulti = codes => {
const getLanguageName = (code) => {
const specialLanguageNames = {
ja_easy: 'やさしいにほんご',
'nan-TW': '臺語(閩南語)',
zh: '简体中文',
zh_Hant: '繁體中文'
}

18
tools/check-changelog Normal file
View File

@ -0,0 +1,18 @@
#!/bin/sh
echo "looking for change log"
git remote add upstream https://git.pleroma.social/pleroma/pleroma-fe.git
git fetch upstream ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}:refs/remotes/upstream/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
git diff --raw --no-renames upstream/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME HEAD -- changelog.d | \
grep ' A\t' | grep '\.\(skip\|add\|remove\|fix\|security\)$'
ret=$?
if [ $ret -eq 0 ]; then
echo "found a changelog entry"
exit 0
else
echo "changelog entry not found"
exit 1
fi

536
yarn.lock
View File

@ -60,26 +60,26 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.5.tgz#86f172690b093373a933223b4745deeb6049e733"
integrity sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==
"@babel/compat-data@^7.21.4":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.4.tgz#457ffe647c480dff59c2be092fc3acf71195c87f"
integrity sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==
"@babel/compat-data@^7.21.5":
version "7.21.7"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.7.tgz#61caffb60776e49a57ba61a88f02bedd8714f6bc"
integrity sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==
"@babel/core@7.21.4":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.4.tgz#c6dc73242507b8e2a27fd13a9c1814f9fa34a659"
integrity sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==
"@babel/core@7.21.8":
version "7.21.8"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.8.tgz#2a8c7f0f53d60100ba4c32470ba0281c92aa9aa4"
integrity sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==
dependencies:
"@ampproject/remapping" "^2.2.0"
"@babel/code-frame" "^7.21.4"
"@babel/generator" "^7.21.4"
"@babel/helper-compilation-targets" "^7.21.4"
"@babel/helper-module-transforms" "^7.21.2"
"@babel/helpers" "^7.21.0"
"@babel/parser" "^7.21.4"
"@babel/generator" "^7.21.5"
"@babel/helper-compilation-targets" "^7.21.5"
"@babel/helper-module-transforms" "^7.21.5"
"@babel/helpers" "^7.21.5"
"@babel/parser" "^7.21.8"
"@babel/template" "^7.20.7"
"@babel/traverse" "^7.21.4"
"@babel/types" "^7.21.4"
"@babel/traverse" "^7.21.5"
"@babel/types" "^7.21.5"
convert-source-map "^1.7.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
@ -107,10 +107,10 @@
json5 "^2.2.1"
semver "^6.3.0"
"@babel/eslint-parser@7.21.3":
version "7.21.3"
resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.21.3.tgz#d79e822050f2de65d7f368a076846e7184234af7"
integrity sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==
"@babel/eslint-parser@7.21.8":
version "7.21.8"
resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz#59fb6fc4f3b017ab86987c076226ceef7b2b2ef2"
integrity sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==
dependencies:
"@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1"
eslint-visitor-keys "^2.1.0"
@ -161,16 +161,6 @@
"@jridgewell/gen-mapping" "^0.3.2"
jsesc "^2.5.1"
"@babel/generator@^7.21.0":
version "7.21.1"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.1.tgz#951cc626057bc0af2c35cd23e9c64d384dea83dd"
integrity sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==
dependencies:
"@babel/types" "^7.21.0"
"@jridgewell/gen-mapping" "^0.3.2"
"@jridgewell/trace-mapping" "^0.3.17"
jsesc "^2.5.1"
"@babel/generator@^7.21.4":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.4.tgz#64a94b7448989f421f919d5239ef553b37bb26bc"
@ -181,6 +171,16 @@
"@jridgewell/trace-mapping" "^0.3.17"
jsesc "^2.5.1"
"@babel/generator@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.5.tgz#c0c0e5449504c7b7de8236d99338c3e2a340745f"
integrity sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==
dependencies:
"@babel/types" "^7.21.5"
"@jridgewell/gen-mapping" "^0.3.2"
"@jridgewell/trace-mapping" "^0.3.17"
jsesc "^2.5.1"
"@babel/helper-annotate-as-pure@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862"
@ -224,12 +224,12 @@
lru-cache "^5.1.1"
semver "^6.3.0"
"@babel/helper-compilation-targets@^7.21.4":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz#770cd1ce0889097ceacb99418ee6934ef0572656"
integrity sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==
"@babel/helper-compilation-targets@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz#631e6cc784c7b660417421349aac304c94115366"
integrity sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==
dependencies:
"@babel/compat-data" "^7.21.4"
"@babel/compat-data" "^7.21.5"
"@babel/helper-validator-option" "^7.21.0"
browserslist "^4.21.3"
lru-cache "^5.1.1"
@ -315,6 +315,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
"@babel/helper-environment-visitor@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz#c769afefd41d171836f7cb63e295bedf689d48ba"
integrity sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==
"@babel/helper-explode-assignable-expression@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096"
@ -460,7 +465,7 @@
"@babel/traverse" "^7.18.9"
"@babel/types" "^7.18.9"
"@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.2":
"@babel/helper-module-transforms@^7.20.11":
version "7.21.2"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz#160caafa4978ac8c00ac66636cb0fa37b024e2d2"
integrity sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==
@ -474,6 +479,20 @@
"@babel/traverse" "^7.21.2"
"@babel/types" "^7.21.2"
"@babel/helper-module-transforms@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz#d937c82e9af68d31ab49039136a222b17ac0b420"
integrity sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==
dependencies:
"@babel/helper-environment-visitor" "^7.21.5"
"@babel/helper-module-imports" "^7.21.4"
"@babel/helper-simple-access" "^7.21.5"
"@babel/helper-split-export-declaration" "^7.18.6"
"@babel/helper-validator-identifier" "^7.19.1"
"@babel/template" "^7.20.7"
"@babel/traverse" "^7.21.5"
"@babel/types" "^7.21.5"
"@babel/helper-optimise-call-expression@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe"
@ -511,6 +530,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629"
integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==
"@babel/helper-plugin-utils@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz#345f2377d05a720a4e5ecfa39cbf4474a4daed56"
integrity sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==
"@babel/helper-remap-async-to-generator@^7.18.9":
version "7.18.9"
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519"
@ -558,6 +582,13 @@
dependencies:
"@babel/types" "^7.20.2"
"@babel/helper-simple-access@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz#d697a7971a5c39eac32c7e63c0921c06c8a249ee"
integrity sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==
dependencies:
"@babel/types" "^7.21.5"
"@babel/helper-skip-transparent-expression-wrappers@^7.20.0":
version "7.20.0"
resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684"
@ -589,6 +620,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63"
integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==
"@babel/helper-string-parser@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz#2b3eea65443c6bdc31c22d037c65f6d323b6b2bd"
integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==
"@babel/helper-validator-identifier@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad"
@ -633,14 +669,14 @@
"@babel/traverse" "^7.18.9"
"@babel/types" "^7.18.9"
"@babel/helpers@^7.21.0":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e"
integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==
"@babel/helpers@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.5.tgz#5bac66e084d7a4d2d9696bdf0175a93f7fb63c08"
integrity sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==
dependencies:
"@babel/template" "^7.20.7"
"@babel/traverse" "^7.21.0"
"@babel/types" "^7.21.0"
"@babel/traverse" "^7.21.5"
"@babel/types" "^7.21.5"
"@babel/highlight@^7.0.0":
version "7.0.0"
@ -703,16 +739,16 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b"
integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==
"@babel/parser@^7.21.0":
version "7.21.1"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.1.tgz#a8f81ee2fe872af23faea4b17a08fcc869de7bcc"
integrity sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg==
"@babel/parser@^7.21.4":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.4.tgz#94003fdfc520bbe2875d4ae557b43ddb6d880f17"
integrity sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==
"@babel/parser@^7.21.5", "@babel/parser@^7.21.8":
version "7.21.8"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.8.tgz#642af7d0333eab9c0ad70b14ac5e76dbde7bfdf8"
integrity sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2"
@ -908,6 +944,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.19.0"
"@babel/plugin-syntax-import-meta@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51"
integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==
dependencies:
"@babel/helper-plugin-utils" "^7.10.4"
"@babel/plugin-syntax-json-strings@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a"
@ -978,12 +1021,12 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-transform-arrow-functions@^7.20.7":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz#bea332b0e8b2dab3dafe55a163d8227531ab0551"
integrity sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==
"@babel/plugin-transform-arrow-functions@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.21.5.tgz#9bb42a53de447936a57ba256fbf537fc312b6929"
integrity sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA==
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/helper-plugin-utils" "^7.21.5"
"@babel/plugin-transform-async-to-generator@^7.20.7":
version "7.20.7"
@ -1023,12 +1066,12 @@
"@babel/helper-split-export-declaration" "^7.18.6"
globals "^11.1.0"
"@babel/plugin-transform-computed-properties@^7.20.7":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz#704cc2fd155d1c996551db8276d55b9d46e4d0aa"
integrity sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==
"@babel/plugin-transform-computed-properties@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.21.5.tgz#3a2d8bb771cd2ef1cd736435f6552fe502e11b44"
integrity sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q==
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/helper-plugin-utils" "^7.21.5"
"@babel/template" "^7.20.7"
"@babel/plugin-transform-destructuring@^7.21.3":
@ -1069,12 +1112,12 @@
"@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6"
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-transform-for-of@^7.21.0":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz#964108c9988de1a60b4be2354a7d7e245f36e86e"
integrity sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==
"@babel/plugin-transform-for-of@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz#e890032b535f5a2e237a18535f56a9fdaa7b83fc"
integrity sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ==
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/helper-plugin-utils" "^7.21.5"
"@babel/plugin-transform-function-name@^7.18.9":
version "7.18.9"
@ -1107,14 +1150,14 @@
"@babel/helper-module-transforms" "^7.20.11"
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/plugin-transform-modules-commonjs@^7.21.2":
version "7.21.2"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz#6ff5070e71e3192ef2b7e39820a06fb78e3058e7"
integrity sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==
"@babel/plugin-transform-modules-commonjs@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.5.tgz#d69fb947eed51af91de82e4708f676864e5e47bc"
integrity sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ==
dependencies:
"@babel/helper-module-transforms" "^7.21.2"
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/helper-simple-access" "^7.20.2"
"@babel/helper-module-transforms" "^7.21.5"
"@babel/helper-plugin-utils" "^7.21.5"
"@babel/helper-simple-access" "^7.21.5"
"@babel/plugin-transform-modules-systemjs@^7.20.11":
version "7.20.11"
@ -1178,12 +1221,12 @@
dependencies:
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-transform-regenerator@^7.20.5":
version "7.20.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz#57cda588c7ffb7f4f8483cc83bdcea02a907f04d"
integrity sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==
"@babel/plugin-transform-regenerator@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz#576c62f9923f94bcb1c855adc53561fd7913724e"
integrity sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w==
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/helper-plugin-utils" "^7.21.5"
regenerator-transform "^0.15.1"
"@babel/plugin-transform-reserved-words@^7.18.6":
@ -1241,12 +1284,12 @@
dependencies:
"@babel/helper-plugin-utils" "^7.18.9"
"@babel/plugin-transform-unicode-escapes@^7.18.10":
version "7.18.10"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246"
integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==
"@babel/plugin-transform-unicode-escapes@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.21.5.tgz#1e55ed6195259b0e9061d81f5ef45a9b009fb7f2"
integrity sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg==
dependencies:
"@babel/helper-plugin-utils" "^7.18.9"
"@babel/helper-plugin-utils" "^7.21.5"
"@babel/plugin-transform-unicode-regex@^7.18.6":
version "7.18.6"
@ -1256,14 +1299,14 @@
"@babel/helper-create-regexp-features-plugin" "^7.18.6"
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/preset-env@7.21.4":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.21.4.tgz#a952482e634a8dd8271a3fe5459a16eb10739c58"
integrity sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==
"@babel/preset-env@7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.21.5.tgz#db2089d99efd2297716f018aeead815ac3decffb"
integrity sha512-wH00QnTTldTbf/IefEVyChtRdw5RJvODT/Vb4Vcxq1AZvtXj6T0YeX0cAcXhI6/BdGuiP3GcNIL4OQbI2DVNxg==
dependencies:
"@babel/compat-data" "^7.21.4"
"@babel/helper-compilation-targets" "^7.21.4"
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/compat-data" "^7.21.5"
"@babel/helper-compilation-targets" "^7.21.5"
"@babel/helper-plugin-utils" "^7.21.5"
"@babel/helper-validator-option" "^7.21.0"
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6"
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.20.7"
@ -1288,6 +1331,7 @@
"@babel/plugin-syntax-dynamic-import" "^7.8.3"
"@babel/plugin-syntax-export-namespace-from" "^7.8.3"
"@babel/plugin-syntax-import-assertions" "^7.20.0"
"@babel/plugin-syntax-import-meta" "^7.10.4"
"@babel/plugin-syntax-json-strings" "^7.8.3"
"@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
@ -1297,22 +1341,22 @@
"@babel/plugin-syntax-optional-chaining" "^7.8.3"
"@babel/plugin-syntax-private-property-in-object" "^7.14.5"
"@babel/plugin-syntax-top-level-await" "^7.14.5"
"@babel/plugin-transform-arrow-functions" "^7.20.7"
"@babel/plugin-transform-arrow-functions" "^7.21.5"
"@babel/plugin-transform-async-to-generator" "^7.20.7"
"@babel/plugin-transform-block-scoped-functions" "^7.18.6"
"@babel/plugin-transform-block-scoping" "^7.21.0"
"@babel/plugin-transform-classes" "^7.21.0"
"@babel/plugin-transform-computed-properties" "^7.20.7"
"@babel/plugin-transform-computed-properties" "^7.21.5"
"@babel/plugin-transform-destructuring" "^7.21.3"
"@babel/plugin-transform-dotall-regex" "^7.18.6"
"@babel/plugin-transform-duplicate-keys" "^7.18.9"
"@babel/plugin-transform-exponentiation-operator" "^7.18.6"
"@babel/plugin-transform-for-of" "^7.21.0"
"@babel/plugin-transform-for-of" "^7.21.5"
"@babel/plugin-transform-function-name" "^7.18.9"
"@babel/plugin-transform-literals" "^7.18.9"
"@babel/plugin-transform-member-expression-literals" "^7.18.6"
"@babel/plugin-transform-modules-amd" "^7.20.11"
"@babel/plugin-transform-modules-commonjs" "^7.21.2"
"@babel/plugin-transform-modules-commonjs" "^7.21.5"
"@babel/plugin-transform-modules-systemjs" "^7.20.11"
"@babel/plugin-transform-modules-umd" "^7.18.6"
"@babel/plugin-transform-named-capturing-groups-regex" "^7.20.5"
@ -1320,17 +1364,17 @@
"@babel/plugin-transform-object-super" "^7.18.6"
"@babel/plugin-transform-parameters" "^7.21.3"
"@babel/plugin-transform-property-literals" "^7.18.6"
"@babel/plugin-transform-regenerator" "^7.20.5"
"@babel/plugin-transform-regenerator" "^7.21.5"
"@babel/plugin-transform-reserved-words" "^7.18.6"
"@babel/plugin-transform-shorthand-properties" "^7.18.6"
"@babel/plugin-transform-spread" "^7.20.7"
"@babel/plugin-transform-sticky-regex" "^7.18.6"
"@babel/plugin-transform-template-literals" "^7.18.9"
"@babel/plugin-transform-typeof-symbol" "^7.18.9"
"@babel/plugin-transform-unicode-escapes" "^7.18.10"
"@babel/plugin-transform-unicode-escapes" "^7.21.5"
"@babel/plugin-transform-unicode-regex" "^7.18.6"
"@babel/preset-modules" "^0.1.5"
"@babel/types" "^7.21.4"
"@babel/types" "^7.21.5"
babel-plugin-polyfill-corejs2 "^0.3.3"
babel-plugin-polyfill-corejs3 "^0.6.0"
babel-plugin-polyfill-regenerator "^0.4.1"
@ -1364,10 +1408,10 @@
resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
"@babel/runtime@7.21.0":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
"@babel/runtime@7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200"
integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==
dependencies:
regenerator-runtime "^0.13.11"
@ -1494,23 +1538,7 @@
debug "^4.1.0"
globals "^11.1.0"
"@babel/traverse@^7.21.0":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.0.tgz#0e1807abd5db98e6a19c204b80ed1e3f5bca0edc"
integrity sha512-Xdt2P1H4LKTO8ApPfnO1KmzYMFpp7D/EinoXzLYN/cHcBNrVCAkAtGUcXnHXrl/VGktureU6fkQrHSBE2URfoA==
dependencies:
"@babel/code-frame" "^7.18.6"
"@babel/generator" "^7.21.0"
"@babel/helper-environment-visitor" "^7.18.9"
"@babel/helper-function-name" "^7.21.0"
"@babel/helper-hoist-variables" "^7.18.6"
"@babel/helper-split-export-declaration" "^7.18.6"
"@babel/parser" "^7.21.0"
"@babel/types" "^7.21.0"
debug "^4.1.0"
globals "^11.1.0"
"@babel/traverse@^7.21.2", "@babel/traverse@^7.21.4":
"@babel/traverse@^7.21.2":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.4.tgz#a836aca7b116634e97a6ed99976236b3282c9d36"
integrity sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==
@ -1526,6 +1554,22 @@
debug "^4.1.0"
globals "^11.1.0"
"@babel/traverse@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.5.tgz#ad22361d352a5154b498299d523cf72998a4b133"
integrity sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==
dependencies:
"@babel/code-frame" "^7.21.4"
"@babel/generator" "^7.21.5"
"@babel/helper-environment-visitor" "^7.21.5"
"@babel/helper-function-name" "^7.21.0"
"@babel/helper-hoist-variables" "^7.18.6"
"@babel/helper-split-export-declaration" "^7.18.6"
"@babel/parser" "^7.21.5"
"@babel/types" "^7.21.5"
debug "^4.1.0"
globals "^11.1.0"
"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.2.tgz#44e10fc24e33af524488b716cdaee5360ea8ed1e"
@ -1603,6 +1647,15 @@
"@babel/helper-validator-identifier" "^7.19.1"
to-fast-properties "^2.0.0"
"@babel/types@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.5.tgz#18dfbd47c39d3904d5db3d3dc2cc80bedb60e5b6"
integrity sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==
dependencies:
"@babel/helper-string-parser" "^7.21.5"
"@babel/helper-validator-identifier" "^7.19.1"
to-fast-properties "^2.0.0"
"@babel/types@^7.7.4":
version "7.7.4"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.4.tgz#516570d539e44ddf308c07569c258ff94fde9193"
@ -1642,31 +1695,31 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@fortawesome/fontawesome-common-types@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz#51f734e64511dbc3674cd347044d02f4dd26e86b"
integrity sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg==
"@fortawesome/fontawesome-common-types@6.4.0":
version "6.4.0"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.0.tgz#88da2b70d6ca18aaa6ed3687832e11f39e80624b"
integrity sha512-HNii132xfomg5QVZw0HwXXpN22s7VBHQBv9CeOu9tfJnhsWQNd2lmTNi8CSrnw5B+5YOmzu1UoPAyxaXsJ6RgQ==
"@fortawesome/fontawesome-svg-core@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.3.0.tgz#b6a17d48d231ac1fad93e43fca7271676bf316cf"
integrity sha512-uz9YifyKlixV6AcKlOX8WNdtF7l6nakGyLYxYaCa823bEBqyj/U2ssqtctO38itNEwXb8/lMzjdoJ+aaJuOdrw==
"@fortawesome/fontawesome-svg-core@6.4.0":
version "6.4.0"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.0.tgz#3727552eff9179506e9203d72feb5b1063c11a21"
integrity sha512-Bertv8xOiVELz5raB2FlXDPKt+m94MQ3JgDfsVbrqNpLU9+UE2E18GKjLKw+d3XbeYPqg1pzyQKGsrzbw+pPaw==
dependencies:
"@fortawesome/fontawesome-common-types" "6.3.0"
"@fortawesome/fontawesome-common-types" "6.4.0"
"@fortawesome/free-regular-svg-icons@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.3.0.tgz#286f87f777e6c96af59151e86647c81083029ee2"
integrity sha512-cZnwiVHZ51SVzWHOaNCIA+u9wevZjCuAGSvSYpNlm6A4H4Vhwh8481Bf/5rwheIC3fFKlgXxLKaw8Xeroz8Ntg==
"@fortawesome/free-regular-svg-icons@6.4.0":
version "6.4.0"
resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.0.tgz#cacc53bd8d832d46feead412d9ea9ce80a55e13a"
integrity sha512-ZfycI7D0KWPZtf7wtMFnQxs8qjBXArRzczABuMQqecA/nXohquJ5J/RCR77PmY5qGWkxAZDxpnUFVXKwtY/jPw==
dependencies:
"@fortawesome/fontawesome-common-types" "6.3.0"
"@fortawesome/fontawesome-common-types" "6.4.0"
"@fortawesome/free-solid-svg-icons@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.3.0.tgz#d3bd33ae18bb15fdfc3ca136e2fea05f32768a65"
integrity sha512-x5tMwzF2lTH8pyv8yeZRodItP2IVlzzmBuD1M7BjawWgg9XAvktqJJ91Qjgoaf8qJpHQ8FEU9VxRfOkLhh86QA==
"@fortawesome/free-solid-svg-icons@6.4.0":
version "6.4.0"
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.0.tgz#48c0e790847fa56299e2f26b82b39663b8ad7119"
integrity sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ==
dependencies:
"@fortawesome/fontawesome-common-types" "6.3.0"
"@fortawesome/fontawesome-common-types" "6.4.0"
"@fortawesome/vue-fontawesome@3.0.3":
version "3.0.3"
@ -1902,10 +1955,10 @@
pathval "1.1.1"
type-detect "4.0.8"
"@nightwatch/html-reporter-template@0.1.4":
version "0.1.4"
resolved "https://registry.yarnpkg.com/@nightwatch/html-reporter-template/-/html-reporter-template-0.1.4.tgz#c70db1a13bb2e7e1932e6b10ac1e022e61177c94"
integrity sha512-fVylXypRuNJbyFAwY/5H2QM1A1XVoZWis0zhiMwA5LQN0cxHzpG2aUheb+qP1EfkxhFxwSUHOcrvphFLbPA8ow==
"@nightwatch/html-reporter-template@0.2.1":
version "0.2.1"
resolved "https://registry.yarnpkg.com/@nightwatch/html-reporter-template/-/html-reporter-template-0.2.1.tgz#9fa86e8cab6ee703d2e55b47abac92613f97a298"
integrity sha512-GEBeGoXVmTYPtNC4Yq34vfgxf6mlFyEagxpsfH18Qe5BvctF2rprX+wI5dKBm9p5IqHo6ZOcXHCufOeP3cjuOw==
"@nodelib/fs.scandir@2.1.3":
version "2.1.3"
@ -1959,13 +2012,6 @@
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f"
integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==
"@sinonjs/commons@^1.7.0":
version "1.8.3"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==
dependencies:
type-detect "4.0.8"
"@sinonjs/commons@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3"
@ -1973,24 +2019,24 @@
dependencies:
type-detect "4.0.8"
"@sinonjs/fake-timers@10.0.2":
"@sinonjs/commons@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72"
integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==
dependencies:
type-detect "4.0.8"
"@sinonjs/fake-timers@^10.0.2":
version "10.0.2"
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c"
integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==
dependencies:
"@sinonjs/commons" "^2.0.0"
"@sinonjs/fake-timers@^7.0.4":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5"
integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==
dependencies:
"@sinonjs/commons" "^1.7.0"
"@sinonjs/samsam@^7.0.1":
version "7.0.1"
resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-7.0.1.tgz#5b5fa31c554636f78308439d220986b9523fc51f"
integrity sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==
"@sinonjs/samsam@^8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-8.0.0.tgz#0d488c91efb3fa1442e26abea81759dfc8b5ac60"
integrity sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==
dependencies:
"@sinonjs/commons" "^2.0.0"
lodash.get "^4.4.2"
@ -2299,10 +2345,10 @@
dependencies:
js-beautify "1.14.6"
"@vuelidate/core@2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@vuelidate/core/-/core-2.0.0.tgz#dfe73ba3f997646e07bd4da4f327fe53c29782cb"
integrity sha512-xIFgdQlScO0aaSZ0wTGPJh8YcTMNAj5veI8yPgiAyxOT+GV7vNQFiU1vpYWCL4cklkkhYvRRSC2OEX7YOZNmPQ==
"@vuelidate/core@2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@vuelidate/core/-/core-2.0.2.tgz#e874afc830ccc5295e83a0c0a0f0621e084348c9"
integrity sha512-aG1OZWv6xVws3ljyKy/pyxq1rdZZ2ryj+FEREcC9d4GP4qOvNHHZUl/NQxa0Bck3Ooc0RfXU8vwCA9piRoWy6w==
dependencies:
vue-demi "^0.13.11"
@ -2699,13 +2745,13 @@ asynckit@^0.4.0:
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
autoprefixer@10.4.13:
version "10.4.13"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8"
integrity sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==
autoprefixer@10.4.14:
version "10.4.14"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d"
integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==
dependencies:
browserslist "^4.21.4"
caniuse-lite "^1.0.30001426"
browserslist "^4.21.5"
caniuse-lite "^1.0.30001464"
fraction.js "^4.2.0"
normalize-range "^0.1.2"
picocolors "^1.0.0"
@ -2929,6 +2975,16 @@ browserslist@^4.21.3, browserslist@^4.21.4:
node-releases "^2.0.6"
update-browserslist-db "^1.0.9"
browserslist@^4.21.5:
version "4.21.5"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7"
integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==
dependencies:
caniuse-lite "^1.0.30001449"
electron-to-chromium "^1.4.284"
node-releases "^2.0.8"
update-browserslist-db "^1.0.10"
buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
@ -3031,10 +3087,10 @@ caniuse-lite@^1.0.30001400:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz#5f459215192a024c99e3e3a53aac310fc7cf24e6"
integrity sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==
caniuse-lite@^1.0.30001426:
version "1.0.30001439"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz#ab7371faeb4adff4b74dad1718a6fd122e45d9cb"
integrity sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==
caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464:
version "1.0.30001474"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001474.tgz#13b6fe301a831fe666cce8ca4ef89352334133d5"
integrity sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q==
chai-nightwatch@0.5.3:
version "0.5.3"
@ -3744,7 +3800,7 @@ diff@5.0.0:
resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==
diff@^5.0.0:
diff@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40"
integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==
@ -3902,6 +3958,11 @@ electron-to-chromium@^1.4.251:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.276.tgz#17837b19dafcc43aba885c4689358b298c19b520"
integrity sha512-EpuHPqu8YhonqLBXHoU6hDJCD98FCe6KDoet3/gY1qsQ6usjJoHqBH2YIVs8FXaAtHwVL8Uqa/fsYao/vq9VWQ==
electron-to-chromium@^1.4.284:
version "1.4.353"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.353.tgz#20e9cb4c83a08e35b3314d3fa8988764c105e6b7"
integrity sha512-IdJVpMHJoBT/nn0GQ02wPfbhogDVpd1ud95lP//FTf5l35wzxKJwibB4HBdY7Q+xKPA1nkZ0UDLOMyRj5U5IAQ==
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
@ -5044,10 +5105,10 @@ html-tags@^3.2.0:
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961"
integrity sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==
html-webpack-plugin@5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50"
integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==
html-webpack-plugin@5.5.1:
version "5.5.1"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz#826838e31b427f5f7f30971f8d8fa2422dfa6763"
integrity sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA==
dependencies:
"@types/html-minifier-terser" "^6.0.0"
html-minifier-terser "^6.0.2"
@ -5863,10 +5924,10 @@ karma-webpack@5.0.0:
minimatch "^3.0.4"
webpack-merge "^4.1.5"
karma@6.4.1:
version "6.4.1"
resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.1.tgz#f2253716dd3a41aaa813fa9f54b6ee047e1127d9"
integrity sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==
karma@6.4.2:
version "6.4.2"
resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.2.tgz#a983f874cee6f35990c4b2dcc3d274653714de8e"
integrity sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==
dependencies:
"@colors/colors" "1.5.0"
body-parser "^1.19.0"
@ -5902,11 +5963,16 @@ kind-of@^6.0.3:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
klona@^2.0.4, klona@^2.0.5:
klona@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc"
integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==
klona@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22"
integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==
known-css-properties@^0.26.0:
version "0.26.0"
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.26.0.tgz#008295115abddc045a9f4ed7e2a84dc8b3a77649"
@ -6457,10 +6523,10 @@ min-indent@^1.0.0:
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
mini-css-extract-plugin@2.7.2:
version "2.7.2"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz#e049d3ea7d3e4e773aad585c6cb329ce0c7b72d7"
integrity sha512-EdlUizq13o0Pd+uCp+WO/JpkLvHRVGt97RqfeGhXqAcorYo1ypJSpkV+WDT0vY/kmh/p7wRdJNJtuyK540PXDw==
mini-css-extract-plugin@2.7.5:
version "2.7.5"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.5.tgz#afbb344977659ec0f1f6e050c7aea456b121cfc5"
integrity sha512-9HaR++0mlgom81s95vvNjxkg52n2b5s//3ZTI1EtzFb98awsLSivs2LMsVqnQ3ay0PVhqWcGNyDaTE961FOcjQ==
dependencies:
schema-utils "^4.0.0"
@ -6543,10 +6609,6 @@ mkdirp@^0.5.5:
dependencies:
minimist "^1.2.5"
mkpath@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/mkpath/-/mkpath-1.0.0.tgz#ebb3a977e7af1c683ae6fda12b545a6ba6c5853d"
mocha@10.2.0:
version "10.2.0"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8"
@ -6637,6 +6699,11 @@ nanoid@^3.3.4:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
nanoid@^3.3.6:
version "3.3.6"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
@ -6662,13 +6729,13 @@ nightwatch-axe-verbose@^2.1.0:
dependencies:
axe-core "^4.6.1"
nightwatch@2.6.19:
version "2.6.19"
resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-2.6.19.tgz#2c35304eb67e06d24f982cb42cce618c617a3fcb"
integrity sha512-AxuPEWlf+MCfo4tZ0BFKkxqUIL0x/jZeFSvxV7Wwp/sBM8XmVA1rEEhNe/pCVsyjL+Q4G97rMKTonFYF/aXsBw==
nightwatch@2.6.20:
version "2.6.20"
resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-2.6.20.tgz#8c3b808f4f33699bcd67987b22e6ebeee61ddc9c"
integrity sha512-XEyxuSGhESdHj4LHqA5snrc/nMgH4tsB/mWrbyGt3EwW1AgjyE7DRzJUbhG7J00Np3Dv3k2nmyJs0Xq0FX/yvQ==
dependencies:
"@nightwatch/chai" "5.0.2"
"@nightwatch/html-reporter-template" "0.1.4"
"@nightwatch/html-reporter-template" "0.2.1"
ansi-to-html "0.7.2"
assertion-error "1.1.0"
boxen "5.1.2"
@ -6689,7 +6756,6 @@ nightwatch@2.6.19:
lodash.pick "4.4.0"
minimatch "3.1.2"
minimist "1.2.6"
mkpath "1.0.0"
mocha "9.2.2"
nightwatch-axe-verbose "^2.1.0"
open "8.4.0"
@ -6701,13 +6767,13 @@ nightwatch@2.6.19:
untildify "^4.0.0"
uuid "8.3.2"
nise@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.2.tgz#a7b8909c216b3491fd4fc0b124efb69f3939b449"
integrity sha512-+gQjFi8v+tkfCuSCxfURHLhRhniE/+IaYbIphxAN2JRR9SHKhY8hgXpaXiYfHdw+gcGe4buxgbprBQFab9FkhA==
nise@^5.1.4:
version "5.1.4"
resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.4.tgz#491ce7e7307d4ec546f5a659b2efe94a18b4bbc0"
integrity sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==
dependencies:
"@sinonjs/commons" "^2.0.0"
"@sinonjs/fake-timers" "^7.0.4"
"@sinonjs/fake-timers" "^10.0.2"
"@sinonjs/text-encoding" "^0.7.1"
just-extend "^4.0.2"
path-to-regexp "^1.7.0"
@ -6725,6 +6791,11 @@ node-releases@^2.0.5, node-releases@^2.0.6:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==
node-releases@^2.0.8:
version "2.0.10"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f"
integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==
nopt@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d"
@ -7426,12 +7497,12 @@ postcss-value-parser@^4.2.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@8.4.20, postcss@^8.4.19:
version "8.4.20"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.20.tgz#64c52f509644cecad8567e949f4081d98349dc56"
integrity sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==
postcss@8.4.23:
version "8.4.23"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab"
integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==
dependencies:
nanoid "^3.3.4"
nanoid "^3.3.6"
picocolors "^1.0.0"
source-map-js "^1.0.2"
@ -7462,6 +7533,15 @@ postcss@^8.4.17:
picocolors "^1.0.0"
source-map-js "^1.0.2"
postcss@^8.4.19:
version "8.4.20"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.20.tgz#64c52f509644cecad8567e949f4081d98349dc56"
integrity sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==
dependencies:
nanoid "^3.3.4"
picocolors "^1.0.0"
source-map-js "^1.0.2"
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@ -7929,12 +8009,12 @@ safe-regex-test@^1.0.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
sass-loader@13.2.0:
version "13.2.0"
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-13.2.0.tgz#80195050f58c9aac63b792fa52acb6f5e0f6bdc3"
integrity sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==
sass-loader@13.2.2:
version "13.2.2"
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-13.2.2.tgz#f97e803993b24012c10d7ba9676548bf7a6b18b9"
integrity sha512-nrIdVAAte3B9icfBiGWvmMhT/D+eCDwnk+yA7VE/76dp/WkHX+i44Q/pfo71NYbwj0Ap+PGsn0ekOuU1WFJ2AA==
dependencies:
klona "^2.0.4"
klona "^2.0.6"
neo-async "^2.6.2"
sass@1.60.0:
@ -8127,16 +8207,16 @@ sinon-chai@3.7.0:
resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.7.0.tgz#cfb7dec1c50990ed18c153f1840721cf13139783"
integrity sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==
sinon@15.0.1:
version "15.0.1"
resolved "https://registry.yarnpkg.com/sinon/-/sinon-15.0.1.tgz#ce062611a0b131892e2c18f03055b8eb6e8dc234"
integrity sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==
sinon@15.0.4:
version "15.0.4"
resolved "https://registry.yarnpkg.com/sinon/-/sinon-15.0.4.tgz#bcca6fef19b14feccc96473f0d7adc81e0bc5268"
integrity sha512-uzmfN6zx3GQaria1kwgWGeKiXSSbShBbue6Dcj0SI8fiCNFbiUDqKl57WFlY5lyhxZVUKmXvzgG2pilRQCBwWg==
dependencies:
"@sinonjs/commons" "^2.0.0"
"@sinonjs/fake-timers" "10.0.2"
"@sinonjs/samsam" "^7.0.1"
diff "^5.0.0"
nise "^5.1.2"
"@sinonjs/commons" "^3.0.0"
"@sinonjs/fake-timers" "^10.0.2"
"@sinonjs/samsam" "^8.0.0"
diff "^5.1.0"
nise "^5.1.4"
supports-color "^7.2.0"
slash@^3.0.0:
@ -8818,6 +8898,14 @@ untildify@^4.0.0:
resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
update-browserslist-db@^1.0.10, update-browserslist-db@^1.0.9:
version "1.0.10"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3"
integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==
dependencies:
escalade "^3.1.1"
picocolors "^1.0.0"
update-browserslist-db@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.4.tgz#dbfc5a789caa26b1db8990796c2c8ebbce304824"
@ -8834,14 +8922,6 @@ update-browserslist-db@^1.0.5:
escalade "^3.1.1"
picocolors "^1.0.0"
update-browserslist-db@^1.0.9:
version "1.0.10"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3"
integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==
dependencies:
escalade "^3.1.1"
picocolors "^1.0.0"
uri-js@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
@ -8981,9 +9061,9 @@ vue-template-compiler@2.7.14:
he "^1.2.0"
vue-virtual-scroller@^2.0.0-beta.7:
version "2.0.0-beta.7"
resolved "https://registry.yarnpkg.com/vue-virtual-scroller/-/vue-virtual-scroller-2.0.0-beta.7.tgz#4ea8158638c84b2033b001a8b26c5fcb6896b271"
integrity sha512-OrouVj1i2939jaLjVfu8f5fsDlbzhAb4bOsYZYrAkpcVLylAmMoGtIL7eT3hJrdTiaKbwQpRdnv7DKf9Fn+tHg==
version "2.0.0-beta.8"
resolved "https://registry.yarnpkg.com/vue-virtual-scroller/-/vue-virtual-scroller-2.0.0-beta.8.tgz#eeceda57e4faa5ba1763994c873923e2a956898b"
integrity sha512-b8/f5NQ5nIEBRTNi6GcPItE4s7kxNHw2AIHLtDp+2QvqdTjVN0FgONwX9cr53jWRgnu+HRLPaWDOR2JPI5MTfQ==
dependencies:
mitt "^2.1.0"
vue-observe-visibility "^2.0.0-alpha.1"