Merge remote-tracking branch 'origin/main'

This commit is contained in:
778a69cd 2023-08-03 16:43:36 +02:00
commit 496ba488b6
126 changed files with 2807 additions and 1865 deletions

4
.husky/pre-commit Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
cd js
yarn run lint-staged

View file

@ -41,3 +41,5 @@ FE1EEB91EA633570F703B251AE2D4D4E
E7967805C1EA5301F2722C7BDB2F25F3 E7967805C1EA5301F2722C7BDB2F25F3
BDFB0FB1AAF69C18212CBCFD42F8B717 BDFB0FB1AAF69C18212CBCFD42F8B717
40220A533CCACB3A1CE9DBF1A8A430A1 40220A533CCACB3A1CE9DBF1A8A430A1
EEB29D1DDA3A3015BC645A989B5BD38E
5AEE3C678C80E0389C3B0D9D11886EB6

View file

@ -5,6 +5,189 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 3.1.3 (2023-06-21)
### Bug Fixes
* **groups:** fix unauthenticated access to groups because of missing read:group:members permission ([3714925](https://framagit.org/framasoft/mobilizon/commits/3714925896ad0415496352b9901ebec199afa0f2)), closes [#1311](https://framagit.org/framasoft/mobilizon/issues/1311)
## 3.1.2 (2023-06-21)
### Bug Fixes
* **activity settings:** fix saving activity settings ([6c1e1e9](https://framagit.org/framasoft/mobilizon/commits/6c1e1e98d81c7469f41beed17cfa1d4b718b5d13)), closes [#1251](https://framagit.org/framasoft/mobilizon/issues/1251)
* **apps:** fix pruning old application device activations ([dd00620](https://framagit.org/framasoft/mobilizon/commits/dd00620b9a54b2b1356855d280e03c82befe15e4))
* **backend:** filter out nil tags before starting looking for existing ones ([f04d2b9](https://framagit.org/framasoft/mobilizon/commits/f04d2b9225b80333f03a3cc9366df4a05af88a73))
* **deps:** fix compatibility with elixir-plug/mime 2.0.5 ([d63999c](https://framagit.org/framasoft/mobilizon/commits/d63999c081bcbb5923af17b71edbfd13a3720d7d))
* **discussions:** handle changeset errors when updating discussion ([ca06ec3](https://framagit.org/framasoft/mobilizon/commits/ca06ec397fbd6848e340dfae12c635736069a9f3))
* **exports:** properly handle export format not being handled ([a76b1ca](https://framagit.org/framasoft/mobilizon/commits/a76b1ca66d776fbe4566d7f23b38b087ae32530b))
* **federation:** allow federated usernames with capitals ([d502164](https://framagit.org/framasoft/mobilizon/commits/d5021647d753e6457e459b1f992da60876292428))
* **federation:** handle fetch_actor with a map ([552ab4c](https://framagit.org/framasoft/mobilizon/commits/552ab4c80b2f99095028ab3685c71ff9efdb94eb))
* **federation:** handle string values for tags when constructing mentions ([2729d5e](https://framagit.org/framasoft/mobilizon/commits/2729d5ed7acef7c20a4388f019152e80a9db163c))
* **federation:** ignore mentions from everything that's not a AP Person ([56f341e](https://framagit.org/framasoft/mobilizon/commits/56f341e960b7ae0a5fe78d7174f0e05d14add3f2))
* **federation:** only refresh instances once a day ([6745590](https://framagit.org/framasoft/mobilizon/commits/6745590e54dce236dc7a2319f9c49c4aa6858306))
* **federation:** prevent fetching own relay actor ([b981f91](https://framagit.org/framasoft/mobilizon/commits/b981f91cf748079847ae7a71b68f98b6914c951f))
* **federation:** restrict fetch_group first arg to binaries ([e8d34b4](https://framagit.org/framasoft/mobilizon/commits/e8d34b4ea9f06d16a5982da8e5ff5140852c985d))
* **federation:** rotate relay keys on startup if missing private keys ([5381eaa](https://framagit.org/framasoft/mobilizon/commits/5381eaae22248cdc6585d19c10be7fe2b7f5709f))
* **front:** add missing title to Participants View page ([a5a86a5](https://framagit.org/framasoft/mobilizon/commits/a5a86a5e1be08cf9123ee7ad0979974bc2be1cb4))
* **front:** fix displaying user activity settings checkboxes ([8e21c30](https://framagit.org/framasoft/mobilizon/commits/8e21c30f92f47dcb742d8f7df2aed59191158d80)), closes [#1251](https://framagit.org/framasoft/mobilizon/issues/1251)
* **front:** fix wrong key name for dialog.confirm() option ([c8f49e1](https://framagit.org/framasoft/mobilizon/commits/c8f49e1837d719cd737c3e1ae976f14b20345e2b))
* **front:** fix wrong value for timezone when it has no prefix ([2dd0e13](https://framagit.org/framasoft/mobilizon/commits/2dd0e13eba8bb5c04af45bae0de059deb93c2efa)), closes [#1275](https://framagit.org/framasoft/mobilizon/issues/1275)
* **group:** fix getting group members count ([f749518](https://framagit.org/framasoft/mobilizon/commits/f749518bf7a29a86da559bfe6aba6d7485e7cfeb)), closes [#1303](https://framagit.org/framasoft/mobilizon/issues/1303)
* **participant exports:** fix participants by returning the export type as well as the file path ([49b04c9](https://framagit.org/framasoft/mobilizon/commits/49b04c9b19517daa0a07656779d53001b39ab803))
* **participant:** handle re-confirming participation ([5cc5c99](https://framagit.org/framasoft/mobilizon/commits/5cc5c9943cbc9a53246dda98958e99d004f0dfa9))
### Features
* **graphql:** validate timezone id as a GraphQL Scalar ([845bb6a](https://framagit.org/framasoft/mobilizon/commits/845bb6ac90081ef8cb4cff8d6ec3d11bfc19857c)), closes [#1299](https://framagit.org/framasoft/mobilizon/issues/1299)
## 3.1.1 (2023-06-02)
### Features
* **anti-spam:** allow to only scan for spam in profiles or events ([c971287](https://framagit.org/framasoft/mobilizon/-/commit/c971287624913c8555fe288af0df1175701e6209))
### Bug Fixes
* **front:** fix group settings getting unresponsive because of reactive bug ([f1e119c](https://framagit.org/framasoft/mobilizon/-/commit/f1e119cb7ad580dfab73de3083f20a7303822888)), closes [#1298](https://framagit.org/framasoft/mobilizon/-/issues/1298)
* **search:** fix global search sorting ([39e24c3](https://framagit.org/framasoft/mobilizon/-/commit/39e24c328a21f7058e4d2526e13eae85e39bae86)), closes [#1297](https://framagit.org/framasoft/mobilizon/-/issues/1297)
## 3.1.0 (2023-05-31)
### Features
* **API:** Allow to create apps, with permissions and both Authorization Code Flow and Device Flow
* **addresses:** Allow to enter manual addresses ([85d643d](https://framagit.org/framasoft/mobilizon/-/commit/85d643d0ecd5e7504f32953b9ed1509697b915e2))
* **docker:** Specify the folder where tzdata downloads data so that it can be used in a volume ([4bb0625](https://framagit.org/framasoft/mobilizon/-/commit/4bb062528f12be530a3754ca23c1bc6dbc862e5a)), closes [#1280](https://framagit.org/framasoft/mobilizon/-/issues/1280)
* **spam:** Introduce checking new accounts, events & comments for spam with the help of Akismet ([317a343](https://framagit.org/framasoft/mobilizon/-/commit/317a3434b221a1a91b66d8443984269404863a8e))
* **rate-limiting:** Introduce rate-limiting on some endpoints ([c07ba3a5](https://framagit.org/framasoft/mobilizon/-/commit/c07ba3a5d19c419ef8aaf3ea9ca6e7f48e4f4487))
* **front:** improve padding on event tags ([7fa452d](https://framagit.org/framasoft/mobilizon/-/commit/7fa452d9e3f9bb2443e571c9a32eaed51e32480a))
* **front:** make admin profile view linkable directly with parameters ([08ce7e2](https://framagit.org/framasoft/mobilizon/-/commit/08ce7e26b73045279261ab87a14cb4f3dab5df1e))
* **front:** make profile members link to profile on group admin view and the reverse ([96129d2](https://framagit.org/framasoft/mobilizon/-/commit/96129d2339133027220d3b5fcb1c52f84bcc5cbb))
* **front:** make profiles and group admin views default to local ([3e0324d](https://framagit.org/framasoft/mobilizon/-/commit/3e0324d36ec5a8aa388e6b5d598a6f9a0c596797))
* **front:** redirect user to homepage on disconnect when currently on private page ([d5a6df9](https://framagit.org/framasoft/mobilizon/-/commit/d5a6df9940fb458c5dbaee149015c02ebc370c6b)), closes [#1278](https://framagit.org/framasoft/mobilizon/-/issues/1278)
* **front:** show skeleton content on event view until the event is loaded ([dc3b93f](https://framagit.org/framasoft/mobilizon/-/commit/dc3b93ffb5a4b072aec792533fd6e4b58ed7a893))
* **i18n:** activate croatian language ([94182ae](https://framagit.org/framasoft/mobilizon/-/commit/94182aed2d8a22d00534f6376dfda2658bc8ba7e))
* **i18n:** activate japanese language ([6bd8034](https://framagit.org/framasoft/mobilizon/-/commit/6bd8034fe816a432c3547de6d1ad8a18e73dc314)), closes [#1293](https://framagit.org/framasoft/mobilizon/-/issues/1293)
* **post:** show post visibily in PostListItem component ([ec7ca4d](https://framagit.org/framasoft/mobilizon/-/commit/ec7ca4ddf18a38cf6f51d38b540eecc9858f3c98))
### Bug Fixes
* **global-search:** Add option values in debug log before calling global search service ([8141bb0](https://framagit.org/framasoft/mobilizon/-/commit/8141bb0acbc4eb02a917c5bc18712d0d954c4ee5))
* **apps:** Fix cleaning application data background job ([aa20f69](https://framagit.org/framasoft/mobilizon/-/commit/aa20f6991127ddee546fc0b867298c1342dbcb4d))
* **apps:** Show message when the user doesn't have approved apps yet ([e0ee9c1](https://framagit.org/framasoft/mobilizon/-/commit/e0ee9c143b0335753db5dfae19e324781d55bd4e))
* **auth:** Handle logging-in with disabled auth provider ([a22a5e3](https://framagit.org/framasoft/mobilizon/-/commit/a22a5e3cb924869e32cb9ed71dab3e03d91c018f))
* **backend:** Fix Mobilizon.Events.list_participations_for_user_query/1 ([bcf6fd8](https://framagit.org/framasoft/mobilizon/-/commit/bcf6fd893c762c12b63d7e02da43cd5c05db509b))
* **backend:** Handle CLDR data having no standard property for a language ([dbe2da7](https://framagit.org/framasoft/mobilizon/-/commit/dbe2da79c3aa1543b87dce61b5fd90195fb53afe))
* **backend:** Ignore group mentions for now ([b5f106b](https://framagit.org/framasoft/mobilizon/-/commit/b5f106b0a81fefba3203f8ec5855e834a2078222))
* **back:** Improve error message when requesting reset passwords and new instructions ([1c1d0d4](https://framagit.org/framasoft/mobilizon/-/commit/1c1d0d47d70cf19abe5be42e7ec3a73656a8172b))
* **back:** Replace NaiveDateTime uses with DateTime for consistency ([8ea00e7](https://framagit.org/framasoft/mobilizon/-/commit/8ea00e7c1827ce3056ae51968a62fb3dc03ac6eb))
* **back:** Various small fixes in backend ([2a57340](https://framagit.org/framasoft/mobilizon/-/commit/2a57340a82e414e69924ad89e8db9fc326742cc7))
* bind pagination current prop ([4bcf572](https://framagit.org/framasoft/mobilizon/-/commit/4bcf572c54d904587d0409e2eb68b4ca6cf48fec))
* **federation:** Account suspension should use actor in question as author and not relay actor ([79b48da](https://framagit.org/framasoft/mobilizon/-/commit/79b48da22209a8b2f1b234b8b8e121543a39b22b))
* **feeds:** Only provide future events in ICS/Atom feeds ([f3a4431](https://framagit.org/framasoft/mobilizon/-/commit/f3a443138a0e1e6cf34fc593f5c174d56c21e904)), closes [#1246](https://framagit.org/framasoft/mobilizon/-/issues/1246)
* Fix type of variable in navbar ([50ab531](https://framagit.org/framasoft/mobilizon/-/commit/50ab531156214f883cb03f785ccf65e3f19ef50e))
* **follow-instances:** Show correct error message when trying to follow already following actor ([d969c66](https://framagit.org/framasoft/mobilizon/-/commit/d969c6648f15e1ed280169a4c55d612bb002f03f))
* **front:** Fix about sections titles ([487f406](https://framagit.org/framasoft/mobilizon/-/commit/487f4069b14fde6304c9a42cec5b1c1af79814c5))
* **front:** Fix autocomplete attribute in o-inputitems after Oruga new version BC ([d2ba732](https://framagit.org/framasoft/mobilizon/-/commit/d2ba732b8b51986b739f6fbe3d74fa68e4b74ba0))
* **front:** Fix behaviour when deleting an event from event list ([cfd10ea](https://framagit.org/framasoft/mobilizon/-/commit/cfd10ea96078f03ad3b4f5682e37078ffae16ee4))
* **front:** Fix event list month order ([63c9ed6](https://framagit.org/framasoft/mobilizon/-/commit/63c9ed62de94d6d150798c949bad3d8a2dd4db23)), closes [#1244](https://framagit.org/framasoft/mobilizon/-/issues/1244)
* **front:** Fix instances list pagination ([8543204](https://framagit.org/framasoft/mobilizon/-/commit/8543204bd95de886d8d35bd491f23ecbc0a6ef8d)), closes [#1277](https://framagit.org/framasoft/mobilizon/-/issues/1277)
* **front:** Fix pagination display on dark mode ([4375438](https://framagit.org/framasoft/mobilizon/-/commit/4375438dc9fd2f1c5c9d7ed6670dde04f2da520f))
* **front:** Fix style of My Events participations ([35b07dc](https://framagit.org/framasoft/mobilizon/-/commit/35b07dceaa41c74c28ea49655b755e341f56df32))
* **front:** Focus report comment input in report modal ([2c28312](https://framagit.org/framasoft/mobilizon/-/commit/2c28312fc957901b86c2f3d1db8fc3376f505d37)), closes [#1236](https://framagit.org/framasoft/mobilizon/-/issues/1236)
* **front:** Handle "Failed to fetch dynamically imported module" errors by refreshing the page ([3d21a06](https://framagit.org/framasoft/mobilizon/-/commit/3d21a067897e4aa24f6404686ca6896044584796))
* **front:** Improve Delete account modal UI ([c420bbc](https://framagit.org/framasoft/mobilizon/-/commit/c420bbccc9bd1c348e41904e826dc49c71d7eeb4))
* **front:** Improve resend inscription instructions view and show error when appropriate ([5563052](https://framagit.org/framasoft/mobilizon/-/commit/55630527957d4f6a2e1e6845e64a92bc4794efc8))
* **front:** No cache-only for config ([8dcb76c](https://framagit.org/framasoft/mobilizon/-/commit/8dcb76c30d4fa835837fd3b3833f83682fbae615))
* **front:** Small UI fixes on identity pickers ([6faafd6](https://framagit.org/framasoft/mobilizon/-/commit/6faafd639303e4b57ed81db2ffb5db4ad598b904))
* **i18n:** Update translations ([3b7dbcd](https://framagit.org/framasoft/mobilizon/-/commit/3b7dbcd71f0d19d5e723a03c56ca0b1abbd16f5d))
* **map:** Fix style of the map marker ([c7b90cd](https://framagit.org/framasoft/mobilizon/-/commit/c7b90cd60a14abea7aebab7e1d87f37a44371f7c))
* **map:** Only show map details when needed ([23b5e59](https://framagit.org/framasoft/mobilizon/-/commit/23b5e5930cb9bdb57b1d7fa3ec899d7e4d3571be))
* **map:** Only show marker if we have it's position ([f0cc5ff](https://framagit.org/framasoft/mobilizon/-/commit/f0cc5ffb8feb2f4d70416792a8ab2f4f44bfba85))
* **password-reset:** Lower time before being available to reset password or resend instructions ([73eb460](https://framagit.org/framasoft/mobilizon/-/commit/73eb4603b185c341b63481ed934f66e19aa0784f))
* **search:** Fix event search order ([a4e7ee3](https://framagit.org/framasoft/mobilizon/-/commit/a4e7ee37bedc63b2193a401c801b3b1298f566d2))
* **typespec:** Fix missing return type in typespec ([2043c98](https://framagit.org/framasoft/mobilizon/-/commit/2043c98717e8621b3953d347be0b4a35f494af98))
* Change the way preferredUsername is synced ([a73e5a08](https://framagit.org/framasoft/mobilizon/-/commit/a73e5a085ef48a88dbb8f9c407df0430ca89fe1f))
* datetimepicker: change colors for day & time selectors on dark mode ([b18e8fd3](https://framagit.org/framasoft/mobilizon/-/commit/b18e8fd37c76190ca7f6db82e408cdb005d1810a))
* Save IP and login date from directly registered accounts ([1db5c4ae](https://framagit.org/framasoft/mobilizon/-/commit/1db5c4ae2d49d5adbda2c0825ee0320322b525d6))
* Make sure every cache is properly cleared when managing an event ([f531c39b](https://framagit.org/framasoft/mobilizon/-/commit/f531c39b7e8829a5e3ff68f624b04e12266f2148))
* Add page title for Categories view ([0775814e](https://framagit.org/framasoft/mobilizon/-/commit/0775814e19e6f6ddde564f7a29ae80fab2175d3f))
* Fix notifications settings not working ([31fd99bd](https://framagit.org/framasoft/mobilizon/-/commit/31fd99bd3760872e452351b33765d25b2b9720f2))
* **discussionlistitem:** remove unecessary parameter in vue router target ([779812c](https://framagit.org/framasoft/mobilizon/-/commit/779812c746cf722dd86bcc0ad3bc58e558c13223))
* **emails:** make sure group notification emails are only sent once per email ([927e95f](https://framagit.org/framasoft/mobilizon/-/commit/927e95f387653c7d620e9051c30843ba49c2d65c))
* **frontend:** event edition UI improvements ([0e14a36](https://framagit.org/framasoft/mobilizon/-/commit/0e14a36c6d30ebe386b2136d29539f3b3e914efc))
* **frontend:** only show map on event edition when we have an address or we want to put in details ([02867e6](https://framagit.org/framasoft/mobilizon/-/commit/02867e6e1482ac8770f94fd2bd00174bb31fbdc7))
* **front:** fix showing current group avatar & banners ([20b4aaa](https://framagit.org/framasoft/mobilizon/-/commit/20b4aaabc97080e85cb68fd03393379c7ef82d95))
* **front:** fix showing current identity avatar & banners ([d0f4721](https://framagit.org/framasoft/mobilizon/-/commit/d0f4721925d0c50340d6db8a4e9f4d3e4ca01457))
* **front:** improve UI of the glossary page ([d47b69d](https://framagit.org/framasoft/mobilizon/-/commit/d47b69d6caa7c4405ab2e573ba407f9b2450c3bb))
* **front:** increase padding next to arrow down in `<select>` elements ([94f186c](https://framagit.org/framasoft/mobilizon/-/commit/94f186ce5080316cd633e0344651b0050c2f14d4))
* **front:** remove cache-only for ABOUT GraphQL details on homepage ([6858bcb](https://framagit.org/framasoft/mobilizon/-/commit/6858bcbbda6d8527bd15b9138e7bb30c5ead72d7))
* **front:** remove leftover console.logs ([6da0dba](https://framagit.org/framasoft/mobilizon/-/commit/6da0dba0fd6d071ce5978802104538d0c2ef7dae))
* **front:** reset page number to 1 when search criteria changes ([d73bafe](https://framagit.org/framasoft/mobilizon/-/commit/d73bafec97cd7d8eda887d21870427262befab0f)), closes [#1272](https://framagit.org/framasoft/mobilizon/-/issues/1272)
* **front:** various UI improvements for group page ([b097567](https://framagit.org/framasoft/mobilizon/-/commit/b0975672c1c06ace364cf47bfcfa39db9c3b712b))
* **graphql:** fix calling GET_GROUP ([2933ee0](https://framagit.org/framasoft/mobilizon/-/commit/2933ee06791a24dbf8c8b2a2eabc67f71e56f361))
* **group:** rephrase "Public Page" to "Announcements", as all posts are not necessary public ([b0a564f](https://framagit.org/framasoft/mobilizon/-/commit/b0a564f64f72f40b6bb9560f9bc0fbea5d099fd7)), closes [#900](https://framagit.org/framasoft/mobilizon/-/issues/900)
* **i18n:** fix Swedish translations error that prevented Participate button from showing up ([643a5b5](https://framagit.org/framasoft/mobilizon/-/commit/643a5b5921f91fed6a9f674c0ab3a36bf2d05835)), closes [#1281](https://framagit.org/framasoft/mobilizon/-/issues/1281)
* **rich media:** fix error handling when resource preview URL leads to empty parsed data ([850b4e2](https://framagit.org/framasoft/mobilizon/-/commit/850b4e2a735e335c4737caa8b60e190613e778ef)), closes [#1279](https://framagit.org/framasoft/mobilizon/-/issues/1279)
* **sharepostmodal:** only show the share warning message if the post is accessible by link ([8e626dc](https://framagit.org/framasoft/mobilizon/-/commit/8e626dce7807640a89770e50ca2621d34d6a5d97))
* **apps:** fix device flow authorization process ([9a457fb](https://framagit.org/framasoft/mobilizon/-/commit/9a457fb011b77b27dc465f1bc7327a08f554ccfb))
* **apps:** fix typo in redirect_uri parameter ([5664625](https://framagit.org/framasoft/mobilizon/-/commit/5664625c1c57ccba947400475414c1301d4bf955))
* **apps:** show scope from device activation in authorize device view ([c9d2074](https://framagit.org/framasoft/mobilizon/-/commit/c9d20748a4dd3e0687515f4776335d0ec9bdfcdc))
* **front:** fix homepage event and groups cards snapping ([8809db5](https://framagit.org/framasoft/mobilizon/-/commit/8809db582ccf45fcd477f46dcf70e106720626a8))
* **front:** fix selecting addresses in autocomplete ([e0488dd](https://framagit.org/framasoft/mobilizon/-/commit/e0488dd87ffc0184162a2ff67a13717e6263d56d))
* include user role in moderator role ([c4d6019](https://framagit.org/framasoft/mobilizon/-/commit/c4d60194a6900a3f9430355c5fbb346d910e4df6))
## 3.1.0-rc.2 (2023-05-30)
### Bug Fixes
* **apps:** fix device flow authorization process ([9a457fb](https://framagit.org/framasoft/mobilizon/-/commit/9a457fb011b77b27dc465f1bc7327a08f554ccfb))
* **apps:** fix typo in redirect_uri parameter ([5664625](https://framagit.org/framasoft/mobilizon/-/commit/5664625c1c57ccba947400475414c1301d4bf955))
* **apps:** show scope from device activation in authorize device view ([c9d2074](https://framagit.org/framasoft/mobilizon/-/commit/c9d20748a4dd3e0687515f4776335d0ec9bdfcdc))
* **front:** fix homepage event and groups cards snapping ([8809db5](https://framagit.org/framasoft/mobilizon/-/commit/8809db582ccf45fcd477f46dcf70e106720626a8))
* **front:** fix selecting addresses in autocomplete ([e0488dd](https://framagit.org/framasoft/mobilizon/-/commit/e0488dd87ffc0184162a2ff67a13717e6263d56d))
## 3.1.0-rc.1 (2023-05-30)
### Bug Fixes
* **discussionlistitem:** remove unecessary parameter in vue router target ([779812c](https://framagit.org/framasoft/mobilizon/-/commit/779812c746cf722dd86bcc0ad3bc58e558c13223))
* **emails:** make sure group notification emails are only sent once per email ([927e95f](https://framagit.org/framasoft/mobilizon/-/commit/927e95f387653c7d620e9051c30843ba49c2d65c))
* **frontend:** event edition UI improvements ([0e14a36](https://framagit.org/framasoft/mobilizon/-/commit/0e14a36c6d30ebe386b2136d29539f3b3e914efc))
* **frontend:** only show map on event edition when we have an address or we want to put in details ([02867e6](https://framagit.org/framasoft/mobilizon/-/commit/02867e6e1482ac8770f94fd2bd00174bb31fbdc7))
* **front:** fix showing current group avatar & banners ([20b4aaa](https://framagit.org/framasoft/mobilizon/-/commit/20b4aaabc97080e85cb68fd03393379c7ef82d95))
* **front:** fix showing current identity avatar & banners ([d0f4721](https://framagit.org/framasoft/mobilizon/-/commit/d0f4721925d0c50340d6db8a4e9f4d3e4ca01457))
* **front:** improve UI of the glossary page ([d47b69d](https://framagit.org/framasoft/mobilizon/-/commit/d47b69d6caa7c4405ab2e573ba407f9b2450c3bb))
* **front:** increase padding next to arrow down in `<select>` elements ([94f186c](https://framagit.org/framasoft/mobilizon/-/commit/94f186ce5080316cd633e0344651b0050c2f14d4))
* **front:** remove cache-only for ABOUT GraphQL details on homepage ([6858bcb](https://framagit.org/framasoft/mobilizon/-/commit/6858bcbbda6d8527bd15b9138e7bb30c5ead72d7))
* **front:** remove leftover console.logs ([6da0dba](https://framagit.org/framasoft/mobilizon/-/commit/6da0dba0fd6d071ce5978802104538d0c2ef7dae))
* **front:** reset page number to 1 when search criteria changes ([d73bafe](https://framagit.org/framasoft/mobilizon/-/commit/d73bafec97cd7d8eda887d21870427262befab0f)), closes [#1272](https://framagit.org/framasoft/mobilizon/-/issues/1272)
* **front:** various UI improvements for group page ([b097567](https://framagit.org/framasoft/mobilizon/-/commit/b0975672c1c06ace364cf47bfcfa39db9c3b712b))
* **graphql:** fix calling GET_GROUP ([2933ee0](https://framagit.org/framasoft/mobilizon/-/commit/2933ee06791a24dbf8c8b2a2eabc67f71e56f361))
* **group:** rephrase "Public Page" to "Announcements", as all posts are not necessary public ([b0a564f](https://framagit.org/framasoft/mobilizon/-/commit/b0a564f64f72f40b6bb9560f9bc0fbea5d099fd7)), closes [#900](https://framagit.org/framasoft/mobilizon/-/issues/900)
* **i18n:** fix Swedish translations error that prevented Participate button from showing up ([643a5b5](https://framagit.org/framasoft/mobilizon/-/commit/643a5b5921f91fed6a9f674c0ab3a36bf2d05835)), closes [#1281](https://framagit.org/framasoft/mobilizon/-/issues/1281)
* **rich media:** fix error handling when resource preview URL leads to empty parsed data ([850b4e2](https://framagit.org/framasoft/mobilizon/-/commit/850b4e2a735e335c4737caa8b60e190613e778ef)), closes [#1279](https://framagit.org/framasoft/mobilizon/-/issues/1279)
* **sharepostmodal:** only show the share warning message if the post is accessible by link ([8e626dc](https://framagit.org/framasoft/mobilizon/-/commit/8e626dce7807640a89770e50ca2621d34d6a5d97))
### Features
* **front:** improve padding on event tags ([7fa452d](https://framagit.org/framasoft/mobilizon/-/commit/7fa452d9e3f9bb2443e571c9a32eaed51e32480a))
* **front:** make admin profile view linkable directly with parameters ([08ce7e2](https://framagit.org/framasoft/mobilizon/-/commit/08ce7e26b73045279261ab87a14cb4f3dab5df1e))
* **front:** make profile members link to profile on group admin view and the reverse ([96129d2](https://framagit.org/framasoft/mobilizon/-/commit/96129d2339133027220d3b5fcb1c52f84bcc5cbb))
* **front:** make profiles and group admin views default to local ([3e0324d](https://framagit.org/framasoft/mobilizon/-/commit/3e0324d36ec5a8aa388e6b5d598a6f9a0c596797))
* **front:** redirect user to homepage on disconnect when currently on private page ([d5a6df9](https://framagit.org/framasoft/mobilizon/-/commit/d5a6df9940fb458c5dbaee149015c02ebc370c6b)), closes [#1278](https://framagit.org/framasoft/mobilizon/-/issues/1278)
* **front:** show skeleton content on event view until the event is loaded ([dc3b93f](https://framagit.org/framasoft/mobilizon/-/commit/dc3b93ffb5a4b072aec792533fd6e4b58ed7a893))
* **i18n:** activate croatian language ([94182ae](https://framagit.org/framasoft/mobilizon/-/commit/94182aed2d8a22d00534f6376dfda2658bc8ba7e))
* **i18n:** activate japanese language ([6bd8034](https://framagit.org/framasoft/mobilizon/-/commit/6bd8034fe816a432c3547de6d1ad8a18e73dc314)), closes [#1293](https://framagit.org/framasoft/mobilizon/-/issues/1293)
* **post:** show post visibily in PostListItem component ([ec7ca4d](https://framagit.org/framasoft/mobilizon/-/commit/ec7ca4ddf18a38cf6f51d38b540eecc9858f3c98))
## 3.1.0-beta.2 (2023-05-23) ## 3.1.0-beta.2 (2023-05-23)
### Bug Fixes ### Bug Fixes
@ -18,7 +201,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* **API:** Allow to create apps, with permissions and both Authorization Code Flow and Device Flow * **API:** Allow to create apps, with permissions and both Authorization Code Flow and Device Flow
* **addresses:** Allow to enter manual addresses ([85d643d](https://framagit.org/framasoft/mobilizon/-/commit/85d643d0ecd5e7504f32953b9ed1509697b915e2)) * **addresses:** Allow to enter manual addresses ([85d643d](https://framagit.org/framasoft/mobilizon/-/commit/85d643d0ecd5e7504f32953b9ed1509697b915e2))
* **docker:** Specify the folder where tzdata downloads data so that it can be used in a volume ([4bb0625](https://framagit.org/framasoft/mobilizon/-/commit/4bb062528f12be530a3754ca23c1bc6dbc862e5a)), closes [#1280](https://framagit.org/framasoft/mobilizon/issues/1280) * **docker:** Specify the folder where tzdata downloads data so that it can be used in a volume ([4bb0625](https://framagit.org/framasoft/mobilizon/-/commit/4bb062528f12be530a3754ca23c1bc6dbc862e5a)), closes [#1280](https://framagit.org/framasoft/mobilizon/-/issues/1280)
* **spam:** Introduce checking new accounts, events & comments for spam with the help of Akismet ([317a343](https://framagit.org/framasoft/mobilizon/-/commit/317a3434b221a1a91b66d8443984269404863a8e)) * **spam:** Introduce checking new accounts, events & comments for spam with the help of Akismet ([317a343](https://framagit.org/framasoft/mobilizon/-/commit/317a3434b221a1a91b66d8443984269404863a8e))
* **rate-limiting:** Introduce rate-limiting on some endpoints ([c07ba3a5](https://framagit.org/framasoft/mobilizon/-/commit/c07ba3a5d19c419ef8aaf3ea9ca6e7f48e4f4487)) * **rate-limiting:** Introduce rate-limiting on some endpoints ([c07ba3a5](https://framagit.org/framasoft/mobilizon/-/commit/c07ba3a5d19c419ef8aaf3ea9ca6e7f48e4f4487))
@ -36,17 +219,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* **back:** Various small fixes in backend ([2a57340](https://framagit.org/framasoft/mobilizon/-/commit/2a57340a82e414e69924ad89e8db9fc326742cc7)) * **back:** Various small fixes in backend ([2a57340](https://framagit.org/framasoft/mobilizon/-/commit/2a57340a82e414e69924ad89e8db9fc326742cc7))
* bind pagination current prop ([4bcf572](https://framagit.org/framasoft/mobilizon/-/commit/4bcf572c54d904587d0409e2eb68b4ca6cf48fec)) * bind pagination current prop ([4bcf572](https://framagit.org/framasoft/mobilizon/-/commit/4bcf572c54d904587d0409e2eb68b4ca6cf48fec))
* **federation:** Account suspension should use actor in question as author and not relay actor ([79b48da](https://framagit.org/framasoft/mobilizon/-/commit/79b48da22209a8b2f1b234b8b8e121543a39b22b)) * **federation:** Account suspension should use actor in question as author and not relay actor ([79b48da](https://framagit.org/framasoft/mobilizon/-/commit/79b48da22209a8b2f1b234b8b8e121543a39b22b))
* **feeds:** Only provide future events in ICS/Atom feeds ([f3a4431](https://framagit.org/framasoft/mobilizon/-/commit/f3a443138a0e1e6cf34fc593f5c174d56c21e904)), closes [#1246](https://framagit.org/framasoft/mobilizon/issues/1246) * **feeds:** Only provide future events in ICS/Atom feeds ([f3a4431](https://framagit.org/framasoft/mobilizon/-/commit/f3a443138a0e1e6cf34fc593f5c174d56c21e904)), closes [#1246](https://framagit.org/framasoft/mobilizon/-/issues/1246)
* Fix type of variable in navbar ([50ab531](https://framagit.org/framasoft/mobilizon/-/commit/50ab531156214f883cb03f785ccf65e3f19ef50e)) * Fix type of variable in navbar ([50ab531](https://framagit.org/framasoft/mobilizon/-/commit/50ab531156214f883cb03f785ccf65e3f19ef50e))
* **follow-instances:** Show correct error message when trying to follow already following actor ([d969c66](https://framagit.org/framasoft/mobilizon/-/commit/d969c6648f15e1ed280169a4c55d612bb002f03f)) * **follow-instances:** Show correct error message when trying to follow already following actor ([d969c66](https://framagit.org/framasoft/mobilizon/-/commit/d969c6648f15e1ed280169a4c55d612bb002f03f))
* **front:** Fix about sections titles ([487f406](https://framagit.org/framasoft/mobilizon/-/commit/487f4069b14fde6304c9a42cec5b1c1af79814c5)) * **front:** Fix about sections titles ([487f406](https://framagit.org/framasoft/mobilizon/-/commit/487f4069b14fde6304c9a42cec5b1c1af79814c5))
* **front:** Fix autocomplete attribute in o-inputitems after Oruga new version BC ([d2ba732](https://framagit.org/framasoft/mobilizon/-/commit/d2ba732b8b51986b739f6fbe3d74fa68e4b74ba0)) * **front:** Fix autocomplete attribute in o-inputitems after Oruga new version BC ([d2ba732](https://framagit.org/framasoft/mobilizon/-/commit/d2ba732b8b51986b739f6fbe3d74fa68e4b74ba0))
* **front:** Fix behaviour when deleting an event from event list ([cfd10ea](https://framagit.org/framasoft/mobilizon/-/commit/cfd10ea96078f03ad3b4f5682e37078ffae16ee4)) * **front:** Fix behaviour when deleting an event from event list ([cfd10ea](https://framagit.org/framasoft/mobilizon/-/commit/cfd10ea96078f03ad3b4f5682e37078ffae16ee4))
* **front:** Fix event list month order ([63c9ed6](https://framagit.org/framasoft/mobilizon/-/commit/63c9ed62de94d6d150798c949bad3d8a2dd4db23)), closes [#1244](https://framagit.org/framasoft/mobilizon/issues/1244) * **front:** Fix event list month order ([63c9ed6](https://framagit.org/framasoft/mobilizon/-/commit/63c9ed62de94d6d150798c949bad3d8a2dd4db23)), closes [#1244](https://framagit.org/framasoft/mobilizon/-/issues/1244)
* **front:** Fix instances list pagination ([8543204](https://framagit.org/framasoft/mobilizon/-/commit/8543204bd95de886d8d35bd491f23ecbc0a6ef8d)), closes [#1277](https://framagit.org/framasoft/mobilizon/issues/1277) * **front:** Fix instances list pagination ([8543204](https://framagit.org/framasoft/mobilizon/-/commit/8543204bd95de886d8d35bd491f23ecbc0a6ef8d)), closes [#1277](https://framagit.org/framasoft/mobilizon/-/issues/1277)
* **front:** Fix pagination display on dark mode ([4375438](https://framagit.org/framasoft/mobilizon/-/commit/4375438dc9fd2f1c5c9d7ed6670dde04f2da520f)) * **front:** Fix pagination display on dark mode ([4375438](https://framagit.org/framasoft/mobilizon/-/commit/4375438dc9fd2f1c5c9d7ed6670dde04f2da520f))
* **front:** Fix style of My Events participations ([35b07dc](https://framagit.org/framasoft/mobilizon/-/commit/35b07dceaa41c74c28ea49655b755e341f56df32)) * **front:** Fix style of My Events participations ([35b07dc](https://framagit.org/framasoft/mobilizon/-/commit/35b07dceaa41c74c28ea49655b755e341f56df32))
* **front:** Focus report comment input in report modal ([2c28312](https://framagit.org/framasoft/mobilizon/-/commit/2c28312fc957901b86c2f3d1db8fc3376f505d37)), closes [#1236](https://framagit.org/framasoft/mobilizon/issues/1236) * **front:** Focus report comment input in report modal ([2c28312](https://framagit.org/framasoft/mobilizon/-/commit/2c28312fc957901b86c2f3d1db8fc3376f505d37)), closes [#1236](https://framagit.org/framasoft/mobilizon/-/issues/1236)
* **front:** Handle "Failed to fetch dynamically imported module" errors by refreshing the page ([3d21a06](https://framagit.org/framasoft/mobilizon/-/commit/3d21a067897e4aa24f6404686ca6896044584796)) * **front:** Handle "Failed to fetch dynamically imported module" errors by refreshing the page ([3d21a06](https://framagit.org/framasoft/mobilizon/-/commit/3d21a067897e4aa24f6404686ca6896044584796))
* **front:** Improve Delete account modal UI ([c420bbc](https://framagit.org/framasoft/mobilizon/-/commit/c420bbccc9bd1c348e41904e826dc49c71d7eeb4)) * **front:** Improve Delete account modal UI ([c420bbc](https://framagit.org/framasoft/mobilizon/-/commit/c420bbccc9bd1c348e41904e826dc49c71d7eeb4))
* **front:** Improve resend inscription instructions view and show error when appropriate ([5563052](https://framagit.org/framasoft/mobilizon/-/commit/55630527957d4f6a2e1e6845e64a92bc4794efc8)) * **front:** Improve resend inscription instructions view and show error when appropriate ([5563052](https://framagit.org/framasoft/mobilizon/-/commit/55630527957d4f6a2e1e6845e64a92bc4794efc8))

View file

@ -65,6 +65,10 @@ config :mime, :types, %{
"application/xrd+xml" => ["xrd-xml"] "application/xrd+xml" => ["xrd-xml"]
} }
config :mime, :extensions, %{
"activity-json" => "application/activity+json"
}
# Upload configuration # Upload configuration
config :mobilizon, Mobilizon.Web.Upload, config :mobilizon, Mobilizon.Web.Upload,
uploader: Mobilizon.Web.Upload.Uploader.Local, uploader: Mobilizon.Web.Upload.Uploader.Local,
@ -306,7 +310,7 @@ config :mobilizon, Oban,
crontab: [ crontab: [
{"@hourly", Mobilizon.Service.Workers.BuildSiteMap, queue: :background}, {"@hourly", Mobilizon.Service.Workers.BuildSiteMap, queue: :background},
{"17 4 * * *", Mobilizon.Service.Workers.RefreshGroups, queue: :background}, {"17 4 * * *", Mobilizon.Service.Workers.RefreshGroups, queue: :background},
{"36 * * * *", Mobilizon.Service.Workers.RefreshInstances, queue: :background}, {"36 3 * * *", Mobilizon.Service.Workers.RefreshInstances, queue: :background},
{"@hourly", Mobilizon.Service.Workers.CleanOrphanMediaWorker, queue: :background}, {"@hourly", Mobilizon.Service.Workers.CleanOrphanMediaWorker, queue: :background},
{"@hourly", Mobilizon.Service.Workers.CleanUnconfirmedUsersWorker, queue: :background}, {"@hourly", Mobilizon.Service.Workers.CleanUnconfirmedUsersWorker, queue: :background},
{"@hourly", Mobilizon.Service.Workers.ExportCleanerWorker, queue: :background}, {"@hourly", Mobilizon.Service.Workers.ExportCleanerWorker, queue: :background},
@ -377,6 +381,8 @@ config :mobilizon, Mobilizon.Service.GlobalSearch.SearchMobilizon,
img_src: ["search.joinmobilizon.org"] img_src: ["search.joinmobilizon.org"]
] ]
config :mobilizon, Mobilizon.Service.AntiSpam, service: Mobilizon.Service.AntiSpam.Akismet
# Import environment specific config. This must remain at the bottom # Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above. # of this file so it overrides the configuration defined above.
import_config "#{config_env()}.exs" import_config "#{config_env()}.exs"

View file

@ -90,6 +90,8 @@ config :junit_formatter, report_dir: "."
config :mobilizon, :http_security, report_uri: "https://endpoint.com" config :mobilizon, :http_security, report_uri: "https://endpoint.com"
config :mobilizon, Mobilizon.Service.AntiSpam, service: Mobilizon.Service.AntiSpam.Mock
if System.get_env("DOCKER", "false") == "false" && File.exists?("./config/test.secret.exs") do if System.get_env("DOCKER", "false") == "false" && File.exists?("./config/test.secret.exs") do
import_config "test.secret.exs" import_config "test.secret.exs"
end end

View file

@ -1,6 +1,6 @@
{ {
"name": "mobilizon", "name": "mobilizon",
"version": "3.1.0-beta.2", "version": "3.1.3",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@ -14,7 +14,14 @@
"story:build": "histoire build", "story:build": "histoire build",
"story:preview": "histoire preview", "story:preview": "histoire preview",
"test": "vitest", "test": "vitest",
"coverage": "vitest run --coverage" "coverage": "vitest run --coverage",
"prepare": "cd ../ && husky install"
},
"lint-staged": {
"**/*.{js,ts,vue}": [
"eslint --fix",
"prettier --write"
]
}, },
"dependencies": { "dependencies": {
"@absinthe/socket": "^0.2.1", "@absinthe/socket": "^0.2.1",
@ -49,7 +56,7 @@
"@tiptap/vue-3": "^2.0.0-beta.96", "@tiptap/vue-3": "^2.0.0-beta.96",
"@vue-a11y/announcer": "^2.1.0", "@vue-a11y/announcer": "^2.1.0",
"@vue-a11y/skip-to": "^2.1.2", "@vue-a11y/skip-to": "^2.1.2",
"@vue-leaflet/vue-leaflet": "^0.9.0", "@vue-leaflet/vue-leaflet": "^0.10.1",
"@vue/apollo-composable": "^4.0.0-beta.5", "@vue/apollo-composable": "^4.0.0-beta.5",
"@vue/compiler-sfc": "^3.2.37", "@vue/compiler-sfc": "^3.2.37",
"@vueuse/core": "^10.0.2", "@vueuse/core": "^10.0.2",
@ -104,8 +111,8 @@
"@types/phoenix": "^1.5.2", "@types/phoenix": "^1.5.2",
"@types/sanitize-html": "^2.5.0", "@types/sanitize-html": "^2.5.0",
"@vitejs/plugin-vue": "^4.0.0", "@vitejs/plugin-vue": "^4.0.0",
"@vitest/coverage-c8": "^0.31.0", "@vitest/coverage-c8": "^0.32.2",
"@vitest/ui": "^0.31.0", "@vitest/ui": "^0.32.2",
"@vue/eslint-config-prettier": "^7.0.0", "@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^11.0.0", "@vue/eslint-config-typescript": "^11.0.0",
"@vue/test-utils": "^2.0.2", "@vue/test-utils": "^2.0.2",
@ -116,16 +123,18 @@
"eslint-plugin-vue": "^9.3.0", "eslint-plugin-vue": "^9.3.0",
"flush-promises": "^1.0.2", "flush-promises": "^1.0.2",
"histoire": "^0.16.1", "histoire": "^0.16.1",
"husky": "^8.0.3",
"jsdom": "^22.0.0", "jsdom": "^22.0.0",
"lint-staged": "^13.2.2",
"mock-apollo-client": "^1.1.0", "mock-apollo-client": "^1.1.0",
"prettier": "^2.2.1", "prettier": "^2.2.1",
"prettier-eslint": "^15.0.1", "prettier-eslint": "^15.0.1",
"rollup-plugin-visualizer": "^5.7.1", "rollup-plugin-visualizer": "^5.7.1",
"sass": "^1.34.1", "sass": "^1.34.1",
"typescript": "~5.0.0", "typescript": "~5.1.3",
"vite": "^4.0.4", "vite": "^4.0.4",
"vite-plugin-pwa": "^0.14.1", "vite-plugin-pwa": "^0.16.4",
"vitest": "^0.31.0", "vitest": "^0.32.2",
"vue-i18n-extract": "^2.0.4" "vue-i18n-extract": "^2.0.4"
} }
} }

View file

@ -42,13 +42,13 @@ body {
@apply bg-transparent text-black dark:text-white font-semibold py-2 px-4 border border-mbz-bluegreen dark:border-violet-3; @apply bg-transparent text-black dark:text-white font-semibold py-2 px-4 border border-mbz-bluegreen dark:border-violet-3;
} }
.btn-outlined-success { .btn-outlined-success {
@apply border-mbz-success; @apply border-mbz-success hover:bg-mbz-success;
} }
.btn-outlined-warning { .btn-outlined-warning {
@apply bg-transparent border dark:text-white hover:dark:text-slate-900 hover:bg-mbz-warning border-mbz-warning; @apply bg-transparent border dark:text-white hover:dark:text-slate-900 hover:bg-mbz-warning border-mbz-warning;
} }
.btn-outlined-danger { .btn-outlined-danger {
@apply border-mbz-danger; @apply border-mbz-danger hover:bg-mbz-danger;
} }
.btn-outlined-text { .btn-outlined-text {
@apply bg-transparent hover:text-slate-900; @apply bg-transparent hover:text-slate-900;

View file

@ -1,10 +1,10 @@
<template> <template>
<router-link <router-link
class="flex gap-1 w-full items-center p-2 border-b-stone-200 border-b" class="flex gap-1 w-full items-center p-2 border-b-stone-200 border-b bg-white dark:bg-transparent"
dir="auto" dir="auto"
:to="{ :to="{
name: RouteName.DISCUSSION, name: RouteName.DISCUSSION,
params: { slug: discussion.slug, id: discussion.id }, params: { slug: discussion.slug },
}" }"
> >
<div class=""> <div class="">

View file

@ -3,7 +3,7 @@
class="mbz-card snap-center dark:bg-mbz-purple" class="mbz-card snap-center dark:bg-mbz-purple"
:class="{ :class="{
'sm:flex sm:items-start': mode === 'row', 'sm:flex sm:items-start': mode === 'row',
'sm:max-w-xs sm:w-[18rem] shrink-0 flex flex-col': mode === 'column', 'sm:max-w-xs w-[18rem] shrink-0 flex flex-col': mode === 'column',
}" }"
:to="to" :to="to"
:isInternal="isInternal" :isInternal="isInternal"
@ -129,8 +129,8 @@
{{ {{
t( t(
"{count} participants", "{count} participants",
event.participantStats?.participant, { count: event.participantStats?.participant },
{ count: event.participantStats?.participant } event.participantStats?.participant
) )
}} }}
</mobilizon-tag> </mobilizon-tag>

View file

@ -157,7 +157,10 @@
</footer> </footer>
</form> </form>
</o-collapse> </o-collapse>
<div class="map" v-if="!hideMap"> <div
class="map"
v-if="!hideMap && !disabled && (selected.geom || detailsAddress)"
>
<map-leaflet <map-leaflet
:coords="selected.geom ?? defaultCoords" :coords="selected.geom ?? defaultCoords"
:marker="mapMarkerValue" :marker="mapMarkerValue"
@ -276,6 +279,7 @@ const setSelected = (newValue: IAddress | null) => {
if (!newValue) return; if (!newValue) return;
console.debug("setting selected to model value"); console.debug("setting selected to model value");
Object.assign(selected, newValue); Object.assign(selected, newValue);
emit("update:modelValue", selected);
}; };
const saveManualAddress = (): void => { const saveManualAddress = (): void => {

View file

@ -2,10 +2,10 @@
<LinkOrRouterLink <LinkOrRouterLink
:to="to" :to="to"
:isInternal="isInternal" :isInternal="isInternal"
class="mbz-card shrink-0 dark:bg-mbz-purple dark:text-white rounded-lg shadow-lg flex items-center flex-col" class="mbz-card snap-center shrink-0 dark:bg-mbz-purple dark:text-white rounded-lg shadow-lg flex items-center flex-col"
:class="{ :class="{
'sm:flex-row': mode === 'row', 'sm:flex-row': mode === 'row',
'sm:max-w-xs sm:w-[18rem] shrink-0 flex flex-col': mode === 'column', 'sm:max-w-xs w-[18rem] shrink-0 flex flex-col': mode === 'column',
}" }"
> >
<div class="flex-none p-2 md:p-4"> <div class="flex-none p-2 md:p-4">

View file

@ -1,6 +1,6 @@
<template> <template>
<group-section <group-section
:title="t('Public page')" :title="t('Announcements')"
icon="bullhorn" icon="bullhorn"
:privateSection="false" :privateSection="false"
:route="{ :route="{

View file

@ -8,7 +8,10 @@
}" }"
> >
<template #default> <template #default>
<div v-if="group?.resources?.elements?.length ?? 0 > 0" class="p-1"> <div
v-if="group?.resources?.elements?.length ?? 0 > 0"
class="p-1 bg-white dark:bg-transparent"
>
<div <div
v-for="resource in group?.resources?.elements ?? []" v-for="resource in group?.resources?.elements ?? []"
:key="resource.id" :key="resource.id"

View file

@ -22,7 +22,7 @@
<!-- <div class="hidden sm:block" v-show="showScrollLeftButton"> <!-- <div class="hidden sm:block" v-show="showScrollLeftButton">
<button <button
@click="scrollLeft" @click="scrollLeft"
class="absolute inset-y-0 my-auto z-10 rounded-full bg-white dark:bg-transparent w-10 h-10 border border-shadowColor -left-5" class="absolute inset-y-0 my-auto z-10 rounded-full bg-white dark:bg-transparent w-10 h-10 border border-shadowColor -left-5 ml-2"
> >
<span class="">&lt;</span> <span class="">&lt;</span>
</button> </button>
@ -34,6 +34,14 @@
<slot name="content" /> <slot name="content" />
</div> </div>
</div> </div>
<div class="" v-show="showScrollRightButton">
<button
@click="scrollRight"
class="absolute inset-y-0 my-auto z-10 rounded-full bg-white dark:bg-transparent w-10 h-10 border border-shadowColor -right-5 mr-2"
>
<span class="">&gt;</span>
</button>
</div>
</div> </div>
</template> </template>

View file

@ -1,5 +1,15 @@
<template> <template>
<div> <div v-if="checkDevice">
<div class="rounded-lg bg-white dark:bg-zinc-900 shadow-xl my-6 p-4 pt-1">
<h1 class="text-3xl">
{{ t("Application authorized") }}
</h1>
<p>
{{ t("Check your device to continue. You may now close this window.") }}
</p>
</div>
</div>
<div v-else>
<h1 class="text-3xl"> <h1 class="text-3xl">
{{ t("Autorize this application to access your account?") }} {{ t("Autorize this application to access your account?") }}
</h1> </h1>
@ -68,7 +78,7 @@
<div class="flex gap-3 p-4"> <div class="flex gap-3 p-4">
<o-button <o-button
:disabled="collapses.length === 0" :disabled="collapses.length === 0"
@click="() => authorize()" @click="() => (userCode ? authorizeDevice() : authorize())"
>{{ t("Authorize") }}</o-button >{{ t("Authorize") }}</o-button
> >
<o-button outlined tag="router-link" :to="{ name: RouteName.HOME }">{{ <o-button outlined tag="router-link" :to="{ name: RouteName.HOME }">{{
@ -84,10 +94,13 @@ import { useHead } from "@vueuse/head";
import { computed, ref } from "vue"; import { computed, ref } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useMutation } from "@vue/apollo-composable"; import { useMutation } from "@vue/apollo-composable";
import { AUTORIZE_APPLICATION } from "@/graphql/application"; import {
AUTORIZE_APPLICATION,
AUTORIZE_DEVICE_APPLICATION,
} from "@/graphql/application";
import RouteName from "@/router/name"; import RouteName from "@/router/name";
import { IApplication } from "@/types/application.model"; import { IApplication } from "@/types/application.model";
import { scope } from "./scopes"; import { scope as oAuthScopes } from "./scopes";
import AlertCircle from "vue-material-design-icons/AlertCircle.vue"; import AlertCircle from "vue-material-design-icons/AlertCircle.vue";
const { t } = useI18n({ useScope: "global" }); const { t } = useI18n({ useScope: "global" });
@ -97,14 +110,16 @@ const props = defineProps<{
redirectURI?: string | null; redirectURI?: string | null;
state?: string | null; state?: string | null;
scope?: string | null; scope?: string | null;
userCode?: string;
}>(); }>();
const isOpen = ref<number>(-1); const isOpen = ref<number>(-1);
const checkDevice = ref(false);
const collapses = computed(() => const collapses = computed(() =>
(props.scope ?? "") (props.scope ?? "")
.split(" ") .split(" ")
.map((localScope) => scope[localScope]) .map((localScope) => oAuthScopes[localScope])
.filter((localScope) => localScope) .filter((localScope) => localScope)
); );
@ -135,6 +150,37 @@ const authorize = () => {
}); });
}; };
const {
mutate: authorizeDeviceMutation,
onDone: onAuthorizeDeviceMutationDone,
} = useMutation<
{
authorizeDeviceApplication: {
clientId: string;
scope: string;
};
},
{
applicationClientId: string;
userCode: string;
}
>(AUTORIZE_DEVICE_APPLICATION);
const authorizeDevice = () => {
authorizeDeviceMutation({
applicationClientId: props.authApplication.clientId,
userCode: props.userCode ?? "",
});
};
onAuthorizeDeviceMutationDone(({ data }) => {
const localClientId = data?.authorizeDeviceApplication?.clientId;
const localScope = data?.authorizeDeviceApplication?.scope;
if (!localClientId || !localScope) return;
checkDevice.value = true;
});
onAuthorizeMutationDone(({ data }) => { onAuthorizeMutationDone(({ data }) => {
const code = data?.authorizeApplication?.code; const code = data?.authorizeApplication?.code;
const localClientId = data?.authorizeApplication?.clientId; const localClientId = data?.authorizeApplication?.clientId;
@ -143,6 +189,11 @@ onAuthorizeMutationDone(({ data }) => {
if (!code || !localClientId || !localScope) return; if (!code || !localClientId || !localScope) return;
if (props.redirectURI === "urn:ietf:wg:oauth:2.0:oob") {
checkDevice.value = true;
return;
}
if (props.redirectURI) { if (props.redirectURI) {
const params = new URLSearchParams( const params = new URLSearchParams(
Object.entries({ Object.entries({

View file

@ -104,13 +104,6 @@ export const scope: Record<
), ),
icon: "chat", icon: "chat",
}, },
"read:group:members": {
title: t("Access group members"),
text: t(
"This application will be allowed to list group members in all of the groups you're a member of"
),
icon: "account-circle",
},
"read:group:followers": { "read:group:followers": {
title: t("Access group followers"), title: t("Access group followers"),
text: t( text: t(

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="posts-wrapper"> <div class="posts-wrapper grid gap-4">
<post-list-item <post-list-item
v-for="post in posts" v-for="post in posts"
:key="post.id" :key="post.id"
@ -22,8 +22,6 @@ withDefaults(
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.posts-wrapper { .posts-wrapper {
display: grid;
grid-gap: 20px;
grid-template: 1fr; grid-template: 1fr;
} }
</style> </style>

View file

@ -18,7 +18,7 @@
</h3> </h3>
<p class="flex gap-2"> <p class="flex gap-2">
<Clock /> <Clock />
<span dir="auto" class="" v-if="isBeforeLastWeek">{{ <span dir="auto" class="" v-if="publishedAt && isBeforeLastWeek">{{
formatDateTimeString( formatDateTimeString(
publishedAt.toString(), publishedAt.toString(),
undefined, undefined,
@ -26,7 +26,7 @@
"short" "short"
) )
}}</span> }}</span>
<span v-else>{{ <span v-else-if="publishedAt">{{
formatDistanceToNow(publishedAt, { formatDistanceToNow(publishedAt, {
locale: dateFnsLocale, locale: dateFnsLocale,
addSuffix: true, addSuffix: true,
@ -47,6 +47,24 @@
</template> </template>
</i18n-t> </i18n-t>
</p> </p>
<p
v-if="post.visibility === PostVisibility.UNLISTED"
class="flex gap-2 items-center"
>
<Link :size="16" />
{{ t("Accessible only by link") }}
</p>
<p
v-else-if="post.visibility === PostVisibility.PRIVATE"
class="flex gap-2 items-center"
>
<Lock :size="16" />
{{
t("Accessible only to members", {
group: post.attributedTo?.name,
})
}}
</p>
</div> </div>
</router-link> </router-link>
</template> </template>
@ -61,7 +79,11 @@ import { formatDateTimeString } from "@/filters/datetime";
import Tag from "vue-material-design-icons/Tag.vue"; import Tag from "vue-material-design-icons/Tag.vue";
import AccountEdit from "vue-material-design-icons/AccountEdit.vue"; import AccountEdit from "vue-material-design-icons/AccountEdit.vue";
import Clock from "vue-material-design-icons/Clock.vue"; import Clock from "vue-material-design-icons/Clock.vue";
import Lock from "vue-material-design-icons/Lock.vue";
import Link from "vue-material-design-icons/Link.vue";
import MbzTag from "@/components/TagElement.vue"; import MbzTag from "@/components/TagElement.vue";
import { PostVisibility } from "@/types/enums";
import { useI18n } from "vue-i18n";
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
@ -71,34 +93,27 @@ const props = withDefaults(
{ isCurrentActorMember: false } { isCurrentActorMember: false }
); );
const { t } = useI18n({ useScope: "global" });
const dateFnsLocale = inject<Locale>("dateFnsLocale"); const dateFnsLocale = inject<Locale>("dateFnsLocale");
const postTags = computed(() => (props.post.tags ?? []).slice(0, 3)); const postTags = computed(() => (props.post.tags ?? []).slice(0, 3));
const publishedAt = computed((): Date => { const publishedAt = computed((): Date | undefined => {
return new Date((props.post.publishAt ?? props.post.insertedAt) as Date); const date = props.post.publishAt ?? props.post.insertedAt;
if (!date) return undefined;
return new Date(date);
}); });
const isBeforeLastWeek = computed((): boolean => { const isBeforeLastWeek = computed((): boolean => {
return isBefore(publishedAt.value, subWeeks(new Date(), 1)); return (
publishedAt.value !== undefined &&
isBefore(publishedAt.value, subWeeks(new Date(), 1))
);
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@use "@/styles/_mixins" as *; @use "@/styles/_mixins" as *;
// .post-minimalist-card-wrapper {
// display: grid;
// grid-gap: 5px 10px;
// grid-template-areas: "preview" "body";
// text-decoration: none;
// // width: 100%;
// // color: initial;
// // @include desktop {
// grid-template-columns: 200px 3fr;
// grid-template-areas: "preview body";
// // }
.title-info-wrapper { .title-info-wrapper {
.post-minimalist-title { .post-minimalist-title {
font-size: 18px; font-size: 18px;

View file

@ -7,7 +7,7 @@
> >
<o-notification <o-notification
variant="warning" variant="warning"
v-if="post.visibility !== PostVisibility.PUBLIC" v-if="post.visibility === PostVisibility.UNLISTED"
:closable="false" :closable="false"
> >
{{ {{

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="resource-wrapper" dir="auto"> <div class="resource-wrapper bg-white dark:bg-transparent" dir="auto">
<router-link <router-link
:to="{ :to="{
name: RouteName.RESOURCE_FOLDER, name: RouteName.RESOURCE_FOLDER,

View file

@ -1,7 +1,12 @@
<template> <template>
<div class="flex flex-1 items-center w-full" dir="auto"> <div
class="flex flex-1 items-center w-full bg-white dark:bg-transparent"
dir="auto"
>
<a :href="resource.resourceUrl" target="_blank"> <a :href="resource.resourceUrl" target="_blank">
<div class="preview text-mbz-purple dark:text-mbz-purple-300"> <div
class="min-w-fit relative flex items-center justify-center text-mbz-purple dark:text-mbz-purple-300"
>
<div <div
v-if=" v-if="
resource.type && resource.type &&
@ -14,10 +19,12 @@
customSize="48" customSize="48"
/> />
</div> </div>
<div <img
class="preview-image"
v-else-if="resource.metadata && resource.metadata.imageRemoteUrl" v-else-if="resource.metadata && resource.metadata.imageRemoteUrl"
:style="`background-image: url(${resource.metadata.imageRemoteUrl})`" :src="resource.metadata.imageRemoteUrl"
alt=""
height="48"
width="48"
/> />
<div class="preview-type" v-else> <div class="preview-type" v-else>
<Link :size="48" /> <Link :size="48" />
@ -99,25 +106,6 @@ a {
overflow: hidden; overflow: hidden;
flex: 1; flex: 1;
.preview {
flex: 0 0 50px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
.preview-image {
border-radius: 4px 0 0 4px;
display: block;
margin: 0;
width: 100%;
height: 100%;
object-fit: cover;
background-size: cover;
background-position: 50%;
}
}
.body { .body {
img.favicon { img.favicon {
display: inline-block; display: inline-block;

View file

@ -34,7 +34,7 @@
import { computed, onMounted, ref } from "vue"; import { computed, onMounted, ref } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
type position = type positionValues =
| "top-right" | "top-right"
| "top" | "top"
| "top-left" | "top-left"
@ -49,7 +49,7 @@ const props = withDefaults(
onAction?: () => any; onAction?: () => any;
cancelText?: string | null; cancelText?: string | null;
variant?: string; variant?: string;
position?: position; position?: positionValues;
pauseOnHover?: boolean; pauseOnHover?: boolean;
indefinite?: boolean; indefinite?: boolean;
}>(), }>(),

View file

@ -35,7 +35,7 @@ export const AUTORIZE_APPLICATION = gql`
export const AUTORIZE_DEVICE_APPLICATION = gql` export const AUTORIZE_DEVICE_APPLICATION = gql`
mutation AuthorizeDeviceApplication( mutation AuthorizeDeviceApplication(
$applicationClientId: String! $applicationClientId: String!
$userCode: String $userCode: String!
) { ) {
authorizeDeviceApplication( authorizeDeviceApplication(
clientId: $applicationClientId clientId: $applicationClientId

View file

@ -295,7 +295,7 @@ export const JOIN_EVENT = gql`
$email: String $email: String
$message: String $message: String
$locale: String $locale: String
$timezone: String $timezone: Timezone
) { ) {
joinEvent( joinEvent(
eventId: $eventId eventId: $eventId
@ -482,6 +482,9 @@ export const EXPORT_EVENT_PARTICIPATIONS = gql`
$format: ExportFormatEnum $format: ExportFormatEnum
$roles: [ParticipantRoleEnum] $roles: [ParticipantRoleEnum]
) { ) {
exportEventParticipants(eventId: $eventId, format: $format, roles: $roles) exportEventParticipants(eventId: $eventId, format: $format, roles: $roles) {
path
format
}
} }
`; `;

View file

@ -186,6 +186,9 @@ export const GROUP_BASIC_FIELDS_FRAGMENTS = gql`
...PostBasicFields ...PostBasicFields
} }
} }
members {
total
}
} }
${ACTOR_FRAGMENT} ${ACTOR_FRAGMENT}
${ADDRESS_FRAGMENT} ${ADDRESS_FRAGMENT}

View file

@ -151,7 +151,7 @@ export const LOGGED_USER_TIMEZONE = gql`
export const SET_USER_SETTINGS = gql` export const SET_USER_SETTINGS = gql`
mutation SetUserSettings( mutation SetUserSettings(
$timezone: String $timezone: Timezone
$notificationOnDay: Boolean $notificationOnDay: Boolean
$notificationEachWeek: Boolean $notificationEachWeek: Boolean
$notificationBeforeEvent: Boolean $notificationBeforeEvent: Boolean

View file

@ -707,7 +707,6 @@
"Public event": "فعالية للعامة", "Public event": "فعالية للعامة",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "انشرها", "Publish": "انشرها",

View file

@ -707,7 +707,6 @@
"Public event": "", "Public event": "",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "", "Publish": "",

View file

@ -707,7 +707,6 @@
"Public event": "", "Public event": "",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "", "Publish": "",

View file

@ -707,7 +707,6 @@
"Public event": "Activitat pública", "Public event": "Activitat pública",
"Public feeds": "Fluxos públics", "Public feeds": "Fluxos públics",
"Public iCal Feed": "Flux iCal públic", "Public iCal Feed": "Flux iCal públic",
"Public page": "Pàgina pública",
"Public preview": "Previsualització pública", "Public preview": "Previsualització pública",
"Publication date": "Data de publicació", "Publication date": "Data de publicació",
"Publish": "Publica", "Publish": "Publica",

View file

@ -110,8 +110,10 @@
"An event from one of my groups has been published": "V jedné z mých skupin byla zveřejněna událost", "An event from one of my groups has been published": "V jedné z mých skupin byla zveřejněna událost",
"An event from one of my groups has been updated or deleted": "Událost z jedné z mých skupin byla aktualizována nebo odstraněna", "An event from one of my groups has been updated or deleted": "Událost z jedné z mých skupin byla aktualizována nebo odstraněna",
"An instance is an installed version of the Mobilizon software running on a server. An instance can be run by anyone using the {mobilizon_software} or other federated apps, aka the “fediverse”. This instance's name is {instance_name}. Mobilizon is a federated network of multiple instances (just like email servers), users registered on different instances may communicate even though they didn't register on the same instance.": "Instance je nainstalovaná verze softwaru Mobilizon spuštěná na serveru. Instanci může spustit kdokoli, kdo používá {mobilizon_software} nebo jiné federativní aplikace, tzv. \"fediverse\". Název této instance je {instance_name}. Mobilizon je federativní síť více instancí (stejně jako e-mailové servery), uživatelé registrovaní v různých instancích spolu mohou komunikovat, i když se nezaregistrovali ve stejné instanci.", "An instance is an installed version of the Mobilizon software running on a server. An instance can be run by anyone using the {mobilizon_software} or other federated apps, aka the “fediverse”. This instance's name is {instance_name}. Mobilizon is a federated network of multiple instances (just like email servers), users registered on different instances may communicate even though they didn't register on the same instance.": "Instance je nainstalovaná verze softwaru Mobilizon spuštěná na serveru. Instanci může spustit kdokoli, kdo používá {mobilizon_software} nebo jiné federativní aplikace, tzv. \"fediverse\". Název této instance je {instance_name}. Mobilizon je federativní síť více instancí (stejně jako e-mailové servery), uživatelé registrovaní v různých instancích spolu mohou komunikovat, i když se nezaregistrovali ve stejné instanci.",
"An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events on your behalf, automatically and remotely.": "„Aplikační programovací rozhraní“ neboli „API“ je komunikační protokol, který umožňuje softwarovým komponentám vzájemně komunikovat. Mobilizon API například umožňuje softwarovým nástrojům třetích stran komunikovat s instancemi Mobilizon a provádět určité akce, jako je odesílání událostí vaším jménem, automaticky a na dálku.",
"An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events, automatically and remotely.": "\"Aplikační programové rozhraní\" nebo \"API\" je komunikační protokol, který umožňuje softwarovým komponentám vzájemně komunikovat. Rozhraní API Mobilizonu může například umožnit softwarovým nástrojům třetích stran komunikovat s instancemi Mobilizonu a automaticky a na dálku provádět určité akce, například odesílání událostí.", "An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events, automatically and remotely.": "\"Aplikační programové rozhraní\" nebo \"API\" je komunikační protokol, který umožňuje softwarovým komponentám vzájemně komunikovat. Rozhraní API Mobilizonu může například umožnit softwarovým nástrojům třetích stran komunikovat s instancemi Mobilizonu a automaticky a na dálku provádět určité akce, například odesílání událostí.",
"And {number} comments": "A {number} komentářů", "And {number} comments": "A {number} komentářů",
"Announcements": "Oznámení",
"Announcements and mentions notifications are always sent straight away.": "Oznámení a zmínky jsou vždy odesílány ihned.", "Announcements and mentions notifications are always sent straight away.": "Oznámení a zmínky jsou vždy odesílány ihned.",
"Anonymous participant": "Anonymní účastník", "Anonymous participant": "Anonymní účastník",
"Anonymous participants will be asked to confirm their participation through e-mail.": "Anonymní účastníci budou požádáni o potvrzení své účasti e-mailem.", "Anonymous participants will be asked to confirm their participation through e-mail.": "Anonymní účastníci budou požádáni o potvrzení své účasti e-mailem.",
@ -860,7 +862,6 @@
"Public event": "Veřejná událost", "Public event": "Veřejná událost",
"Public feeds": "Veřejné kanály", "Public feeds": "Veřejné kanály",
"Public iCal Feed": "Veřejný iCal kanál", "Public iCal Feed": "Veřejný iCal kanál",
"Public page": "Veřejná strana",
"Public preview": "Veřejný náhled", "Public preview": "Veřejný náhled",
"Publication date": "Datum zveřejnění", "Publication date": "Datum zveřejnění",
"Publish": "Zveřejnit", "Publish": "Zveřejnit",
@ -1348,6 +1349,7 @@
"You excluded member {member}.": "Vyloučili jste člena {member}.", "You excluded member {member}.": "Vyloučili jste člena {member}.",
"You have attended {count} events in the past.": "V minulosti jste se nezúčastnili žádné akce.|V minulosti jste se zúčastnili jedné akce.|V minulosti jste se zúčastnili {count} akcí.", "You have attended {count} events in the past.": "V minulosti jste se nezúčastnili žádné akce.|V minulosti jste se zúčastnili jedné akce.|V minulosti jste se zúčastnili {count} akcí.",
"You have been invited by {invitedBy} to the following group:": "Byli jste pozváni společností {invitedBy} do následující skupiny:", "You have been invited by {invitedBy} to the following group:": "Byli jste pozváni společností {invitedBy} do následující skupiny:",
"You have been logged-out": "Byli jste odhlášeni",
"You have been removed from this group's members.": "Byli jste odstraněni z členů této skupiny.", "You have been removed from this group's members.": "Byli jste odstraněni z členů této skupiny.",
"You have cancelled your participation": "Zrušili jste svou účast", "You have cancelled your participation": "Zrušili jste svou účast",
"You have one event in {days} days.": "Za {days} dní nemáte žádnou událost | Za {days} dní máte jednu událost. | Máte {count} událostí za {days} dní", "You have one event in {days} days.": "Za {days} dní nemáte žádnou událost | Za {days} dní máte jednu událost. | Máte {count} událostí za {days} dní",

View file

@ -707,7 +707,6 @@
"Public event": "", "Public event": "",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "", "Publish": "",

View file

@ -841,7 +841,6 @@
"Public event": "Öffentliche Veranstaltung", "Public event": "Öffentliche Veranstaltung",
"Public feeds": "Öffentliche Feeds", "Public feeds": "Öffentliche Feeds",
"Public iCal Feed": "Öffentlicher iCal-Feed", "Public iCal Feed": "Öffentlicher iCal-Feed",
"Public page": "Öffentliche Seite",
"Public preview": "Öffentliche Vorschau", "Public preview": "Öffentliche Vorschau",
"Publication date": "Erstellungsdatum", "Publication date": "Erstellungsdatum",
"Publish": "Veröffentlichen", "Publish": "Veröffentlichen",

View file

@ -430,7 +430,6 @@
"Text": "Text", "Text": "Text",
"Upcoming events": "Upcoming events", "Upcoming events": "Upcoming events",
"Resources": "Resources", "Resources": "Resources",
"Public page": "Public page",
"Discussions": "Discussions", "Discussions": "Discussions",
"No public upcoming events": "No public upcoming events", "No public upcoming events": "No public upcoming events",
"Latest posts": "Latest posts", "Latest posts": "Latest posts",
@ -1564,5 +1563,9 @@
"This application will be allowed to publish and manage events, post and manage comments, participate to events, manage all of your groups, including group events, resources, posts and discussions. It will also be allowed to manage your account and profile settings.": "This application will be allowed to publish and manage events, post and manage comments, participate to events, manage all of your groups, including group events, resources, posts and discussions. It will also be allowed to manage your account and profile settings.", "This application will be allowed to publish and manage events, post and manage comments, participate to events, manage all of your groups, including group events, resources, posts and discussions. It will also be allowed to manage your account and profile settings.": "This application will be allowed to publish and manage events, post and manage comments, participate to events, manage all of your groups, including group events, resources, posts and discussions. It will also be allowed to manage your account and profile settings.",
"No apps authorized yet": "No apps authorized yet", "No apps authorized yet": "No apps authorized yet",
"You have been logged-out": "You have been logged-out", "You have been logged-out": "You have been logged-out",
"An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events on your behalf, automatically and remotely.": "An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events on your behalf, automatically and remotely." "An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events on your behalf, automatically and remotely.": "An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events on your behalf, automatically and remotely.",
"Announcements": "Announcements",
"Application authorized": "Application authorized",
"Check your device to continue. You may now close this window.": "Check your device to continue. You may now close this window.",
"Participants to {eventTitle}": "Participants to {eventTitle}"
} }

View file

@ -707,7 +707,6 @@
"Public event": "", "Public event": "",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "", "Publish": "",

View file

@ -810,7 +810,6 @@
"Public event": "Evento público", "Public event": "Evento público",
"Public feeds": "Feeds públicos", "Public feeds": "Feeds públicos",
"Public iCal Feed": "Feed público de iCal", "Public iCal Feed": "Feed público de iCal",
"Public page": "Página pública",
"Public preview": "Vista previa pública", "Public preview": "Vista previa pública",
"Publication date": "Fecha de publicación", "Publication date": "Fecha de publicación",
"Publish": "Publicar", "Publish": "Publicar",

View file

@ -707,7 +707,6 @@
"Public event": "", "Public event": "",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "", "Publish": "",

View file

@ -707,7 +707,6 @@
"Public event": "", "Public event": "",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "", "Publish": "",

View file

@ -707,7 +707,6 @@
"Public event": "Julkinen tapahtuma", "Public event": "Julkinen tapahtuma",
"Public feeds": "Julkiset syötteet", "Public feeds": "Julkiset syötteet",
"Public iCal Feed": "Julkinen iCal-syöte", "Public iCal Feed": "Julkinen iCal-syöte",
"Public page": "Julkinen sivu",
"Public preview": "Julkinen esikatselu", "Public preview": "Julkinen esikatselu",
"Publication date": "Julkaisupäivä", "Publication date": "Julkaisupäivä",
"Publish": "Julkaise", "Publish": "Julkaise",

View file

@ -47,6 +47,17 @@
"Accept": "Accepter", "Accept": "Accepter",
"Accept follow": "Accepter le suivi", "Accept follow": "Accepter le suivi",
"Accepted": "Accepté", "Accepted": "Accepté",
"Access followed groups": "Accéder à la liste des groupes suivis",
"Access group activities": "Accéder aux activités des groupes",
"Access group discussions": "Accéder aux discussions des groupes",
"Access group events": "Accéder aux événements des groupes",
"Access group followers": "Accéder à la liste des abonnés des groupes",
"Access group members": "Accéder à la liste des membres des groupes",
"Access group memberships": "Accéder à la liste de vos adhésions à des groupes",
"Access group todo-lists": "Accéder aux listes de tâches des groupes",
"Access organized events": "Accéder à la liste de vos événements organisés",
"Access participations": "Accéder à la liste de vos participations",
"Access your group's resources": "Accéder aux ressources de vos groupes",
"Accessibility": "Accessibilité", "Accessibility": "Accessibilité",
"Accessible only by link": "Accessible uniquement par lien", "Accessible only by link": "Accessible uniquement par lien",
"Accessible only to members": "Accessible uniquement aux membres", "Accessible only to members": "Accessible uniquement aux membres",
@ -99,8 +110,10 @@
"An event from one of my groups has been published": "Un événement d'un de mes groupes a été publié", "An event from one of my groups has been published": "Un événement d'un de mes groupes a été publié",
"An event from one of my groups has been updated or deleted": "Un événement d'un de mes groupes a été mis à jour ou supprimé", "An event from one of my groups has been updated or deleted": "Un événement d'un de mes groupes a été mis à jour ou supprimé",
"An instance is an installed version of the Mobilizon software running on a server. An instance can be run by anyone using the {mobilizon_software} or other federated apps, aka the “fediverse”. This instance's name is {instance_name}. Mobilizon is a federated network of multiple instances (just like email servers), users registered on different instances may communicate even though they didn't register on the same instance.": "Une instance est une version du logiciel Mobilizon fonctionnant sur un serveur. Une instance peut être gérée par n'importe qui avec le {mobilizon_software} ou d'autres applications fédérées, correspondant au « fediverse ». Cette instance se nomme {instance_name}. Mobilizon est un réseau fédéré de multiples instances (tout comme des serveurs email), des utilisateur·rice·s inscrites sur différentes instances peuvent communiquer bien qu'il·elle·s ne se soient pas enregistré·e·s sur la même instance.", "An instance is an installed version of the Mobilizon software running on a server. An instance can be run by anyone using the {mobilizon_software} or other federated apps, aka the “fediverse”. This instance's name is {instance_name}. Mobilizon is a federated network of multiple instances (just like email servers), users registered on different instances may communicate even though they didn't register on the same instance.": "Une instance est une version du logiciel Mobilizon fonctionnant sur un serveur. Une instance peut être gérée par n'importe qui avec le {mobilizon_software} ou d'autres applications fédérées, correspondant au « fediverse ». Cette instance se nomme {instance_name}. Mobilizon est un réseau fédéré de multiples instances (tout comme des serveurs email), des utilisateur·rice·s inscrites sur différentes instances peuvent communiquer bien qu'il·elle·s ne se soient pas enregistré·e·s sur la même instance.",
"An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events on your behalf, automatically and remotely.": "Une « interface de programmation dapplication » ou « API » est un protocole de communication qui permet aux composants logiciels de communiquer entre eux. L'API Mobilizon, par exemple, peut permettre à des outils logiciels tiers de communiquer avec les instances Mobilizon pour effectuer certaines actions, telles que la publication d'événements en votre nom, automatiquement et à distance.",
"An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events, automatically and remotely.": "Une « interface de programmation d'application » ou « API » est un protocole de communication qui permet à des composants logiciels de communiquer entre eux. L'API de Mobilizon, par exemple, peut permettre à des outils logiciels tiers de communiquer avec des instances de Mobilizon pour effectuer certaines actions, comme la publication d'événements, automatiquement et à distance.", "An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events, automatically and remotely.": "Une « interface de programmation d'application » ou « API » est un protocole de communication qui permet à des composants logiciels de communiquer entre eux. L'API de Mobilizon, par exemple, peut permettre à des outils logiciels tiers de communiquer avec des instances de Mobilizon pour effectuer certaines actions, comme la publication d'événements, automatiquement et à distance.",
"And {number} comments": "Et {number} commentaires", "And {number} comments": "Et {number} commentaires",
"Announcements": "Annonces",
"Announcements and mentions notifications are always sent straight away.": "Les notifications d'annonces et de mentions sont toujours envoyées directement.", "Announcements and mentions notifications are always sent straight away.": "Les notifications d'annonces et de mentions sont toujours envoyées directement.",
"Anonymous participant": "Participant⋅e anonyme", "Anonymous participant": "Participant⋅e anonyme",
"Anonymous participants will be asked to confirm their participation through e-mail.": "Les participants anonymes devront confirmer leur participation par email.", "Anonymous participants will be asked to confirm their participation through e-mail.": "Les participants anonymes devront confirmer leur participation par email.",
@ -113,8 +126,11 @@
"Anyone can request being a member, but an administrator needs to approve the membership.": "N'importe qui peut demander à être membre, mais un⋅e administrateur⋅ice devra approuver leur adhésion.", "Anyone can request being a member, but an administrator needs to approve the membership.": "N'importe qui peut demander à être membre, mais un⋅e administrateur⋅ice devra approuver leur adhésion.",
"Anyone wanting to be a member from your group will be able to from your group page.": "N'importe qui voulant devenir membre pourra le faire depuis votre page de groupe.", "Anyone wanting to be a member from your group will be able to from your group page.": "N'importe qui voulant devenir membre pourra le faire depuis votre page de groupe.",
"Application": "Application", "Application": "Application",
"Application not found": "Application non trouvée",
"Application was revoked": "L'application a été révoquée",
"Apply filters": "Appliquer les filtres", "Apply filters": "Appliquer les filtres",
"Approve member": "Approuver le ou la membre", "Approve member": "Approuver le ou la membre",
"Apps": "Applications",
"Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "Êtes-vous vraiment certain⋅e de vouloir supprimer votre compte ? Vous allez tout perdre. Identités, paramètres, événements créés, messages et participations disparaîtront pour toujours.", "Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "Êtes-vous vraiment certain⋅e de vouloir supprimer votre compte ? Vous allez tout perdre. Identités, paramètres, événements créés, messages et participations disparaîtront pour toujours.",
"Are you sure you want to <b>completely delete</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>.": "Êtes-vous certain·e de vouloir <b>complètement supprimer</b> ce groupe ? Tous les membres - y compris ceux·elles sur d'autres instances - seront notifié·e·s et supprimé·e·s du groupe, et <b>toutes les données associées au groupe (événements, billets, discussions, todos…) seront irrémédiablement détruites</b>.", "Are you sure you want to <b>completely delete</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>.": "Êtes-vous certain·e de vouloir <b>complètement supprimer</b> ce groupe ? Tous les membres - y compris ceux·elles sur d'autres instances - seront notifié·e·s et supprimé·e·s du groupe, et <b>toutes les données associées au groupe (événements, billets, discussions, todos…) seront irrémédiablement détruites</b>.",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Êtes-vous certain⋅e de vouloir <b>supprimer</b> ce commentaire ? Cette action ne peut pas être annulée.", "Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Êtes-vous certain⋅e de vouloir <b>supprimer</b> ce commentaire ? Cette action ne peut pas être annulée.",
@ -133,6 +149,10 @@
"Assigned to": "Assigné à", "Assigned to": "Assigné à",
"Atom feed for events and posts": "Flux Atom pour les événements et les billets", "Atom feed for events and posts": "Flux Atom pour les événements et les billets",
"Attending": "Participant⋅e", "Attending": "Participant⋅e",
"Authorize": "Autoriser",
"Authorize application": "Autoriser l'application",
"Authorized on {authorization_date}": "Authorisée le {authorization_date}",
"Autorize this application to access your account?": "Autoriser cette application à accéder à votre compte ?",
"Avatar": "Avatar", "Avatar": "Avatar",
"Back to group list": "Retour à la liste des groupes", "Back to group list": "Retour à la liste des groupes",
"Back to homepage": "Retour à la page d'accueil", "Back to homepage": "Retour à la page d'accueil",
@ -215,6 +235,7 @@
"Confirmed: Will happen": "Confirmé : aura lieu", "Confirmed: Will happen": "Confirmé : aura lieu",
"Congratulations, your account is now created!": "Bravo, votre compte est dorénavant créé !", "Congratulations, your account is now created!": "Bravo, votre compte est dorénavant créé !",
"Contact": "Contact", "Contact": "Contact",
"Continue": "Continuer",
"Continue editing": "Continuer la modification", "Continue editing": "Continuer la modification",
"Cookies and Local storage": "Cookies et stockage local", "Cookies and Local storage": "Cookies et stockage local",
"Copy URL to clipboard": "Copier l'URL dans le presse-papiers", "Copy URL to clipboard": "Copier l'URL dans le presse-papiers",
@ -228,18 +249,23 @@
"Create a new group": "Créer un nouveau groupe", "Create a new group": "Créer un nouveau groupe",
"Create a new identity": "Créer une nouvelle identité", "Create a new identity": "Créer une nouvelle identité",
"Create a new list": "Créer une nouvelle liste", "Create a new list": "Créer une nouvelle liste",
"Create a new metadata element": "Créer un nouvel élément de métadonnées",
"Create a new profile": "Créer un nouveau profil", "Create a new profile": "Créer un nouveau profil",
"Create a pad": "Créer un pad", "Create a pad": "Créer un pad",
"Create a videoconference": "Créer une visio-conférence", "Create a videoconference": "Créer une visio-conférence",
"Create an account": "Créer un compte", "Create an account": "Créer un compte",
"Create discussion": "Créer une discussion", "Create discussion": "Créer une discussion",
"Create event": "Créer un événement", "Create event": "Créer un événement",
"Create feed tokens": "Créer des jetons de flux",
"Create group": "Créer un groupe", "Create group": "Créer un groupe",
"Create group discussions": "Créer des discussions de groupes",
"Create group resources": "Créer des ressources de groupes",
"Create identity": "Créer une identité", "Create identity": "Créer une identité",
"Create my event": "Créer mon événement", "Create my event": "Créer mon événement",
"Create my group": "Créer mon groupe", "Create my group": "Créer mon groupe",
"Create my profile": "Créer mon profil", "Create my profile": "Créer mon profil",
"Create new links": "Créer de nouveaux liens", "Create new links": "Créer de nouveaux liens",
"Create new profiles": "Créer des nouveaux profils",
"Create resource": "Créer une ressource", "Create resource": "Créer une ressource",
"Create the discussion": "Créer la discussion", "Create the discussion": "Créer la discussion",
"Create to-do lists for all the tasks you need to do, assign them and set due dates.": "Créez des listes de choses à faire pour toutes les tâches que vous devez faire, attribuez les et fixez des dates d'échéance.", "Create to-do lists for all the tasks you need to do, assign them and set due dates.": "Créez des listes de choses à faire pour toutes les tâches que vous devez faire, attribuez les et fixez des dates d'échéance.",
@ -268,13 +294,20 @@
"Delete Comment": "Supprimer le commentaire", "Delete Comment": "Supprimer le commentaire",
"Delete Event": "Supprimer l'événement", "Delete Event": "Supprimer l'événement",
"Delete account": "Suppression du compte", "Delete account": "Suppression du compte",
"Delete comments": "Supprimer des commentaires",
"Delete conversation": "Supprimer la conversation", "Delete conversation": "Supprimer la conversation",
"Delete discussion": "Supprimer la discussion", "Delete discussion": "Supprimer la discussion",
"Delete event": "Supprimer un événement", "Delete event": "Supprimer un événement",
"Delete events": "Supprimer des événements",
"Delete everything": "Tout supprimer", "Delete everything": "Tout supprimer",
"Delete feed tokens": "Supprimer les jetons de flux",
"Delete group": "Supprimer le groupe", "Delete group": "Supprimer le groupe",
"Delete group discussions": "Supprimer des discussions de groupes",
"Delete group posts": "Supprimer des billets de groupes",
"Delete group resources": "Supprimer des ressources de groupes",
"Delete my account": "Supprimer mon compte", "Delete my account": "Supprimer mon compte",
"Delete post": "Supprimer le billet", "Delete post": "Supprimer le billet",
"Delete profiles": "Supprimer des profils",
"Delete this discussion": "Supprimer cette discussion", "Delete this discussion": "Supprimer cette discussion",
"Delete this identity": "Supprimer cette identité", "Delete this identity": "Supprimer cette identité",
"Delete your identity": "Supprimer votre identité", "Delete your identity": "Supprimer votre identité",
@ -288,6 +321,7 @@
"Describe your event": "Décrivez votre événement", "Describe your event": "Décrivez votre événement",
"Description": "Description", "Description": "Description",
"Details": "Détails", "Details": "Détails",
"Device activation": "Activation de l'appareil",
"Didn't receive the instructions?": "Vous n'avez pas reçu les instructions ?", "Didn't receive the instructions?": "Vous n'avez pas reçu les instructions ?",
"Disabled": "Désactivé", "Disabled": "Désactivé",
"Discussions": "Discussions", "Discussions": "Discussions",
@ -326,6 +360,7 @@
"Emails usually don't contain capitals, make sure you haven't made a typo.": "Les emails ne contiennent d'ordinaire pas de capitales, assurez-vous de n'avoir pas fait de faute de frappe.", "Emails usually don't contain capitals, make sure you haven't made a typo.": "Les emails ne contiennent d'ordinaire pas de capitales, assurez-vous de n'avoir pas fait de faute de frappe.",
"Enabled": "Activé", "Enabled": "Activé",
"Ends on…": "Se termine le…", "Ends on…": "Se termine le…",
"Enter the code displayed on your device": "Saisissez le code affiché sur votre appareil",
"Enter the link URL": "Entrez l'URL du lien", "Enter the link URL": "Entrez l'URL du lien",
"Enter your email address below, and we'll email you instructions on how to change your password.": "Indiquez votre adresse e-mail ci-dessous. Nous vous enverrons des instructions concernant la modification de votre mot de passe.", "Enter your email address below, and we'll email you instructions on how to change your password.": "Indiquez votre adresse e-mail ci-dessous. Nous vous enverrons des instructions concernant la modification de votre mot de passe.",
"Enter your own privacy policy. HTML tags allowed. The {mobilizon_privacy_policy} is provided as template.": "Entrez votre propre politique de confidentialité. Les balises HTML sont autorisées. La {mobilizon_privacy_policy} est fournie comme modèle.", "Enter your own privacy policy. HTML tags allowed. The {mobilizon_privacy_policy} is provided as template.": "Entrez votre propre politique de confidentialité. Les balises HTML sont autorisées. La {mobilizon_privacy_policy} est fournie comme modèle.",
@ -540,6 +575,7 @@
"Last published events": "Derniers événements publiés", "Last published events": "Derniers événements publiés",
"Last seen on": "Vu pour la dernière fois", "Last seen on": "Vu pour la dernière fois",
"Last sign-in": "Dernière connexion", "Last sign-in": "Dernière connexion",
"Last used on {last_used_date}": "Utilisée pour la dernière fois le {last_used_date}",
"Last week": "La semaine dernière", "Last week": "La semaine dernière",
"Latest posts": "Derniers billets", "Latest posts": "Derniers billets",
"Learn more": "En apprendre plus", "Learn more": "En apprendre plus",
@ -575,8 +611,14 @@
"Login status": "Statut de connexion", "Login status": "Statut de connexion",
"Main languages you/your moderators speak": "Principales langues parlées par vous / vos modérateurs", "Main languages you/your moderators speak": "Principales langues parlées par vous / vos modérateurs",
"Make sure that all words are spelled correctly.": "Vérifiez lorthographe des termes de recherche.", "Make sure that all words are spelled correctly.": "Vérifiez lorthographe des termes de recherche.",
"Manage activity settings": "Gérer les paramètres d'activité",
"Manage event participations": "Gérer les participations aux événements",
"Manage group members": "Gérer les membres des groupes",
"Manage group memberships": "Gérer vos adhésions à des groupes",
"Manage participations": "Gérer les participations", "Manage participations": "Gérer les participations",
"Manage push notification settings": "Gérer les paramètres de notification push",
"Manually approve new followers": "Approuver les nouvelles demandes de suivi manuellement", "Manually approve new followers": "Approuver les nouvelles demandes de suivi manuellement",
"Manually enter address": "Saisir manuellement l'adresse",
"Manually invite new members": "Inviter des nouveaux·elles membres manuellement", "Manually invite new members": "Inviter des nouveaux·elles membres manuellement",
"Map": "Carte", "Map": "Carte",
"Mark as resolved": "Marquer comme résolu", "Mark as resolved": "Marquer comme résolu",
@ -606,6 +648,7 @@
"Moderation log": "Journaux de modération", "Moderation log": "Journaux de modération",
"Moderation logs": "Journaux de modération", "Moderation logs": "Journaux de modération",
"Moderator": "Moderateur·ice", "Moderator": "Moderateur·ice",
"Modify all of your account's data": "Modifier toutes les données de votre compte",
"More options": "Plus d'options", "More options": "Plus d'options",
"Most recently published": "Publié récemment", "Most recently published": "Publié récemment",
"Move": "Déplacer", "Move": "Déplacer",
@ -620,6 +663,7 @@
"NOTE! The default terms have not been checked over by a lawyer and thus are unlikely to provide full legal protection for all situations for an instance admin using them. They are also not specific to all countries and jurisdictions. If you are unsure, please check with a lawyer.": "REMARQUE : les conditions par défaut n'ont pas été vérifiées par un·e juriste et sont donc susceptibles de ne pas offrir une protection juridique complète dans toutes les situations pour un·e administrateur·rice d'instance qui les utilise. Elles ne sont pas non plus spécifiques à tous les pays et juridictions. Si vous n'êtes pas sûr·e, veuillez consulter un·e juriste.", "NOTE! The default terms have not been checked over by a lawyer and thus are unlikely to provide full legal protection for all situations for an instance admin using them. They are also not specific to all countries and jurisdictions. If you are unsure, please check with a lawyer.": "REMARQUE : les conditions par défaut n'ont pas été vérifiées par un·e juriste et sont donc susceptibles de ne pas offrir une protection juridique complète dans toutes les situations pour un·e administrateur·rice d'instance qui les utilise. Elles ne sont pas non plus spécifiques à tous les pays et juridictions. Si vous n'êtes pas sûr·e, veuillez consulter un·e juriste.",
"Name": "Nom", "Name": "Nom",
"Navigated to {pageTitle}": "Navigué vers {pageTitle}", "Navigated to {pageTitle}": "Navigué vers {pageTitle}",
"Never used": "Jamais utilisée",
"New discussion": "Nouvelle discussion", "New discussion": "Nouvelle discussion",
"New email": "Nouvelle adresse e-mail", "New email": "Nouvelle adresse e-mail",
"New folder": "Nouveau dossier", "New folder": "Nouveau dossier",
@ -634,6 +678,7 @@
"Next page": "Page suivante", "Next page": "Page suivante",
"Next week": "La semaine prochaine", "Next week": "La semaine prochaine",
"No address defined": "Aucune adresse définie", "No address defined": "Aucune adresse définie",
"No apps authorized yet": "Aucune application autorisée pour le moment",
"No categories with public upcoming events on this instance were found.": "Aucune catégorie avec des événements publics à venir n'a été trouvée.", "No categories with public upcoming events on this instance were found.": "Aucune catégorie avec des événements publics à venir n'a été trouvée.",
"No closed reports yet": "Aucun signalement fermé pour le moment", "No closed reports yet": "Aucun signalement fermé pour le moment",
"No comment": "Pas de commentaire", "No comment": "Pas de commentaire",
@ -789,6 +834,7 @@
"Post a comment": "Ajouter un commentaire", "Post a comment": "Ajouter un commentaire",
"Post a reply": "Envoyer une réponse", "Post a reply": "Envoyer une réponse",
"Post body": "Corps du billet", "Post body": "Corps du billet",
"Post comments": "Poster des commentaires",
"Post {eventTitle} reported": "Billet {eventTitle} signalé", "Post {eventTitle} reported": "Billet {eventTitle} signalé",
"Postal Code": "Code postal", "Postal Code": "Code postal",
"Posts": "Billets", "Posts": "Billets",
@ -816,10 +862,11 @@
"Public event": "Événement public", "Public event": "Événement public",
"Public feeds": "Flux publics", "Public feeds": "Flux publics",
"Public iCal Feed": "Flux iCal public", "Public iCal Feed": "Flux iCal public",
"Public page": "Page publique",
"Public preview": "Aperçu public", "Public preview": "Aperçu public",
"Publication date": "Date de publication", "Publication date": "Date de publication",
"Publish": "Publier", "Publish": "Publier",
"Publish events": "Publier des événements",
"Publish group posts": "Publier des billets de groupes",
"Published by {name}": "Publié par {name}", "Published by {name}": "Publié par {name}",
"Published events with <b>{comments}</b> comments and <b>{participations}</b> confirmed participations": "Événements publiés avec <b>{comments}</b> commentaires et <b>{participations}</b> participations confirmées", "Published events with <b>{comments}</b> comments and <b>{participations}</b> confirmed participations": "Événements publiés avec <b>{comments}</b> commentaires et <b>{participations}</b> participations confirmées",
"Published events with {comments} comments and {participations} confirmed participations": "Événements publiés avec {comments} commentaires et {participations} participations confirmées", "Published events with {comments} comments and {participations} confirmed participations": "Événements publiés avec {comments} commentaires et {participations} participations confirmées",
@ -827,6 +874,7 @@
"Quote": "Citation", "Quote": "Citation",
"RSS/Atom Feed": "Flux RSS/Atom", "RSS/Atom Feed": "Flux RSS/Atom",
"Radius": "Rayon", "Radius": "Rayon",
"Read all of your account's data": "Lire toutes les données de votre compte",
"Recap every week": "Récapitulatif hebdomadaire", "Recap every week": "Récapitulatif hebdomadaire",
"Receive one email for each activity": "Recevoir un e-mail à chaque activité", "Receive one email for each activity": "Recevoir un e-mail à chaque activité",
"Receive one email per request": "Recevoir un e-mail par demande", "Receive one email per request": "Recevoir un e-mail par demande",
@ -852,6 +900,7 @@
"Remember my participation in this browser": "Se souvenir de ma participation dans ce navigateur", "Remember my participation in this browser": "Se souvenir de ma participation dans ce navigateur",
"Remove": "Exclure", "Remove": "Exclure",
"Remove link": "Enlever un lien", "Remove link": "Enlever un lien",
"Remove uploaded media": "Supprimer des médias téléversés",
"Rename": "Renommer", "Rename": "Renommer",
"Rename resource": "Renommer la ressource", "Rename resource": "Renommer la ressource",
"Reopen": "Réouvrir", "Reopen": "Réouvrir",
@ -890,6 +939,7 @@
"Resources": "Ressources", "Resources": "Ressources",
"Restricted": "Restreintes", "Restricted": "Restreintes",
"Return to the group page": "Retourner à la page du groupe", "Return to the group page": "Retourner à la page du groupe",
"Revoke": "Révoquer",
"Right now": "À l'instant", "Right now": "À l'instant",
"Role": "Rôle", "Role": "Rôle",
"Rules": "Règles", "Rules": "Règles",
@ -981,6 +1031,7 @@
"The actual number of participants may differ, as this event is hosted on another instance.": "Le nombre réel de participant⋅e⋅s peut être différent, car cet événement provient d'une autre instance.", "The actual number of participants may differ, as this event is hosted on another instance.": "Le nombre réel de participant⋅e⋅s peut être différent, car cet événement provient d'une autre instance.",
"The calc will be created on {service}": "Le calc sera créé sur {service}", "The calc will be created on {service}": "Le calc sera créé sur {service}",
"The content came from another server. Transfer an anonymous copy of the report?": "Le contenu provient d'une autre instance. Transférer une copie anonyme du signalement ?", "The content came from another server. Transfer an anonymous copy of the report?": "Le contenu provient d'une autre instance. Transférer une copie anonyme du signalement ?",
"The device code is incorrect or no longer valid.": "Le code de l'appareil est incorrect ou n'est plus valide.",
"The draft event has been updated": "L'événement brouillon a été mis à jour", "The draft event has been updated": "L'événement brouillon a été mis à jour",
"The event has a sign language interpreter": "L'événement a un interprète en langue des signes", "The event has a sign language interpreter": "L'événement a un interprète en langue des signes",
"The event has been created as a draft": "L'événement a été créé en tant que brouillon", "The event has been created as a draft": "L'événement a été créé en tant que brouillon",
@ -1023,6 +1074,7 @@
"The post {post} was created by {profile}.": "Le billet {post} a été créé par {profile}.", "The post {post} was created by {profile}.": "Le billet {post} a été créé par {profile}.",
"The post {post} was deleted by {profile}.": "Le billet {post} a été supprimé par {profile}.", "The post {post} was deleted by {profile}.": "Le billet {post} a été supprimé par {profile}.",
"The post {post} was updated by {profile}.": "Le billet {post} a été mis à jour par {profile}.", "The post {post} was updated by {profile}.": "Le billet {post} a été mis à jour par {profile}.",
"The provided application was not found.": "L'application fournie n'a pas été trouvée.",
"The report contents (eventual comments and event) and the reported profile details will be transmitted to Akismet.": "Les contenus du signalement (les éventuels commentaires et événement) et les détails du profil signalé seront transmis à Akismet.", "The report contents (eventual comments and event) and the reported profile details will be transmitted to Akismet.": "Les contenus du signalement (les éventuels commentaires et événement) et les détails du profil signalé seront transmis à Akismet.",
"The report will be sent to the moderators of your instance. You can explain why you report this content below.": "Le signalement sera envoyé aux modérateur⋅ices de votre instance. Vous pouvez expliquer pourquoi vous signalez ce contenu ci-dessous.", "The report will be sent to the moderators of your instance. You can explain why you report this content below.": "Le signalement sera envoyé aux modérateur⋅ices de votre instance. Vous pouvez expliquer pourquoi vous signalez ce contenu ci-dessous.",
"The selected picture is too heavy. You need to select a file smaller than {size}.": "L'image sélectionnée est trop lourde. Vous devez sélectionner un fichier de moins de {size}.", "The selected picture is too heavy. You need to select a file smaller than {size}.": "L'image sélectionnée est trop lourde. Vous devez sélectionner un fichier de moins de {size}.",
@ -1036,12 +1088,56 @@
"There is no activity yet. Start doing some things to see activity appear here.": "Il n'y a pas encore d'activité. Commencez par effectuer des actions pour voir des éléments s'afficher ici.", "There is no activity yet. Start doing some things to see activity appear here.": "Il n'y a pas encore d'activité. Commencez par effectuer des actions pour voir des éléments s'afficher ici.",
"There will be no way to recover your data.": "Il n'y aura aucun moyen de récupérer vos données.", "There will be no way to recover your data.": "Il n'y aura aucun moyen de récupérer vos données.",
"There's no discussions yet": "Il n'y a pas encore de discussions", "There's no discussions yet": "Il n'y a pas encore de discussions",
"These apps can access your account through the API. If you see here apps that you don't recognize, that don't work as expected or that you don't use anymore, you can revoke their access.": "Ces applications peuvent accéder à votre compte via l'API. Si vous voyez ici des applications que vous ne reconnaissez pas, qui ne fonctionnent pas comme prévu ou que vous n'utilisez plus, vous pouvez révoquer leur accès.",
"These events may interest you": "Ces événements peuvent vous intéresser", "These events may interest you": "Ces événements peuvent vous intéresser",
"These feeds contain event data for the events for which any of your profiles is a participant or creator. You should keep these private. You can find feeds for specific profiles on each profile edition page.": "Ces flux contiennent des informations sur les événements pour lesquels n'importe lequel de vos profils est un⋅e participant⋅e ou un⋅e créateur⋅ice. Vous devriez les garder privés. Vous pouvez trouver des flux spécifiques à chaque profil sur la page d'édition des profils.", "These feeds contain event data for the events for which any of your profiles is a participant or creator. You should keep these private. You can find feeds for specific profiles on each profile edition page.": "Ces flux contiennent des informations sur les événements pour lesquels n'importe lequel de vos profils est un⋅e participant⋅e ou un⋅e créateur⋅ice. Vous devriez les garder privés. Vous pouvez trouver des flux spécifiques à chaque profil sur la page d'édition des profils.",
"These feeds contain event data for the events for which this specific profile is a participant or creator. You should keep these private. You can find feeds for all of your profiles into your notification settings.": "Ces flux contiennent des informations sur les événements pour lesquels ce profil spécifique est un⋅e participant⋅e ou un⋅e créateur⋅ice. Vous devriez les garder privés. Vous pouvez trouver des flux pour l'ensemble de vos profils dans vos paramètres de notification.", "These feeds contain event data for the events for which this specific profile is a participant or creator. You should keep these private. You can find feeds for all of your profiles into your notification settings.": "Ces flux contiennent des informations sur les événements pour lesquels ce profil spécifique est un⋅e participant⋅e ou un⋅e créateur⋅ice. Vous devriez les garder privés. Vous pouvez trouver des flux pour l'ensemble de vos profils dans vos paramètres de notification.",
"This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.": "Cette instance Mobilizon et l'organisateur⋅ice de l'événement autorise les participations anonymes, mais requiert une validation à travers une confirmation par email.", "This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.": "Cette instance Mobilizon et l'organisateur⋅ice de l'événement autorise les participations anonymes, mais requiert une validation à travers une confirmation par email.",
"This URL doesn't seem to be valid": "Cette URL ne semble pas être valide", "This URL doesn't seem to be valid": "Cette URL ne semble pas être valide",
"This URL is not supported": "Cette URL n'est pas supportée", "This URL is not supported": "Cette URL n'est pas supportée",
"This application asks for the following permissions:": "Cette application demande les autorisations suivantes :",
"This application didn't ask for known permissions. It's likely the request is incorrect.": "Cette application n'a pas demandé d'autorisations connues. Il est probable que la demande soit incorrecte.",
"This application will be able to access all of your informations and post content. Make sure you only approve applications you trust.": "Cette application sera capable d'accéder à toutes vos informations et poster du contenu. Assurez-vous d'approuver uniquement des applications en lesquelles vous avez confiance.",
"This application will be allowed to access all of the groups you're a member of": "Cette application pourra accéder à tous les groupes dont vous êtes membres",
"This application will be allowed to access group activities in all of the groups you're a member of": "This application will be allowed to access group activities in all of the groups you're a member of",
"This application will be allowed to create feed tokens": "This application will be allowed to create feed tokens",
"This application will be allowed to create group discussions": "This application will be allowed to create group discussions",
"This application will be allowed to create new profiles for your account": "This application will be allowed to create new profiles for your account",
"This application will be allowed to create resources in all of the groups you're a member of": "Cette application pourra créer des ressources dans chacun des groupes dont vous êtes membre",
"This application will be allowed to delete comments": "This application will be allowed to delete comments",
"This application will be allowed to delete events": "Cette application pourra supprimer des événements",
"This application will be allowed to delete feed tokens": "This application will be allowed to delete feed tokens",
"This application will be allowed to delete group discussions": "This application will be allowed to delete group discussions",
"This application will be allowed to delete group posts": "Cette application pourra supprimer des billets de groupes",
"This application will be allowed to delete resources in all of the groups you're a member of": "Cette application pourra supprimer des ressources dans chacun des groupes dont vous êtes membre",
"This application will be allowed to delete your profiles": "This application will be allowed to delete your profiles",
"This application will be allowed to join and leave groups": "This application will be allowed to join and leave groups",
"This application will be allowed to list and access group discussions in all of the groups you're a member of": "This application will be allowed to list and access group discussions in all of the groups you're a member of",
"This application will be allowed to list and access group events in all of the groups you're a member of": "Cette application pourra lister et accéder aux événements des groupes dont vous êtes membre",
"This application will be allowed to list and access group todo-lists in all of the groups you're a member of": "This application will be allowed to list and access group todo-lists in all of the groups you're a member of",
"This application will be allowed to list and view the events you're participating to": "This application will be allowed to list and view the events you're participating to",
"This application will be allowed to list and view the groups you're a member of": "This application will be allowed to list and view the groups you're a member of",
"This application will be allowed to list and view the groups you're following": "This application will be allowed to list and view the groups you're following",
"This application will be allowed to list and view your organized events": "This application will be allowed to list and view your organized events",
"This application will be allowed to list group followers in all of the groups you're a member of": "This application will be allowed to list group followers in all of the groups you're a member of",
"This application will be allowed to list group members in all of the groups you're a member of": "This application will be allowed to list group members in all of the groups you're a member of",
"This application will be allowed to manage events participations": "Cette application sera autorisée à gérer vos participations à des événements",
"This application will be allowed to manage group members in all of the groups you're a member of": "This application will be allowed to manage group members in all of the groups you're a member of",
"This application will be allowed to manage your account activity settings": "Cette application sera autorisée à gérer vos paramètres d'activité",
"This application will be allowed to manage your account push notification settings": "Cette application sera autorisée à gérer vos paramètres de notification push",
"This application will be allowed to post comments": "This application will be allowed to post comments",
"This application will be allowed to publish and manage events, post and manage comments, participate to events, manage all of your groups, including group events, resources, posts and discussions. It will also be allowed to manage your account and profile settings.": "Cette application sera autorisée à publier et à gérer des événements, à publier et à gérer des commentaires, à participer à des événements, à gérer tous vos groupes, y compris les événements de groupe, les ressources, les messages et les discussions. Elle pourra également gérer les paramètres de votre compte et de votre profil.",
"This application will be allowed to publish events": "Cette application pourra publier des événements",
"This application will be allowed to publish group posts": "Cette application pourra publier des billets de groupes",
"This application will be allowed to remove uploaded media": "Cette application pourra supprimer des médias téléversés",
"This application will be allowed to see all of your events organized, the events you participate to, as well as every data from your groups.": "Cette application vous permettra de voir tous les événements que vous avez organisés, les événements auxquels vous participez, ainsi que toutes les données de vos groupes.",
"This application will be allowed to update comments": "This application will be allowed to update comments",
"This application will be allowed to update events": "Cette application pourra mettre à jour des événements",
"This application will be allowed to update group discussions": "This application will be allowed to update group discussions",
"This application will be allowed to update group posts": "Cette application pourra mettre à jour des billets de groupes",
"This application will be allowed to update resources in all of the groups you're a member of": "Cette application pourra mettre à jour des ressources dans chacun des groupes dont vous êtes membre",
"This application will be allowed to update your profiles": "This application will be allowed to update your profiles",
"This application will be allowed to upload media": "Cette application pourra téléverser des médias",
"This event has been cancelled.": "Cet événement a été annulé.", "This event has been cancelled.": "Cet événement a été annulé.",
"This event is accessible only through it's link. Be careful where you post this link.": "Cet événement est accessible uniquement à travers son lien. Faites attention où vous le diffusez.", "This event is accessible only through it's link. Be careful where you post this link.": "Cet événement est accessible uniquement à travers son lien. Faites attention où vous le diffusez.",
"This group doesn't have a description yet.": "Ce groupe n'a pas encore de description.", "This group doesn't have a description yet.": "Ce groupe n'a pas encore de description.",
@ -1125,12 +1221,19 @@
"Upcoming events from your groups": "Événements de vos groupes à venir", "Upcoming events from your groups": "Événements de vos groupes à venir",
"Update": "Éditer", "Update": "Éditer",
"Update app": "Mettre à jour", "Update app": "Mettre à jour",
"Update comments": "Mettre à jour des commentaires",
"Update discussion title": "Mettre à jour le titre de la discussion", "Update discussion title": "Mettre à jour le titre de la discussion",
"Update event {name}": "Mettre à jour l'événement {name}", "Update event {name}": "Mettre à jour l'événement {name}",
"Update events": "Mettre à jour des événements",
"Update group": "Mettre à jour le groupe", "Update group": "Mettre à jour le groupe",
"Update group discussions": "Mettre à jour des discussions de groupes",
"Update group posts": "Mettre à jour des billets de groupes",
"Update group resources": "Mettre à jour des ressources de groupes",
"Update my event": "Mettre à jour mon événement", "Update my event": "Mettre à jour mon événement",
"Update post": "Mettre à jour le billet", "Update post": "Mettre à jour le billet",
"Update profiles": "Mettre à jour des profils",
"Updated": "Mis à jour", "Updated": "Mis à jour",
"Upload media": "Téléverser des médias",
"Uploaded media size": "Taille des médias téléversés", "Uploaded media size": "Taille des médias téléversés",
"Uploaded media total size": "Taille totale des médias téléversés", "Uploaded media total size": "Taille totale des médias téléversés",
"Use my location": "Utiliser ma position", "Use my location": "Utiliser ma position",
@ -1216,7 +1319,10 @@
"You are participating in this event anonymously but didn't confirm participation": "Vous participez à cet événement anonymement mais vous n'avez pas confirmé votre participation", "You are participating in this event anonymously but didn't confirm participation": "Vous participez à cet événement anonymement mais vous n'avez pas confirmé votre participation",
"You can add resources by using the button above.": "Vous pouvez ajouter des ressources en utilisant le bouton au dessus.", "You can add resources by using the button above.": "Vous pouvez ajouter des ressources en utilisant le bouton au dessus.",
"You can add tags by hitting the Enter key or by adding a comma": "Vous pouvez ajouter des tags en appuyant sur la touche Entrée ou bien en ajoutant une virgule", "You can add tags by hitting the Enter key or by adding a comma": "Vous pouvez ajouter des tags en appuyant sur la touche Entrée ou bien en ajoutant une virgule",
"You can drag and drop the marker below to the desired location": "Vous pouvez faire glisser et déposer le marqueur ci-dessous à l'endroit souhaité",
"You can pick your timezone into your preferences.": "Vous pouvez choisir votre fuseau horaire dans vos préférences.", "You can pick your timezone into your preferences.": "Vous pouvez choisir votre fuseau horaire dans vos préférences.",
"You can put any arbitrary content in this element. URLs will be clickable.": "Vous pouvez placer n'importe quel contenu arbitraire dans cet élément. Les URL seront cliquables.",
"You can try another search term or add the address details manually below.": "Vous pouvez essayer un autre terme de recherche ou ajouter manuellement les détails de l'adresse ci-dessous.",
"You can try another search term or drag and drop the marker on the map": "Vous pouvez essayer avec d'autres termes de recherche ou bien glisser et déposer le marqueur sur la carte", "You can try another search term or drag and drop the marker on the map": "Vous pouvez essayer avec d'autres termes de recherche ou bien glisser et déposer le marqueur sur la carte",
"You can't change your password because you are registered through {provider}.": "Vous ne pouvez pas changer votre mot de passe car vous vous êtes enregistré via {provider}.", "You can't change your password because you are registered through {provider}.": "Vous ne pouvez pas changer votre mot de passe car vous vous êtes enregistré via {provider}.",
"You can't use push notifications in this browser.": "Vous ne pouvez pas utiliser les notifications push dans ce navigateur.", "You can't use push notifications in this browser.": "Vous ne pouvez pas utiliser les notifications push dans ce navigateur.",
@ -1241,6 +1347,7 @@
"You excluded member {member}.": "Vous avez exclu le ou la membre {member}.", "You excluded member {member}.": "Vous avez exclu le ou la membre {member}.",
"You have attended {count} events in the past.": "Vous n'avez participé à aucun événement par le passé.|Vous avez participé à un événement par le passé.|Vous avez participé à {count} événements par le passé.", "You have attended {count} events in the past.": "Vous n'avez participé à aucun événement par le passé.|Vous avez participé à un événement par le passé.|Vous avez participé à {count} événements par le passé.",
"You have been invited by {invitedBy} to the following group:": "Vous avez été invité par {invitedBy} à rejoindre le groupe suivant :", "You have been invited by {invitedBy} to the following group:": "Vous avez été invité par {invitedBy} à rejoindre le groupe suivant :",
"You have been logged-out": "Vous avez été déconnecté·e",
"You have been removed from this group's members.": "Vous avez été exclu⋅e des membres de ce groupe.", "You have been removed from this group's members.": "Vous avez été exclu⋅e des membres de ce groupe.",
"You have cancelled your participation": "Vous avez annulé votre participation", "You have cancelled your participation": "Vous avez annulé votre participation",
"You have one event in {days} days.": "Vous n'avez pas d'événements dans {days} jours | Vous avez un événement dans {days} jours. | Vous avez {count} événements dans {days} jours", "You have one event in {days} days.": "Vous n'avez pas d'événements dans {days} jours | Vous avez un événement dans {days} jours. | Vous avez {count} événements dans {days} jours",
@ -1258,6 +1365,7 @@
"You moved the resource {resource} into {new_path}.": "Vous avez déplacé la ressource {resource} dans {new_path}.", "You moved the resource {resource} into {new_path}.": "Vous avez déplacé la ressource {resource} dans {new_path}.",
"You moved the resource {resource} to the root folder.": "Vous avez déplacé la ressource {resource} dans le dossier racine.", "You moved the resource {resource} to the root folder.": "Vous avez déplacé la ressource {resource} dans le dossier racine.",
"You need to login.": "Vous devez vous connecter.", "You need to login.": "Vous devez vous connecter.",
"You need to provide the following code to your application. It will only be valid for a few minutes.": "Vous devez fournir le code suivant à votre application. Il sera seulement valide pendant quelques minutes.",
"You posted a comment on the event {event}.": "Vous avez posté un commentaire sur l'événement {event}.", "You posted a comment on the event {event}.": "Vous avez posté un commentaire sur l'événement {event}.",
"You promoted the member {member} to an unknown role.": "Vous avez promu le ou la membre {member} à un role inconnu.", "You promoted the member {member} to an unknown role.": "Vous avez promu le ou la membre {member} à un role inconnu.",
"You promoted {member} to administrator.": "Vous avez promu {member} en tant qu'adminstrateur⋅ice.", "You promoted {member} to administrator.": "Vous avez promu {member} en tant qu'adminstrateur⋅ice.",
@ -1284,6 +1392,7 @@
"You will find here all the events you have created or of which you are a participant, as well as events organized by groups you follow or are a member of.": "Vous trouverez ici tous les événements que vous avez créé ou dont vous êtes un·e participant·e, ainsi que les événements organisés par les groupes que vous suivez ou dont vous êtes membre.", "You will find here all the events you have created or of which you are a participant, as well as events organized by groups you follow or are a member of.": "Vous trouverez ici tous les événements que vous avez créé ou dont vous êtes un·e participant·e, ainsi que les événements organisés par les groupes que vous suivez ou dont vous êtes membre.",
"You will receive notifications about this group's public activity depending on %{notification_settings}.": "Vous recevrez des notifications à propos de l'activité publique de ce groupe en fonction de %{notification_settings}.", "You will receive notifications about this group's public activity depending on %{notification_settings}.": "Vous recevrez des notifications à propos de l'activité publique de ce groupe en fonction de %{notification_settings}.",
"You wish to participate to the following event": "Vous souhaitez participer à l'événement suivant", "You wish to participate to the following event": "Vous souhaitez participer à l'événement suivant",
"You'll be able to revoke access for this application in your account settings.": "Vous pourrez révoquer l'accès pour cette applications dans les paramètres de votre compte.",
"You'll get a weekly recap every Monday for upcoming events, if you have any.": "Vous recevrez un récapitulatif hebdomadaire chaque lundi pour les événements de la semaine, si vous en avez.", "You'll get a weekly recap every Monday for upcoming events, if you have any.": "Vous recevrez un récapitulatif hebdomadaire chaque lundi pour les événements de la semaine, si vous en avez.",
"You'll need to change the URLs where there were previously entered.": "Vous devrez changer les URLs là où vous les avez entrées précédemment.", "You'll need to change the URLs where there were previously entered.": "Vous devrez changer les URLs là où vous les avez entrées précédemment.",
"You'll need to transmit the group URL so people may access the group's profile. The group won't be findable in Mobilizon's search or regular search engines.": "Vous aurez besoin de transmettre l'URL du groupe pour que d'autres personnes accèdent au profil du groupe. Le groupe ne sera pas trouvable dans la recherche de Mobilizon ni dans les moteurs de recherche habituels.", "You'll need to transmit the group URL so people may access the group's profile. The group won't be findable in Mobilizon's search or regular search engines.": "Vous aurez besoin de transmettre l'URL du groupe pour que d'autres personnes accèdent au profil du groupe. Le groupe ne sera pas trouvable dans la recherche de Mobilizon ni dans les moteurs de recherche habituels.",
@ -1294,6 +1403,7 @@
"Your account has been validated": "Votre compte a été validé", "Your account has been validated": "Votre compte a été validé",
"Your account is being validated": "Votre compte est en cours de validation", "Your account is being validated": "Votre compte est en cours de validation",
"Your account is nearly ready, {username}": "Votre compte est presque prêt, {username}", "Your account is nearly ready, {username}": "Votre compte est presque prêt, {username}",
"Your application code": "Votre code d'application",
"Your city or region and the radius will only be used to suggest you events nearby. The event radius will consider the administrative center of the area.": "Votre ville ou région et le rayon seront uniquement utilisés pour vous suggérer des événements proches. Le rayon des événements proches sera calculé par rapport au centre administratif de la zone.", "Your city or region and the radius will only be used to suggest you events nearby. The event radius will consider the administrative center of the area.": "Votre ville ou région et le rayon seront uniquement utilisés pour vous suggérer des événements proches. Le rayon des événements proches sera calculé par rapport au centre administratif de la zone.",
"Your current email is {email}. You use it to log in.": "Votre adresse e-mail actuelle est {email}. Vous l'utilisez pour vous connecter.", "Your current email is {email}. You use it to log in.": "Votre adresse e-mail actuelle est {email}. Vous l'utilisez pour vous connecter.",
"Your email": "Votre adresse e-mail", "Your email": "Votre adresse e-mail",
@ -1451,114 +1561,7 @@
"{user}'s follow request was accepted": "La demande de suivi de {user} a été acceptée", "{user}'s follow request was accepted": "La demande de suivi de {user} a été acceptée",
"{user}'s follow request was rejected": "La demande de suivi de {user} a été rejetée", "{user}'s follow request was rejected": "La demande de suivi de {user} a été rejetée",
"© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap", "© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap",
"Autorize this application to access your account?": "Autoriser cette application à accéder à votre compte ?", "Application authorized": "Application autorisée",
"This application will be able to access all of your informations and post content. Make sure you only approve applications you trust.": "Cette application sera capable d'accéder à toutes vos informations et poster du contenu. Assurez-vous d'approuver uniquement des applications en lesquelles vous avez confiance.", "Check your device to continue. You may now close this window.": "Vérifiez votre appareil pour continuer. Vous pouvez maintenant fermer cette fenêtre.",
"Authorize application": "Autoriser l'application", "Participants to {eventTitle}": "Participant·es à {eventTitle}"
"Authorize": "Autoriser",
"You'll be able to revoke access for this application in your account settings.": "Vous pourrez révoquer l'accès pour cette applications dans les paramètres de votre compte.",
"Read all of your account's data": "Lire toutes les données de votre compte",
"Modify all of your account's data": "Modifier toutes les données de votre compte",
"Publish events": "Publier des événements",
"This application will be allowed to publish events": "Cette application pourra publier des événements",
"Update events": "Mettre à jour des événements",
"This application will be allowed to update events": "Cette application pourra mettre à jour des événements",
"Delete events": "Supprimer des événements",
"This application will be allowed to delete events": "Cette application pourra supprimer des événements",
"Upload media": "Téléverser des médias",
"This application will be allowed to upload media": "Cette application pourra téléverser des médias",
"Remove uploaded media": "Supprimer des médias téléversés",
"This application will be allowed to remove uploaded media": "Cette application pourra supprimer des médias téléversés",
"Publish group posts": "Publier des billets de groupes",
"This application will be allowed to publish group posts": "Cette application pourra publier des billets de groupes",
"Update group posts": "Mettre à jour des billets de groupes",
"This application will be allowed to update group posts": "Cette application pourra mettre à jour des billets de groupes",
"Delete group posts": "Supprimer des billets de groupes",
"This application will be allowed to delete group posts": "Cette application pourra supprimer des billets de groupes",
"Access your group's resources": "Accéder aux ressources de vos groupes",
"This application will be allowed to access all of the groups you're a member of": "Cette application pourra accéder à tous les groupes dont vous êtes membres",
"Create group resources": "Créer des ressources de groupes",
"This application will be allowed to create resources in all of the groups you're a member of": "Cette application pourra créer des ressources dans chacun des groupes dont vous êtes membre",
"Update group resources": "Mettre à jour des ressources de groupes",
"This application will be allowed to update resources in all of the groups you're a member of": "Cette application pourra mettre à jour des ressources dans chacun des groupes dont vous êtes membre",
"Delete group resources": "Supprimer des ressources de groupes",
"This application will be allowed to delete resources in all of the groups you're a member of": "Cette application pourra supprimer des ressources dans chacun des groupes dont vous êtes membre",
"Access group events": "Accéder aux événements des groupes",
"This application will be allowed to list and access group events in all of the groups you're a member of": "Cette application pourra lister et accéder aux événements des groupes dont vous êtes membre",
"Access group discussions": "Accéder aux discussions des groupes",
"This application will be allowed to list and access group discussions in all of the groups you're a member of": "This application will be allowed to list and access group discussions in all of the groups you're a member of",
"Access group members": "Accéder à la liste des membres des groupes",
"This application will be allowed to list group members in all of the groups you're a member of": "This application will be allowed to list group members in all of the groups you're a member of",
"Access group followers": "Accéder à la liste des abonnés des groupes",
"This application will be allowed to list group followers in all of the groups you're a member of": "This application will be allowed to list group followers in all of the groups you're a member of",
"Access group activities": "Accéder aux activités des groupes",
"This application will be allowed to access group activities in all of the groups you're a member of": "This application will be allowed to access group activities in all of the groups you're a member of",
"Access group todo-lists": "Accéder aux listes de tâches des groupes",
"This application will be allowed to list and access group todo-lists in all of the groups you're a member of": "This application will be allowed to list and access group todo-lists in all of the groups you're a member of",
"Manage group memberships": "Gérer vos adhésions à des groupes",
"This application will be allowed to join and leave groups": "This application will be allowed to join and leave groups",
"Manage group members": "Gérer les membres des groupes",
"This application will be allowed to manage group members in all of the groups you're a member of": "This application will be allowed to manage group members in all of the groups you're a member of",
"Access organized events": "Accéder à la liste de vos événements organisés",
"This application will be allowed to list and view your organized events": "This application will be allowed to list and view your organized events",
"Access participations": "Accéder à la liste de vos participations",
"This application will be allowed to list and view the events you're participating to": "This application will be allowed to list and view the events you're participating to",
"Access group memberships": "Accéder à la liste de vos adhésions à des groupes",
"This application will be allowed to list and view the groups you're a member of": "This application will be allowed to list and view the groups you're a member of",
"Access followed groups": "Accéder à la liste des groupes suivis",
"This application will be allowed to list and view the groups you're following": "This application will be allowed to list and view the groups you're following",
"Create new profiles": "Créer des nouveaux profils",
"This application will be allowed to create new profiles for your account": "This application will be allowed to create new profiles for your account",
"Update profiles": "Mettre à jour des profils",
"This application will be allowed to update your profiles": "This application will be allowed to update your profiles",
"Delete profiles": "Supprimer des profils",
"This application will be allowed to delete your profiles": "This application will be allowed to delete your profiles",
"Post comments": "Poster des commentaires",
"This application will be allowed to post comments": "This application will be allowed to post comments",
"Update comments": "Mettre à jour des commentaires",
"This application will be allowed to update comments": "This application will be allowed to update comments",
"Delete comments": "Supprimer des commentaires",
"This application will be allowed to delete comments": "This application will be allowed to delete comments",
"Create group discussions": "Créer des discussions de groupes",
"This application will be allowed to create group discussions": "This application will be allowed to create group discussions",
"Update group discussions": "Mettre à jour des discussions de groupes",
"This application will be allowed to update group discussions": "This application will be allowed to update group discussions",
"Delete group discussions": "Supprimer des discussions de groupes",
"This application will be allowed to delete group discussions": "This application will be allowed to delete group discussions",
"Create feed tokens": "Créer des jetons de flux",
"This application will be allowed to create feed tokens": "This application will be allowed to create feed tokens",
"Delete feed tokens": "Supprimer les jetons de flux",
"This application will be allowed to delete feed tokens": "This application will be allowed to delete feed tokens",
"Manage event participations": "Gérer les participations aux événements",
"This application will be allowed to manage events participations": "Cette application sera autorisée à gérer vos participations à des événements",
"Manage activity settings": "Gérer les paramètres d'activité",
"This application will be allowed to manage your account activity settings": "Cette application sera autorisée à gérer vos paramètres d'activité",
"Manage push notification settings": "Gérer les paramètres de notification push",
"This application will be allowed to manage your account push notification settings": "Cette application sera autorisée à gérer vos paramètres de notification push",
"Apps": "Applications",
"Device activation": "Activation de l'appareil",
"Application not found": "Application non trouvée",
"The provided application was not found.": "L'application fournie n'a pas été trouvée.",
"Your application code": "Votre code d'application",
"You need to provide the following code to your application. It will only be valid for a few minutes.": "Vous devez fournir le code suivant à votre application. Il sera seulement valide pendant quelques minutes.",
"Enter the code displayed on your device": "Saisissez le code affiché sur votre appareil",
"Continue": "Continuer",
"The device code is incorrect or no longer valid.": "Le code de l'appareil est incorrect ou n'est plus valide.",
"These apps can access your account through the API. If you see here apps that you don't recognize, that don't work as expected or that you don't use anymore, you can revoke their access.": "Ces applications peuvent accéder à votre compte via l'API. Si vous voyez ici des applications que vous ne reconnaissez pas, qui ne fonctionnent pas comme prévu ou que vous n'utilisez plus, vous pouvez révoquer leur accès.",
"Last used on {last_used_date}": "Utilisée pour la dernière fois le {last_used_date}",
"Never used": "Jamais utilisée",
"Authorized on {authorization_date}": "Authorisée le {authorization_date}",
"Revoke": "Révoquer",
"Application was revoked": "L'application a été révoquée",
"Create a new metadata element": "Créer un nouvel élément de métadonnées",
"You can put any arbitrary content in this element. URLs will be clickable.": "Vous pouvez placer n'importe quel contenu arbitraire dans cet élément. Les URL seront cliquables.",
"You can try another search term or add the address details manually below.": "Vous pouvez essayer un autre terme de recherche ou ajouter manuellement les détails de l'adresse ci-dessous.",
"Manually enter address": "Saisir manuellement l'adresse",
"You can drag and drop the marker below to the desired location": "Vous pouvez faire glisser et déposer le marqueur ci-dessous à l'endroit souhaité",
"This application didn't ask for known permissions. It's likely the request is incorrect.": "Cette application n'a pas demandé d'autorisations connues. Il est probable que la demande soit incorrecte.",
"This application asks for the following permissions:": "Cette application demande les autorisations suivantes :",
"This application will be allowed to see all of your events organized, the events you participate to, as well as every data from your groups.": "Cette application vous permettra de voir tous les événements que vous avez organisés, les événements auxquels vous participez, ainsi que toutes les données de vos groupes.",
"This application will be allowed to publish and manage events, post and manage comments, participate to events, manage all of your groups, including group events, resources, posts and discussions. It will also be allowed to manage your account and profile settings.": "Cette application sera autorisée à publier et à gérer des événements, à publier et à gérer des commentaires, à participer à des événements, à gérer tous vos groupes, y compris les événements de groupe, les ressources, les messages et les discussions. Elle pourra également gérer les paramètres de votre compte et de votre profil.",
"No apps authorized yet": "Aucune application autorisée pour le moment",
"You have been logged-out": "Vous avez été déconnecté·e",
"An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events on your behalf, automatically and remotely.": "Une « interface de programmation dapplication » ou « API » est un protocole de communication qui permet aux composants logiciels de communiquer entre eux. L'API Mobilizon, par exemple, peut permettre à des outils logiciels tiers de communiquer avec les instances Mobilizon pour effectuer certaines actions, telles que la publication d'événements en votre nom, automatiquement et à distance."
} }

View file

@ -755,7 +755,6 @@
"Public event": "Tachartas poblach", "Public event": "Tachartas poblach",
"Public feeds": "Inbhirean poblach", "Public feeds": "Inbhirean poblach",
"Public iCal Feed": "Inbhir iCal poblach", "Public iCal Feed": "Inbhir iCal poblach",
"Public page": "Duilleag phoblach",
"Public preview": "Ro-shealladh poblach", "Public preview": "Ro-shealladh poblach",
"Publication date": "Ceann-là an fhoillseachaidh", "Publication date": "Ceann-là an fhoillseachaidh",
"Publish": "Foillsich", "Publish": "Foillsich",

View file

@ -707,7 +707,6 @@
"Public event": "Evento público", "Public event": "Evento público",
"Public feeds": "Fontes públicas", "Public feeds": "Fontes públicas",
"Public iCal Feed": "Fonte pública iCal", "Public iCal Feed": "Fonte pública iCal",
"Public page": "Páxina pública",
"Public preview": "Vista previa pública", "Public preview": "Vista previa pública",
"Publication date": "Data de publicación", "Publication date": "Data de publicación",
"Publish": "Publicar", "Publish": "Publicar",

View file

@ -16,7 +16,7 @@
"A cookie is a small file containing information that is sent to your computer when you visit a website. When you visit the site again, the cookie allows that site to recognize your browser. Cookies may store user preferences and other information. You can configure your browser to refuse all cookies. However, this may result in some website features or services partially working. Local storage works the same way but allows you to store more data.": "Kolačić je mala datoteka koja sadrži sve informacije poslane vašem računalu kada posjetite stranicu. Kada ju opet posjetite, kolačić omogućuje stranici da prepozna vaš preglednik. Kolačić može sadržavati vaše postavke ili druge informacije. Možete postaviti svoj preglednik da blokira sve kolačiće, ali to može dovesti do djelomičnog kvara nekih funkcija stranice. Lokalno spremište radi na isti način ali vam dopušta da spremite više podataka.", "A cookie is a small file containing information that is sent to your computer when you visit a website. When you visit the site again, the cookie allows that site to recognize your browser. Cookies may store user preferences and other information. You can configure your browser to refuse all cookies. However, this may result in some website features or services partially working. Local storage works the same way but allows you to store more data.": "Kolačić je mala datoteka koja sadrži sve informacije poslane vašem računalu kada posjetite stranicu. Kada ju opet posjetite, kolačić omogućuje stranici da prepozna vaš preglednik. Kolačić može sadržavati vaše postavke ili druge informacije. Možete postaviti svoj preglednik da blokira sve kolačiće, ali to može dovesti do djelomičnog kvara nekih funkcija stranice. Lokalno spremište radi na isti način ali vam dopušta da spremite više podataka.",
"A discussion has been created or updated": "Jedna diskusija je stvorena ili aktualizirana", "A discussion has been created or updated": "Jedna diskusija je stvorena ili aktualizirana",
"A federated software": "Federaliziran softver", "A federated software": "Federaliziran softver",
"A fediverse account URL to follow for event updates": "", "A fediverse account URL to follow for event updates": "URL Fediverse računa za praćenje aktualiziranja događaja",
"A few lines about your group": "Par redaka o tvojoj grupi", "A few lines about your group": "Par redaka o tvojoj grupi",
"A link to a page presenting the event schedule": "Poveznica na stranicu s rasporedom događaja", "A link to a page presenting the event schedule": "Poveznica na stranicu s rasporedom događaja",
"A link to a page presenting the price options": "Poveznica na stranicu sa cijenama", "A link to a page presenting the price options": "Poveznica na stranicu sa cijenama",
@ -32,7 +32,7 @@
"A practical tool": "Praktični alat", "A practical tool": "Praktični alat",
"A resource has been created or updated": "Jedan resurs je stvoren ili aktualiziran", "A resource has been created or updated": "Jedan resurs je stvoren ili aktualiziran",
"A short tagline for your instance homepage. Defaults to \"Gather ⋅ Organize ⋅ Mobilize\"": "Kartki slogan za naslovnu stranicu instance. Zadan je na \"Skupi ⋅ Organiziraj ⋅ Mobiliziraj\"", "A short tagline for your instance homepage. Defaults to \"Gather ⋅ Organize ⋅ Mobilize\"": "Kartki slogan za naslovnu stranicu instance. Zadan je na \"Skupi ⋅ Organiziraj ⋅ Mobiliziraj\"",
"A twitter account handle to follow for event updates": "", "A twitter account handle to follow for event updates": "Twitter račun za praćenje aktualiziranja događaja",
"A user-friendly, emancipatory and ethical tool for gathering, organising, and mobilising.": "Emancipacijski i etični alat za okupljanje, organiziranje, i mobiliziranje, sa prijateljskim korisničkim sučeljem.", "A user-friendly, emancipatory and ethical tool for gathering, organising, and mobilising.": "Emancipacijski i etični alat za okupljanje, organiziranje, i mobiliziranje, sa prijateljskim korisničkim sučeljem.",
"A validation email was sent to {email}": "E-mail za ovjeru je poslan na {email}", "A validation email was sent to {email}": "E-mail za ovjeru je poslan na {email}",
"API": "API", "API": "API",
@ -48,7 +48,7 @@
"Accept follow": "Prihvati praćenje", "Accept follow": "Prihvati praćenje",
"Accepted": "Prihvaćeno", "Accepted": "Prihvaćeno",
"Accessibility": "Pristupačnost", "Accessibility": "Pristupačnost",
"Accessible only by link": "", "Accessible only by link": "Dostupno samo putem poveznice",
"Accessible only to members": "Dostupno samo članovima", "Accessible only to members": "Dostupno samo članovima",
"Accessible through link": "Dostupno kroz poveznicu", "Accessible through link": "Dostupno kroz poveznicu",
"Account": "Račun", "Account": "Račun",
@ -86,7 +86,7 @@
"All the places have already been taken": "Sva mjesta su već zauzeta", "All the places have already been taken": "Sva mjesta su već zauzeta",
"Allow all comments from users with accounts": "Dozvoli sve komentare prijavljenih korisnika", "Allow all comments from users with accounts": "Dozvoli sve komentare prijavljenih korisnika",
"Allow registrations": "Dozvoli registracije", "Allow registrations": "Dozvoli registracije",
"An URL to an external ticketing platform": "", "An URL to an external ticketing platform": "URL-adresa eksterne platforme za prodaju karata",
"An error has occured while refreshing the page.": "Dogodila se greška prilikom aktualiziranja stranice.", "An error has occured while refreshing the page.": "Dogodila se greška prilikom aktualiziranja stranice.",
"An error has occured. Sorry about that. You may try to reload the page.": "Desila se greška! Isprike. Možete probati ponovno učitati stranicu.", "An error has occured. Sorry about that. You may try to reload the page.": "Desila se greška! Isprike. Možete probati ponovno učitati stranicu.",
"An ethical alternative": "Etična alternativa", "An ethical alternative": "Etična alternativa",
@ -98,6 +98,7 @@
"An event from one of my groups has been published": "Događaj jedne od mojih grupa je objavljen", "An event from one of my groups has been published": "Događaj jedne od mojih grupa je objavljen",
"An event from one of my groups has been updated or deleted": "Događaj jedne od mojih grupa je aktualiziran ili izbrisan", "An event from one of my groups has been updated or deleted": "Događaj jedne od mojih grupa je aktualiziran ili izbrisan",
"An instance is an installed version of the Mobilizon software running on a server. An instance can be run by anyone using the {mobilizon_software} or other federated apps, aka the “fediverse”. This instance's name is {instance_name}. Mobilizon is a federated network of multiple instances (just like email servers), users registered on different instances may communicate even though they didn't register on the same instance.": "Instanca je instalirana verzija Mobilizon softvera koja radi na serveru. Instancu može postaviti bilo tko, tko koristi {mobilizon_software} ili druge federalizirane aplikacije, poznato i kao „fediverse”. Ime ove instance je {instance_name}. Mobilizon je federalizirana mreža kaj se sastoji od više instanca (kao e-mail serveri) gdje korisnici, koji su registrirani na različitim instancama mogu komunicirati iako se ne nalaze na istoj instanci.", "An instance is an installed version of the Mobilizon software running on a server. An instance can be run by anyone using the {mobilizon_software} or other federated apps, aka the “fediverse”. This instance's name is {instance_name}. Mobilizon is a federated network of multiple instances (just like email servers), users registered on different instances may communicate even though they didn't register on the same instance.": "Instanca je instalirana verzija Mobilizon softvera koja radi na serveru. Instancu može postaviti bilo tko, tko koristi {mobilizon_software} ili druge federalizirane aplikacije, poznato i kao „fediverse”. Ime ove instance je {instance_name}. Mobilizon je federalizirana mreža kaj se sastoji od više instanca (kao e-mail serveri) gdje korisnici, koji su registrirani na različitim instancama mogu komunicirati iako se ne nalaze na istoj instanci.",
"An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events, automatically and remotely.": "„Sučelje za programiranje aplikacija” ili „API” je komunikacijski protokol koji omogućuje komponentama softvera da međusobno komuniciraju. Mobilizon API, na primjer, može dozvoliti softverskim alatima trećih strana da komuniciraju s Mobilizon instancama za izvođenje određenih radnji, kao što je objavljivanje događaja, automatski i na daljinski način.",
"And {number} comments": "I {number} komentara", "And {number} comments": "I {number} komentara",
"Announcements and mentions notifications are always sent straight away.": "Najave i obavijesti o spominjanjima uvijek se šalju odmah.", "Announcements and mentions notifications are always sent straight away.": "Najave i obavijesti o spominjanjima uvijek se šalju odmah.",
"Anonymous participant": "Anonimni sudionik", "Anonymous participant": "Anonimni sudionik",
@ -125,7 +126,7 @@
"Are you sure you want to delete this entire discussion?": "Jeste li sigurni da želite izbrisati cijeli razgovor?", "Are you sure you want to delete this entire discussion?": "Jeste li sigurni da želite izbrisati cijeli razgovor?",
"Are you sure you want to delete this event? This action cannot be reverted.": "Jeste li sigurni da želite izbrisati ovaj događaj? Nećete moći poništiti ovu odluku.", "Are you sure you want to delete this event? This action cannot be reverted.": "Jeste li sigurni da želite izbrisati ovaj događaj? Nećete moći poništiti ovu odluku.",
"Are you sure you want to delete this post? This action cannot be reverted.": "Stvarno želiš izbrisati ovaj događaj? Ovo je nepovratna radnja.", "Are you sure you want to delete this post? This action cannot be reverted.": "Stvarno želiš izbrisati ovaj događaj? Ovo je nepovratna radnja.",
"Are you sure you want to leave the group {groupName}? You'll loose access to this group's private content. This action cannot be undone.": "", "Are you sure you want to leave the group {groupName}? You'll loose access to this group's private content. This action cannot be undone.": "Stvarno želiš napustiti grupu {groupName}? Izgubit ćeš pristup privatnom sadržaju ove grupe. Ova je nepovratna radnja.",
"As the event organizer has chosen to manually validate participation requests, your participation will be really confirmed only once you receive an email stating it's being accepted.": "Budući da su organizatori odlučili ručno potvrđivati zahtjeve, vaše sudjelovanje će biti potvrđeno kada primite e-mail s prihvaćanjem zahtjeva.", "As the event organizer has chosen to manually validate participation requests, your participation will be really confirmed only once you receive an email stating it's being accepted.": "Budući da su organizatori odlučili ručno potvrđivati zahtjeve, vaše sudjelovanje će biti potvrđeno kada primite e-mail s prihvaćanjem zahtjeva.",
"Ask your instance admin to {enable_feature}.": "Zatraži administratora instance da {enable_feature}.", "Ask your instance admin to {enable_feature}.": "Zatraži administratora instance da {enable_feature}.",
"Assigned to": "Dodijeljeno", "Assigned to": "Dodijeljeno",
@ -158,9 +159,9 @@
"Cancel": "Otkaži", "Cancel": "Otkaži",
"Cancel anonymous participation": "Otkaži anonimno sudjelovanje", "Cancel anonymous participation": "Otkaži anonimno sudjelovanje",
"Cancel creation": "Otkaži stvaranje", "Cancel creation": "Otkaži stvaranje",
"Cancel discussion title edition": "", "Cancel discussion title edition": "Prekini mijenjanje naslova diskusije",
"Cancel edition": "Otkaži uređivanje", "Cancel edition": "Otkaži uređivanje",
"Cancel follow request": "", "Cancel follow request": "Otkaži zahtjev za praćenje",
"Cancel membership request": "", "Cancel membership request": "",
"Cancel my participation request…": "Otkaži moj zahtjev za sudjelovanje…", "Cancel my participation request…": "Otkaži moj zahtjev za sudjelovanje…",
"Cancel my participation…": "Otkaži moje sudjelovanje…", "Cancel my participation…": "Otkaži moje sudjelovanje…",
@ -180,12 +181,12 @@
"Change user email": "Promijeni e-mail adresu korisnika", "Change user email": "Promijeni e-mail adresu korisnika",
"Change user role": "Promijeni ulogu korisnika", "Change user role": "Promijeni ulogu korisnika",
"Check your inbox (and your junk mail folder).": "Provjeri svoj inbox (i spam mapu).", "Check your inbox (and your junk mail folder).": "Provjeri svoj inbox (i spam mapu).",
"Choose the source of the instance's Privacy Policy": "", "Choose the source of the instance's Privacy Policy": "Odaberi izvor politike privatnosti instance",
"Choose the source of the instance's Terms": "", "Choose the source of the instance's Terms": "Odaberi izvor uvjeta instance",
"City or region": "Grad ili regija", "City or region": "Grad ili regija",
"Clear": "Očisti", "Clear": "Očisti",
"Clear address field": "Isprazni polje adreses", "Clear address field": "Isprazni polje adrese",
"Clear date filter field": "", "Clear date filter field": "Isprazni polje filtra datuma",
"Clear participation data for all events": "Očisti podatke o sudjelovanju svih događaja", "Clear participation data for all events": "Očisti podatke o sudjelovanju svih događaja",
"Clear participation data for this event": "Očisti podatke o sudjelovanju ovog događaja", "Clear participation data for this event": "Očisti podatke o sudjelovanju ovog događaja",
"Clear timezone field": "Isprazni polje vremenske zone", "Clear timezone field": "Isprazni polje vremenske zone",
@ -218,7 +219,7 @@
"Country": "Država", "Country": "Država",
"Create": "Stvori", "Create": "Stvori",
"Create a calc": "Stvori calc", "Create a calc": "Stvori calc",
"Create a discussion": "Stvori razgovor", "Create a discussion": "Pokreni diskusiju",
"Create a folder": "Stvori mapu", "Create a folder": "Stvori mapu",
"Create a new event": "Stvori novi događaj", "Create a new event": "Stvori novi događaj",
"Create a new group": "Stvori novu grupu", "Create a new group": "Stvori novu grupu",
@ -237,7 +238,7 @@
"Create my profile": "Stvori moj profil", "Create my profile": "Stvori moj profil",
"Create new links": "Stvori nove poveznice", "Create new links": "Stvori nove poveznice",
"Create resource": "Stvori resurs", "Create resource": "Stvori resurs",
"Create the discussion": "Stvori razgovor", "Create the discussion": "Pokreni diskusiju",
"Create to-do lists for all the tasks you need to do, assign them and set due dates.": "Izradite popise obveza za sve zadatke koje trebate napraviti, dodijelite ih i postavite rokove.", "Create to-do lists for all the tasks you need to do, assign them and set due dates.": "Izradite popise obveza za sve zadatke koje trebate napraviti, dodijelite ih i postavite rokove.",
"Create token": "Stvori token", "Create token": "Stvori token",
"Created by {name}": "Stvorili {name}", "Created by {name}": "Stvorili {name}",
@ -297,7 +298,7 @@
"Do you really want to suspend this account? All of the user's profiles will be deleted.": "Stvarno želiš suspendirati ovaj račun? Svi korisnički profili će se izbrisati.", "Do you really want to suspend this account? All of the user's profiles will be deleted.": "Stvarno želiš suspendirati ovaj račun? Svi korisnički profili će se izbrisati.",
"Do you wish to {create_event} or {explore_events}?": "Želite li {create_event} ili {explore_event}?", "Do you wish to {create_event} or {explore_events}?": "Želite li {create_event} ili {explore_event}?",
"Do you wish to {create_group} or {explore_groups}?": "Želite li {create_group} ili {explore_groups}?", "Do you wish to {create_group} or {explore_groups}?": "Želite li {create_group} ili {explore_groups}?",
"Does the event needs to be confirmed later or is it cancelled?": "", "Does the event needs to be confirmed later or is it cancelled?": "Treba li događaj kasnije potvrditi ili je otkazan?",
"Domain": "Domena", "Domain": "Domena",
"Draft": "Skica", "Draft": "Skica",
"Drafts": "Skice", "Drafts": "Skice",
@ -318,7 +319,7 @@
"Element value": "Vrijednost elementa", "Element value": "Vrijednost elementa",
"Email": "E-mail", "Email": "E-mail",
"Email address": "E-mail adresa", "Email address": "E-mail adresa",
"Email validate": "", "Email validate": "Ovjeri e-mail adresu",
"Emails usually don't contain capitals, make sure you haven't made a typo.": "E-mailovi obično ne sadrže velika slova, provjerite pravopis.", "Emails usually don't contain capitals, make sure you haven't made a typo.": "E-mailovi obično ne sadrže velika slova, provjerite pravopis.",
"Enabled": "Omogućeno", "Enabled": "Omogućeno",
"Ends on…": "Završava na…", "Ends on…": "Završava na…",
@ -354,7 +355,7 @@
"Event metadata": "Metapodaci događaja", "Event metadata": "Metapodaci događaja",
"Event page settings": "Postavke stranice događaja", "Event page settings": "Postavke stranice događaja",
"Event status": "Stanje događaja", "Event status": "Stanje događaja",
"Event timezone will default to the timezone of the event's address if there is one, or to your own timezone setting.": "", "Event timezone will default to the timezone of the event's address if there is one, or to your own timezone setting.": "Vremenska zona događaja će se postaviti na vremensku zonu adrese događaja ako postoji ili na tvoju vremensku zonu.",
"Event to be confirmed": "Događaj iščekuje potvrdu", "Event to be confirmed": "Događaj iščekuje potvrdu",
"Event {eventTitle} deleted": "Događaj {eventTitle} izbrisan", "Event {eventTitle} deleted": "Događaj {eventTitle} izbrisan",
"Event {eventTitle} reported": "Događaj {eventTitle} prijavljen", "Event {eventTitle} reported": "Događaj {eventTitle} prijavljen",
@ -384,11 +385,11 @@
"Find an instance": "Pronađi instancu", "Find an instance": "Pronađi instancu",
"Find another instance": "Nađi drugu instancu", "Find another instance": "Nađi drugu instancu",
"Find or add an element": "Pronađi ili dodaj jedan element", "Find or add an element": "Pronađi ili dodaj jedan element",
"First steps": "", "First steps": "Prvi koraci",
"Follow": "Prati", "Follow": "Prati",
"Follower": "Pratioc", "Follower": "Pratilac",
"Followers": "Pratitelji", "Followers": "Pratioci",
"Followers will receive new public events and posts.": "Pratitelji će dobiti nove javne događaje i objave.", "Followers will receive new public events and posts.": "Pratioci će primati obavijesti o novim javnim događajima i objave.",
"Following the group will allow you to be informed of the {group_upcoming_public_events}, whereas joining the group means you will {access_to_group_private_content_as_well}, including group discussions, group resources and members-only posts.": "", "Following the group will allow you to be informed of the {group_upcoming_public_events}, whereas joining the group means you will {access_to_group_private_content_as_well}, including group discussions, group resources and members-only posts.": "",
"Followings": "Praćenja", "Followings": "Praćenja",
"For instance: London": "Na primjer: Osijek", "For instance: London": "Na primjer: Osijek",
@ -396,7 +397,7 @@
"Forgot your password ?": "Zaboravio/la si lozinku?", "Forgot your password ?": "Zaboravio/la si lozinku?",
"Forgot your password?": "Zaboravio/la si svoju lozinku?", "Forgot your password?": "Zaboravio/la si svoju lozinku?",
"Framadate poll": "Framadate anketa", "Framadate poll": "Framadate anketa",
"From my groups": "", "From my groups": "Iz mojih grupa",
"From the {startDate} at {startTime} to the {endDate}": "Od {startDate} u {startTime} do {endDate}", "From the {startDate} at {startTime} to the {endDate}": "Od {startDate} u {startTime} do {endDate}",
"From the {startDate} at {startTime} to the {endDate} at {endTime}": "Od {startDate} u {startTime} do {endDate} u {endTime}", "From the {startDate} at {startTime} to the {endDate} at {endTime}": "Od {startDate} u {startTime} do {endDate} u {endTime}",
"From the {startDate} to the {endDate}": "Od {startDate} do {endDate}", "From the {startDate} to the {endDate}": "Od {startDate} do {endDate}",
@ -407,6 +408,7 @@
"General information": "Opće informacije", "General information": "Opće informacije",
"General settings": "Opće postavke", "General settings": "Opće postavke",
"Geolocation was not determined in time.": "Geolokaliziranje nije na vrijeme utvrđeno.", "Geolocation was not determined in time.": "Geolokaliziranje nije na vrijeme utvrđeno.",
"Get informed of the upcoming public events": "Informiraj se o nadolazećim javnim događanjima",
"Getting location": "Lociranje", "Getting location": "Lociranje",
"Getting there": "Dolazak", "Getting there": "Dolazak",
"Glossary": "Glosar", "Glossary": "Glosar",
@ -415,7 +417,7 @@
"Go!": "Kreni!", "Go!": "Kreni!",
"Google Meet": "Google Meet", "Google Meet": "Google Meet",
"Group": "Grupe", "Group": "Grupe",
"Group Followers": "Pratitelji grupe", "Group Followers": "Pratioci grupe",
"Group Members": "Članovi Grupe", "Group Members": "Članovi Grupe",
"Group URL": "URL grupe", "Group URL": "URL grupe",
"Group activity": "Aktivnost grupe", "Group activity": "Aktivnost grupe",
@ -507,11 +509,12 @@
"Jitsi Meet": "Jitsi Meet", "Jitsi Meet": "Jitsi Meet",
"Join": "Pridruži se", "Join": "Pridruži se",
"Join <b>{instance}</b>, a Mobilizon instance": "Pridruži se <b>{instance}</b>, Mobilizon instanca", "Join <b>{instance}</b>, a Mobilizon instance": "Pridruži se <b>{instance}</b>, Mobilizon instanca",
"Join group": "Pridruži se", "Join group": "Pridruži se grupi",
"Join group {group}": "Pridruži se grupi {group}", "Join group {group}": "Pridruži se grupi {group}",
"Join {instance}, a Mobilizon instance": "Pridruži se instanci {instance}, Mobilizon instanca", "Join {instance}, a Mobilizon instance": "Pridruži se instanci {instance}, Mobilizon instanca",
"Keep the entire conversation about a specific topic together on a single page.": "Držite zajedno cijeli razgovor o nekoj temi na jednoj stranici.", "Keep the entire conversation about a specific topic together on a single page.": "Držite zajedno cijeli razgovor o nekoj temi na jednoj stranici.",
"Key words": "Ključne riječi", "Key words": "Ključne riječi",
"Keyword, event title, group name, etc.": "Ključna riječ, naslov događaja, ime grupe itd.",
"Language": "Jezik", "Language": "Jezik",
"Languages": "Jezici", "Languages": "Jezici",
"Last IP adress": "Zadnja IP adresa", "Last IP adress": "Zadnja IP adresa",
@ -555,7 +558,7 @@
"Main languages you/your moderators speak": "Glavni jezici koje vi/vaši moderatori govorite", "Main languages you/your moderators speak": "Glavni jezici koje vi/vaši moderatori govorite",
"Make sure that all words are spelled correctly.": "Provjeri ispravnost pisanja riječi.", "Make sure that all words are spelled correctly.": "Provjeri ispravnost pisanja riječi.",
"Manage participations": "Uredi sudjelovanja", "Manage participations": "Uredi sudjelovanja",
"Manually approve new followers": "Ručno odobri nove pratitelje", "Manually approve new followers": "Ručno odobri nove pratioce",
"Manually invite new members": "Ručno pozivanje novih članova", "Manually invite new members": "Ručno pozivanje novih članova",
"Map": "Karta", "Map": "Karta",
"Mark as resolved": "Označi kao obavljeno", "Mark as resolved": "Označi kao obavljeno",
@ -594,7 +597,7 @@
"My identities": "Moji identiteti", "My identities": "Moji identiteti",
"NOTE! The default terms have not been checked over by a lawyer and thus are unlikely to provide full legal protection for all situations for an instance admin using them. They are also not specific to all countries and jurisdictions. If you are unsure, please check with a lawyer.": "PAZI! Zadani uvjeti nisu bili pregledani od odvjetnika i time nisu predviđeni za sve situacije ili punu legalnu zaštitu administratora koji ih koriste. Također nisu specifične za sve države ili nadležnosti. Ako nisi siguran/na, savjetuj odvjetnika.", "NOTE! The default terms have not been checked over by a lawyer and thus are unlikely to provide full legal protection for all situations for an instance admin using them. They are also not specific to all countries and jurisdictions. If you are unsure, please check with a lawyer.": "PAZI! Zadani uvjeti nisu bili pregledani od odvjetnika i time nisu predviđeni za sve situacije ili punu legalnu zaštitu administratora koji ih koriste. Također nisu specifične za sve države ili nadležnosti. Ako nisi siguran/na, savjetuj odvjetnika.",
"Name": "Ime", "Name": "Ime",
"Navigated to {pageTitle}": "", "Navigated to {pageTitle}": "Prijelaz na {pageTitle}",
"New discussion": "Novi razgovor", "New discussion": "Novi razgovor",
"New email": "Novi email", "New email": "Novi email",
"New folder": "Nova mapa", "New folder": "Nova mapa",
@ -618,7 +621,7 @@
"No event found at this address": "Na ovoj adresi nije pronađen nijedan događaj", "No event found at this address": "Na ovoj adresi nije pronađen nijedan događaj",
"No events found": "Bez rezultata", "No events found": "Bez rezultata",
"No events found for {search}": "Nema događaja za {search}", "No events found for {search}": "Nema događaja za {search}",
"No follower matches the filters": "Nijedan pratioc ne paše filterima", "No follower matches the filters": "Nijedan pratilac ne odgovara filtrima",
"No group found": "Bez rezultata", "No group found": "Bez rezultata",
"No group matches the filters": "Nijedna grupa ne odgovara filterima", "No group matches the filters": "Nijedna grupa ne odgovara filterima",
"No group member found": "", "No group member found": "",
@ -630,7 +633,7 @@
"No instance to reject|Reject instance|Reject {number} instances": "Nema instance za odbiti|Odbij instancu|Odbij {number} instanca", "No instance to reject|Reject instance|Reject {number} instances": "Nema instance za odbiti|Odbij instancu|Odbij {number} instanca",
"No instance to remove|Remove instance|Remove {number} instances": "Nema instanca za ukloniti|Ukolni instancu|Ukloni {number} instanca", "No instance to remove|Remove instance|Remove {number} instances": "Nema instanca za ukloniti|Ukolni instancu|Ukloni {number} instanca",
"No languages found": "Nema pronađenih jezika", "No languages found": "Nema pronađenih jezika",
"No member matches the filters": "Nijedan član ne paše filterima", "No member matches the filters": "Nijedan član ne odgovara filtrima",
"No members found": "Nema članova", "No members found": "Nema članova",
"No memberships found": "Nema članstva", "No memberships found": "Nema članstva",
"No message": "Nema poruke", "No message": "Nema poruke",
@ -684,7 +687,8 @@
"On {instance} and other federated instances": "Na {instance} i drugim federaliziranim instancama", "On {instance} and other federated instances": "Na {instance} i drugim federaliziranim instancama",
"Online": "Online", "Online": "Online",
"Online events": "Online događaji", "Online events": "Online događaji",
"Online ticketing": "", "Online ticketing": "Online prodaja karata",
"Online upcoming events": "Nadolazeći online događaji",
"Only accessible through link": "Dostupno samo preko poveznice", "Only accessible through link": "Dostupno samo preko poveznice",
"Only accessible through link (private)": "Dostupno samo kroz poveznicu (privatno)", "Only accessible through link (private)": "Dostupno samo kroz poveznicu (privatno)",
"Only accessible to members of the group": "Dostupno samo članovima grupe", "Only accessible to members of the group": "Dostupno samo članovima grupe",
@ -737,6 +741,7 @@
"PeerTube replay": "PeerTube repriza", "PeerTube replay": "PeerTube repriza",
"Pending": "U tijeku", "Pending": "U tijeku",
"Personal feeds": "Osobni feedovi", "Personal feeds": "Osobni feedovi",
"Photo by {author} on {source}": "Autor fotografije je {author} na {source}",
"Pick": "Izaberi", "Pick": "Izaberi",
"Pick a profile or a group": "Izaberi profil ili grupu", "Pick a profile or a group": "Izaberi profil ili grupu",
"Pick an identity": "Izaberite identitet", "Pick an identity": "Izaberite identitet",
@ -749,8 +754,8 @@
"Please make sure the address is correct and that the page hasn't been moved.": "Provjeri je li adresa točna i da stranica nije premještena.", "Please make sure the address is correct and that the page hasn't been moved.": "Provjeri je li adresa točna i da stranica nije premještena.",
"Please read the {fullRules} published by {instance}'s administrators.": "Pročitaj {fullRules} koje je objavio administrator instance {instance}.", "Please read the {fullRules} published by {instance}'s administrators.": "Pročitaj {fullRules} koje je objavio administrator instance {instance}.",
"Popular groups close to you": "Popularne grupe u tvojoj blizini", "Popular groups close to you": "Popularne grupe u tvojoj blizini",
"Post": "Objavi", "Post": "Objava",
"Post URL": "", "Post URL": "URL objave",
"Post a comment": "Pošalji komentar", "Post a comment": "Pošalji komentar",
"Post a reply": "Pošalji odgovor", "Post a reply": "Pošalji odgovor",
"Post body": "Tekst objave", "Post body": "Tekst objave",
@ -781,11 +786,10 @@
"Public event": "Javni događaj", "Public event": "Javni događaj",
"Public feeds": "Javni feed", "Public feeds": "Javni feed",
"Public iCal Feed": "Javni iCal Feed", "Public iCal Feed": "Javni iCal Feed",
"Public page": "Javna stranica",
"Public preview": "Javni pregled", "Public preview": "Javni pregled",
"Publication date": "Datum objave", "Publication date": "Datum objave",
"Publish": "Objavi", "Publish": "Objavi",
"Published by {name}": "", "Published by {name}": "Autor objave: {name}",
"Published events with <b>{comments}</b> comments and <b>{participations}</b> confirmed participations": "Objavljeni događaji sa <b>{comments}</b> komentarima i <b>{participations}</b> potvrđenim sudjelovanjima", "Published events with <b>{comments}</b> comments and <b>{participations}</b> confirmed participations": "Objavljeni događaji sa <b>{comments}</b> komentarima i <b>{participations}</b> potvrđenim sudjelovanjima",
"Push": "Automatska obavijest", "Push": "Automatska obavijest",
"Quote": "Citat", "Quote": "Citat",
@ -853,7 +857,7 @@
"Resources": "Resursi", "Resources": "Resursi",
"Restricted": "Restrikcije", "Restricted": "Restrikcije",
"Return to the group page": "Vrati se na stranicu grupe", "Return to the group page": "Vrati se na stranicu grupe",
"Right now": "Sad", "Right now": "Sada",
"Role": "Uloga", "Role": "Uloga",
"Rules": "Pravila", "Rules": "Pravila",
"SSL and it's successor TLS are encryption technologies to secure data communications when using the service. You can recognize an encrypted connection in your browser's address line when the URL begins with {https} and the lock icon is displayed in your browser's address bar.": "SSL i nasljedni TLS su tehnologije za šifrianje koje se koriste za zaštitu prijenosa podataka i komunikacije pri korištenju servisa. Možete prepoznati šifriranu vezu u poveznici na vrhu vašeg preglednika, gdje URL počinje sa {https} i pored toga se nalazi ikona lokota.", "SSL and it's successor TLS are encryption technologies to secure data communications when using the service. You can recognize an encrypted connection in your browser's address line when the URL begins with {https} and the lock icon is displayed in your browser's address bar.": "SSL i nasljedni TLS su tehnologije za šifrianje koje se koriste za zaštitu prijenosa podataka i komunikacije pri korištenju servisa. Možete prepoznati šifriranu vezu u poveznici na vrhu vašeg preglednika, gdje URL počinje sa {https} i pored toga se nalazi ikona lokota.",
@ -886,7 +890,7 @@
"Share": "Dijeli", "Share": "Dijeli",
"Share this event": "Podijeli ovaj događaj", "Share this event": "Podijeli ovaj događaj",
"Share this group": "Dijeli ovu grupu", "Share this group": "Dijeli ovu grupu",
"Share this post": "", "Share this post": "Dijeli ovu objavu",
"Short bio": "Kratki opis", "Short bio": "Kratki opis",
"Show filters": "Prikaži filtre", "Show filters": "Prikaži filtre",
"Show map": "Prikaži kartu", "Show map": "Prikaži kartu",
@ -900,7 +904,7 @@
"Sign in with": "Prijavi se sa", "Sign in with": "Prijavi se sa",
"Sign up": "Upiši se", "Sign up": "Upiši se",
"Since you are a new member, private content can take a few minutes to appear.": "Pošto ste novi član, privatni sadržaj će trebati vremena da se prikaže.", "Since you are a new member, private content can take a few minutes to appear.": "Pošto ste novi član, privatni sadržaj će trebati vremena da se prikaže.",
"Skip to main content": "", "Skip to main content": "Prijeđi na glavni sadržaj",
"Smoke free": "Zabranjeno pušenje", "Smoke free": "Zabranjeno pušenje",
"Smoking allowed": "Dozvoljeno pušenje", "Smoking allowed": "Dozvoljeno pušenje",
"Social": "Društvene mreže", "Social": "Društvene mreže",
@ -919,7 +923,7 @@
"Suspend the account": "Suspendiraj račun", "Suspend the account": "Suspendiraj račun",
"Suspend the account?": "Suspendirati račun?", "Suspend the account?": "Suspendirati račun?",
"Suspended": "Obustavljeno", "Suspended": "Obustavljeno",
"Tag search": "", "Tag search": "Pretraga oznakama",
"Task lists": "Popisi zadataka", "Task lists": "Popisi zadataka",
"Technical details": "Tehnički detalji", "Technical details": "Tehnički detalji",
"Tentative": "Privremeno", "Tentative": "Privremeno",
@ -927,7 +931,7 @@
"Terms": "Uvjeti", "Terms": "Uvjeti",
"Terms of service": "Uvjeti korištenja", "Terms of service": "Uvjeti korištenja",
"Text": "Tekst", "Text": "Tekst",
"That you follow or of which you are a member": "", "That you follow or of which you are a member": "Koje pratiš ili čiji si član",
"The Big Blue Button video teleconference URL": "URL Big Blue Button videokonferencije", "The Big Blue Button video teleconference URL": "URL Big Blue Button videokonferencije",
"The Google Meet video teleconference URL": "URL Google Meet videokonferencije", "The Google Meet video teleconference URL": "URL Google Meet videokonferencije",
"The Jitsi Meet video teleconference URL": "URL Jitsi Meet videokonferencije", "The Jitsi Meet video teleconference URL": "URL Jitsi Meet videokonferencije",
@ -947,7 +951,7 @@
"The event has been updated": "Događaj je ažuriran", "The event has been updated": "Događaj je ažuriran",
"The event has been updated and published": "Događaj je ažuriran i objavljen", "The event has been updated and published": "Događaj je ažuriran i objavljen",
"The event hasn't got a sign language interpreter": "Događaj se ne prevodi na znakovni jezik", "The event hasn't got a sign language interpreter": "Događaj se ne prevodi na znakovni jezik",
"The event is fully online": "", "The event is fully online": "Događaj se održava online",
"The event live video contains subtitles": "Video događaja uživo sadrži titlove", "The event live video contains subtitles": "Video događaja uživo sadrži titlove",
"The event live video does not contain subtitles": "Video događaja uživo ne sadrži titlove", "The event live video does not contain subtitles": "Video događaja uživo ne sadrži titlove",
"The event organiser has chosen to validate manually participations. Do you want to add a little note to explain why you want to participate to this event?": "Organizatori su odlučili ručno odobriti svako sudjelovanje. Želite li dodati malu bilješku kako bi objasnili zašto želite sudjelovati u ovom događaju?", "The event organiser has chosen to validate manually participations. Do you want to add a little note to explain why you want to participate to this event?": "Organizatori su odlučili ručno odobriti svako sudjelovanje. Želite li dodati malu bilješku kako bi objasnili zašto želite sudjelovati u ovom događaju?",
@ -998,6 +1002,7 @@
"This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.": "Ova instanca i ovi organizatori dozvoljavaju anonimne prijave, ali očekuju ovjerenje kroz email potvrdu.", "This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.": "Ova instanca i ovi organizatori dozvoljavaju anonimne prijave, ali očekuju ovjerenje kroz email potvrdu.",
"This URL doesn't seem to be valid": "Čini se da je ovaj URL neispravan", "This URL doesn't seem to be valid": "Čini se da je ovaj URL neispravan",
"This URL is not supported": "Ovaj URL nije podržan", "This URL is not supported": "Ovaj URL nije podržan",
"This application will be allowed to list group followers in all of the groups you're a member of": "Ova će aplikacija smjeti prikazati popis pratioca grupe u svim grupama čiji si član",
"This event has been cancelled.": "Ovaj je događaj otkazan.", "This event has been cancelled.": "Ovaj je događaj otkazan.",
"This event is accessible only through it's link. Be careful where you post this link.": "Ovaj je događaj dostupan samo kroz njegovu poveznicu. Budite pažljivi gdje šaljete ovu poveznicu.", "This event is accessible only through it's link. Be careful where you post this link.": "Ovaj je događaj dostupan samo kroz njegovu poveznicu. Budite pažljivi gdje šaljete ovu poveznicu.",
"This group doesn't have a description yet.": "Ova grupa nema opis.", "This group doesn't have a description yet.": "Ova grupa nema opis.",
@ -1014,7 +1019,7 @@
"This month": "Ovaj mjesec", "This month": "Ovaj mjesec",
"This post is accessible only for members. You have access to it for moderation purposes only because you are an instance moderator.": "Ova objava je dostupna samo članovima. Imaš pristup u svrhu moderiranja budući da si moderator instance.", "This post is accessible only for members. You have access to it for moderation purposes only because you are an instance moderator.": "Ova objava je dostupna samo članovima. Imaš pristup u svrhu moderiranja budući da si moderator instance.",
"This post is accessible only through it's link. Be careful where you post this link.": "Ova je objava dostupna samo putem njene poveznice. Pazi gdje objavljuješ ovu poveznicu.", "This post is accessible only through it's link. Be careful where you post this link.": "Ova je objava dostupna samo putem njene poveznice. Pazi gdje objavljuješ ovu poveznicu.",
"This profile is from another instance, the informations shown here may be incomplete.": "", "This profile is from another instance, the informations shown here may be incomplete.": "Ovaj profil je iz jedne druge instance, ovdje prikazane informacije mogu biti nepotpune.",
"This profile was not found": "", "This profile was not found": "",
"This setting will be used to display the website and send you emails in the correct language.": "Ova postavka će se koristiti za prikazivanje web-stranice i slanje e-maila u ispravnom jeziku.", "This setting will be used to display the website and send you emails in the correct language.": "Ova postavka će se koristiti za prikazivanje web-stranice i slanje e-maila u ispravnom jeziku.",
"This user doesn't have any profiles": "Korisnik nema nijedan profil", "This user doesn't have any profiles": "Korisnik nema nijedan profil",
@ -1073,10 +1078,10 @@
"Unsuspend": "Poništi suspendiranje", "Unsuspend": "Poništi suspendiranje",
"Upcoming": "Nadolazeće", "Upcoming": "Nadolazeće",
"Upcoming events": "Nadolazeći događaji", "Upcoming events": "Nadolazeći događaji",
"Upcoming events from your groups": "", "Upcoming events from your groups": "Nadolazeći događaji iz tvojih grupa",
"Update": "Ažuriraj", "Update": "Ažuriraj",
"Update app": "Aktualiziraj program", "Update app": "Aktualiziraj program",
"Update discussion title": "", "Update discussion title": "Aktualiziraj naslov diskusije",
"Update event {name}": "Ažuriraj događaj {name}", "Update event {name}": "Ažuriraj događaj {name}",
"Update group": "Ažuriraj grupu", "Update group": "Ažuriraj grupu",
"Update my event": "Ažuriraj moj događaj", "Update my event": "Ažuriraj moj događaj",
@ -1100,10 +1105,11 @@
"View all posts": "Prikaži sve objave", "View all posts": "Prikaži sve objave",
"View event page": "Prikaži stranicu događaja", "View event page": "Prikaži stranicu događaja",
"View everything": "Prikaži sve", "View everything": "Prikaži sve",
"View full profile": "Prikaži cijeli profil", "View full profile": "Prikaži potpuni profil",
"View less": "Prikaži manje", "View less": "Prikaži manje",
"View more": "Prikaži više", "View more": "Prikaži više",
"View more events": "Prikaži još događaja", "View more events": "Prikaži još događaja",
"View more online events": "Prikaži još online događaja",
"View page on {hostname} (in a new window)": "Prikaži stranicu na {hostname} (u novom prozoru)", "View page on {hostname} (in a new window)": "Prikaži stranicu na {hostname} (u novom prozoru)",
"View past events": "Prikaži prošle događaje", "View past events": "Prikaži prošle događaje",
"Visibility was set to an unknown value.": "Vidljivost je postavljena na nepoznatu vrijednost.", "Visibility was set to an unknown value.": "Vidljivost je postavljena na nepoznatu vrijednost.",
@ -1113,6 +1119,7 @@
"Visible everywhere on the web (public)": "Vidljivo svima na internetu (javno)", "Visible everywhere on the web (public)": "Vidljivo svima na internetu (javno)",
"Waiting for organization team approval.": "Iščekivanje odobrenja organizacijskog tima.", "Waiting for organization team approval.": "Iščekivanje odobrenja organizacijskog tima.",
"Warning": "Upozorenje", "Warning": "Upozorenje",
"We collect your feedback and the error information in order to improve this service.": "Prikupljamo tvoje povratne informacije i informacije o pogrešci kako bismo poboljšali ovu uslugu.",
"We couldn't save your participation inside this browser. Not to worry, you have successfully confirmed your participation, we just couldn't save it's status in this browser because of a technical issue.": "Nismo mogli spremiti tvoje sudjelovanje u ovom pregledniku. Bez brige, tvoje je sudjelovanje potvrđeno, ali zbog tehničkog problema stanje nismo mogli spremiti.", "We couldn't save your participation inside this browser. Not to worry, you have successfully confirmed your participation, we just couldn't save it's status in this browser because of a technical issue.": "Nismo mogli spremiti tvoje sudjelovanje u ovom pregledniku. Bez brige, tvoje je sudjelovanje potvrđeno, ali zbog tehničkog problema stanje nismo mogli spremiti.",
"We improve this software thanks to your feedback. To let us know about this issue, two possibilities (both unfortunately require user account creation):": "Softver poboljšavamo pomoću vaše povratne informacije. Imate dvije mogućnosti kako bi nas obavijestili (obje nažalost zahtijevaju stvaranje korisničkog računa):", "We improve this software thanks to your feedback. To let us know about this issue, two possibilities (both unfortunately require user account creation):": "Softver poboljšavamo pomoću vaše povratne informacije. Imate dvije mogućnosti kako bi nas obavijestili (obje nažalost zahtijevaju stvaranje korisničkog računa):",
"We just sent an email to {email}": "Upravo smo poslali e-mail na {email}", "We just sent an email to {email}": "Upravo smo poslali e-mail na {email}",
@ -1131,13 +1138,13 @@
"What happened?": "Što se dogodilo?", "What happened?": "Što se dogodilo?",
"Wheelchair accessibility": "Pristup invalidskim kolicima", "Wheelchair accessibility": "Pristup invalidskim kolicima",
"When a moderator from the group creates an event and attributes it to the group, it will show up here.": "Kada moderator grupe stvori događaj i pripiše ga grupi, prikazati će se ovdje.", "When a moderator from the group creates an event and attributes it to the group, it will show up here.": "Kada moderator grupe stvori događaj i pripiše ga grupi, prikazati će se ovdje.",
"When the event is private, you'll need to share the link around.": "", "When the event is private, you'll need to share the link around.": "Kada je događaj privatan, morat ćeš dijeliti vezu s drugima.",
"When the post is private, you'll need to share the link around.": "", "When the post is private, you'll need to share the link around.": "Kada je objava privatna, morat ćeš dijeliti vezu s drugima.",
"Whether smoking is prohibited during the event": "Je li je pušenje dozvoljeno tijekom događaja", "Whether smoking is prohibited during the event": "Je li je pušenje dozvoljeno tijekom događaja",
"Whether the event is accessible with a wheelchair": "Je li postoji pristup za osobe u invalidskim kolicima", "Whether the event is accessible with a wheelchair": "Je li postoji pristup za osobe u invalidskim kolicima",
"Whether the event is interpreted in sign language": "Je li se događaj prevodi na znakovni jezik", "Whether the event is interpreted in sign language": "Je li se događaj prevodi na znakovni jezik",
"Whether the event live video is subtitled": "Je li video događaja uživo titlovan", "Whether the event live video is subtitled": "Je li video događaja uživo titlovan",
"Who can post a comment?": "", "Who can post a comment?": "Tko smije komentirati?",
"Who can view this event and participate": "Tko može vidjeti ovaj događaj i sudjelovati", "Who can view this event and participate": "Tko može vidjeti ovaj događaj i sudjelovati",
"Who can view this post": "Tko može vidjeti ovu objavu", "Who can view this post": "Tko može vidjeti ovu objavu",
"Who published {number} events": "Koji su objavili {number} događaja", "Who published {number} events": "Koji su objavili {number} događaja",
@ -1183,7 +1190,7 @@
"You demoted {member} to simple member.": "Snizili ste {member} u člana.", "You demoted {member} to simple member.": "Snizili ste {member} u člana.",
"You didn't create or join any event yet.": "Niste stvorili i se pridružili nijednom događaju.", "You didn't create or join any event yet.": "Niste stvorili i se pridružili nijednom događaju.",
"You don't follow any instances yet.": "Ne pratite nijednu instancu.", "You don't follow any instances yet.": "Ne pratite nijednu instancu.",
"You don't have any upcoming events. Maybe try another filter?": "", "You don't have any upcoming events. Maybe try another filter?": "Nemaš nijedan nadolazeći događaj. Želiš li probati jedan drugi filtar?",
"You excluded member {member}.": "Isključili ste člana {member}.", "You excluded member {member}.": "Isključili ste člana {member}.",
"You have attended {count} events in the past.": "", "You have attended {count} events in the past.": "",
"You have been invited by {invitedBy} to the following group:": "{invitedBy} su vas pozvali u grupu:", "You have been invited by {invitedBy} to the following group:": "{invitedBy} su vas pozvali u grupu:",
@ -1308,7 +1315,7 @@
"{count} events": "{count} događaja", "{count} events": "{count} događaja",
"{count} km": "{count} km", "{count} km": "{count} km",
"{count} members": "Nema članova|Jedan član|{count} člana/članova", "{count} members": "Nema članova|Jedan član|{count} člana/članova",
"{count} members or followers": "", "{count} members or followers": "Nema članova ili pratilaca|Jedan član ili pratilac|{count} članova ili pratilaca",
"{count} participants": "Nema sudionika | Jedan sudionik | {count} sudionika", "{count} participants": "Nema sudionika | Jedan sudionik | {count} sudionika",
"{count} requests waiting": "{count} zahtjeva na čekanju", "{count} requests waiting": "{count} zahtjeva na čekanju",
"{folder} - Resources": "{folder} resursi", "{folder} - Resources": "{folder} resursi",

View file

@ -815,7 +815,6 @@
"Public event": "Nyilvános esemény", "Public event": "Nyilvános esemény",
"Public feeds": "Nyilvános hírforrások", "Public feeds": "Nyilvános hírforrások",
"Public iCal Feed": "Nyilvános iCal hírforrás", "Public iCal Feed": "Nyilvános iCal hírforrás",
"Public page": "Nyilvános oldal",
"Public preview": "Nyilvános előnézet", "Public preview": "Nyilvános előnézet",
"Publication date": "Közzététel dátuma", "Publication date": "Közzététel dátuma",
"Publish": "Közzététel", "Publish": "Közzététel",

View file

@ -717,7 +717,6 @@
"Public event": "Acara publik", "Public event": "Acara publik",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "Tanggal publikasi", "Publication date": "Tanggal publikasi",
"Publish": "Publikasikan", "Publish": "Publikasikan",

View file

@ -815,7 +815,6 @@
"Public event": "Eventi pubblici", "Public event": "Eventi pubblici",
"Public feeds": "Feed pubblici", "Public feeds": "Feed pubblici",
"Public iCal Feed": "Feed iCal pubblico", "Public iCal Feed": "Feed iCal pubblico",
"Public page": "Pagina pubblica",
"Public preview": "Anteprima pubblica", "Public preview": "Anteprima pubblica",
"Publication date": "Data di pubblicazione", "Publication date": "Data di pubblicazione",
"Publish": "Pubblica", "Publish": "Pubblica",

View file

@ -180,7 +180,7 @@
"Click to upload": "クリックしてアップロードする", "Click to upload": "クリックしてアップロードする",
"Close": "閉じる", "Close": "閉じる",
"Close comments for all (except for admins)": "管理者以外のアカウントはコメントが不可にする", "Close comments for all (except for admins)": "管理者以外のアカウントはコメントが不可にする",
"Closed": "閉じる", "Closed": "停止",
"Comment body": "", "Comment body": "",
"Comment deleted": "コメントが削除されました。", "Comment deleted": "コメントが削除されました。",
"Comment text can't be empty": "コメントのテキストは空白にはできません", "Comment text can't be empty": "コメントのテキストは空白にはできません",
@ -438,7 +438,7 @@
"Identity {displayName} created": "{displayName}のアイデンティティが作成されました", "Identity {displayName} created": "{displayName}のアイデンティティが作成されました",
"Identity {displayName} deleted": "{displayName}のアイデンティティが削除されました", "Identity {displayName} deleted": "{displayName}のアイデンティティが削除されました",
"Identity {displayName} updated": "{displayName}のアイデンティティが更新されました", "Identity {displayName} updated": "{displayName}のアイデンティティが更新されました",
"If allowed by organizer": "", "If allowed by organizer": "イベントの主催者が決める",
"If an account with this email exists, we just sent another confirmation email to {email}": "", "If an account with this email exists, we just sent another confirmation email to {email}": "",
"If this identity is the only administrator of some groups, you need to delete them before being able to delete this identity.": "", "If this identity is the only administrator of some groups, you need to delete them before being able to delete this identity.": "",
"If you are being asked for your federated indentity, it's composed of your username and your instance. For instance, the federated identity for your first profile is:": "連合のアイデンティティー、また連合のアカウントの場合はあなたのユーバー名とインスタンスのドメインです。例えば、一番最初に作成したプロフィールの連合のアイデンティティーは:", "If you are being asked for your federated indentity, it's composed of your username and your instance. For instance, the federated identity for your first profile is:": "連合のアイデンティティー、また連合のアカウントの場合はあなたのユーバー名とインスタンスのドメインです。例えば、一番最初に作成したプロフィールの連合のアイデンティティーは:",
@ -629,7 +629,7 @@
"Notifications for manually approved participations to an event": "", "Notifications for manually approved participations to an event": "",
"Notify participants": "", "Notify participants": "",
"Now, create your first profile:": "", "Now, create your first profile:": "",
"Number of places": "行う場所の数", "Number of places": "参加可能の人の数",
"OK": "OK", "OK": "OK",
"Old password": "古いパスワード", "Old password": "古いパスワード",
"On {date}": "{date} に行う", "On {date}": "{date} に行う",
@ -648,7 +648,7 @@
"Only group moderators can create, edit and delete events.": "グループのモデレーターのみがイベントを作成、編集、削除できます。", "Only group moderators can create, edit and delete events.": "グループのモデレーターのみがイベントを作成、編集、削除できます。",
"Only group moderators can create, edit and delete posts.": "", "Only group moderators can create, edit and delete posts.": "",
"Only registered users may fetch remote events from their URL.": "", "Only registered users may fetch remote events from their URL.": "",
"Open": "", "Open": "可能",
"Open a topic on our forum": "フォーラムでトピックを作成する", "Open a topic on our forum": "フォーラムでトピックを作成する",
"Open an issue on our bug tracker (advanced users)": "上級ユーザー向けバグトラッカー上でissueを開く", "Open an issue on our bug tracker (advanced users)": "上級ユーザー向けバグトラッカー上でissueを開く",
"Opened reports": "", "Opened reports": "",
@ -731,7 +731,6 @@
"Public event": "公開イベント", "Public event": "公開イベント",
"Public feeds": "公開フィード", "Public feeds": "公開フィード",
"Public iCal Feed": "公開iCalフィード", "Public iCal Feed": "公開iCalフィード",
"Public page": "公開ページ",
"Public preview": "公開プレビュー", "Public preview": "公開プレビュー",
"Publication date": "", "Publication date": "",
"Publish": "投稿", "Publish": "投稿",
@ -757,7 +756,7 @@
"Registration is allowed, anyone can register.": "制限なくアカウントの新規登録可能です。", "Registration is allowed, anyone can register.": "制限なくアカウントの新規登録可能です。",
"Registration is closed.": "アカウントの新規登録が停止されています。", "Registration is closed.": "アカウントの新規登録が停止されています。",
"Registration is currently closed.": "アカウントの新規登録が停止中です。", "Registration is currently closed.": "アカウントの新規登録が停止中です。",
"Registrations": "", "Registrations": "アカウントの新規登録",
"Registrations are restricted by allowlisting.": "新規登録は管理者と事前連絡済みの方のみができます。", "Registrations are restricted by allowlisting.": "新規登録は管理者と事前連絡済みの方のみができます。",
"Reject": "拒否する", "Reject": "拒否する",
"Reject member": "", "Reject member": "",
@ -956,8 +955,8 @@
"This week": "今週", "This week": "今週",
"This weekend": "今週末", "This weekend": "今週末",
"This will delete / anonymize all content (events, comments, messages, participations…) created from this identity.": "", "This will delete / anonymize all content (events, comments, messages, participations…) created from this identity.": "",
"Time in your timezone ({timezone})": "", "Time in your timezone ({timezone})": "あなたのタイムゾーン ({timezone})",
"Times in your timezone ({timezone})": "", "Times in your timezone ({timezone})": "あなたのタイムゾーン ({timezone})",
"Timezone": "タイムゾーン", "Timezone": "タイムゾーン",
"Timezone detected as {timezone}.": "", "Timezone detected as {timezone}.": "",
"Title": "タイトル", "Title": "タイトル",

View file

@ -707,7 +707,6 @@
"Public event": "", "Public event": "",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "Suffeɣ-d", "Publish": "Suffeɣ-d",

View file

@ -707,7 +707,6 @@
"Public event": "", "Public event": "",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "", "Publish": "",

View file

@ -713,7 +713,6 @@
"Public event": "Openbaar evenement", "Public event": "Openbaar evenement",
"Public feeds": "Openbare feeds", "Public feeds": "Openbare feeds",
"Public iCal Feed": "Openbaar iCalfeed", "Public iCal Feed": "Openbaar iCalfeed",
"Public page": "Publieke pagina",
"Public preview": "Openbare voorvertoning", "Public preview": "Openbare voorvertoning",
"Publication date": "Publicatiedatum", "Publication date": "Publicatiedatum",
"Publish": "Publiceren", "Publish": "Publiceren",

View file

@ -815,7 +815,6 @@
"Public event": "Offentleg hending", "Public event": "Offentleg hending",
"Public feeds": "Offentlege straumar", "Public feeds": "Offentlege straumar",
"Public iCal Feed": "Offentleg iCal-straum", "Public iCal Feed": "Offentleg iCal-straum",
"Public page": "Offentleg side",
"Public preview": "Offentleg førehandsvising", "Public preview": "Offentleg førehandsvising",
"Publication date": "Lagt ut dato", "Publication date": "Lagt ut dato",
"Publish": "Legg ut", "Publish": "Legg ut",

View file

@ -707,7 +707,6 @@
"Public event": "Eveniment public", "Public event": "Eveniment public",
"Public feeds": "Flux publics", "Public feeds": "Flux publics",
"Public iCal Feed": "Flux iCal public", "Public iCal Feed": "Flux iCal public",
"Public page": "Pagina publica",
"Public preview": "Apercebut public", "Public preview": "Apercebut public",
"Publication date": "Data de publicacion", "Publication date": "Data de publicacion",
"Publish": "Publicar", "Publish": "Publicar",

View file

@ -707,7 +707,6 @@
"Public event": "Publiczne wydarzenie", "Public event": "Publiczne wydarzenie",
"Public feeds": "Publiczne strumienie", "Public feeds": "Publiczne strumienie",
"Public iCal Feed": "Publiczny strumień iCal", "Public iCal Feed": "Publiczny strumień iCal",
"Public page": "Publiczna strona",
"Public preview": "", "Public preview": "",
"Publication date": "Data publikacji", "Publication date": "Data publikacji",
"Publish": "Publikuj", "Publish": "Publikuj",

View file

@ -707,7 +707,6 @@
"Public event": "", "Public event": "",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "", "Publish": "",

View file

@ -707,7 +707,6 @@
"Public event": "Evento público", "Public event": "Evento público",
"Public feeds": "Feeds públicos", "Public feeds": "Feeds públicos",
"Public iCal Feed": "Feed iCal público", "Public iCal Feed": "Feed iCal público",
"Public page": "Página pública",
"Public preview": "", "Public preview": "",
"Publication date": "Data da publicação", "Publication date": "Data da publicação",
"Publish": "Publicar", "Publish": "Publicar",

View file

@ -707,7 +707,6 @@
"Public event": "Публичное мероприятие", "Public event": "Публичное мероприятие",
"Public feeds": "Публичные ленты", "Public feeds": "Публичные ленты",
"Public iCal Feed": "Публичная iCal-лента", "Public iCal Feed": "Публичная iCal-лента",
"Public page": "Публичная страница",
"Public preview": "Публичный предварительный просмотр", "Public preview": "Публичный предварительный просмотр",
"Publication date": "Дата публикации", "Publication date": "Дата публикации",
"Publish": "Опубликовать", "Publish": "Опубликовать",

View file

@ -707,7 +707,6 @@
"Public event": "Javni dogodek", "Public event": "Javni dogodek",
"Public feeds": "Javni viri", "Public feeds": "Javni viri",
"Public iCal Feed": "Javni vir iCal", "Public iCal Feed": "Javni vir iCal",
"Public page": "Javna stran",
"Public preview": "", "Public preview": "",
"Publication date": "Datum objave", "Publication date": "Datum objave",
"Publish": "Objavi", "Publish": "Objavi",

View file

@ -708,7 +708,6 @@
"Public event": "Publikt evenemang", "Public event": "Publikt evenemang",
"Public feeds": "Publika flöden", "Public feeds": "Publika flöden",
"Public iCal Feed": "Publika iCal-flöde", "Public iCal Feed": "Publika iCal-flöde",
"Public page": "Publik sida",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "Publicera", "Publish": "Publicera",

View file

@ -815,7 +815,6 @@
"Public event": "公共活动", "Public event": "公共活动",
"Public feeds": "公开推送", "Public feeds": "公开推送",
"Public iCal Feed": "公开iCal推送", "Public iCal Feed": "公开iCal推送",
"Public page": "公共页面",
"Public preview": "公开预览", "Public preview": "公开预览",
"Publication date": "发表日期", "Publication date": "发表日期",
"Publish": "发布", "Publish": "发布",

View file

@ -735,7 +735,6 @@
"Public event": "", "Public event": "",
"Public feeds": "", "Public feeds": "",
"Public iCal Feed": "", "Public iCal Feed": "",
"Public page": "",
"Public preview": "", "Public preview": "",
"Publication date": "", "Publication date": "",
"Publish": "", "Publish": "",

View file

@ -215,7 +215,7 @@ import { IPerson, displayName } from "@/types/actor";
import PictureUpload from "@/components/PictureUpload.vue"; import PictureUpload from "@/components/PictureUpload.vue";
import { MOBILIZON_INSTANCE_HOST } from "@/api/_entrypoint"; import { MOBILIZON_INSTANCE_HOST } from "@/api/_entrypoint";
import RouteName from "@/router/name"; import RouteName from "@/router/name";
import { buildFileVariable } from "@/utils/image"; import { buildFileFromIMedia, buildFileVariable } from "@/utils/image";
import { changeIdentity } from "@/utils/identity"; import { changeIdentity } from "@/utils/identity";
import { import {
CREATE_FEED_TOKEN_ACTOR, CREATE_FEED_TOKEN_ACTOR,
@ -237,6 +237,7 @@ import { Dialog } from "@/plugins/dialog";
import { Notifier } from "@/plugins/notifier"; import { Notifier } from "@/plugins/notifier";
import { AbsintheGraphQLErrors } from "@/types/errors.model"; import { AbsintheGraphQLErrors } from "@/types/errors.model";
import { ICurrentUser } from "@/types/current-user.model"; import { ICurrentUser } from "@/types/current-user.model";
import { useHead } from "@vueuse/head";
const { t } = useI18n({ useScope: "global" }); const { t } = useI18n({ useScope: "global" });
const router = useRouter(); const router = useRouter();
@ -245,7 +246,11 @@ const props = defineProps<{ isUpdate: boolean; identityName?: string }>();
const { currentActor } = useCurrentActorClient(); const { currentActor } = useCurrentActorClient();
const { result: personResult, onError: onPersonError } = useQuery<{ const {
result: personResult,
onError: onPersonError,
onResult: onPersonResult,
} = useQuery<{
fetchPerson: IPerson; fetchPerson: IPerson;
}>( }>(
FETCH_PERSON, FETCH_PERSON,
@ -257,6 +262,10 @@ const { result: personResult, onError: onPersonError } = useQuery<{
}) })
); );
onPersonResult(async ({ data }) => {
avatarFile.value = await buildFileFromIMedia(data?.fetchPerson?.avatar);
});
onPersonError((err) => handleErrors(err as unknown as AbsintheGraphQLErrors)); onPersonError((err) => handleErrors(err as unknown as AbsintheGraphQLErrors));
const person = computed(() => personResult.value?.fetchPerson); const person = computed(() => personResult.value?.fetchPerson);
@ -285,24 +294,6 @@ watch(person, () => {
const avatarMaxSize = useAvatarMaxSize(); const avatarMaxSize = useAvatarMaxSize();
// error({ graphQLErrors }) {
// this.handleErrors(graphQLErrors);
// },
// metaInfo() {
// // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// // @ts-ignore
// const { isUpdate, identityName } = this;
// let title = t("Create a new profile") as string;
// if (isUpdate) {
// title = t("Edit profile {profile}", {
// profile: identityName,
// }) as string;
// }
// return {
// title,
// };
// },
const errors = ref<string[]>([]); const errors = ref<string[]>([]);
const avatarFile = ref<File | null>(null); const avatarFile = ref<File | null>(null);
const showCopiedTooltip = reactive({ ics: false, atom: false }); const showCopiedTooltip = reactive({ ics: false, atom: false });
@ -764,4 +755,16 @@ const breadcrumbsLinks = computed(
const updateUsername = (value: string) => { const updateUsername = (value: string) => {
identity.value.preferredUsername = convertToUsername(value); identity.value.preferredUsername = convertToUsername(value);
}; };
useHead({
title: computed(() => {
let title = t("Create a new profile") as string;
if (isUpdate.value) {
title = t("Edit profile {profile}", {
profile: identityName.value,
}) as string;
}
return title;
}),
});
</script> </script>

View file

@ -102,7 +102,7 @@ import RouteName from "@/router/name";
import EmptyContent from "@/components/Utils/EmptyContent.vue"; import EmptyContent from "@/components/Utils/EmptyContent.vue";
import { useQuery } from "@vue/apollo-composable"; import { useQuery } from "@vue/apollo-composable";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { computed, ref } from "vue"; import { computed } from "vue";
import { useHead } from "@vueuse/head"; import { useHead } from "@vueuse/head";
import { import {
useRouteQuery, useRouteQuery,

View file

@ -426,7 +426,9 @@
> >
<option <option
v-for="timezone in groupTimezones" v-for="timezone in groupTimezones"
:value="`${group}/${timezone}`" :value="
group === t('Other') ? timezone : `${group}/${timezone}`
"
:key="timezone" :key="timezone"
> >
{{ sanitizeTimezone(timezone) }} {{ sanitizeTimezone(timezone) }}
@ -483,6 +485,7 @@
<span class="" v-if="event.draft === true"> <span class="" v-if="event.draft === true">
<o-button <o-button
variant="primary" variant="primary"
class="!text-black hover:!text-white"
outlined outlined
@click="createOrUpdateDraft" @click="createOrUpdateDraft"
:disabled="saving" :disabled="saving"

View file

@ -55,22 +55,16 @@
:key="format" :key="format"
aria-role="listitem" aria-role="listitem"
@click=" @click="
exportParticipants( exportParticipants({
{ eventId: event.id ?? '',
eventId: event?.id,
format, format,
}, })
{ context: { type: format } }
)
" "
@keyup.enter=" @keyup.enter="
exportParticipants( exportParticipants({
{ eventId: event.id ?? '',
eventId: event?.id,
format, format,
}, })
{ context: { type: format } }
)
" "
> >
<button class="dropdown-button"> <button class="dropdown-button">
@ -284,6 +278,7 @@ import Incognito from "vue-material-design-icons/Incognito.vue";
import EmptyContent from "@/components/Utils/EmptyContent.vue"; import EmptyContent from "@/components/Utils/EmptyContent.vue";
import { Notifier } from "@/plugins/notifier"; import { Notifier } from "@/plugins/notifier";
import Tag from "@/components/TagElement.vue"; import Tag from "@/components/TagElement.vue";
import { useHead } from "@vueuse/head";
const PARTICIPANTS_PER_PAGE = 10; const PARTICIPANTS_PER_PAGE = 10;
const MESSAGE_ELLIPSIS_LENGTH = 130; const MESSAGE_ELLIPSIS_LENGTH = 130;
@ -379,15 +374,15 @@ const {
mutate: exportParticipants, mutate: exportParticipants,
onDone: onExportParticipantsMutationDone, onDone: onExportParticipantsMutationDone,
onError: onExportParticipantsMutationError, onError: onExportParticipantsMutationError,
} = useMutation(EXPORT_EVENT_PARTICIPATIONS); } = useMutation<
{ exportEventParticipants: { path: string; format: string } },
{ eventId: string; format?: exportFormat; roles?: string[] }
>(EXPORT_EVENT_PARTICIPATIONS);
onExportParticipantsMutationDone(({ data, context }) => { onExportParticipantsMutationDone(({ data }) => {
const link = const path = data?.exportEventParticipants?.path;
window.origin + const format = data?.exportEventParticipants?.format;
"/exports/" + const link = window.origin + "/exports/" + format?.toLowerCase() + "/" + path;
context?.type.toLowerCase() +
"/" +
data?.exportEventParticipants;
console.debug(link); console.debug(link);
const a = document.createElement("a"); const a = document.createElement("a");
a.style.display = "none"; a.style.display = "none";
@ -458,6 +453,12 @@ const toggleQueueDetails = (row: IParticipant): void => {
}; };
const openDetailedRows = ref<Record<string, boolean>>({}); const openDetailedRows = ref<Record<string, boolean>>({});
useHead({
title: computed(() =>
t("Participants to {eventTitle}", { eventTitle: event.value?.title })
),
});
</script> </script>
<!-- Add "scoped" attribute to limit CSS to this component only --> <!-- Add "scoped" attribute to limit CSS to this component only -->

View file

@ -196,7 +196,7 @@ import RouteName from "@/router/name";
import { buildFileFromIMedia } from "@/utils/image"; import { buildFileFromIMedia } from "@/utils/image";
import { useAvatarMaxSize, useBannerMaxSize } from "@/composition/config"; import { useAvatarMaxSize, useBannerMaxSize } from "@/composition/config";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { computed, ref, watch, defineAsyncComponent, inject } from "vue"; import { computed, ref, defineAsyncComponent, inject } from "vue";
import { useGroup, useUpdateGroup } from "@/composition/apollo/group"; import { useGroup, useUpdateGroup } from "@/composition/apollo/group";
import { import {
useCurrentActorClient, useCurrentActorClient,
@ -262,38 +262,17 @@ const copyURL = async (): Promise<void> => {
}, 2000); }, 2000);
}; };
onGroupResult(({ data }) => { onGroupResult(async ({ data }) => {
if (!data) return;
editableGroup.value = data.group; editableGroup.value = data.group;
});
watch(
group,
async (newGroup: IGroup | undefined, oldGroup: IGroup | undefined) => {
console.debug("watching group");
if (!newGroup) return;
try { try {
if ( avatarFile.value = await buildFileFromIMedia(editableGroup.value?.avatar);
oldGroup?.avatar !== undefined && bannerFile.value = await buildFileFromIMedia(editableGroup.value?.banner);
oldGroup?.avatar !== newGroup?.avatar
) {
avatarFile.value = await buildFileFromIMedia(newGroup?.avatar);
}
if (
oldGroup?.banner !== undefined &&
oldGroup?.banner !== newGroup?.banner
) {
bannerFile.value = await buildFileFromIMedia(newGroup?.banner);
}
} catch (e) { } catch (e) {
// Catch errors while building media // Catch errors while building media
console.error(e); console.error(e);
} }
editableGroup.value = { ...newGroup }; });
},
{
immediate: true,
}
);
const buildVariables = computed(() => { const buildVariables = computed(() => {
let avatarObj = {}; let avatarObj = {};
@ -365,11 +344,11 @@ const canShowCopyButton = computed((): boolean => {
}); });
const currentAddress = computed({ const currentAddress = computed({
get(): IAddress { get(): IAddress | null {
return new Address(editableGroup.value?.physicalAddress); return editableGroup.value?.physicalAddress ?? null;
}, },
set(address: IAddress) { set(address: IAddress | null) {
if (editableGroup.value) { if (editableGroup.value && address) {
editableGroup.value = { editableGroup.value = {
...editableGroup.value, ...editableGroup.value,
physicalAddress: address, physicalAddress: address,

View file

@ -57,7 +57,12 @@
<o-button native-type="submit">{{ t("Continue") }}</o-button> <o-button native-type="submit">{{ t("Continue") }}</o-button>
</div> </div>
</form> </form>
<AuthorizeApplication v-if="application" :auth-application="application" /> <AuthorizeApplication
v-if="application"
:auth-application="application"
:user-code="code"
:scope="scope"
/>
</div> </div>
</template> </template>
@ -85,11 +90,14 @@ const {
const inputs = reactive<string[]>([]); const inputs = reactive<string[]>([]);
const application = ref<IApplication | null>(null); const application = ref<IApplication | null>(null);
const scope = ref<string | null>(null);
onDeviceActivationDone(({ data }) => { onDeviceActivationDone(({ data }) => {
console.debug("onDeviceActivationDone", data);
const foundApplication = data?.deviceActivation?.application; const foundApplication = data?.deviceActivation?.application;
if (foundApplication) { if (foundApplication) {
application.value = foundApplication; application.value = foundApplication;
scope.value = data?.deviceActivation?.scope;
} }
}); });
@ -114,7 +122,11 @@ const error = ref<string | null>(null);
onDeviceActivationError( onDeviceActivationError(
({ graphQLErrors }: { graphQLErrors: AbsintheGraphQLErrors }) => { ({ graphQLErrors }: { graphQLErrors: AbsintheGraphQLErrors }) => {
if (graphQLErrors[0].status_code === 404) { const err = graphQLErrors[0];
if (
err.status_code === 400 &&
err.code === "device_application_code_expired"
) {
error.value = t("The device code is incorrect or no longer valid."); error.value = t("The device code is incorrect or no longer valid.");
} }
resetInputs(); resetInputs();

View file

@ -1,5 +1,5 @@
<template> <template>
<section class="container mx-auto pt-4 is-max-desktop max-w-2xl"> <section class="container mx-auto py-4 is-max-desktop max-w-2xl">
<div class=""> <div class="">
<div class=""> <div class="">
<h1 class="text-4xl mb-3"> <h1 class="text-4xl mb-3">

View file

@ -78,13 +78,16 @@
}) })
}} }}
</span> </span>
<span v-if="post.visibility === PostVisibility.UNLISTED" class=""> <span
<o-icon icon="link" size="small" /> v-if="post.visibility === PostVisibility.UNLISTED"
class="flex gap-2 items-center"
>
<Link :size="16" />
{{ t("Accessible only by link") }} {{ t("Accessible only by link") }}
</span> </span>
<span <span
v-else-if="post.visibility === PostVisibility.PRIVATE" v-else-if="post.visibility === PostVisibility.PRIVATE"
class="" class="flex gap-2 items-center"
> >
<Lock :size="16" /> <Lock :size="16" />
{{ {{
@ -275,9 +278,11 @@ import Pencil from "vue-material-design-icons/Pencil.vue";
import Delete from "vue-material-design-icons/Delete.vue"; import Delete from "vue-material-design-icons/Delete.vue";
import Share from "vue-material-design-icons/Share.vue"; import Share from "vue-material-design-icons/Share.vue";
import Flag from "vue-material-design-icons/Flag.vue"; import Flag from "vue-material-design-icons/Flag.vue";
import Link from "vue-material-design-icons/Link.vue";
import { Dialog } from "@/plugins/dialog"; import { Dialog } from "@/plugins/dialog";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { Notifier } from "@/plugins/notifier"; import { Notifier } from "@/plugins/notifier";
import { AbsintheGraphQLErrors } from "@/types/errors.model";
const props = defineProps<{ const props = defineProps<{
slug: string; slug: string;
@ -299,10 +304,27 @@ const { result: membershipsResult, loading: membershipsLoading } = useQuery<{
); );
const memberships = computed(() => membershipsResult.value?.person.memberships); const memberships = computed(() => membershipsResult.value?.person.memberships);
const { result: postResult, loading: postLoading } = useQuery<{ const {
result: postResult,
loading: postLoading,
onError: onFetchPostError,
} = useQuery<{
post: IPost; post: IPost;
}>(FETCH_POST, () => ({ slug: props.slug })); }>(FETCH_POST, () => ({ slug: props.slug }));
const handleErrors = (errors: AbsintheGraphQLErrors): void => {
if (
errors.some((error) => error.status_code === 404) ||
errors.some(({ message }) => message.includes("has invalid value $uuid"))
) {
router.replace({ name: RouteName.PAGE_NOT_FOUND });
}
};
onFetchPostError(({ graphQLErrors }) =>
handleErrors(graphQLErrors as AbsintheGraphQLErrors)
);
const post = computed(() => postResult.value?.post); const post = computed(() => postResult.value?.post);
usePersonStatusGroup(usernameWithDomain(post.value?.attributedTo as IGroup)); usePersonStatusGroup(usernameWithDomain(post.value?.attributedTo as IGroup));

View file

@ -73,7 +73,7 @@
<tr v-for="subType in notificationType.subtypes" :key="subType.id"> <tr v-for="subType in notificationType.subtypes" :key="subType.id">
<td v-for="(method, key) in notificationMethods" :key="key"> <td v-for="(method, key) in notificationMethods" :key="key">
<o-checkbox <o-checkbox
:value="notificationValues[subType.id][key].enabled" :modelValue="notificationValues[subType.id][key].enabled"
@update:modelValue=" @update:modelValue="
(e: boolean) => (e: boolean) =>
updateNotificationValue({ updateNotificationValue({
@ -645,7 +645,7 @@ const dialog = inject<Dialog>("dialog");
const openRegenerateFeedTokensConfirmation = () => { const openRegenerateFeedTokensConfirmation = () => {
dialog?.confirm({ dialog?.confirm({
type: "warning", variant: "warning",
title: t("Regenerate new links") as string, title: t("Regenerate new links") as string,
message: t( message: t(
"You'll need to change the URLs where there were previously entered." "You'll need to change the URLs where there were previously entered."

View file

@ -4,7 +4,7 @@ import { createRouter, createWebHistory, Router } from "vue-router";
import { routes } from "@/router"; import { routes } from "@/router";
import { CommentModeration, EventJoinOptions } from "@/types/enums"; import { CommentModeration, EventJoinOptions } from "@/types/enums";
import { InMemoryCache } from "@apollo/client/cache"; import { InMemoryCache } from "@apollo/client/cache";
import { beforeEach, describe, expect, vi, it } from "vitest"; import { beforeEach, describe, expect, it } from "vitest";
import Oruga from "@oruga-ui/oruga-next"; import Oruga from "@oruga-ui/oruga-next";
import FloatingVue from "floating-vue"; import FloatingVue from "floating-vue";
@ -34,12 +34,7 @@ const eventData = {
describe("ParticipationSection", () => { describe("ParticipationSection", () => {
let wrapper: VueWrapper; let wrapper: VueWrapper;
const generateWrapper = ( const generateWrapper = (customProps: Record<string, unknown> = {}) => {
customProps: Record<string, unknown> = {},
baseData: Record<string, unknown> = {}
) => {
const cache = new InMemoryCache({ addTypename: false });
wrapper = mount(ParticipationSection, { wrapper = mount(ParticipationSection, {
stubs: { stubs: {
ParticipationButton: true, ParticipationButton: true,

View file

@ -1,6 +1,6 @@
import { config, mount } from "@vue/test-utils"; import { mount } from "@vue/test-utils";
import PostListItem from "@/components/Post/PostListItem.vue"; import PostListItem from "@/components/Post/PostListItem.vue";
import { vi, beforeEach, describe, it, expect } from "vitest"; import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale"; import { enUS } from "date-fns/locale";
import { routes } from "@/router"; import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router"; import { createRouter, createWebHistory, Router } from "vue-router";

View file

@ -1,9 +1,7 @@
import { config, mount } from "@vue/test-utils"; import { mount } from "@vue/test-utils";
import ReportCard from "@/components/Report/ReportCard.vue"; import ReportCard from "@/components/Report/ReportCard.vue";
import { ActorType } from "@/types/enums"; import { ActorType } from "@/types/enums";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { createI18n } from "vue-i18n";
import en from "@/i18n/en_US.json";
const reportData = { const reportData = {
id: "1", id: "1",

View file

@ -1,5 +1,7 @@
const useRouterMock = vi.fn(() => ({ const useRouterMock = vi.fn(() => ({
push: () => {}, push: function () {
// do nothing
},
})); }));
import { config, mount } from "@vue/test-utils"; import { config, mount } from "@vue/test-utils";

View file

@ -1,8 +1,14 @@
const useRouterMock = vi.fn(() => ({ const useRouterMock = vi.fn(() => ({
push: () => {}, push: function () {
replace: () => {}, // do nothing
},
replace: function () {
// do nothing
},
})); }));
const useRouteMock = vi.fn(() => {}); const useRouteMock = vi.fn(function () {
// do nothing
});
import { config, mount, VueWrapper } from "@vue/test-utils"; import { config, mount, VueWrapper } from "@vue/test-utils";
import Login from "@/views/User/LoginView.vue"; import Login from "@/views/User/LoginView.vue";

View file

@ -1,5 +1,7 @@
const useRouterMock = vi.fn(() => ({ const useRouterMock = vi.fn(() => ({
push: () => {}, push: function () {
// do nothing
},
})); }));
import { shallowMount, VueWrapper } from "@vue/test-utils"; import { shallowMount, VueWrapper } from "@vue/test-utils";
@ -21,7 +23,6 @@ vi.mock("vue-router/dist/vue-router.mjs", () => ({
describe("App component", () => { describe("App component", () => {
let wrapper: VueWrapper; let wrapper: VueWrapper;
let mockClient: MockApolloClient | null; let mockClient: MockApolloClient | null;
let requestHandlers: Record<string, RequestHandler>;
const createComponent = (handlers = {}) => { const createComponent = (handlers = {}) => {
const cache = new InMemoryCache({ addTypename: false }); const cache = new InMemoryCache({ addTypename: false });
@ -31,8 +32,6 @@ describe("App component", () => {
resolvers: buildCurrentUserResolver(cache), resolvers: buildCurrentUserResolver(cache),
}); });
requestHandlers = { ...handlers };
wrapper = shallowMount(NavBar, { wrapper = shallowMount(NavBar, {
// stubs: ["router-link", "router-view", "o-dropdown", "o-dropdown-item"], // stubs: ["router-link", "router-view", "o-dropdown", "o-dropdown-item"],
global: { global: {

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,9 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
| {:error, | {:error,
:invalid_url | :http_gone | :http_error | :http_not_found | :content_not_json} :invalid_url | :http_gone | :http_error | :http_not_found | :content_not_json}
def fetch(url, options \\ []) do def fetch(url, options \\ []) do
on_behalf_of = Keyword.get(options, :on_behalf_of, Relay.get_actor()) Logger.debug("Fetching #{url} with AP Fetcher")
on_behalf_of = Keyword.get(options, :on_behalf_of, actor_relay())
Logger.debug("Fetching on behalf of #{inspect(on_behalf_of.url)}")
date = Signature.generate_date_header() date = Signature.generate_date_header()
headers = headers =
@ -32,29 +34,8 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
client = ActivityPubClient.client(headers: headers) client = ActivityPubClient.client(headers: headers)
if address_valid?(url) do if address_valid?(url) and url != on_behalf_of.url do
case ActivityPubClient.get(client, url) do do_fetch(url, client)
{:ok, %Tesla.Env{body: data, status: code}} when code in 200..299 and is_map(data) ->
{:ok, data}
{:ok, %Tesla.Env{status: 410}} ->
Logger.debug("Resource at #{url} is 410 Gone")
{:error, :http_gone}
{:ok, %Tesla.Env{status: 404}} ->
Logger.debug("Resource at #{url} is 404 Gone")
{:error, :http_not_found}
{:ok, %Tesla.Env{body: data}} when is_binary(data) ->
{:error, :content_not_json}
{:ok, %Tesla.Env{} = res} ->
Logger.debug("Resource returned bad HTTP code #{inspect(res)}")
{:error, :http_error}
{:error, err} ->
{:error, err}
end
else else
{:error, :invalid_url} {:error, :invalid_url}
end end
@ -169,4 +150,38 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
%URI{host: host, scheme: scheme} = URI.parse(address) %URI{host: host, scheme: scheme} = URI.parse(address)
is_valid_string(host) and is_valid_string(scheme) is_valid_string(host) and is_valid_string(scheme)
end end
defp actor_relay do
Relay.get_actor()
end
@spec do_fetch(String.t(), Tesla.Client.t()) ::
{:ok, map()}
| {:error,
:invalid_url | :http_gone | :http_error | :http_not_found | :content_not_json}
defp do_fetch(url, client) do
case ActivityPubClient.get(client, url) do
{:ok, %Tesla.Env{body: data, status: code}} when code in 200..299 and is_map(data) ->
Logger.debug("Found the following from ActivityPubClient fetch: #{inspect(data)}")
{:ok, data}
{:ok, %Tesla.Env{status: 410}} ->
Logger.debug("Resource at #{url} is 410 Gone")
{:error, :http_gone}
{:ok, %Tesla.Env{status: 404}} ->
Logger.debug("Resource at #{url} is 404 Gone")
{:error, :http_not_found}
{:ok, %Tesla.Env{body: data}} when is_binary(data) ->
{:error, :content_not_json}
{:ok, %Tesla.Env{} = res} ->
Logger.debug("Resource returned bad HTTP code #{inspect(res)}")
{:error, :http_error}
{:error, err} ->
{:error, err}
end
end
end end

View file

@ -55,7 +55,7 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do
@type fetch_actor_errors :: ActivityPubActor.make_actor_errors() | fetch_collection_errors() @type fetch_actor_errors :: ActivityPubActor.make_actor_errors() | fetch_collection_errors()
@spec fetch_group(String.t(), Actor.t()) :: :ok | {:error, fetch_actor_errors} @spec fetch_group(String.t(), Actor.t()) :: :ok | {:error, fetch_actor_errors}
def fetch_group(group_url, %Actor{} = on_behalf_of) do def fetch_group(group_url, %Actor{} = on_behalf_of) when is_binary(group_url) do
Logger.debug("Fetching group #{group_url}") Logger.debug("Fetching group #{group_url}")
case ActivityPubActor.make_actor_from_url(group_url, on_behalf_of: on_behalf_of) do case ActivityPubActor.make_actor_from_url(group_url, on_behalf_of: on_behalf_of) do

View file

@ -23,7 +23,13 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do
def init do def init do
# Wait for everything to settle. # Wait for everything to settle.
Process.sleep(1000 * 5) Process.sleep(1000 * 5)
get_actor() relay = get_actor()
unless Regex.match?(~r/BEGIN RSA PRIVATE KEY/, relay.keys) do
{:ok, _relay} = Actors.actor_key_rotation(relay)
end
relay
end end
@spec get_actor() :: Actor.t() | no_return @spec get_actor() :: Actor.t() | no_return

View file

@ -36,10 +36,18 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
@spec as_to_model_data(map()) :: map() | {:error, :actor_not_allowed_type} @spec as_to_model_data(map()) :: map() | {:error, :actor_not_allowed_type}
def as_to_model_data(%{"type" => type} = data) when type in @allowed_types do def as_to_model_data(%{"type" => type} = data) when type in @allowed_types do
avatar = avatar =
download_picture(get_in(data, ["icon", "url"]), get_in(data, ["icon", "name"]), "avatar") download_picture(
get_picture(data, ["icon", "url"]),
get_picture(data, ["icon", "name"]),
"avatar"
)
banner = banner =
download_picture(get_in(data, ["image", "url"]), get_in(data, ["image", "name"]), "banner") download_picture(
get_picture(data, ["image", "url"]),
get_picture(data, ["image", "name"]),
"banner"
)
address = get_address(data["location"]) address = get_address(data["location"])
@ -193,4 +201,10 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
end end
defp maybe_add_physical_address(res, _), do: res defp maybe_add_physical_address(res, _), do: res
defp get_picture(nil, _keys), do: nil
defp get_picture(url, _keys) when is_binary(url), do: url
defp get_picture(data, [key | rest] = keys) when is_map(data) and is_list(keys),
do: get_picture(data[key], rest)
end end

View file

@ -26,7 +26,11 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
Logger.debug("fetching tags") Logger.debug("fetching tags")
Logger.debug(inspect(tags)) Logger.debug(inspect(tags))
tags |> Enum.flat_map(&fetch_tag/1) |> Enum.uniq() |> Enum.map(&existing_tag_or_data/1) tags
|> Enum.flat_map(&fetch_tag/1)
|> Enum.uniq()
|> Enum.filter(& &1)
|> Enum.map(&existing_tag_or_data/1)
end end
def fetch_tags(_), do: [] def fetch_tags(_), do: []
@ -122,6 +126,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
create_mention(mention, acc) create_mention(mention, acc)
end end
defp create_mention(_, acc), do: acc
@spec maybe_fetch_actor_and_attributed_to_id(map()) :: @spec maybe_fetch_actor_and_attributed_to_id(map()) ::
{:ok, Actor.t(), Actor.t() | nil} | {:error, atom()} {:ok, Actor.t(), Actor.t() | nil} | {:error, atom()}
def maybe_fetch_actor_and_attributed_to_id(%{ def maybe_fetch_actor_and_attributed_to_id(%{
@ -179,8 +185,10 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
def maybe_fetch_actor_and_attributed_to_id(_), do: {:error, :no_actor_found} def maybe_fetch_actor_and_attributed_to_id(_), do: {:error, :no_actor_found}
@spec fetch_actor(String.t()) :: {:ok, Actor.t()} | {:error, atom()} @spec fetch_actor(String.t() | map()) :: {:ok, Actor.t()} | {:error, atom()}
def fetch_actor(actor_url) do def fetch_actor(%{"id" => actor_url}) when is_binary(actor_url), do: fetch_actor(actor_url)
def fetch_actor(actor_url) when is_binary(actor_url) do
case ActivityPubActor.get_or_fetch_actor_by_url(actor_url) do case ActivityPubActor.get_or_fetch_actor_by_url(actor_url) do
{:ok, %Actor{suspended: false} = actor} -> {:ok, %Actor{suspended: false} = actor} ->
{:ok, actor} {:ok, actor}
@ -193,6 +201,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
end end
end end
def fetch_actor(_), do: {:error, :no_actor_found}
@spec process_pictures(map(), integer()) :: Keyword.t() @spec process_pictures(map(), integer()) :: Keyword.t()
def process_pictures(object, actor_id) do def process_pictures(object, actor_id) do
attachements = Map.get(object, "attachment", []) attachements = Map.get(object, "attachment", [])

View file

@ -12,6 +12,7 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
alias Mobilizon.Federation.ActivityPub.Relay
require Logger require Logger
@ -94,7 +95,12 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
%{"keyId" => kid} = HTTPSignatures.signature_for_conn(conn) %{"keyId" => kid} = HTTPSignatures.signature_for_conn(conn)
actor_url = key_id_to_actor_url(kid) actor_url = key_id_to_actor_url(kid)
Logger.debug("Refetching public key for #{actor_url}") Logger.debug("Refetching public key for #{actor_url}")
relay = Relay.get_actor()
if actor_url == relay.url do
# Special case if ever it's our own actor fetching ourselves
get_actor_public_key(relay)
else
# In this specific case we don't sign object fetches because # In this specific case we don't sign object fetches because
# this would cause infinite recursion when servers both need # this would cause infinite recursion when servers both need
# to fetch each other's keys # to fetch each other's keys
@ -103,6 +109,7 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
get_actor_public_key(actor) get_actor_public_key(actor)
end end
end end
end
@spec sign(Actor.t(), map()) :: String.t() | {:error, :pem_decode_error} | no_return @spec sign(Actor.t(), map()) :: String.t() | {:error, :pem_decode_error} | no_return
def sign(%Actor{domain: domain, keys: keys, url: url} = actor, headers) when is_nil(domain) do def sign(%Actor{domain: domain, keys: keys, url: url} = actor, headers) when is_nil(domain) do

View file

@ -8,7 +8,7 @@ defmodule Mobilizon.GraphQL.API.Reports do
alias Mobilizon.Federation.ActivityPub.{Actions, Activity} alias Mobilizon.Federation.ActivityPub.{Actions, Activity}
alias Mobilizon.Reports, as: ReportsAction alias Mobilizon.Reports, as: ReportsAction
alias Mobilizon.Reports.{Note, Report, ReportStatus} alias Mobilizon.Reports.{Note, Report, ReportStatus}
alias Mobilizon.Service.Akismet alias Mobilizon.Service.AntiSpam.Akismet
alias Mobilizon.Users.User alias Mobilizon.Users.User
import Mobilizon.Web.Gettext, only: [dgettext: 2] import Mobilizon.Web.Gettext, only: [dgettext: 2]
require Logger require Logger

View file

@ -67,7 +67,6 @@ defmodule Mobilizon.GraphQL.Authorization.AppScope do
:"read:group:events", :"read:group:events",
:"read:group:discussions", :"read:group:discussions",
:"read:group:resources", :"read:group:resources",
:"read:group:members",
:"read:group:followers", :"read:group:followers",
:"read:group:todo_lists", :"read:group:todo_lists",
:"read:group:activities" :"read:group:activities"

View file

@ -5,6 +5,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Application do
alias Mobilizon.Applications, as: ApplicationManager alias Mobilizon.Applications, as: ApplicationManager
alias Mobilizon.Applications.{Application, ApplicationDeviceActivation, ApplicationToken} alias Mobilizon.Applications.{Application, ApplicationDeviceActivation, ApplicationToken}
alias Mobilizon.GraphQL.Error
alias Mobilizon.Service.Auth.Applications alias Mobilizon.Service.Auth.Applications
alias Mobilizon.Users.User alias Mobilizon.Users.User
import Mobilizon.Web.Gettext, only: [dgettext: 2] import Mobilizon.Web.Gettext, only: [dgettext: 2]
@ -17,7 +18,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Application do
@spec authorize(any(), map(), Absinthe.Resolution.t()) :: {:ok, map()} | {:error, String.t()} @spec authorize(any(), map(), Absinthe.Resolution.t()) :: {:ok, map()} | {:error, String.t()}
def authorize( def authorize(
_parent, _parent,
%{client_id: client_id, redirect_uri: redirect_uri, scope: scope, state: state}, %{client_id: client_id, redirect_uri: redirect_uri, scope: scope} = args,
%{context: %{current_user: %User{id: user_id}}} %{context: %{current_user: %User{id: user_id}}}
) do ) do
case Applications.autorize(client_id, redirect_uri, scope, user_id) do case Applications.autorize(client_id, redirect_uri, scope, user_id) do
@ -27,7 +28,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Application do
scope: scope, scope: scope,
authorization_code: code authorization_code: code
}} -> }} ->
{:ok, %{code: code, state: state, client_id: client_id, scope: scope}} {:ok, %{code: code, state: Map.get(args, :state), client_id: client_id, scope: scope}}
{:error, %Ecto.Changeset{} = err} -> {:error, %Ecto.Changeset{} = err} ->
{:error, err} {:error, err}
@ -106,7 +107,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Application do
{:ok, app_device_activation |> Map.from_struct() |> Map.take([:application, :id, :scope])} {:ok, app_device_activation |> Map.from_struct() |> Map.take([:application, :id, :scope])}
{:error, :expired} -> {:error, :expired} ->
{:error, dgettext("errors", "The given user code has expired")} {:error,
%Error{
message: dgettext("errors", "The given user code has expired"),
status_code: 400,
code: :device_application_code_expired
}}
{:error, :not_found} -> {:error, :not_found} ->
{:error, dgettext("errors", "The given user code is invalid")} {:error, dgettext("errors", "The given user code is invalid")}
@ -143,7 +149,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Application do
)} )}
{:error, :expired} -> {:error, :expired} ->
{:error, dgettext("errors", "The given user code has expired")} {:error,
%Error{
message: dgettext("errors", "The given user code has expired"),
status_code: 400,
code: :device_application_code_expired
}}
end end
end end

View file

@ -7,7 +7,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Discussions.Comment, as: CommentModel alias Mobilizon.Discussions.Comment, as: CommentModel
alias Mobilizon.Events.{Event, EventOptions} alias Mobilizon.Events.{Event, EventOptions}
alias Mobilizon.Service.Akismet alias Mobilizon.Service.AntiSpam
alias Mobilizon.Users.User alias Mobilizon.Users.User
import Mobilizon.Web.Gettext import Mobilizon.Web.Gettext
@ -45,14 +45,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
if comment_moderation != :closed || actor_id == organizer_actor_id do if comment_moderation != :closed || actor_id == organizer_actor_id do
args = Map.put(args, :actor_id, actor_id) args = Map.put(args, :actor_id, actor_id)
if Akismet.check_comment( if AntiSpam.service().check_comment(
args.text, args.text,
preferred_username, preferred_username,
!is_nil(Map.get(args, :in_reply_to_comment_id)), !is_nil(Map.get(args, :in_reply_to_comment_id)),
email, email,
current_ip, current_ip,
user_agent user_agent
) do ) == :ham do
do_create_comment(args) do_create_comment(args)
else else
{:error, {:error,

View file

@ -5,7 +5,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
alias Mobilizon.Config alias Mobilizon.Config
alias Mobilizon.Events.Categories alias Mobilizon.Events.Categories
alias Mobilizon.Service.{Akismet, FrontEndAnalytics} alias Mobilizon.Service.{AntiSpam, FrontEndAnalytics}
@doc """ @doc """
Gets config. Gets config.
@ -146,7 +146,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
features: %{ features: %{
groups: Config.instance_group_feature_enabled?(), groups: Config.instance_group_feature_enabled?(),
event_creation: Config.instance_event_creation_enabled?(), event_creation: Config.instance_event_creation_enabled?(),
antispam: Akismet.ready?() antispam: AntiSpam.service().ready?()
}, },
restrictions: %{ restrictions: %{
only_admin_can_create_groups: Config.only_admin_can_create_groups?(), only_admin_can_create_groups: Config.only_admin_can_create_groups?(),

View file

@ -195,6 +195,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
else else
{:member, false} -> {:member, false} ->
{:error, :unauthorized} {:error, :unauthorized}
{:error, %Ecto.Changeset{} = err} ->
{:error, err}
end end
end end

View file

@ -13,7 +13,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
alias Mobilizon.Federation.ActivityPub.Activity alias Mobilizon.Federation.ActivityPub.Activity
alias Mobilizon.Federation.ActivityPub.Permission alias Mobilizon.Federation.ActivityPub.Permission
alias Mobilizon.Service.Akismet alias Mobilizon.Service.AntiSpam
alias Mobilizon.Service.TimezoneDetector alias Mobilizon.Service.TimezoneDetector
import Mobilizon.Users.Guards, only: [is_moderator: 1] import Mobilizon.Users.Guards, only: [is_moderator: 1]
import Mobilizon.Web.Gettext import Mobilizon.Web.Gettext
@ -260,7 +260,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
args |> Map.put(:organizer_actor, organizer_actor) |> extract_timezone(user.id), args |> Map.put(:organizer_actor, organizer_actor) |> extract_timezone(user.id),
{:askismet, :ham} <- {:askismet, :ham} <-
{:askismet, {:askismet,
Akismet.check_event( AntiSpam.service().check_event(
args.description, args.description,
organizer_actor.preferred_username, organizer_actor.preferred_username,
email, email,

View file

@ -282,6 +282,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
{:error, {:error,
dgettext("errors", "Participation is confirmed but not approved yet by an organizer")} dgettext("errors", "Participation is confirmed but not approved yet by an organizer")}
{:has_participant, %Participant{role: :participant}} ->
{:error, dgettext("errors", "Participation is already confirmed")}
{:has_participant, nil} -> {:has_participant, nil} ->
{:error, dgettext("errors", "This token is invalid")} {:error, dgettext("errors", "This token is invalid")}
@ -302,7 +305,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
if can_event_be_updated_by?(event, moderator_actor) do if can_event_be_updated_by?(event, moderator_actor) do
case export_format(format, event, roles, locale) do case export_format(format, event, roles, locale) do
{:ok, path} -> {:ok, path} ->
{:ok, path} {:ok, %{path: path, format: format}}
{:error, :export_dependency_not_installed} -> {:error, :export_dependency_not_installed} ->
{:error, {:error,

View file

@ -8,7 +8,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
alias Mobilizon.{Actors, Events, Users} alias Mobilizon.{Actors, Events, Users}
alias Mobilizon.Actors.{Actor, Follower, Member} alias Mobilizon.Actors.{Actor, Follower, Member}
alias Mobilizon.Events.Participant alias Mobilizon.Events.Participant
alias Mobilizon.Service.Akismet alias Mobilizon.Service.AntiSpam
alias Mobilizon.Storage.{Page, Repo} alias Mobilizon.Storage.{Page, Repo}
alias Mobilizon.Users.User alias Mobilizon.Users.User
import Mobilizon.Web.Gettext import Mobilizon.Web.Gettext
@ -133,18 +133,20 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
def create_person( def create_person(
_parent, _parent,
%{preferred_username: _preferred_username} = args, %{preferred_username: _preferred_username} = args,
%{context: %{current_user: user}} = _resolution %{context: %{current_user: user} = context} = _resolution
) do ) do
args = Map.put(args, :user_id, user.id) args = Map.put(args, :user_id, user.id)
user_agent = Map.get(context, :user_agent, "")
with args <- Map.update(args, :preferred_username, "", &String.downcase/1), with args <- Map.update(args, :preferred_username, "", &String.downcase/1),
{:akismet, :ham} <- {:spam, :ham} <-
{:akismet, {:spam,
Akismet.check_profile( AntiSpam.service().check_profile(
args.preferred_username, args.preferred_username,
args.summary, args.summary,
user.email, user.email,
user.current_sign_in_ip user.current_sign_in_ip,
user_agent
)}, )},
{:picture, args} when is_map(args) <- {:picture, save_attached_pictures(args)}, {:picture, args} when is_map(args) <- {:picture, save_attached_pictures(args)},
{:ok, %Actor{} = new_person} <- Actors.new_person(args) do {:ok, %Actor{} = new_person} <- Actors.new_person(args) do
@ -308,9 +310,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:ok, %User{} = user} -> {:ok, %User{} = user} ->
if is_nil(Users.get_actor_for_user(user)) do if is_nil(Users.get_actor_for_user(user)) do
# No profile yet, we can create one # No profile yet, we can create one
with {:akismet, :ham} <- with {:spam, :ham} <-
{:akismet, {:spam,
Akismet.check_profile( AntiSpam.service().check_profile(
args.preferred_username, args.preferred_username,
args.summary, args.summary,
args.email, args.email,
@ -326,7 +328,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:error, _err} -> {:error, _err} ->
{:error, dgettext("errors", "Error while uploading pictures")} {:error, dgettext("errors", "Error while uploading pictures")}
{:akismet, _} -> {:spam, _} ->
{:error, dgettext("errors", "Your profile was detected as spam.")} {:error, dgettext("errors", "Your profile was detected as spam.")}
end end
else else

View file

@ -80,6 +80,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
} }
} = _resolution } = _resolution
) do ) do
Logger.debug("Getting resource for group with username #{username}")
with {:group, %Actor{id: group_id}} <- {:group, Actors.get_actor_by_name(username, :Group)}, with {:group, %Actor{id: group_id}} <- {:group, Actors.get_actor_by_name(username, :Group)},
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)}, {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
{:resource, %Resource{} = resource} <- {:resource, %Resource{} = resource} <-
@ -222,13 +224,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
{:ok, data} when is_map(data) -> {:ok, data} when is_map(data) ->
{:ok, struct(Metadata, data)} {:ok, struct(Metadata, data)}
{:error, :invalid_parsed_data} -> {:error, _error_type, _} ->
{:error, dgettext("errors", "Unable to fetch resource details from this URL.")} {:error, dgettext("errors", "Unable to fetch resource details from this URL.")}
{:error, err} ->
Logger.warn("Error while fetching preview from #{inspect(resource_url)}")
Logger.debug(inspect(err))
{:error, :unknown_resource}
end end
end end

View file

@ -8,7 +8,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
alias Mobilizon.{Actors, Admin, Config, Events, FollowedGroupActivity, Users} alias Mobilizon.{Actors, Admin, Config, Events, FollowedGroupActivity, Users}
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Federation.ActivityPub.Actions alias Mobilizon.Federation.ActivityPub.Actions
alias Mobilizon.Service.Akismet alias Mobilizon.Service.AntiSpam
alias Mobilizon.Service.Auth.Authenticator alias Mobilizon.Service.Auth.Authenticator
alias Mobilizon.Storage.{Page, Repo} alias Mobilizon.Storage.{Page, Repo}
alias Mobilizon.Users.{Setting, User} alias Mobilizon.Users.{Setting, User}
@ -161,8 +161,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
with {:ok, email} <- lowercase_domain(email), with {:ok, email} <- lowercase_domain(email),
:registration_ok <- check_registration_config(email), :registration_ok <- check_registration_config(email),
:not_deny_listed <- check_registration_denylist(email), :not_deny_listed <- check_registration_denylist(email),
{:akismet, :ham} <- {:spam, :ham} <-
{:akismet, Akismet.check_user(email, current_ip, user_agent)}, {:spam, AntiSpam.service().check_user(email, current_ip, user_agent)},
{:ok, %User{} = user} <- {:ok, %User{} = user} <-
args args
|> Map.merge(%{email: email, current_sign_in_ip: current_ip, current_sign_in_at: now}) |> Map.merge(%{email: email, current_sign_in_ip: current_ip, current_sign_in_at: now})
@ -186,7 +186,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
"Your e-mail has been denied registration or uses a disallowed e-mail provider" "Your e-mail has been denied registration or uses a disallowed e-mail provider"
)} )}
{:akismet, _} -> {:spam, _} ->
{:error, {:error,
dgettext( dgettext(
"errors", "errors",

View file

@ -31,6 +31,7 @@ defmodule Mobilizon.GraphQL.Schema do
import_types(Absinthe.Plug.Types) import_types(Absinthe.Plug.Types)
import_types(Custom.UUID) import_types(Custom.UUID)
import_types(Custom.Point) import_types(Custom.Point)
import_types(Custom.Timezone)
import_types(Schema.ActivityType) import_types(Schema.ActivityType)
import_types(Schema.UserType) import_types(Schema.UserType)

View file

@ -125,7 +125,7 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
description: "Whether the group is opened to all or has restricted access" description: "Whether the group is opened to all or has restricted access"
) )
field :members, :paginated_member_list, meta: [private: true, rule: :"read:group:members"] do field :members, :paginated_member_list do
arg(:name, :string, description: "A name to filter members by") arg(:name, :string, description: "A name to filter members by")
arg(:page, :integer, default_value: 1, description: "The page in the paginated member list") arg(:page, :integer, default_value: 1, description: "The page in the paginated member list")
arg(:limit, :integer, default_value: 10, description: "The limit of members per page") arg(:limit, :integer, default_value: 10, description: "The limit of members per page")

View file

@ -38,7 +38,7 @@ defmodule Mobilizon.GraphQL.Schema.Actors.MemberType do
A paginated list of members A paginated list of members
""" """
object :paginated_member_list do object :paginated_member_list do
meta(:authorize, :user) meta(:authorize, :all)
field(:elements, list_of(:member), description: "A list of members") field(:elements, list_of(:member), description: "A list of members")
field(:total, :integer, description: "The total number of elements in the list") field(:total, :integer, description: "The total number of elements in the list")
end end

View file

@ -22,7 +22,7 @@ defmodule Mobilizon.GraphQL.Schema.AddressType do
field(:url, :string, description: "The address's URL") field(:url, :string, description: "The address's URL")
field(:id, :id, description: "The address's ID") field(:id, :id, description: "The address's ID")
field(:origin_id, :string, description: "The address's original ID from the provider") field(:origin_id, :string, description: "The address's original ID from the provider")
field(:timezone, :string, description: "The (estimated) timezone of the location") field(:timezone, :timezone, description: "The (estimated) timezone of the location")
field(:picture_info, :picture_info, description: "A picture associated with the address") field(:picture_info, :picture_info, description: "A picture associated with the address")
end end
@ -75,7 +75,7 @@ defmodule Mobilizon.GraphQL.Schema.AddressType do
field(:url, :string, description: "The address's URL") field(:url, :string, description: "The address's URL")
field(:id, :id, description: "The address's ID") field(:id, :id, description: "The address's ID")
field(:origin_id, :string, description: "The address's original ID from the provider") field(:origin_id, :string, description: "The address's original ID from the provider")
field(:timezone, :string, description: "The (estimated) timezone of the location") field(:timezone, :timezone, description: "The (estimated) timezone of the location")
end end
@desc """ @desc """

View file

@ -111,7 +111,7 @@ defmodule Mobilizon.GraphQL.Schema.AuthApplicationType do
resolve(&Application.activate_device/3) resolve(&Application.activate_device/3)
end end
@desc "Activate an user device" @desc "Authorize an user device"
field :authorize_device_application, :auth_application do field :authorize_device_application, :auth_application do
arg(:client_id, non_null(:string), description: "The application's client_id") arg(:client_id, non_null(:string), description: "The application's client_id")

View file

@ -43,7 +43,7 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
field(:upload_limits, :upload_limits, description: "The configuration for upload limits") field(:upload_limits, :upload_limits, description: "The configuration for upload limits")
field(:timezones, list_of(:string), description: "The instance's available timezones") field(:timezones, list_of(:timezone), description: "The instance's available timezones")
field(:features, :features, description: "The instance's features") field(:features, :features, description: "The instance's features")
field(:restrictions, :restrictions, description: "The instance's restrictions") field(:restrictions, :restrictions, description: "The instance's restrictions")
field(:version, :string, description: "The instance's version") field(:version, :string, description: "The instance's version")

View file

@ -0,0 +1,35 @@
defmodule Mobilizon.GraphQL.Schema.Custom.Timezone do
@moduledoc """
The timezone scalar type allows timezone ID strings to be passed in and out.
"""
use Absinthe.Schema.Notation
import Mobilizon.Web.Gettext, only: [dgettext: 3]
scalar :timezone, name: "Timezone" do
description("""
The `Timezone` scalar type represents a timezone identifier,
as registered in the IANA Time Zone Database.
""")
serialize(&encode/1)
parse(&decode/1)
end
@spec decode(Absinthe.Blueprint.Input.String.t()) :: {:ok, term} | :error
@spec decode(Absinthe.Blueprint.Input.Null.t()) :: {:ok, nil}
defp decode(%Absinthe.Blueprint.Input.String{value: value}) do
if Tzdata.zone_exists?(value),
do: {:ok, value},
else: {:error, dgettext("errors", "Timezone ID %{timezone} is invalid", timezone: value)}
end
defp decode(%Absinthe.Blueprint.Input.Null{}) do
{:ok, nil}
end
defp decode(_) do
:error
end
defp encode(value), do: value
end

Some files were not shown because too many files have changed in this diff Show more