Compare commits

..
201 Commits
Author SHA1 Message Date
Wyatt Johnson 32962aa1e8 External User Fix (#2220)
* fix: fixed bug with user upserting

* chore: version bump
2019-03-11 19:35:22 +00:00
Kim Gardner 049357a09c Bump version 4.8.1 (#2218) 2019-03-07 16:00:18 +00:00
Wyatt Johnson 5e7fe7cf5a fix: upgrade passport-google-oauth2 (#2217)
- Fixes #2215
2019-03-07 01:12:08 +00:00
Kim Gardner 6243fcba91 Merge pull request #2212 from vittoboa/italian-translation
Italian translation
2019-03-04 11:53:41 -05:00
vittoboa 805825e5d2 Fix typo 2019-03-02 22:42:13 +01:00
vittoboa a40e721a68 Fix typo 2019-03-02 22:38:16 +01:00
vittoboa 1dd8d0a706 Add italian translation for plugins 2019-03-02 22:33:52 +01:00
Leandro da1a8bb539 Remove duplicate placeholder proptype. (#2211) 2019-03-01 19:34:24 +01:00
Kim Gardner 18add4cdea Merge pull request #2210 from sanoma/feature/talk_470_dutch_translations
Feature/talk 470 dutch translations
2019-02-28 12:28:17 -05:00
Kim Gardner de5de26c82 Merge branch 'master' into feature/talk_470_dutch_translations 2019-02-28 11:09:19 -05:00
Besma 934e4b4754 Replace email with e-mail for Dutch translation consistency 2019-02-27 10:11:39 +01:00
Kim Gardner 049658508c Merge pull request #2206 from coralproject/bump-version-4-8-0
v4.8.0
2019-02-26 17:03:38 -05:00
Kim Gardner f0ead66f68 v4.8.0 2019-02-26 14:30:35 -05:00
David Burke 14f1343930 Additional Replies Increment (#2203)
* added ADDTL_REPLIES_ON_LOAD_MORE variable

* feat: added docs and onbuild ref
2019-02-26 16:18:55 +00:00
Besma b21845b963 Update translations 2019-02-26 09:39:54 +01:00
Kim Gardner 0ff20bed5e Merge pull request #2201 from mazzi/fix/issue-2141
Suspended vs. Banned  translations and typos in Spanish fixed
2019-02-25 17:33:27 -05:00
Besma 0bb2d4cbca Add Dutch translation 2019-02-25 16:18:33 +01:00
Lautaro Mazzitelli 927a34a579 ci: quotation not needed 2019-02-22 17:37:38 -03:00
Lautaro Mazzitelli 75f2f05534 fix: Suspended vs. Banned. Fixed in spanish translations. 2019-02-22 17:21:56 -03:00
Lautaro Mazzitelli 2998db46ad fix: three different typos were fixed on spanish translation file. 2019-02-22 16:21:02 -03:00
Gerardo Gálvez 8163b52301 Flag users as "Always premoderate" (#2145)
* Flag users as "Always premoderate"

Status can be set using the action dropdown in the People tab and in User Details.
Users flagged as "Always premoderate" will have their comments sent to the premod queue.
Users can be filtered with the Always Premoderate status.
Include Always Premoderate status changes in User History.
Add spanish translations.

* Reorder CSS as per cvle's suggestion

* Address second comment
2019-02-13 20:08:22 +01:00
Kim Gardner 19b425dc1a Merge pull request #2182 from mkonikov/snackbar-improvements
Snackbar improvements
2019-02-13 13:57:35 -05:00
Kim Gardner be81ced2f5 Merge branch 'master' into snackbar-improvements 2019-02-13 11:42:57 -05:00
Kim Gardner f6e5f24722 Merge pull request #2189 from javierbarriosafonso/master
Spanish (es) translations for talk notifications plugins
2019-02-13 11:42:48 -05:00
Kim Gardner 2c1dc9c118 Merge branch 'master' into master 2019-02-13 11:34:21 -05:00
Steven 657bf388cf fix: rename devToolsExtension (#2192)
Note that starting from v2.7, window.devToolsExtension was renamed to window.__REDUX_DEVTOOLS_EXTENSION__ / window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__.
2019-02-12 17:12:29 +01:00
Javier Barrios b3412a46cf Spanish (es) translations for talk notifications plugins 2019-02-11 14:08:31 -03:00
Mendel Konikov c6ee54c2f5 Rename classes to match id 2019-02-08 10:46:32 -05:00
Mendel Konikov 174a80c377 Reorder style as previous 2019-02-08 10:34:40 -05:00
Mendel Konikov 17a05059d9 Add working close button and style 2019-02-08 10:31:57 -05:00
Mendel Konikov 8c53c25a89 Merge branch 'master' of github.com:mkonikov/talk into snackbar-improvements 2019-02-08 09:15:07 -05:00
Mendel Konikov 1928a7b02e Create Moderation actions notification plugin (#2175)
* Create Moderation actions plugin

* Clarify env var in readme

* Reword log message

* Update with suggestion from Wyatt

* Whitelist notification types

* Update messaging

* Rename unpublished to pending
2019-02-07 15:20:44 +01:00
immber 5173af2a27 talk-plugin-toxic-comments - ADD MODEL VARIABLE TO TOXIC COMMENTS (#2178)
* updated readme

* added config var TALK_PERSPECTIVE_MODEL

* fixed duplication on readme

* fixed link on readme

* fix: applied some changes
2019-02-07 00:22:10 +00:00
Kim Gardner 9077f31872 Merge pull request #2179 from mkonikov/patch-1
Break word on long description
2019-02-06 18:14:51 -05:00
Mendel Konikov 51e8035533 Break word on long description
Also fix font size
2019-02-06 11:40:51 -05:00
Wyatt Johnson 94786c2711 fix: repairs poor performance for assets (#2174)
- fixes #2158
2019-02-05 22:06:05 +01:00
Nacho Toledo 456abaf862 Update appropriate <section> class in Profile section (#2170)
* Update appropriate <section> class in user profile section

Download my comment history has `talk-plugin-ignore-user-section` class. Should be `talk-plugin-profile-data--download-my-comment-history` (couldn't figure out the proper naming convention used).

* Fix linting error

* Fix lint second try
2019-02-05 16:49:25 +01:00
Kim Gardner fe9f92d3fc Merge pull request #2165 from mkonikov/hebrew
Add Hebrew Language Support
2019-02-04 17:37:46 -05:00
Kim Gardner a49fbf2d05 Yml fix 2019-02-04 17:16:15 -05:00
Kim Gardner 51bb158446 Merge branch 'master' into hebrew 2019-02-04 15:52:14 -05:00
Kim Gardner d601bd1466 Merge pull request #2177 from coralproject/remove-pt-link
Update Readme
2019-02-04 15:51:53 -05:00
immber 8eb8294987 Merge branch 'master' into remove-pt-link 2019-02-04 12:08:11 -08:00
Kim Gardner 99332323a8 Merge branch 'master' into hebrew 2019-02-04 14:52:29 -05:00
Kim Gardner 1a23cc1fa7 Merge pull request #2159 from mkonikov/fix-ios-copy
Fix Permalink copy on iOS
2019-02-04 19:48:38 +00:00
Kim Gardner 798f55ed79 Merge branch 'master' into hebrew 2019-02-04 19:47:24 +00:00
Kim Gardner 6897c0e18d Merge branch 'master' into fix-ios-copy 2019-02-04 19:34:31 +00:00
Kim Gardner 9d7b9a91cd Merge pull request #2153 from ljubar/master
sr_ME translations (Montenegrin version of Serbian language, Latin letters)
2019-02-04 19:32:56 +00:00
Kim Gardner 51a62b8c26 Merge branch 'master' into master 2019-02-04 19:28:23 +00:00
Kim Gardner f11a51ebfc Update Readme 2019-02-04 12:56:50 -05:00
Kim Gardner dbdf38af73 Merge branch 'master' into hebrew 2019-02-04 17:30:32 +00:00
Mendel Konikov abc1664ef7 WIP: Snackbar close 2019-01-31 09:59:58 -05:00
immber c16514502c Update recommended release version to link (#2168)
* Update recommended release version to 4.7

* update release link on readme!
2019-01-29 20:41:26 +00:00
Mendel Konikov 9d3e3ce45d Add additional Hebrew translations 2019-01-27 21:59:38 -05:00
Mendel Konikov f6bfef3fb5 Sort Translations ABC, Add missing Hebrew 2019-01-27 21:31:51 -05:00
Mendel Konikov 9b0173e6bf Add few more translations 2019-01-26 21:41:02 -05:00
Mendel Konikov 43219eed4b Replace quote marks 2019-01-24 22:32:50 -05:00
Mendel Konikov 9300359ed1 Merge branch 'master' of github.com:coralproject/talk into hebrew 2019-01-24 22:31:15 -05:00
Mendel Konikov 80c3367259 Merge branch 'master' into fix-ios-copy 2019-01-24 13:58:22 -05:00
Andrew Losowsky ef731f719d added Vox Media link (#2161) 2019-01-24 18:11:04 +00:00
Kim Gardner 9c09509a08 Merge pull request #2163 from mkonikov/fix-typo
Fix typo for Asset URL translation
2019-01-23 20:10:58 +00:00
Mendel Konikov 313310a097 Fix typo 2019-01-23 00:55:23 -05:00
Mendel Konikov fa42c028df Fix quotes 2019-01-23 00:45:31 -05:00
Mendel Konikov 905e43e745 Remove deleted plugin 2019-01-23 00:41:29 -05:00
Mendel Konikov 6cc0c60ade Add Final hebrew translations 2019-01-23 00:38:53 -05:00
Mendel Konikov ca44588095 Add Hebrew profile translations - server 2019-01-22 23:38:10 -05:00
Mendel Konikov 9a49044030 Add client profile translations 2019-01-22 23:30:39 -05:00
Mendel Konikov 02963dc5ac Fix translation 2019-01-22 23:18:18 -05:00
Mendel Konikov 5ad90e00cb Add Hebrew to profile plugin 2019-01-22 23:16:09 -05:00
Mendel Konikov 1dfc4b83c7 Remove unnecessary diffs 2019-01-22 23:11:25 -05:00
Mendel Konikov d522a72d42 Add additional hebrew 2019-01-22 23:09:30 -05:00
Mendel Konikov d1a22f9dc8 Remove merge comments 2019-01-22 22:10:53 -05:00
Mendel Konikov 5ac3910687 Fix lint 2019-01-22 22:08:29 -05:00
Mendel Konikov d007c2295e Fix Permalink copy on iOS 2019-01-21 17:15:16 -05:00
Kim Gardner 7ebcc4c793 Merge pull request #2157 from coralproject/docs-update
added native comments pdf
2019-01-18 19:41:19 +00:00
immber 582d45bb21 moved pdf to wp and updated copy 2019-01-17 09:56:55 -08:00
immber 6ef5c3a42f added link to sidebar 2019-01-16 14:29:35 -08:00
immber 00883a3739 added link to sidebar 2019-01-16 14:25:52 -08:00
immber d7fb0056be added native comments pdf 2019-01-16 14:16:04 -08:00
Kim Gardner ad55d715f6 Merge branch 'master' into master 2019-01-16 21:24:52 +00:00
Kim Gardner 0a855cd3d4 Merge pull request #2154 from coralproject/losowsky-patch-1
Fixed blog url
2019-01-16 21:24:18 +00:00
Andrew Losowsky c02d2b9b4e Fixed blog url 2019-01-16 10:46:49 -05:00
Kim Gardner 68255bec70 Merge branch 'master' into master 2019-01-16 14:44:51 +00:00
immber 28edd98ff1 Merge pull request #2151 from coralproject/docs-update
added TALK_CONCURRENCY to adv config
2019-01-14 13:53:12 -08:00
immber d1b5409e44 Merge branch 'master' into docs-update 2019-01-14 13:46:43 -08:00
Wyatt Johnsonandimmber df5e863cc4 updated default phrasing to be consistent
Co-Authored-By: immber <jessiekrushing@gmail.com>
2019-01-14 13:45:28 -08:00
immber acc83e27ce added TALK_CONCURRENCY to adv config 2019-01-14 10:37:36 -08:00
Kim Gardner ca13fde87d Merge pull request #2148 from coralproject/docs-update
Docs update
2019-01-11 15:46:35 +00:00
immber f69a9c826d removed link to community from faq 2019-01-10 17:04:22 -08:00
immber 76ef0f7d52 pulled community link from readme 2019-01-10 10:55:20 -08:00
immber 8f54c1d3c3 fixed md typo 2019-01-09 12:38:33 -08:00
immber 83379b58a7 em that can not be opted out of 2019-01-08 16:46:49 -08:00
immber b0b5807c8b added scaling talk 2019-01-08 16:39:06 -08:00
immber c98d227411 updated notifications page 2019-01-08 15:12:44 -08:00
immber 83819df922 added talk-plugin-comment-count to plugins directory 2019-01-08 13:27:08 -08:00
immber db5bf9a676 added twitter faq 2019-01-08 10:04:39 -08:00
immber ba31dbbdf9 added logout wait time 2019-01-08 09:53:46 -08:00
immber 8f633fbe78 added comment count to checklist 2019-01-04 17:20:49 -08:00
immber 886222260d fb requires ssl 2019-01-04 16:55:56 -08:00
immber 2c3589cdac added cert to auth section 2019-01-04 16:49:16 -08:00
Ljuba Rankovic ed953b5e7e Change translation 2018-12-24 15:41:05 +01:00
Ljuba Rankovic 79d1f059c2 fixes 2018-12-22 16:34:16 +01:00
Kim Gardner dd0601a801 Merge pull request #2135 from coralproject/concurrency
Concurrency
2018-12-19 20:53:30 +00:00
Wyatt Johnson 9f7d485871 Update package.json 2018-12-19 20:39:25 +00:00
Wyatt Johnson ec816636e6 feat: added concurrency features 2018-12-19 12:40:08 -07:00
Kim Gardner 08f579225b Bump version 4.6.11 (#2130) 2018-12-17 16:34:43 +00:00
Kim Gardner 46987b6303 Merge pull request #2122 from oafx/oafx/qbb-localization
Add localization for QuestionBoxBuilder
2018-12-17 15:09:31 +00:00
Kim Gardner c2d07ec79f Merge branch 'master' into oafx/qbb-localization 2018-12-17 14:43:32 +00:00
Kim Gardner a98f5ef980 Merge pull request #2128 from oafx/oafx/fix/moderate-commentcontainer-wordbreak
fix minor ui/css bug in moderation/comment component caused by long links
2018-12-17 14:42:54 +00:00
Christian Ruttorf d6515e23f8 fix ui/css bug in moderation/comment component caused by long words/links 2018-12-16 08:48:21 +01:00
Ljuba Rankovic 282db6847a locale sr added 2018-12-15 09:40:53 +01:00
immber a3db05845d Merge pull request #2126 from coralproject/docs-update
Add Documentation Redirect - asset management to cms integration
2018-12-14 13:06:59 -08:00
Wyatt Johnson c8fc419cec Update _redirects 2018-12-14 20:46:57 +00:00
immber 677c8a0828 Merge branch 'master' into docs-update 2018-12-14 12:06:22 -08:00
immber 08146fd979 added redirect 2018-12-14 12:04:28 -08:00
Kim Gardner ab92fe3fe8 Merge branch 'master' into oafx/qbb-localization 2018-12-14 18:18:33 +00:00
immber 95435f0793 Docs update (#2120)
* merging in typo fixes from docs (rtd) branch

* revert generateIntrospectionResult.json

* revert git ignore

* added asset mgmt to prelaunch checklist

* updated cusotm plugin docker onbuild instructions

* add google to auth options

* add google to auth options

* added yarn watch to from source

* added dev links to quickstart

* typo on following

* fixed typos

* fixing links

* added lazy render and updated lazy load

* added version note

* renamed asset management to cms-integration

* added link to asset scraping
2018-12-14 17:05:52 +00:00
immber 7eed540671 added link to asset scraping 2018-12-13 13:10:14 -08:00
immber 374951bd33 renamed asset management to cms-integration 2018-12-13 13:04:01 -08:00
immber 42a694f56e Merge branch 'master' of https://github.com/coralproject/talk into docs-update 2018-12-13 12:52:18 -08:00
immber 1c997aea31 Merge branch 'docs-update' of https://github.com/coralproject/talk into docs-update 2018-12-13 12:51:58 -08:00
immber 44830f6cb1 added version note 2018-12-13 12:51:50 -08:00
Wyatt Johnson 22d263c6d2 Embed Optimizations (#2121)
* feat: refactored bridge

- Cleaned up implementation of bridge
- Removed unneeded babel-polyfill and webpack globals

* fix: fixed up some static headers

- bumped version

* fix: moved intersection observer out of chunk

* fix: fixed misplaced "!"
2018-12-13 20:41:40 +00:00
Christian Ruttorf 78ba82cc05 add localization for QuestionBoxBuilder title, add PropTypes for QuestionBoxBuilder 2018-12-13 17:42:50 +01:00
immber a6b9cc57ac Merge branch 'master' into docs-update 2018-12-12 12:46:04 -08:00
immber cd9cb56844 added lazy render and updated lazy load 2018-12-12 12:44:19 -08:00
immber 8b1b61f695 pulling changes from upstream 2018-12-10 14:26:58 -08:00
immber 99777d6b49 fixing links 2018-12-03 11:07:40 -08:00
immber 6f6da1fa25 merging changes from master 2018-12-03 09:34:25 -08:00
immber 2fac304163 fixed typos 2018-12-03 09:33:03 -08:00
immber 5ca7c092db Merge branch 'master' into docs-update 2018-11-30 18:05:35 -08:00
immber cfae6b5374 typo on following 2018-11-30 18:04:20 -08:00
immber 3668a2cffa added dev links to quickstart 2018-11-30 17:56:20 -08:00
immber 92681f52aa added yarn watch to from source 2018-11-30 17:39:02 -08:00
immber 847ded5bb4 add google to auth options 2018-11-30 17:19:27 -08:00
immber 76c959f790 add google to auth options 2018-11-30 17:11:42 -08:00
immber 4659392ad3 updated cusotm plugin docker onbuild instructions 2018-11-30 15:10:00 -08:00
immber e9cec73966 added asset mgmt to prelaunch checklist 2018-11-30 14:44:35 -08:00
immber bac0ee9c3b revert git ignore 2018-11-28 14:00:07 -08:00
immber 5ae293af89 revert generateIntrospectionResult.json 2018-11-28 13:58:56 -08:00
immber cce464b82a merging in typo fixes from docs (rtd) branch 2018-11-28 13:56:31 -08:00
Mendel Konikov 63400a455f Merge https://github.com/coralproject/talk 2018-05-10 20:53:41 -04:00
Mendel Konikov b7d8fb950b Merge master 2018-05-01 20:25:05 -04:00
Mendel Konikov 3915ffc4e0 Merge master 2018-04-10 20:10:21 -04:00
Mendel Konikov ac9899406a Merge 2018-03-07 12:02:01 -05:00
Mendel Konikov 13e1b288b3 Add more translations 2018-03-07 12:00:38 -05:00
Mendel Konikov 8c8f5d8fee Fix apostrophes 2018-03-07 12:00:38 -05:00
Mendel Konikov 35cf694b60 Add More hebrew translations 2018-03-07 12:00:38 -05:00
Mendel Konikov fa4dbfe9d0 Trigger build 2018-03-07 12:00:38 -05:00
Mendel Konikov 0ea08ccc9c Remove extra space 2018-03-07 12:00:38 -05:00
Mendel Konikov fd5bbe0234 Viewing options Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov b43f657c8d Toxic comments Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov 9456c79bad Most respected Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov 0cd18a458d More Hebrew translations 2018-03-07 12:00:38 -05:00
Mendel Konikov fdcd1404ef Most loved Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov 741d5000dd Most liked Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov 8f413852d9 Settings Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov 420fc6daa7 Off-top Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov ad69086888 Moderation actions Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov f18c51dc68 Member since Hebrew Translation 2018-03-07 12:00:38 -05:00
Mendel Konikov 8e1822af21 Google Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov 5d3e8f3fb6 Flag Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov 71288f543e Featured comments Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov a1890a0bfe Facebook Auth translation 2018-03-07 12:00:38 -05:00
Mendel Konikov 1f17d71a76 Ignore user hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov fc8b9c3547 Like hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov 8ebb90c160 Subscriber hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov b0c230a1df Akismet Hebrew translations 2018-03-07 12:00:38 -05:00
Mendel Konikov be15734c77 Respect hebrew translations 2018-03-07 12:00:38 -05:00
Mendel Konikov 4478ced205 Auth Hebrew translations 2018-03-07 12:00:38 -05:00
Mendel Konikov 769437c8fb Add more translations 2018-03-07 12:00:38 -05:00
Mendel Konikov 5fde3235ad Add Hebrew template to all translation files 2018-03-07 12:00:38 -05:00
Mendel Konikov 2a8975711a Begin adding Hebrew translation 2018-03-07 12:00:38 -05:00
Mendel Konikov da56cd5b18 Add more translations 2018-03-06 13:02:03 -05:00
Mendel Konikov 90424b4766 Fix apostrophes 2018-02-26 16:39:28 -05:00
Mendel Konikov cf23bdba12 Add More hebrew translations 2018-02-26 16:37:40 -05:00
Mendel Konikov 0f983109e1 Trigger build 2018-02-26 16:14:16 -05:00
Mendel Konikov 8f7edde93f Remove extra space 2018-02-24 21:38:07 -05:00
Mendel Konikov 1946d023cd Viewing options Hebrew translation 2018-02-24 21:27:31 -05:00
Mendel Konikov 1e5f5848b2 Toxic comments Hebrew translation 2018-02-24 21:25:58 -05:00
Mendel Konikov 3cbf5fef07 Most respected Hebrew translation 2018-02-24 21:21:02 -05:00
Mendel Konikov 4f276ed944 More Hebrew translations 2018-02-24 21:19:43 -05:00
Mendel Konikov e69afc4e76 Most loved Hebrew translation 2018-02-24 21:17:02 -05:00
Mendel Konikov c4b46c28fe Most liked Hebrew translation 2018-02-24 21:15:51 -05:00
Mendel Konikov dac823f9c4 Settings Hebrew translation 2018-02-24 21:14:00 -05:00
Mendel Konikov 65deb1cfbe Off-top Hebrew translation 2018-02-24 21:12:04 -05:00
Mendel Konikov 828f200eb6 Moderation actions Hebrew translation 2018-02-24 21:10:23 -05:00
Mendel Konikov fe5c95c27a Member since Hebrew Translation 2018-02-24 21:06:24 -05:00
Mendel Konikov c7fad00b66 Google Hebrew translation 2018-02-24 21:05:14 -05:00
Mendel Konikov 5165d06d64 Flag Hebrew translation 2018-02-24 21:03:10 -05:00
Mendel Konikov e15275666e Featured comments Hebrew translation 2018-02-24 21:01:25 -05:00
Mendel Konikov 1dc8df4189 Facebook Auth translation 2018-02-24 20:43:18 -05:00
Mendel Konikov ffe83452cd Ignore user hebrew translation 2018-02-24 20:41:22 -05:00
Mendel Konikov 3c3603ee08 Like hebrew translation 2018-02-24 20:34:22 -05:00
Mendel Konikov f6e94b0cc2 Subscriber hebrew translation 2018-02-24 20:30:34 -05:00
Mendel Konikov c3f92e8c8d Akismet Hebrew translations 2018-02-24 20:27:52 -05:00
Mendel Konikov 84a121a1d9 Respect hebrew translations 2018-02-24 20:22:12 -05:00
Mendel Konikov f55f1341e1 Auth Hebrew translations 2018-02-24 20:19:20 -05:00
Mendel Konikov cccac6a8bc Add more translations 2018-02-23 12:17:13 -05:00
Mendel Konikov e775a9f092 Add Hebrew template to all translation files 2018-02-23 12:00:01 -05:00
Mendel Konikov 76237f42da Begin adding Hebrew translation 2018-02-23 11:29:28 -05:00
Mendel Konikov 6e942a1121 Fix typos in comments 2018-02-23 11:11:41 -05:00
141 changed files with 5049 additions and 1386 deletions
+1
View File
@@ -45,6 +45,7 @@ plugins/*
!plugins/talk-plugin-moderation-actions
!plugins/talk-plugin-notifications
!plugins/talk-plugin-notifications-category-featured
!plugins/talk-plugin-notifications-category-moderation-actions
!plugins/talk-plugin-notifications-category-reply
!plugins/talk-plugin-notifications-category-staff
!plugins/talk-plugin-notifications-digest-daily
+1
View File
@@ -4,6 +4,7 @@ FROM coralproject/talk:latest
ONBUILD ARG TALK_ADDTL_COMMENTS_ON_LOAD_MORE=10
ONBUILD ARG TALK_ASSET_COMMENTS_LOAD_DEPTH=10
ONBUILD ARG TALK_REPLY_COMMENTS_LOAD_DEPTH=3
ONBUILD ARG TALK_ADDTL_REPLIES_ON_LOAD_MORE=999999
ONBUILD ARG TALK_THREADING_LEVEL=3
ONBUILD ARG TALK_DEFAULT_STREAM_TAB=all
ONBUILD ARG TALK_DISABLE_EMBED_POLYFILL=FALSE
+3 -5
View File
@@ -2,7 +2,7 @@
Online comments are broken. Our open-source commenting platform, Talk, rethinks how moderation, comment display, and conversation function, creating the opportunity for safer, smarter discussions around your work. [Read more about Talk here](https://coralproject.net/talk).
Built with <3 by The Coral Project.
Built with <3 by The Coral Project, a part of [Vox Media](https://www.voxmedia.com/a/go-deeper/about).
## Getting Started
@@ -22,13 +22,11 @@ For advanced configuration and usage of Talk, check out our [Configuration](http
## Versions & Upgrading
The current recommended release version is v4.5.0. ^4.5 (and all future even-numbered versions) are considered stable LTS versions. We recommend ^4.5 for use in production environments.
Check our Releases page for the latest recommended release version. [Releases](https://github.com/coralproject/talk/releases) All future even-numbered versions are considered stable LTS versions. We recommend the latest verified release for use in production environments.
## More Resources
- [Talk Product Roadmap](https://www.pivotaltracker.com/n/projects/1863625)
- [Our Blog](https://blog.coralproject.net/)
- [Community Forums](https://community.coralproject.net/)
- [Our Blog](https://coralproject.net/blog)
- [Community Guides for Journalism](https://guides.coralproject.net/)
- [More About Us](https://coralproject.net/)
+17 -5
View File
@@ -1,8 +1,10 @@
#!/usr/bin/env node
const throng = require('throng');
const { CONCURRENCY } = require('../config');
const { logger } = require('../services/logging');
const util = require('./util');
const program = require('commander');
const serve = require('../serve');
//==============================================================================
// Setting up the program command line arguments.
@@ -22,8 +24,18 @@ program
)
.parse(process.argv);
// Start serving.
serve(program).catch(err => {
console.error(err);
util.shutdown(1);
throng({
workers: CONCURRENCY,
start: i => {
logger.info({ workerID: i }, 'started worker');
// Load in the serve.
const serve = require('../serve');
// Start serving.
serve(program).catch(err => {
console.error(err);
util.shutdown(1);
});
},
});
+2 -1
View File
@@ -105,7 +105,8 @@ function printUserAsTable(user) {
Suspension: user.suspended
? `Until ${user.status.suspension.until}`
: false,
}
},
{ 'Always premod comments': user.alwaysPremod }
);
console.log(table.toString());
@@ -0,0 +1,14 @@
import {
SHOW_ALWAYS_PREMOD_USER_DIALOG,
HIDE_ALWAYS_PREMOD_USER_DIALOG,
} from '../constants/alwaysPremodUserDialog.js';
export const showAlwaysPremodUserDialog = ({ userId, username }) => ({
type: SHOW_ALWAYS_PREMOD_USER_DIALOG,
userId,
username,
});
export const hideAlwaysPremodUserDialog = () => ({
type: HIDE_ALWAYS_PREMOD_USER_DIALOG,
});
@@ -9,6 +9,8 @@ import {
SET_SEARCH_VALUE,
SHOW_BANUSER_DIALOG,
HIDE_BANUSER_DIALOG,
SHOW_ALWAYS_PREMOD_USER_DIALOG,
HIDE_ALWAYS_PREMOD_USER_DIALOG,
SHOW_REJECT_USERNAME_DIALOG,
HIDE_REJECT_USERNAME_DIALOG,
SET_INDICATOR_TRACK,
@@ -61,6 +63,15 @@ export const setSearchValue = value => ({
export const showBanUserDialog = user => ({ type: SHOW_BANUSER_DIALOG, user });
export const hideBanUserDialog = () => ({ type: HIDE_BANUSER_DIALOG });
// Always premod User Dialog
export const showAlwaysPremodUserDialog = user => ({
type: SHOW_ALWAYS_PREMOD_USER_DIALOG,
user,
});
export const hideAlwaysPremodUserDialog = () => ({
type: HIDE_ALWAYS_PREMOD_USER_DIALOG,
});
// Reject Username Dialog
export const showRejectUsernameDialog = user => ({
type: SHOW_REJECT_USERNAME_DIALOG,
@@ -0,0 +1,29 @@
.dialog {
border: none;
box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
width: 400px;
top: 50%;
transform: translateY(-50%);
padding: 20px;
border-radius: 4px;
}
.header {
color: black;
font-size: 1.5em;
font-weight: 500;
margin: 0 0 8px 0;
}
.subheader {
color: black;
font-size: 1.3em;
font-weight: 500;
margin: 0 0 8px 0;
}
.buttons {
margin-top: 8px;
margin-bottom: 6px;
text-align: right;
}
@@ -0,0 +1,68 @@
import React from 'react';
import cn from 'classnames';
import PropTypes from 'prop-types';
import { Dialog } from 'coral-ui';
import styles from './AlwaysPremodUserDialog.css';
import Button from 'coral-ui/components/Button';
import t from 'coral-framework/services/i18n';
class AlwaysPremodUserDialog extends React.Component {
handlePerform = () => {
this.props.onPerform();
};
render() {
const { open, onCancel, username, info } = this.props;
return (
<Dialog
className={cn(styles.dialog, 'talk-always-premod-user-dialog')}
id="alwaysPremodUserDialog"
open={open}
onCancel={onCancel}
title={t('alwayspremoddialog.always_premod_user')}
>
<span className={styles.close} onClick={onCancel}>
×
</span>
<section>
<h2 className={styles.header}>
{t('alwayspremoddialog.always_premod_user')}
</h2>
<h3 className={styles.subheader}>
{t('alwayspremoddialog.are_you_sure', username)}
</h3>
<p className={styles.description}>{info}</p>
<div className={styles.buttons}>
<Button
className={cn('talk-always-premod-user-dialog-button-cancel')}
cStyle="white"
onClick={onCancel}
raised
>
{t('alwayspremoddialog.cancel')}
</Button>
<Button
className={cn('talk-always-premod-user-dialog-button-confirm')}
cStyle="black"
onClick={this.handlePerform}
raised
>
{t('alwayspremoddialog.yes_always_premod_user')}
</Button>
</div>
</section>
</Dialog>
);
}
}
AlwaysPremodUserDialog.propTypes = {
open: PropTypes.bool,
onPerform: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
username: PropTypes.string,
info: PropTypes.string,
};
export default AlwaysPremodUserDialog;
@@ -137,6 +137,12 @@
display: inline-block;
}
.actionsMenuAlwaysPremod {
background-color: #F0B50B;
border-color: #F0B50B;
color: white;
}
.actionsMenuSuspended {
background-color: #F29336;
border-color: #F29336;
@@ -12,6 +12,7 @@ import {
isUsernameRejected,
isUsernameChanged,
isBanned,
isAlwaysPremod,
getKarma,
} from 'coral-framework/utils/user';
@@ -45,6 +46,7 @@ function getUserStatusArray(user) {
const statusMap = {
suspended: isSuspended,
banned: isBanned,
alwaysPremod: isAlwaysPremod,
usernameRejected: isUsernameRejected,
usernameChanged: isUsernameChanged,
};
@@ -68,6 +70,12 @@ class UserDetail extends React.Component {
username: this.props.root.user.username,
});
showAlwaysPremodUserDialog = () =>
this.props.showAlwaysPremodUserDialog({
userId: this.props.root.user.id,
username: this.props.root.user.username,
});
showRejectUsernameDialog = () =>
this.props.showRejectUsernameDialog({
userId: this.props.root.user.id,
@@ -107,6 +115,8 @@ class UserDetail extends React.Component {
return t('user_detail.suspended');
case 'banned':
return t('user_detail.banned');
case 'alwaysPremod':
return t('user_detail.always_premoded');
case 'usernameRejected':
return (
<span>
@@ -153,6 +163,7 @@ class UserDetail extends React.Component {
toggleSelectAll,
unbanUser,
unsuspendUser,
removeAlwaysPremodUser,
modal,
acceptComment,
rejectComment,
@@ -169,6 +180,7 @@ class UserDetail extends React.Component {
const banned = isBanned(user);
const suspended = isSuspended(user);
const alwaysPremod = isAlwaysPremod(user);
const usernameRejected = isUsernameRejected(user);
const usernameChanged = isUsernameChanged(user);
@@ -200,6 +212,7 @@ class UserDetail extends React.Component {
{
[styles.actionsMenuSuspended]: suspended,
[styles.actionsMenuBanned]: banned,
[styles.actionsMenuAlwaysPremod]: alwaysPremod,
},
'talk-admin-user-detail-actions-button'
)}
@@ -231,6 +244,21 @@ class UserDetail extends React.Component {
</ActionsMenuItem>
)}
{alwaysPremod ? (
<ActionsMenuItem
onClick={() => removeAlwaysPremodUser({ id: user.id })}
>
{t('user_detail.remove_always_premod')}
</ActionsMenuItem>
) : (
<ActionsMenuItem
disabled={me.id === user.id}
onClick={this.showAlwaysPremodUserDialog}
>
{t('user_detail.always_premod')}
</ActionsMenuItem>
)}
{usernameChanged && (
<ActionsMenuItem onClick={this.goToReportedUsernames}>
{t('user_detail.username_needs_approval')}
@@ -476,8 +504,10 @@ UserDetail.propTypes = {
showRejectUsernameDialog: PropTypes.func,
showSuspendUserDialog: PropTypes.func,
showBanUserDialog: PropTypes.func,
showAlwaysPremodUserDialog: PropTypes.func,
unbanUser: PropTypes.func.isRequired,
unsuspendUser: PropTypes.func.isRequired,
removeAlwaysPremodUser: PropTypes.func.isRequired,
modal: PropTypes.bool,
rejectUsername: PropTypes.func.isRequired,
};
@@ -48,6 +48,10 @@ const buildActionResponse = (typename, created_at, until, status) => {
return status
? t('user_history.user_banned')
: t('user_history.ban_removed');
case 'AlwaysPremodStatusHistory':
return status
? t('user_history.user_always_premoded')
: t('user_history.always_premod_removed');
case 'SuspensionStatusHistory':
return until
? t('user_history.suspended', readableDuration(created_at, until))
@@ -0,0 +1,2 @@
export const SHOW_ALWAYS_PREMOD_USER_DIALOG = 'SHOW_ALWAYS_PREMOD_USER_DIALOG';
export const HIDE_ALWAYS_PREMOD_USER_DIALOG = 'HIDE_ALWAYS_PREMOD_USER_DIALOG';
@@ -14,6 +14,9 @@ export const FETCH_FLAGGED_COMMENTERS_FAILURE = `${prefix}_FETCH_FLAGGED_COMMENT
export const SHOW_BANUSER_DIALOG = `${prefix}_SHOW_BANUSER_DIALOG`;
export const HIDE_BANUSER_DIALOG = `${prefix}_HIDE_BANUSER_DIALOG`;
export const SHOW_ALWAYS_PREMOD_USER_DIALOG = `${prefix}_SHOW_ALWAYS_PREMOD_USER_DIALOG`;
export const HIDE_ALWAYS_PREMOD_USER_DIALOG = `${prefix}_HIDE_ALWAYS_PREMOD_USER_DIALOG`;
export const SHOW_REJECT_USERNAME_DIALOG = `${prefix}_SHOW_REJECT_USERNAME_DIALOG`;
export const HIDE_REJECT_USERNAME_DIALOG = `${prefix}_HIDE_REJECT_USERNAME_DIALOG`;
@@ -0,0 +1,66 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import AlwaysPremodUserDialog from '../components/AlwaysPremodUserDialog';
import { hideAlwaysPremodUserDialog } from '../actions/alwaysPremodUserDialog';
import { withAlwaysPremodUser } from 'coral-framework/graphql/mutations';
import { compose } from 'react-apollo';
import t from 'coral-framework/services/i18n';
class AlwaysPremodUserDialogContainer extends Component {
alwaysPremodUser = async () => {
const { userId, alwaysPremodUser, hideAlwaysPremodUserDialog } = this.props;
await alwaysPremodUser({ id: userId });
hideAlwaysPremodUserDialog();
};
getInfo() {
let note = t('alwayspremoddialog.note_always_premod_user');
return t('alwayspremoddialog.note', note);
}
render() {
return (
<AlwaysPremodUserDialog
open={this.props.open}
onPerform={this.alwaysPremodUser}
onCancel={this.props.hideAlwaysPremodUserDialog}
username={this.props.username}
info={this.getInfo()}
/>
);
}
}
AlwaysPremodUserDialogContainer.propTypes = {
alwaysPremodUser: PropTypes.func.isRequired,
hideAlwaysPremodUserDialog: PropTypes.func,
open: PropTypes.bool,
username: PropTypes.string,
};
const mapStateToProps = ({
alwaysPremodUserDialog: { open, userId, username },
}) => ({
open,
userId,
username,
});
const mapDispatchToProps = dispatch => ({
...bindActionCreators(
{
hideAlwaysPremodUserDialog,
},
dispatch
),
});
export default compose(
connect(
mapStateToProps,
mapDispatchToProps
),
withAlwaysPremodUser
)(AlwaysPremodUserDialogContainer);
@@ -5,6 +5,7 @@ import Layout from '../components/Layout';
import Login from '../containers/Login';
import { FullLoading } from '../components/FullLoading';
import BanUserDialog from './BanUserDialog';
import AlwaysPremodUserDialog from './AlwaysPremodUserDialog';
import SuspendUserDialog from './SuspendUserDialog';
import RejectUsernameDialog from './RejectUsernameDialog';
import { toggleModal as toggleShortcutModal } from '../actions/moderation';
@@ -40,6 +41,7 @@ class LayoutContainer extends React.Component {
toggleShortcutModal={toggleShortcutModal}
currentUser={this.props.currentUser}
>
<AlwaysPremodUserDialog />
<BanUserDialog />
<SuspendUserDialog />
<RejectUsernameDialog />
@@ -22,12 +22,14 @@ import {
withSetCommentStatus,
withUnbanUser,
withUnsuspendUser,
withRemoveAlwaysPremodUser,
withRejectUsername,
withPostFlag,
} from 'coral-framework/graphql/mutations';
import UserDetailComment from './UserDetailComment';
import update from 'immutability-helper';
import { showBanUserDialog } from 'actions/banUserDialog';
import { showAlwaysPremodUserDialog } from 'actions/alwaysPremodUserDialog';
import { showSuspendUserDialog } from 'actions/suspendUserDialog';
import { showRejectUsernameDialog } from 'actions/rejectUsernameDialog';
@@ -153,6 +155,7 @@ UserDetailContainer.propTypes = {
selectedCommentIds: PropTypes.array,
unbanUser: PropTypes.func.isRequired,
unsuspendUser: PropTypes.func.isRequired,
removeAlwaysPremodUser: PropTypes.func.isRequired,
rejectUsername: PropTypes.func.isRequired,
userId: PropTypes.string,
};
@@ -218,6 +221,17 @@ export const withUserDetailQuery = withQuery(
created_at
}
}
alwaysPremod {
status
history {
status
assigned_by {
id
username
}
created_at
}
},
username {
status
history {
@@ -280,6 +294,7 @@ const mapDispatchToProps = dispatch => ({
...bindActionCreators(
{
showBanUserDialog,
showAlwaysPremodUserDialog,
showSuspendUserDialog,
showRejectUsernameDialog,
changeTab,
@@ -302,6 +317,7 @@ export default compose(
withSetCommentStatus,
withUnbanUser,
withUnsuspendUser,
withRemoveAlwaysPremodUser,
withRejectUsername,
withPostFlag,
withRouter
+78
View File
@@ -10,6 +10,9 @@ const userStatusFragment = gql`
banned {
status
}
alwaysPremod {
status
}
suspension {
until
}
@@ -125,6 +128,64 @@ export default {
});
},
}),
AlwaysPremodUser: ({
variables: {
input: { id },
},
}) => ({
update: proxy => {
const fragmentId = `User_${id}`;
const data = proxy.readFragment({
fragment: userStatusFragment,
id: fragmentId,
});
const updated = update(data, {
state: {
status: {
alwaysPremod: {
status: { $set: true },
},
},
},
});
proxy.writeFragment({
fragment: userStatusFragment,
id: fragmentId,
data: updated,
});
},
}),
RemoveAlwaysPremodUser: ({
variables: {
input: { id },
},
}) => ({
update: proxy => {
const fragmentId = `User_${id}`;
const data = proxy.readFragment({
fragment: userStatusFragment,
id: fragmentId,
});
const updated = update(data, {
state: {
status: {
alwaysPremod: {
status: { $set: false },
},
},
},
});
proxy.writeFragment({
fragment: userStatusFragment,
id: fragmentId,
data: updated,
});
},
}),
BanUser: ({
variables: {
input: { id },
@@ -154,6 +215,23 @@ export default {
});
},
}),
SetUserAlwaysPremodStatus: ({ variables: { status, id } }) => ({
updateQueries: {
TalkAdmin_Community: prev => {
if (!status) {
return prev;
}
const updated = update(prev, {
users: {
nodes: {
$apply: nodes => nodes.filter(node => node.id !== id),
},
},
});
return updated;
},
},
}),
UnbanUser: ({
variables: {
input: { id },
@@ -0,0 +1,29 @@
import {
SHOW_ALWAYS_PREMOD_USER_DIALOG,
HIDE_ALWAYS_PREMOD_USER_DIALOG,
} from '../constants/alwaysPremodUserDialog';
const initialState = {
open: false,
userId: null,
username: '',
};
export default function alwaysPremodUserDialog(state = initialState, action) {
switch (action.type) {
case SHOW_ALWAYS_PREMOD_USER_DIALOG:
return {
...state,
open: true,
userId: action.userId,
username: action.username,
};
case HIDE_ALWAYS_PREMOD_USER_DIALOG:
return {
...state,
open: false,
};
default:
return state;
}
}
+2
View File
@@ -5,6 +5,7 @@ import moderation from './moderation';
import install from './install';
import banUserDialog from './banUserDialog';
import suspendUserDialog from './suspendUserDialog';
import alwaysPremodUserDialog from './alwaysPremodUserDialog';
import rejectUsernameDialog from './rejectUsernameDialog';
import userDetail from './userDetail';
import ui from './ui';
@@ -14,6 +15,7 @@ export default {
banUserDialog,
configure,
suspendUserDialog,
alwaysPremodUserDialog,
userDetail,
stories,
community,
@@ -11,6 +11,7 @@ const initialState = {
criteria: {
asc: 'false',
filter: 'all',
limit: 20,
},
};
+14
View File
@@ -6,6 +6,10 @@ import {
SHOW_SUSPEND_USER_DIALOG,
HIDE_SUSPEND_USER_DIALOG,
} from '../constants/suspendUserDialog';
import {
SHOW_ALWAYS_PREMOD_USER_DIALOG,
HIDE_ALWAYS_PREMOD_USER_DIALOG,
} from '../constants/alwaysPremodUserDialog';
const initialState = {
modal: false,
@@ -23,6 +27,11 @@ export default function config(state = initialState, action) {
...state,
modal: true,
};
case SHOW_ALWAYS_PREMOD_USER_DIALOG:
return {
...state,
modal: true,
};
case HIDE_BAN_USER_DIALOG:
return {
...state,
@@ -33,6 +42,11 @@ export default function config(state = initialState, action) {
...state,
modal: false,
};
case HIDE_ALWAYS_PREMOD_USER_DIALOG:
return {
...state,
modal: false,
};
default:
return state;
}
@@ -78,9 +78,10 @@
}
.flaggedByReason {
font-size: 1tpx;
font-size: 14px;
margin: 0px;
line-height: 1.4;
word-break: break-word;
}
@@ -130,6 +130,12 @@ th.header:nth-child(2), th.header:nth-child(3) {
font-size: 0.98em;
}
.actionsMenuAlwaysPremod {
background-color: #F0B50B;
border-color: #F0B50B;
color: white;
}
.actionsMenuSuspended {
background-color: #F29336;
border-color: #F29336;
@@ -8,7 +8,11 @@ import LoadMore from '../../../components/LoadMore';
import PropTypes from 'prop-types';
import ActionsMenu from 'coral-admin/src/components/ActionsMenu';
import ActionsMenuItem from 'coral-admin/src/components/ActionsMenuItem';
import { isSuspended, isBanned } from 'coral-framework/utils/user';
import {
isSuspended,
isBanned,
isAlwaysPremod,
} from 'coral-framework/utils/user';
import { RadioGroup, Radio } from 'react-mdl';
import moment from 'moment';
import {
@@ -43,6 +47,8 @@ class People extends React.Component {
return 'Banned';
} else if (isSuspended(user)) {
return 'Suspended';
} else if (isAlwaysPremod(user)) {
return 'Always premoderated';
}
return '';
};
@@ -55,6 +61,10 @@ class People extends React.Component {
this.props.unbanUser(input);
};
removeAlwaysPremodUser = input => {
this.props.removeAlwaysPremodUser(input);
};
showBanUserDialog = input => {
this.props.showBanUserDialog(input);
};
@@ -63,6 +73,10 @@ class People extends React.Component {
this.props.showSuspendUserDialog(input);
};
showAlwaysPremodUserDialog = input => {
this.props.showAlwaysPremodUserDialog(input);
};
render() {
const {
onFilterChange,
@@ -109,6 +123,7 @@ class People extends React.Component {
<Radio value="active">{t('community.active')}</Radio>
<Radio value="suspended">{t('community.suspended')}</Radio>
<Radio value="banned">{t('community.banned')}</Radio>
<Radio value="alwaysPremod">{t('community.always_premod')}</Radio>
</RadioGroup>
<div className={styles.filterDetail}>
{t('community.filter_role')}
@@ -188,6 +203,9 @@ class People extends React.Component {
user
),
[styles.actionsMenuBanned]: isBanned(user),
[styles.actionsMenuAlwaysPremod]: isAlwaysPremod(
user
),
},
'talk-admin-user-detail-actions-button'
)}
@@ -232,6 +250,27 @@ class People extends React.Component {
{t('modqueue.ban_user_actions')}
</ActionsMenuItem>
)}
{isAlwaysPremod(user) ? (
<ActionsMenuItem
onClick={() =>
this.removeAlwaysPremodUser({ id: user.id })
}
>
Remove Always Premoderate
</ActionsMenuItem>
) : (
<ActionsMenuItem
onClick={() =>
this.showAlwaysPremodUserDialog({
userId: user.id,
username: user.username,
})
}
>
{t('modqueue.always_premod_user_actions')}
</ActionsMenuItem>
)}
</ActionsMenu>
</td>
<td className="mdl-data-table__cell--non-numeric">
@@ -294,8 +333,10 @@ People.propTypes = {
viewUserDetail: PropTypes.func.isRequired,
unbanUser: PropTypes.func.isRequired,
unsuspendUser: PropTypes.func.isRequired,
removeAlwaysPremodUser: PropTypes.func.isRequired,
showSuspendUserDialog: PropTypes.func,
showBanUserDialog: PropTypes.func,
showAlwaysPremodUserDialog: PropTypes.func,
loadMore: PropTypes.func.isRequired,
};
@@ -8,9 +8,11 @@ import {
withUnbanUser,
withUnsuspendUser,
withSetUserRole,
withRemoveAlwaysPremodUser,
} from 'coral-framework/graphql/mutations';
import { showBanUserDialog } from 'actions/banUserDialog';
import { showSuspendUserDialog } from 'actions/suspendUserDialog';
import { showAlwaysPremodUserDialog } from 'actions/alwaysPremodUserDialog';
import { viewUserDetail } from '../../../actions/userDetail';
import { appendNewNodes } from 'plugin-api/beta/client/utils';
import update from 'immutability-helper';
@@ -30,6 +32,7 @@ class PeopleContainer extends React.PureComponent {
active: { suspended: false, banned: false },
suspended: { suspended: true },
banned: { banned: true },
alwaysPremod: { alwaysPremod: true },
};
onFilterChange = filter => e =>
@@ -40,7 +43,6 @@ class PeopleContainer extends React.PureComponent {
getFilterState = () => {
const { role, status } = this.state;
return {
status: this.statusToQuery[status] || null,
role: role || null,
@@ -106,8 +108,10 @@ class PeopleContainer extends React.PureComponent {
setUserRole={this.props.setUserRole}
showSuspendUserDialog={this.props.showSuspendUserDialog}
showBanUserDialog={this.props.showBanUserDialog}
showAlwaysPremodUserDialog={this.props.showAlwaysPremodUserDialog}
unbanUser={this.props.unbanUser}
unsuspendUser={this.props.unsuspendUser}
removeAlwaysPremodUser={this.props.removeAlwaysPremodUser}
data={this.props.data}
root={this.props.root}
users={this.props.root.users}
@@ -122,9 +126,11 @@ PeopleContainer.propTypes = {
setUserRole: PropTypes.func.isRequired,
unbanUser: PropTypes.func.isRequired,
unsuspendUser: PropTypes.func.isRequired,
removeAlwaysPremodUser: PropTypes.func.isRequired,
viewUserDetail: PropTypes.func.isRequired,
showSuspendUserDialog: PropTypes.func,
showBanUserDialog: PropTypes.func,
showAlwaysPremodUserDialog: PropTypes.func,
data: PropTypes.object,
root: PropTypes.object,
};
@@ -153,6 +159,9 @@ const LOAD_MORE_QUERY = gql`
banned {
status
}
alwaysPremod {
status
}
suspension {
until
}
@@ -187,6 +196,9 @@ const FILTER_QUERY = gql`
banned {
status
}
alwaysPremod {
status
}
suspension {
until
}
@@ -203,6 +215,7 @@ const mapDispatchToProps = dispatch =>
viewUserDetail,
showSuspendUserDialog,
showBanUserDialog,
showAlwaysPremodUserDialog,
},
dispatch
);
@@ -215,6 +228,7 @@ export default compose(
withSetUserRole,
withUnsuspendUser,
withUnbanUser,
withRemoveAlwaysPremodUser,
withQuery(
gql`
query TalkAdmin_Community_People {
@@ -236,6 +250,9 @@ export default compose(
banned {
status
}
alwaysPremod {
status
}
suspension {
until
}
@@ -62,6 +62,7 @@
font-weight: 300;
margin-bottom: 8px;
overflow-wrap: break-word;
word-break:break-word;
}
.body {
@@ -5,6 +5,9 @@ const prefix = 'TALK_EMBED_STREAM';
export const ADDTL_COMMENTS_ON_LOAD_MORE = parseInt(
defaultTo(process.env.TALK_ADDTL_COMMENTS_ON_LOAD_MORE, '10')
);
export const ADDTL_REPLIES_ON_LOAD_MORE = parseInt(
defaultTo(process.env.TALK_ADDTL_REPLIES_ON_LOAD_MORE, '999999')
);
export const ASSET_COMMENTS_LOAD_DEPTH = parseInt(
defaultTo(process.env.TALK_ASSET_COMMENTS_LOAD_DEPTH, '10')
);
@@ -175,6 +175,9 @@ const USER_BANNED_SUBSCRIPTION = gql`
banned {
status
}
alwaysPremod {
status
}
suspension {
until
}
@@ -196,6 +199,9 @@ const USER_SUSPENDED_SUBSCRIPTION = gql`
banned {
status
}
alwaysPremod {
status
}
suspension {
until
}
@@ -217,6 +223,9 @@ const USERNAME_REJECTED_SUBSCRIPTION = gql`
banned {
status
}
alwaysPremod {
status
}
suspension {
until
}
@@ -253,6 +262,9 @@ const EMBED_QUERY = gql`
banned {
status
}
alwaysPremod {
status
}
suspension {
until
}
@@ -1,6 +1,7 @@
import React from 'react';
import QuestionBox from '../../../components/QuestionBox';
import DefaultQuestionBoxIcon from '../../../components/DefaultQuestionBoxIcon';
import PropTypes from 'prop-types';
import cn from 'classnames';
import styles from './QuestionBoxBuilder.css';
import { Icon } from 'coral-ui';
@@ -12,6 +13,7 @@ const icons = [{ default: DefaultIcon }, 'forum', 'build', 'format_quote'];
class QuestionBoxBuilder extends React.Component {
render() {
const {
title,
questionBoxIcon,
questionBoxContent,
onContentChange,
@@ -20,7 +22,7 @@ class QuestionBoxBuilder extends React.Component {
return (
<div className={styles.root}>
<h4>Include an Icon</h4>
<h4>{title}</h4>
<ul className={styles.iconList}>
{icons.map(item => {
@@ -53,4 +55,12 @@ class QuestionBoxBuilder extends React.Component {
}
}
QuestionBoxBuilder.propTypes = {
title: PropTypes.string,
questionBoxIcon: PropTypes.string,
questionBoxContent: PropTypes.string,
onContentChange: PropTypes.func,
onIconChange: PropTypes.func,
};
export default QuestionBoxBuilder;
@@ -69,6 +69,7 @@ class Settings extends React.Component {
{questionBoxEnable && (
<div className={styles.questionBoxContainer}>
<QuestionBoxBuilder
title={t('configure.include_an_icon')}
questionBoxIcon={questionBoxIcon}
questionBoxContent={questionBoxContent}
onIconChange={onQuestionBoxIconChange}
@@ -6,6 +6,7 @@ import { bindActionCreators } from 'redux';
import {
ADDTL_COMMENTS_ON_LOAD_MORE,
ASSET_COMMENTS_LOAD_DEPTH,
ADDTL_REPLIES_ON_LOAD_MORE,
THREADING_LEVEL,
} from '../../../constants/stream';
import {
@@ -152,7 +153,9 @@ class StreamContainer extends React.Component {
return this.props.data.fetchMore({
query: LOAD_MORE_QUERY,
variables: {
limit: parent_id ? 999999 : ADDTL_COMMENTS_ON_LOAD_MORE,
limit: parent_id
? ADDTL_REPLIES_ON_LOAD_MORE
: ADDTL_COMMENTS_ON_LOAD_MORE,
cursor: comment.replies.endCursor,
parent_id,
asset_id: this.props.asset.id,
@@ -398,6 +401,9 @@ const fragments = {
banned {
status
}
alwaysPremod {
status
}
suspension {
until
}
+324
View File
@@ -0,0 +1,324 @@
import queryString from 'querystringify';
import URLSearchParams from '@ungap/url-search-params';
import pym from 'pym.js';
import EventEmitter from 'eventemitter2';
import { buildUrl } from 'coral-framework/utils/url';
import SnackBar from './SnackBar';
import onIntersect from './onIntersect';
import {
createStorage,
connectStorageToPym,
} from 'coral-framework/services/storage';
// Rebuild the origin if it isn't defined. This is our poor-mans polyfill
// for the location APIs.
if (!window.location.origin) {
window.location.origin = `${window.location.protocol}//${
window.location.hostname
}${window.location.port ? `:${window.location.port}` : ''}`;
}
const NOTIFICATION_OFFSET = 200;
// Ensure there is a trailing slash.
function ensureEndSlash(p) {
return p.match(/\/$/) ? p : `${p}/`;
}
// Build the URL to load in the pym iframe.
function buildStreamIframeUrl(talkBaseUrl, query) {
let url = talkBaseUrl + 'embed/stream?';
url += queryString.stringify(query);
return url;
}
// detectAssetURL will try to grab the canonical url from the head, if it isn't
// available, source the url from the current one.
function detectAssetURL() {
try {
// Try to get the url from the canonical tag on the page.
return document.querySelector('link[rel="canonical"]').href;
} catch (e) {
window.console.warn(
'This page does not include a canonical link tag. Talk has inferred this asset_url from the window object. Query params have been stripped, which may cause a single thread to be present across multiple pages.'
);
return window.location.origin + window.location.pathname;
}
}
function buildQuery({ asset_id, asset_url }) {
// Compose the query to send down to the Talk API so it knows what to load.
const query = {};
// Parse the url parameters to extract some of the information.
const search = new URLSearchParams(window.location.search);
// Pull the Comment ID out of the query string.
const commentID = search.get('commentId') || search.get('commentID');
if (commentID) {
query.comment_id = commentID;
}
// Insert the asset_id into the query.
if (asset_id) {
query.asset_id = asset_id;
}
// If the asset_url is defined, use it, otherwise, detect it.
if (asset_url) {
query.asset_url = asset_url;
} else {
query.asset_url = detectAssetURL();
}
return query;
}
// Get dimensions of viewport.
function viewportDimensions() {
let target = window;
let prefix = 'inner';
if (!('innerWidth' in window)) {
prefix = 'client';
target = document.documentElement || document.body;
}
return {
width: target[`${prefix}Width`],
height: target[`${prefix}Height`],
};
}
export default class Bridge {
constructor(
element,
{
// Pull out the URLs used to setup Talk.
talk: talkBaseUrl,
talkStaticUrl = talkBaseUrl,
// Default the following to null.
events = null,
snackBarStyles = null,
onAuthChanged = null,
// Determine if we're in lazy mode or not. By default, the build argument
// will determine the lazy render status. This default is primarily used
// when the embed code cannot be changed, but control of the Talk serving
// domain is available.
lazy = process.env.TALK_DEFAULT_LAZY_RENDER === 'TRUE',
// Any additional options are extracted to be sent to the embed via the
// pym bridge.
...opts
}
) {
this.pym = null;
this.element = element;
this.opts = opts;
this.query = buildQuery(this.opts);
this.emitter = new EventEmitter({ wildcard: true });
this.snackBar = new SnackBar(snackBarStyles || {});
this.onAuthChanged = onAuthChanged;
this.talkBaseUrl = ensureEndSlash(talkBaseUrl);
this.talkStaticUrl = ensureEndSlash(talkStaticUrl);
this.lazy = lazy;
// Store queued operations in a queue that can be processed once the stream
// is rendered.
this.queued = [];
// Attach to the events emitted by the pym parent.
if (events) {
events(this.emitter);
}
// Start the embed loading process.
if (this.lazy) {
// When the dom element containing the talk embed container is in view,
// render the stream with force turned on so that it skips this portion.
onIntersect(this.element, () => this.load());
} else {
// We aren't being lazy, load it now!
this.load();
}
}
ensureRendered() {
// Check to see if the pym bridge is created, and the embed is loaded.
if (this.pym === null) {
throw new Error('Stream Embed must be rendered first');
}
}
queueWhenRendered(callback) {
// Check to see if the queue is alive, if it isn't, run the callback now,
// otherwise, push the callback to be processed when the stream has loaded.
if (this.queued !== null) {
this.queued.push(callback);
} else {
callback();
}
}
setupPym() {
const url = buildStreamIframeUrl(this.talkBaseUrl, this.query);
this.pym = new pym.Parent(this.element.id, url, {
title: this.opts.title,
id: `${this.element.id}_iframe`,
name: `${this.element.id}_iframe`,
});
// NOTE: Workaround for iOS Safari which ignores `width` but respects `min-width` value.
this.pym.el.firstChild.style.width = '1px';
this.pym.el.firstChild.style.minWidth = '100%';
// Resize parent iframe height when child height changes
let cachedHeight;
this.pym.onMessage('height', height => {
if (height !== cachedHeight) {
this.pym.el.firstChild.style.height = `${height}px`;
cachedHeight = height;
}
});
// Send the config back over the pym bridge if requested.
this.pym.onMessage('getConfig', () => {
this.pym.sendMessage('config', JSON.stringify(this.opts));
});
// If the auth changes, and someone is listening for it, then re-emit it.
if (this.onAuthChanged) {
this.pym.onMessage('coral-auth-changed', message => {
this.onAuthChanged(message ? JSON.parse(message) : null);
});
}
// Remove the permalink comment id from the search.
this.pym.onMessage('coral-view-all-comments', () => {
const query = queryString.parse(location.search);
// Remove the commentId/commentID url param.
delete query.commentId;
delete query.commentID;
// Rebuild the search field without the commentId in it.
const search = queryString.stringify(query);
// Change the url.
window.history.replaceState(
{},
document.title,
buildUrl({ ...location, search })
);
});
// Remove the permalink comment id from the hash.
this.pym.onMessage('coral-view-comment', id => {
const search = queryString.stringify({
...queryString.parse(location.search),
commentId: id,
});
// Change the url to the permalink url.
window.history.replaceState(
{},
document.title,
buildUrl({ ...location, search })
);
});
// Helps child show notifications at the right scrollTop.
this.pym.onMessage('getPosition', () => {
const { height } = viewportDimensions();
let position = height + document.body.scrollTop;
if (position > NOTIFICATION_OFFSET) {
position = position - NOTIFICATION_OFFSET;
}
this.pym.sendMessage('position', position);
});
// When end-user clicks link in iframe, open it in parent context
this.pym.onMessage('navigate', url => {
// Open the new window, detach the opener, and focus on it.
const w = window.open(url, '_blank');
w.opener = null;
w.focus();
});
// Pass events from iframe to the event emitter.
this.pym.onMessage('event', raw => {
const { eventName, value } = JSON.parse(raw);
this.emitter.emit(eventName, value);
});
}
/**
* load will configure the pym parent if it hasn't already been, and setup the
* snackBar. If there are any queued operations, it will run them first.
*/
load() {
if (this.pym !== null) {
throw new Error('Stream Embed already rendered');
}
// Setup Pym.
this.setupPym();
// Attach the snackBar to the pym parent and to the body of the page.
this.snackBar.attach(window.document.body, this.pym);
// If the user clicks outside the embed, then tell the embed.
document.addEventListener('click', this.handleClick.bind(this), true);
// Listens to ${name}Storage requests on pym and relay it to
// ${name}Storage.
['local', 'session'].forEach(name => {
connectStorageToPym(
createStorage(`${name}Storage`),
this.pym,
`${name}Storage`
);
});
// Process any queued operations.
const queued = this.queued;
this.queued = null;
queued.forEach(callback => callback());
}
handleClick() {
this.pym.sendMessage('click');
}
enablePluginsDebug() {
this.pym.sendMessage('enablePluginsDebug');
}
disablePluginsDebug() {
this.pym.sendMessage('disablePluginsDebug');
}
login(token) {
this.pym.sendMessage('login', token);
}
logout() {
this.pym.sendMessage('logout');
}
remove() {
// Remove the event listeners.
document.removeEventListener('click', this.handleClick.bind(this));
this.emitter.removeAllListeners();
// Remove the snackbar.
this.snackBar.remove();
// Remove the pym parent.
this.pym.remove();
this.pym = null;
}
}
@@ -7,17 +7,25 @@ const DEFAULT_STYLE = {
willChange: 'transform, opacity',
transition: 'transform .35s cubic-bezier(.55,0,.1,1), opacity .35s',
pointerEvents: 'none',
padding: '12px 18px',
padding: '12px 18px 0',
color: '#fff',
borderRadius: '3px 3px 0 0',
textAlign: 'center',
borderRadius: '4px',
maxWidth: '400px',
left: '50%',
opacity: 0,
transform: 'translate(-50%, 20px)',
bottom: 0,
bottom: '20px',
boxSizing: 'border-box',
fontFamily: 'Helvetica, "Helvetica Neue", Verdana, sans-serif',
display: 'flex',
};
const CLOSE_STYLE = {
fontSize: '20px',
cursor: 'pointer',
marginLeft: '10px',
position: 'relative',
top: '-4px',
};
export default class Snackbar {
@@ -26,6 +34,20 @@ export default class Snackbar {
this.el = document.createElement('div');
this.el.id = 'coral-notif';
const closeButton = document.createElement('div');
closeButton.className = 'coral-notif-close';
for (let key in CLOSE_STYLE) {
closeButton.style[key] = CLOSE_STYLE[key];
}
closeButton.textContent = '×';
closeButton.onclick = () => this.clear();
this.snackbarText = document.createElement('div');
this.snackbarText.className = 'coral-notif-text';
this.snackbarText.style.paddingBottom = '12px';
this.el.appendChild(this.snackbarText);
this.el.appendChild(closeButton);
// Apply custom styles to the snackbar.
const style = Object.assign({}, DEFAULT_STYLE, customStyle);
for (let key in style) {
@@ -35,6 +57,7 @@ export default class Snackbar {
clear() {
this.el.style.opacity = 0;
this.el.style.pointerEvents = 'none';
}
alert(message) {
@@ -42,7 +65,7 @@ export default class Snackbar {
this.el.style.transform = 'translate(-50%, 20px)';
this.el.style.opacity = 0;
this.el.className = `coral-notif-${type}`;
this.el.textContent = text;
this.snackbarText.textContent = text;
if (this.timeout) {
clearTimeout(this.timeout);
@@ -51,10 +74,12 @@ export default class Snackbar {
this.timeout = setTimeout(() => {
this.el.style.transform = 'translate(-50%, 0)';
this.el.style.opacity = 1;
this.el.style.pointerEvents = 'auto';
this.timeout = setTimeout(() => {
this.el.style.opacity = 0;
}, 7000);
this.el.style.pointerEvents = 'none';
}, 15000);
}, 0);
}
-259
View File
@@ -1,259 +0,0 @@
/* global __webpack_public_path__ */ // eslint-disable-line no-unused-vars
import queryString from 'querystringify';
import pym from 'pym.js';
import EventEmitter from 'eventemitter2';
import { buildUrl } from 'coral-framework/utils/url';
import Snackbar from './Snackbar';
import onIntersect from './onIntersect';
import {
createStorage,
connectStorageToPym,
} from 'coral-framework/services/storage';
const NOTIFICATION_OFFSET = 200;
// Ensure there is a trailing slash.
function ensureEndSlash(p) {
return p.match(/\/$/) ? p : `${p}/`;
}
// Build the URL to load in the pym iframe.
function buildStreamIframeUrl(talkBaseUrl, query) {
let url = talkBaseUrl + 'embed/stream?';
url += queryString.stringify(query);
return url;
}
// Get dimensions of viewport.
function viewportDimensions() {
let e = window,
a = 'inner';
if (!('innerWidth' in window)) {
a = 'client';
e = document.documentElement || document.body;
}
return {
width: e[`${a}Width`],
height: e[`${a}Height`],
};
}
export default class Stream {
constructor(el, talkBaseUrl, query, config) {
this.query = query;
// Extract the non-opts opts from the object.
const {
events = null,
snackBarStyles = null,
onAuthChanged = null,
talkStaticUrl = talkBaseUrl,
...opts
} = config;
this.onAuthChanged = onAuthChanged;
this.el = el;
this.talkBaseUrl = ensureEndSlash(talkBaseUrl);
this.talkStaticUrl = ensureEndSlash(talkStaticUrl);
this.opts = opts;
this.snackBar = new Snackbar(snackBarStyles || {});
this.emitter = new EventEmitter({ wildcard: true });
// Because we're loading chunks dynamically below, we need to point to the
// static URL.
//
// The __webpack_public_path__ can be referenced:
// https://webpack.js.org/configuration/output/#output-publicpath
//
__webpack_public_path__ = this.talkStaticUrl + 'static/';
// Attach to the events emitted by the pym parent.
if (events) {
events(this.emitter);
}
if (config.lazy || process.env.TALK_DEFAULT_LAZY_RENDER === 'TRUE') {
const renderOnIntersect = () => onIntersect(this.el, () => this.render());
if (!window.IntersectionObserver) {
// Include a polyfill for the intersection observer.
import(/* webpackChunkName: "intersection-observer" */ 'intersection-observer')
.then(() => {
// Polyfill applied.
renderOnIntersect();
})
.catch(e => {
console.error(e);
// Loading polyfill failed, just render it directly.
this.render();
});
} else {
// No need for polyfill.
renderOnIntersect();
}
} else {
this.render();
}
}
assertRendered() {
if (!this.pym) {
throw new Error('Stream Embed must be rendered first');
}
}
isRendered() {
return !!this.pym;
}
render() {
if (this.pym) {
throw new Error('Stream Embed already rendered');
}
this.pym = new pym.Parent(
this.el.id,
buildStreamIframeUrl(this.talkBaseUrl, this.query),
{
title: this.opts.title,
id: `${this.el.id}_iframe`,
name: `${this.el.id}_iframe`,
}
);
// Workaround: IOS Safari ignores `width` but respects `min-width` value.
this.pym.el.firstChild.style.width = '1px';
this.pym.el.firstChild.style.minWidth = '100%';
// Resize parent iframe height when child height changes
let cachedHeight;
this.pym.onMessage('height', height => {
if (height !== cachedHeight) {
this.pym.el.firstChild.style.height = `${height}px`;
cachedHeight = height;
}
});
this.pym.onMessage('getConfig', () => {
this.pym.sendMessage('config', JSON.stringify(this.opts));
});
// If the auth changes, and someone is listening for it, then re-emit it.
if (this.onAuthChanged) {
this.pym.onMessage('coral-auth-changed', message => {
this.onAuthChanged(message ? JSON.parse(message) : null);
});
}
// Attach the snackbar to the pym parent and to the body of the page.
this.snackBar.attach(window.document.body, this.pym);
// Remove the permalink comment id from the hash.
this.pym.onMessage('coral-view-all-comments', () => {
const query = queryString.parse(location.search);
// Remove the commentId url param.
delete query.commentId;
const search = queryString.stringify(query);
const url = buildUrl({ ...location, search });
// Change the url.
window.history.replaceState({}, document.title, url);
});
// Remove the permalink comment id from the hash.
this.pym.onMessage('coral-view-comment', id => {
const search = queryString.stringify({
...queryString.parse(location.search),
commentId: id,
});
// Remove the commentId url param.
const url = buildUrl({ ...location, search });
// Change the url.
window.history.replaceState({}, document.title, url);
});
// Helps child show notifications at the right scrollTop.
this.pym.onMessage('getPosition', () => {
const { height } = viewportDimensions();
let position = height + document.body.scrollTop;
if (position > NOTIFICATION_OFFSET) {
position = position - NOTIFICATION_OFFSET;
}
this.pym.sendMessage('position', position);
});
// When end-user clicks link in iframe, open it in parent context
this.pym.onMessage('navigate', url => {
window.open(url, '_blank').focus();
});
// Pass events from iframe to the event emitter.
this.pym.onMessage('event', raw => {
const { eventName, value } = JSON.parse(raw);
this.emitter.emit(eventName, value);
});
// If the user clicks outside the embed, then tell the embed.
document.addEventListener('click', this.handleClick.bind(this), true);
// Listens to local storage requests on pym and relay it to local storage.
connectStorageToPym(
createStorage('localStorage'),
this.pym,
'localStorage'
);
// Listens to session storage requests on pym and relay it to session storage.
connectStorageToPym(
createStorage('sessionStorage'),
this.pym,
'sessionStorage'
);
}
enablePluginsDebug() {
this.assertRendered();
this.pym.sendMessage('enablePluginsDebug');
}
disablePluginsDebug() {
this.assertRendered();
this.pym.sendMessage('disablePluginsDebug');
}
login(token) {
this.assertRendered();
this.pym.sendMessage('login', token);
}
logout() {
this.assertRendered();
this.pym.sendMessage('logout');
}
remove() {
this.assertRendered();
// Remove the event listeners.
document.removeEventListener('click', this.handleClick.bind(this));
this.emitter.removeAllListeners();
// Remove the snackbar.
this.snackBar.remove();
// Remove the pym parent.
this.pym.remove();
}
handleClick() {
this.assertRendered();
this.pym.sendMessage('click');
}
}
-33
View File
@@ -1,33 +0,0 @@
export default class StreamInterface {
constructor(stream) {
this._stream = stream;
}
on(eventName, callback) {
return this._stream.emitter.on(eventName, callback);
}
off(eventName, callback) {
return this._stream.emitter.off(eventName, callback);
}
login(token) {
return this._stream.login(token);
}
logout() {
return this._stream.logout();
}
remove() {
return this._stream.remove();
}
enablePluginsDebug() {
return this._stream.enablePluginsDebug();
}
disablePluginsDebug() {
return this._stream.disablePluginsDebug();
}
}
+55 -91
View File
@@ -1,107 +1,71 @@
import URLSearchParams from 'url-search-params';
import Stream from './Stream';
import StreamInterface from './StreamInterface';
// Polyfill IntersectionObserver always, the alternative is that we have to also
// polyfill for Promise, which itself adds 1KB gziped, which means that the
// 4KB that the intersection observer really doesn't take up that much in terms
// of size.
import 'intersection-observer';
// Rebuild the origin if it isn't defined. This is our poor-mans polyfill
// for the location API's.
if (!window.location.origin) {
window.location.origin = `${window.location.protocol}//${
window.location.hostname
}${window.location.port ? `:${window.location.port}` : ''}`;
}
import Bridge from './Bridge';
import wrapBridge from './wrapBridge';
// parses the Asset URL from the config variable
function parseAssetURL() {
try {
// Try to get the url from the canonical tag on the page.
return document.querySelector('link[rel="canonical"]').href;
} catch (e) {
window.console.warn(
'This page does not include a canonical link tag. Talk has inferred this asset_url from the window object. Query params have been stripped, which may cause a single thread to be present across multiple pages.'
/**
* validateElement will throw an error when the element is not configured
* correctly or is not an HTMLElement at all.
*
* @param {HTMLElement} element the HTMLElement where the stream will be rendered
*/
function validateElement(element) {
if (!element) {
throw new Error(
'Please provide Coral.Talk.render() the HTMLElement you want to render Talk in.'
);
}
return window.location.origin + window.location.pathname;
if (typeof element !== 'object') {
throw new Error(
`Coral.Talk.render() expected HTMLElement but got ${element} (${typeof element})`
);
}
// Ensure element has an id, as pym can't directly accept the HTMLElement.
if (!element.id) {
element.id = `_${Math.random()}`;
}
}
export class Talk {
/**
* validateConfig is the configuration validation tool.
*
* @param {Object} config the configuration that will be used to setup Talk.
*/
function validateConfig(config) {
if (!config || typeof config !== 'object' || !config.talk) {
throw new Error(
'Coral.Talk.render() expected configuration with at least opts.talk as the Talk Base URL, none found'
);
}
}
export const Talk = {
/**
* Render a Talk stream
* @param {HTMLElement} element - Element to render the stream in
* @param {Object} config - Configuration options for talk
* @param {String} config.talk - Talk base URL
* @param {String} [config.title] - Title of Stream (rendered in iframe)
* @param {String} [config.asset_url] - Asset URL
* @param {String} [config.asset_id] - Asset ID
* @param {String} config.talk - URL to the Talk installation
* @param {String} [config.asset_id] - (optional) ID for the Asset
* @param {String} [config.asset_url] - (optional) URL where the Asset is located
* @param {String} [config.auth_token] - (optional) A jwt representing the session
* @param {String} [config.lazy] - (optional) If set the stream will only render lazily.
* @param {String} [config.lazy] - (optional) If set the stream will only render lazily
* @param {String} [config.talkStaticUrl] - (optional) Static URL used to serve Talk
* @return {Object}
*
* Example:
* ```
* const embed = Talk.render(document.getElementById('talkStreamEmbed'), config);
*
* // trigger a login with optional token.
* embed.login(token);
*
* // trigger a logout.
* embed.logout();
*
* // listen to events (in this case all events).
* embed.on('**', function(value) {
* console.log(this.event, value);
* });
* ```
*/
static render(element, config) {
if (!element) {
throw new Error(
'Please provide Coral.Talk.render() the HTMLElement you want to render Talk in.'
);
}
if (typeof element !== 'object') {
throw new Error(
`Coral.Talk.render() expected HTMLElement but got ${element} (${typeof element})`
);
}
if (!config || typeof config !== 'object' || !config.talk) {
throw new Error(
'Coral.Talk.render() expected configuration with at least opts.talk as the Talk Base URL, none found'
);
}
render: (element, config) => {
// Validate the element.
validateElement(element);
// Ensure el has an id, as pym can't directly accept the HTMLElement.
if (!element.id) {
element.id = `_${Math.random()}`;
}
// Validate the configuration.
validateConfig(config);
// Compose the query to send down to the Talk API so it knows what to load.
const query = {};
// Parse the url parameters to extract some of the information.
const search = new URLSearchParams(window.location.search);
// Pull the commentID out from the query params.
const commentID = search.get('commentId') || search.get('commentID');
if (commentID) {
query.comment_id = commentID;
}
// Extract the asset id from the options.
if (config.asset_id) {
query.asset_id = config.asset_id;
}
// Parse the Asset URL.
query.asset_url = config.asset_url;
if (!query.asset_url) {
query.asset_url = parseAssetURL();
}
// Create the new Stream.
const stream = new Stream(element, config.talk, query, config);
// Return the public interface for the stream.
return new StreamInterface(stream);
}
}
// Create the new Bridge, and wrap it up.
return wrapBridge(new Bridge(element, config));
},
};
+20 -10
View File
@@ -1,20 +1,30 @@
export default function onIntersect(el, callback) {
// Ensure that the intersection observer is available.
if (!IntersectionObserver) {
// tslint:disable-next-line:no-console
console.warn('IntersectionObserver not available');
window.console.warn('IntersectionObserver not available, rendering now');
callback();
return;
}
const options = {
rootMargin: '100px',
threshold: 1.0,
};
const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) {
observer.disconnect();
callback();
// Create the Intersection Observer that will wait till the embed is within
// view and will then call the callback.
const observer = new IntersectionObserver(
entries => {
if (entries[0].isIntersecting) {
// Stop receiving intersection events.
observer.disconnect();
// Fire the callback.
callback();
}
},
{
rootMargin: '100px',
threshold: 1.0,
}
}, options);
);
// Start observing the element for visibility.
observer.observe(el);
}
+31
View File
@@ -0,0 +1,31 @@
export default bridge => {
// whenRendered will call the callback when the stream has rendered (or now if
// the stream is already rendered).
const whenRendered = callback => bridge.queueWhenRendered(callback);
// onlyWhenRendered will guard the callback unless the stream is rendered.
const onlyWhenRendered = callback => {
bridge.ensureRendered();
callback();
};
// Return the limited stream interface.
return {
// Directly map the on/off from the event emitter to the stream.
on: (eventName, callback) => bridge.emitter.on(eventName, callback),
off: (eventName, callback) => bridge.emitter.off(eventName, callback),
// Queue up the login operation until the stream has been rendered.
login: token => whenRendered(() => bridge.login(token)),
// Queue up the logout operation until the stream has been rendered.
logout: () => whenRendered(() => bridge.logout()),
// Remove the stream if it's already been rendered.
remove: () => onlyWhenRendered(() => bridge.remove()),
// Queue up the plugin config until the embed has rendered.
enablePluginsDebug: () => whenRendered(() => bridge.enablePluginsDebug()),
disablePluginsDebug: () => whenRendered(() => bridge.disablePluginsDebug()),
};
};
@@ -3,6 +3,7 @@ import { createDefaultResponseFragments } from '../utils';
// fragments defined here are automatically registered.
export default {
...createDefaultResponseFragments(
'AlwaysPremodUserResponse',
'BanUsersResponse',
'ChangeUsernameResponse',
'CloseAssetResponse',
@@ -14,6 +15,7 @@ export default {
'IgnoreUserResponse',
'ModifyTagResponse',
'PostFlagResponse',
'RemoveAlwaysPremodUserResponse',
'SetCommentStatusResponse',
'SetUsernameResponse',
'SetUsernameStatusResponse',
@@ -412,6 +412,48 @@ export const withSetUsername = withMutation(
}
);
export const withAlwaysPremodUser = withMutation(
gql`
mutation AlwaysPremodUser($input: AlwaysPremodUserInput!) {
alwaysPremodUser(input: $input) {
...AlwaysPremodUserResponse
}
}
`,
{
props: ({ mutate }) => ({
alwaysPremodUser: input => {
return mutate({
variables: {
input,
},
});
},
}),
}
);
export const withRemoveAlwaysPremodUser = withMutation(
gql`
mutation RemoveAlwaysPremodUser($input: RemoveAlwaysPremodUserInput!) {
removeAlwaysPremodUser(input: $input) {
...RemoveAlwaysPremodUserResponse
}
}
`,
{
props: ({ mutate }) => ({
removeAlwaysPremodUser: input => {
return mutate({
variables: {
input,
},
});
},
}),
}
);
export const withBanUser = withMutation(
gql`
mutation BanUser($input: BanUserInput!) {
+5
View File
@@ -12,6 +12,7 @@ import 'moment/locale/da';
import 'moment/locale/de';
import 'moment/locale/es';
import 'moment/locale/fr';
import 'moment/locale/he';
import 'moment/locale/it';
import 'moment/locale/nl';
import 'moment/locale/pt-br';
@@ -23,6 +24,7 @@ import daTA from 'timeago.js/locales/da';
import deTA from 'timeago.js/locales/de';
import esTA from 'timeago.js/locales/es';
import frTA from 'timeago.js/locales/fr';
import heTA from 'timeago.js/locales/he';
import itTA from 'timeago.js/locales/it';
import nlTA from 'timeago.js/locales/nl';
import pt_BRTA from 'timeago.js/locales/pt_BR';
@@ -36,6 +38,7 @@ import da from '../../../locales/da.yml';
import de from '../../../locales/de.yml';
import es from '../../../locales/es.yml';
import fr from '../../../locales/fr.yml';
import he from '../../../locales/he.yml';
import it from '../../../locales/it.yml';
import nl_NL from '../../../locales/nl_NL.yml';
import pt_BR from '../../../locales/pt_BR.yml';
@@ -64,6 +67,7 @@ export const translations = {
...de,
...es,
...fr,
...he,
...it,
...nl_NL,
...pt_BR,
@@ -110,6 +114,7 @@ export function setupTranslations() {
ta.register('da', daTA);
ta.register('de', deTA);
ta.register('fr', frTA);
ta.register('he', heTA);
ta.register('it', itTA);
ta.register('nl_NL', nlTA);
ta.register('pt_BR', pt_BRTA);
+2 -2
View File
@@ -14,9 +14,9 @@ import {
export function createStore(reducers, middlewares = []) {
const enhancers = [applyMiddleware(...middlewares)];
if (window.devToolsExtension) {
if (window.__REDUX_DEVTOOLS_EXTENSION__) {
// we can't have the last argument of compose() be undefined
enhancers.push(window.devToolsExtension());
enhancers.push(window.__REDUX_DEVTOOLS_EXTENSION__());
}
return reduxCreateStore(combineReducers(reducers), {}, compose(...enhancers));
+9
View File
@@ -35,6 +35,15 @@ export const isBanned = user => {
return get(user, 'state.status.banned.status');
};
/**
* isAlwaysPremod
* retrieves boolean based on the user premod status
*/
export const isAlwaysPremod = user => {
return get(user, 'state.status.alwaysPremod.status');
};
/**
* isUsernameRejected
* retrieves boolean based on the username status
+10 -2
View File
@@ -16,7 +16,8 @@
text-align: center;
vertical-align: middle;
line-height: 30px;
width: 30px;
min-width: 30px;
padding: 5px;
user-select: none;
}
@@ -24,7 +25,14 @@
font-size: 1.8em;
}
.active {
.page:hover {
background-color: #ababab;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
a {
color: white;
}
}
.active, .active:hover {
background-color: #696969;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
a {
+11
View File
@@ -217,6 +217,9 @@ const CONFIG = {
// messages through the websocket to keep the socket alive.
KEEP_ALIVE: process.env.TALK_KEEP_ALIVE || '30s',
// CONCURRENCY is the number of workers that will serve traffic.
CONCURRENCY: parseInt(process.env.TALK_CONCURRENCY || '1'),
//------------------------------------------------------------------------------
// Cache configuration
//------------------------------------------------------------------------------
@@ -224,6 +227,14 @@ const CONFIG = {
CACHE_EXPIRY_COMMENT_COUNT:
process.env.TALK_CACHE_EXPIRY_COMMENT_COUNT || '1hr',
// EMBED_EXPIRY_TIME is the time that the embed will be cacheable for, sent as
// the max-age= directive on the Cache-Control header.
EMBED_EXPIRY_TIME: ms(process.env.TALK_EMBED_EXPIRY || '24hr'),
// EMBED_EXPIRY_TIME is the time that the rest of the static files will be
// cacheable for, sent as the max-age= directive on the Cache-Control header.
STATIC_EXPIRY_TIME: ms(process.env.TALK_STATIC_EXPIRY || '1w'),
//------------------------------------------------------------------------------
// Recaptcha configuration
//------------------------------------------------------------------------------
+4 -2
View File
@@ -104,8 +104,8 @@ sidebar:
children:
- title: Authentication
url: /integrating/authentication/
- title: Asset Management
url: /integrating/asset-management/
- title: CMS Integration
url: /integrating/cms-integration/
- title: Asset Scraping
url: /integrating/asset-scraping/
- title: Configuring the Comment Stream
@@ -166,6 +166,8 @@ sidebar:
url: /customizing-plugins-coral-ui/
- title: When You've Installed Talk
url: /when-youve-installed-talk/
- title: Embedding Talk in Native Mobile Apps
url: /embedding-in-native-mobile-apps/
- title: Migrating
children:
- title: Migrating from v3.x.x
+2 -1
View File
@@ -1,3 +1,4 @@
/ /talk/
/talk/reference/server/ /talk/api/server/
/talk/reference/graphql/ /talk/api/graphql/
/talk/reference/graphql/ /talk/api/graphql/
/talk/integrating/asset-management/ /talk/integrating/cms-integration/
@@ -19,3 +19,40 @@ Application servers: c4.xlarge (16 VM nginx + Talk VM machine pairs)
Mongo nodes: 3x c3.medium (large db cluster, 1 master, 2 read replicas)
If you need help with Talk performance or want custom scaling help or recommendations, let us know by logging a ticket and one of our engineers will get in touch with you: https://support.coralproject.net
## How to Scale Talk Components
### Scaling the Talk Application
In addition to scaling by adding additional app servers, Talk as a server component can flex to various roles. Depending on the desired configuration the roles can be split up to ensure high availability, and best matching to underlying host resources.
There are three components to the Talk application that can be served independently or in combination on a single thread: API Server, WebSockets, and Jobs
![ServerArchitectureDiagram](/talk/images/ServerArch.png)
In the diagram we see the difference between a Typical configuration (which just adds additional Talk application instances) vs the Split configuration where different Talk components could be spread across different machine resources to optimize infrastructure utilization.
See [Serving the Application](/talk/configuration-cli-tools/#serving-the-application)
### Scaling Redis
Redis serves as a general cache and pub/sub broker. We treat all the data stored in Redis as ephemeral, so using as a cache serves us well for Talk to synchronize expensive query caches. It also serves as our pub/sub broker for use with live updates as propagated through the GraphQL subscription system. For this reason it is not recommended to implement multiple instances of Redis.
### Scaling MongoDB
MongoDB is treated as our general store for persisted data. Talk supports the most common strategies for scaling MongoDB instances including replicas and/or sharding. Depending on your specific data use cases, refer to MongoDBs documentation for more information about scaling https://www.mongodb.com/mongodb-scale.
### Load Balancer
While this subject lives outside the Talk ecosystem, it is critical for application delivery. For websockets to work correctly, a load balancer must be selected that can support long lived connections that are required for websockets to work.
## Running Talk in Production
When you are ready to launch your production instance of Talk update your NODE_ENV environment variable from `development` to `production` mode.
Then launch talk with `yarn start` or with the command `NODE_ENV=production ./bin/cli-serve -j -w`
By default Talk will run on a single thread, but you can also run multiple Talk threads on a single application instance by setting the environment variable `TALK_CONCURRENCY`. [See Advanced Configuration](/talk/advanced-configuration/#talk-concurrency)
+5 -4
View File
@@ -29,7 +29,7 @@ permalink: /pre-launch-checklist/
- See [Authenticating with Talk](/talk/integrating/authentication/)
- [ ] Do you want to integrate Talk with your CMS to automate embedding Talk Comment Stream into your site?
- See [Asset Management](/talk/integrating/asset-management/)
- See [CMS Integration](/talk/integrating/cms-integration/)
- [ ] Do you want to use Social sign-on?
- Facebook
@@ -58,9 +58,10 @@ permalink: /pre-launch-checklist/
- Install [talk-plugin-rich-text](/talk/plugin/talk-plugin-rich-text)
- [ ] Do you want to display comment counts?
- Use the GraphQL [CommentCountQuery](https://docs.coralproject.net/talk/api/graphql/#CommentCountQuery)
- Install [talk-plugin-deep-reply-count](/talk/plugin/talk-plugin-deep-reply-count) if necessary.
- [ ] Do you want to display comment counts on your embed stream or on a homepage with dozens of articles?
- Install [talk-plugin-comment-count](https://github.com/coralproject/talk-plugin-comment-count) for summary counts on multiple articles
- Install [talk-plugin-deep-reply-count](/talk/plugin/talk-plugin-deep-reply-count) to add counts to the embed stream
- Or use the GraphQL [CommentCountQuery](https://docs.coralproject.net/talk/api/graphql/#CommentCountQuery)
- [ ] Do you want to translate Talk to a different language?
@@ -23,6 +23,10 @@ otherwise the application will fail to start.
Configure the duration for which comment counts are cached for, parsed by
[ms](https://www.npmjs.com/package/ms). (Default `1hr`)
## TALK_CONCURRENCY
This environment variable allows multiple worker processes to be spawned to handle traffic. (Default `1`)
## TALK_DEFAULT_LANG
This is a **Build Variable** and must be consumed during build. If using the
@@ -589,3 +593,13 @@ can be used to set an authorization header, or change the user agent. (Default
## TALK_SCRAPER_PROXY_URL
Sets a specific HTTP/S proxy to be used by the Asset Scraper using [https-proxy-agent](https://www.npmjs.com/package/https-proxy-agent). (Default `null`)
## TALK_ADDTL_REPLIES_ON_LOAD_MORE
This is a **Build Variable** and must be consumed during build. If using the
[Docker-onbuild](/talk/installation-from-docker/#onbuild)
image you can specify it with `--build-arg TALK_ADDTL_REPLIES_ON_LOAD_MORE=3`.
Specifies the number of replies to load for a comment when clicking "Load More".
It is defaulted quite high to sort of support "loading the rest of the replies".
(Default `999999`)
+10
View File
@@ -0,0 +1,10 @@
---
title: Embedding Talk in Native Mobile Apps
permalink: /embedding-in-native-mobile-apps/
---
When it comes mobile devices, the Talk client embed is already responsive and mobile friendly. We do not currently have plans to provide mobile SDKs, however, you can do this yourself.
One organization that has taken on the challenge of creating their own iOS native Talk client is [IGN](http://www.ign.com/). They were kind enough to share how they implemented Talk natively on their apps, which can be found [here](http://coralproject.net/wp-content/uploads/2019/01/IGNNativeComments.pdf).
If you implement Talk on your mobile apps and would like to contribute your process for others, you can add those here in our docs via a PR or post an issue on Github and we can help you.
-2
View File
@@ -11,8 +11,6 @@ To log a bug or request a feature, submit a Support ticket ([support@coralprojec
You can also request help on Github by [submitting an issue](https://github.com/coralproject/talk/issues). This also increases your chances of having someone from the community respond to help.
And you can also search our [Coral Community](https://community.coralproject.net) to see if your issue has been solved, or to get tips from the community.
## How can our dev team contribute to Talk?
We are lucky to work with newsroom dev teams and individual contributors who span the world, and come from newsrooms of all sizes. You can read our [Contribution Guide](https://github.com/coralproject/talk/blob/master/CONTRIBUTING.md) to get started, but feel free to reach out to us via Github too.
@@ -38,3 +38,6 @@ If you're using `talk-plugin-auth`:
* See if you can isolate if it's a particular group of users that are experiencing this issue, e.g. mods, admins, subscribers? Confirm they have the appropriate permissions to comment.
* Note if this is a new issue that happened after an upgrade - did you read the [migration docs](/talk/migration/3/) and the [release notes](https://github.com/coralproject/talk/releases)? This might help you resolve the issue.
* If you're still experiencing issues, log a [support ticket](mailto:support@coralproject.net) so we can help diagnose the issue
If a user has been locked out due to too many failed login attempts:
* How long does the user have to wait before they will be allowed to login? 10 mins
+5
View File
@@ -146,3 +146,8 @@
tags:
- default
- sorting
- name: talk-plugin-comment-count
description: This plugin enables adding comment counts to Talks embed or in other locations on your site.
link: https://github.com/coralproject/talk-plugin-comment-count
tags:
- counts
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

@@ -26,6 +26,9 @@ Plugins are available for the following 3rd party authentication providers:
* [Facebook](/talk/plugin/talk-plugin-facebook-auth/)
* [Google](/talk/plugin/talk-plugin-google-auth/)
_FAQ: Can I create a Twitter auth plugin?_
This is currently not possible because Talk uses passport.js which does not support Twitter's oAuth2 requirements.
## Custom Token Integration
You can integrate Talk with any authentication service to enable single sign-on
@@ -61,6 +64,9 @@ The generated JWT must contain the following claims:
- [`iss`](https://tools.ietf.org/html/rfc7519#section-4.1.1): the issuer for the token must match the value of `TALK_JWT_ISSUER`
- [`aud`](https://tools.ietf.org/html/rfc7519#section-4.1.3): the audience for the token must match the value of `TALK_JWT_AUDIENCE`
### Generate a key to sign the JWT
Optionally you can use https://github.com/coralproject/coralcert to generate a key with which to sign the JWTs and specify the secret as an environment variable.
### Push token into embed
We're assuming that your CMS is capable of authenticating a user account, or
@@ -1,23 +1,81 @@
---
title: Asset Management
permalink: /integrating/asset-management/
title: CMS Integration
permalink: /integrating/cms-integration/
---
## Embedding Comments on Your Site
Talk provides an embed script that you can drop into your site where you want a comments section to appear. By default that script dynamically generate Assets
in Talk in order to make it easier for lighter installations.
You can find the embed script inside talk under `Configure > Tech Settings > Embed Script`. It should look something like this, but with your domain in place of `<TALK_ROOT_URL>`:
```
<div id="coral_talk_stream"></div>
<script src="<TALK_ROOT_URL>/static/embed.js" async onload="
Coral.Talk.render(document.getElementById('coral_talk_stream'), {
talk: '<TALK_ROOT_URL>'
});
"></script>
```
## Triggering the Comments Section (client side, i.e. Your site)
When the embed script is triggered on your page load several things are initiated inside Talk, including fetching all comments for the specified article, establishing websocket connections for this user, and checking users session for SSO/authentication.
Instead of greedily triggering the embed to render on _EVERY PAGE LOAD_, we highly recommend implementing a _“lazy”_ rendering strategy to only render the comments section if a user wants to interact with it. This will greatly improve your initial page load performance, and will be critical to managing server resources if youre running Talk on a heavy-traffic production site.
We recommend using one of these _“lazy”_ loading strategies:
#### Scroll to Comments Section
Wait for user to scroll to the comment section before triggering the embed to render.
You can pass lazy: true to the render options, like so:
```
Coral.Talk.render(document.getElementById('container'), {
talk: 'https://my-talk-installation.com',
lazy: true,
});
```
Or you can enable lazy rendering by default on all assets using ENV variable `TALK_DEFAULT_LAZY_RENDER=TRUE`
_*Note: This feature requires Talk version 4.6.8 or greater_
#### Show Comments Button
You can hide the comments section until a user clicks button, then trigger the embed to render
This example uses jQuery to render the embed on the button's click event
```
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div id="coral_talk_stream">
<button>Show Comments</button>
</div>
<script type="text/javascript">
$('#coral_talk_stream button').on('click', function() {
$.getScript('<TALK_ROOT_URL>/static/embed.js', function() {
Coral.Talk.render(document.getElementById('coral_talk_stream'), {
talk: '<TALK_ROOT_URL>',
});
});
});
</script>
```
## Creating Assets in Talk (server side, i.e. What you need to send to Talk)
One of the most frequent questions that we get asked by organizations trying to
integrate Talk is: _How do we hook our CMS up to Talk so that articles are in
sync?_
This guide is designed to explain the steps to take your base installation of
Talk and configure it to allow only assets pushed into it from your CMS, and
keep your URL/title in sync. We won't cover here how to install the plugin, as
it is covered in our [Plugins Overview](/talk/plugins/).
### “Lazy Asset Creation
Talks provided embed script by default dynamically generates Assets in Talk based on each unique url that triggers it. The url must reference an existing Permitted Domain. If your articles/stories always have unique urls, then you will not need to modify the default behavior.
## Why do we need to create a plugin?
Assets created in this way will then be scraped to load metadata, see [Asset Scraping](/talk/integrating/asset-scraping/)
By default, Talk will use "Lazy Asset Creation" to dynamically generate Assets
in Talk in order to make it easier for lighter installations. In order to have
more strict control over this flow, we will create a plugin that will:
## Customizing the Integration with a Plugin
In order to have more strict control over the asset creation flow to allow only assets pushed into it from your CMS, and keep your URL/title in sync we will create a plugin.
We will create a plugin that will:
1. Disable "Lazy Asset Creation" by [Overriding a Resolver](#overriding-a-resolver).
2. Create Assets from our CMS by [Creating a New Asset Route](#creating-a-new-asset-route).
@@ -25,6 +83,9 @@ more strict control over this flow, we will create a plugin that will:
We will then modify our embed so that we can [Target the Asset](#target-the-asset).
This guide is designed to explain the steps to take your base installation of Talk and configure it. We won't cover here how to install the plugin, as it is covered in our [Plugins Overview](/talk/plugins/).
But first we should grab our basic plugin structure:
```sh
+67 -21
View File
@@ -3,22 +3,13 @@ title: Notifications
permalink: /integrating/notifications/
---
Talk currently supports 3 types of email notifications.
There are several plugins included with Talk that once enabled will control how and when Talk sends emails to users based on user activity. Only basic user profile notifications are enabled by default.
1. When someone replies to my comment
2. When a staff member replies to my comment
3. When my comment gets featured
Talk support 3 options for notification frequency: immediately, hourly or daily. Commenters can also opt-out of email notifications. Notifications are set to OFF by default.
Commenters cannot enable notifications until they have verified their email.
Note: Notifications are not currently supported for users that sign-up via Facebook or Google auth, or don't have an email attached to their account for any other reason.
_NOTE: Notifications are only supported for users that have an email address in Talk! If you are using authenticate via Facebook, Google, or SSO and you want to persist the users email, you will also need to enable `talk-plugin-local-auth` ([See Authentication](/talk/integrating/authentication/))_
### Configuring SMTP
You must setup SMTP to use notifications. The following ENV variables must be set:
You must setup SMTP to send email notifications. The following ENV variables must be set:
```
TALK_SMTP_FROM_ADDRESS=email@email.com
@@ -28,28 +19,74 @@ TALK_SMTP_HOST=smtp.domain.net
TALK_SMTP_PORT=2525
```
### Enabling Notifications
See our documentation on [setting env variables](/talk/advanced-configuration/#talk-smtp-from-address) for reference.
Enabling the `talk-plugin-notifications` creates a NotificationManager that creates and manages events send from the event emitter that is linked to the Graph API PubSub system.
When running Talk in production we recommend using a 3rd party mail service provider like SendGrid or MailGun.
Adding the `talk-plugin-notifications` plugin will also enable the `notifications` plugin hook. Any plugin that registers before the `talk-plugin-notifications` plugin will get picked up by.
If you are having difficulty with your SMTP settings you can add `DEBUG=talk:jobs:mailer` to your .env to see additional logs from the mailer service.
See https://github.com/coralproject/talk/blob/8b669a31c551a042f0f079d8cfc16825673eb8f0/plugins/talk-plugin-notifications-reply/index.js for an example.
All notifications require SMTP settings to be correctly configured first, then enable the corresponding plugin, and configure any settings in the Talk Admin. If SMTP is not enabled, it will log to the server console that some variables were not provided.
### Notification Categories
### Notification Types & Plugins
Talk currently supports the following Notifications options out of the box:
In addition to the core notifications included with Talk, some plugins add features that are supported by and will add additional types of email notifications. Commenters can opt-out of most email notifications, and comment activity notifications are set to OFF by default. Commenters cannot enable notifications until they have verified their email.
`talk-plugin-notifications-category-reply`
`talk-plugin-notifications-category-staff-reply`
`talk-plugin-notifications-category-featured`
You can see a list of all the plugins related to notifications by visiting:
https://docs.coralproject.net/talk/plugins-directory/?q=notifications
#### Type: User Profile Notifications (Included by Talk core)
* When user registers, sends email confirmation and verification
* When user requests password reset
* When user changes username, sends confirmation
* When a user is banned or suspended
_NOTE: Users can not opt-out of User Profile Notifications_
#### Type: GDPR Notifications (optional)
`talk-plugin-profile-data:`
* When my comment history is ready for download (only one link can be generated every 7 days, and the link is valid for 24 hours)
`talk-plugin-local-auth:`
* When user changes their email address
* When a user adds a new email address
#### Type: Comment Activity Notifications (optional)
Talk support 3 options for notification frequency for this type of notification:
* immediately
* hourly
* daily
`talk-plugin-notifications:`
* Enables notifications configuration (required for all comment activity notifications below)
`talk-plugin-notifications-category-reply:`
* When someone replies to my comment
`talk-plugin-notifications-category-staff-reply:`
* When a staff member replies to my comment
`talk-plugin-notifications-category-featured:`
* When my comment gets featured
### Notification Digests
Notification digests are enabled by enabling the corresponding plugin, otherwise comment activity notifications are sent immediately.
* `talk-plugin-notifications-digest-daily`
* `talk-plugin-notifications-digest-hourly`
Talk supports hourly and daily digests out the box, if you would like to create your own, refer to the below:
https://github.com/coralproject/talk/blob/9cc9969320dca47bb0f8f81e8d944ae4d19e548b/plugins/talk-plugin-notifications/server/connect.js#L69-L102
### Customizing Notifications
Enabling the `talk-plugin-notifications` creates a NotificationManager that creates and manages events send from the event emitter that is linked to the Graph API PubSub system. This allows the instance that received the mutation to also fire off a notification job that can be handled. It also enabels the `notifications` plugin hook. Any plugin that registers after the `talk-plugin-notifications` can export the notifications plugin to reference it.
See https://github.com/coralproject/talk/blob/8b669a31c551a042f0f079d8cfc16825673eb8f0/plugins/talk-plugin-notifications-reply/index.js for an example.
### Connect API
This exposes the `graph/connectors.js` via the `connect` hook.
@@ -67,3 +104,12 @@ See https://github.com/coralproject/talk/blob/90290cfa2de88e62f687e1ed0235ba6dfe
### Email Templates
Email templates are text based and support translations. If you would like to create a new email template, you can register it via the Connect API, see https://github.com/coralproject/talk/blob/8b669a31c551a042f0f079d8cfc16825673eb8f0/plugins/talk-plugin-notifications/server/connect.js#L12-L28###
Any email template registered with the same name as another template will replace the existing template for that type of email. _NOTE: that also means that the template data sent to each email template will __not__ change, so bear that in mind when designing templates that you may not have rich access to data._
An example of this is with the `talk-plugin-notifications-category-featured` plugin:
Notification translation is located: https://github.com/coralproject/talk/blob/dd0601a80132d2849c53ef7eaf12ff382f3920b9/plugins/talk-plugin-notifications-category-featured/translations.yml#L13
Where the template content is provided: https://github.com/coralproject/talk/blob/dd0601a80132d2849c53ef7eaf12ff382f3920b9/plugins/talk-plugin-notifications-category-featured/index.js#L79
+2 -2
View File
@@ -67,9 +67,9 @@ External plugins can be resolved by running:
This achieves two things:
1. It will traverse into local plugin folders and install their dependencies.
_Note that if the plugin is already installed and available in the
__Note that if the plugin is already installed and available in the
node_modules folder, it will not be fetched again unless there is a version
mismatch._ This will result in the project `package.json` and `yarn.lock`
mismatch.__ This will result in the project `package.json` and `yarn.lock`
files to be modified, this is normal as this ensures that repeated deployments
(with the same config) will have the same config, these changes should not be
committed to source control.
+7 -1
View File
@@ -11,7 +11,7 @@ const mergeState = (query, state) => {
}
if (status) {
const { username, banned, suspended } = status;
const { username, banned, suspended, alwaysPremod } = status;
if (typeof username !== 'undefined' && username && username.length > 0) {
query.merge({
@@ -27,6 +27,12 @@ const mergeState = (query, state) => {
});
}
if (typeof alwaysPremod !== 'undefined' && alwaysPremod !== null) {
query.merge({
'status.alwaysPremod.status': alwaysPremod,
});
}
if (typeof suspended !== 'undefined' && suspended !== null) {
if (suspended) {
query.merge({
+14
View File
@@ -10,6 +10,7 @@ const {
SET_USERNAME,
SET_USER_USERNAME_STATUS,
SET_USER_BAN_STATUS,
SET_USER_ALWAYS_PREMOD_STATUS,
SET_USER_SUSPENSION_STATUS,
UPDATE_USER_ROLES,
DELETE_OTHER_USER,
@@ -32,6 +33,13 @@ const setUserBanStatus = async (ctx, id, status = false, message = null) => {
}
};
const setUserAlwaysPremodStatus = async (ctx, id, status = false) => {
const user = await Users.setAlwaysPremodStatus(id, status, ctx.user.id);
if (user.alwaysPremod) {
ctx.pubsub.publish('userAlwaysPremod', user);
}
};
const setUserSuspensionStatus = async (
ctx,
id,
@@ -220,6 +228,7 @@ module.exports = ctx => {
setRole: () => Promise.reject(new ErrNotAuthorized()),
setUserBanStatus: () => Promise.reject(new ErrNotAuthorized()),
setUserSuspensionStatus: () => Promise.reject(new ErrNotAuthorized()),
setUserAlwaysPremodStatus: () => Promise.reject(new ErrNotAuthorized()),
setUserUsernameStatus: () => Promise.reject(new ErrNotAuthorized()),
setUsername: () => Promise.reject(new ErrNotAuthorized()),
stopIgnoringUser: () => Promise.reject(new ErrNotAuthorized()),
@@ -256,6 +265,11 @@ module.exports = ctx => {
setUserBanStatus(ctx, id, status, message);
}
if (ctx.user.can(SET_USER_ALWAYS_PREMOD_STATUS)) {
mutators.User.setUserAlwaysPremodStatus = (id, status) =>
setUserAlwaysPremodStatus(ctx, id, status);
}
if (ctx.user.can(SET_USER_SUSPENSION_STATUS)) {
mutators.User.setUserSuspensionStatus = (id, until, message) =>
setUserSuspensionStatus(ctx, id, until, message);
@@ -0,0 +1,7 @@
const { decorateUserField } = require('./util');
const AlwaysPremodStatusHistory = {};
decorateUserField(AlwaysPremodStatusHistory, 'assigned_by');
module.exports = AlwaysPremodStatusHistory;
+2
View File
@@ -3,6 +3,7 @@ const debug = require('debug')('talk:graph:resolvers');
const Action = require('./action');
const ActionSummary = require('./action_summary');
const AlwaysPremodStatusHistory = require('./always_premod_status_history');
const Asset = require('./asset');
const AssetActionSummary = require('./asset_action_summary');
const BannedStatusHistory = require('./banned_status_history');
@@ -37,6 +38,7 @@ const plugins = require('../../services/plugins');
let resolvers = {
Action,
ActionSummary,
AlwaysPremodStatusHistory,
Asset,
AssetActionSummary,
BannedStatusHistory,
+10
View File
@@ -74,6 +74,16 @@ const RootMutation = {
unbanUser: async (obj, { input: { id } }, { mutators: { User } }) => {
await User.setUserBanStatus(id, false);
},
alwaysPremodUser: async (obj, { input: { id } }, { mutators: { User } }) => {
await User.setUserAlwaysPremodStatus(id, true);
},
removeAlwaysPremodUser: async (
obj,
{ input: { id } },
{ mutators: { User } }
) => {
await User.setUserAlwaysPremodStatus(id, false);
},
ignoreUser: async (_, { id }, { mutators: { User } }) => {
await User.ignoreUser({ id });
},
+42
View File
@@ -142,6 +142,10 @@ input UserStatusInput {
# suspended will restrict the returned users to only those that are, or are not
# suspended. If not provided, no filtering will be performed.
suspended: Boolean
# alwaysPremod will restrict the returned users to only those that are, or are not
# marked as always premoderate. If not provided, no filtering will be performed.
alwaysPremod: Boolean
}
type UsernameStatusHistory {
@@ -166,6 +170,17 @@ type BannedStatus {
history: [BannedStatusHistory!]
}
type AlwaysPremodStatusHistory {
status: Boolean!
assigned_by: User
created_at: Date!
}
type AlwaysPremodStatus {
status: Boolean!
history: [AlwaysPremodStatusHistory!]
}
type SuspensionStatusHistory {
until: Date
assigned_by: User
@@ -184,6 +199,9 @@ type UserStatus {
# banned is the bool that determines if the user is banned or not.
banned: BannedStatus!
# alwaysPremod is the bool that determines if the user comments are always pushed to the premod queue or not
alwaysPremod: AlwaysPremodStatus!
# suspension is the date that the user is suspended until.
suspension: SuspensionStatus!
}
@@ -1446,6 +1464,22 @@ type UnbanUserResponse implements Response {
errors: [UserError!]
}
input AlwaysPremodUserInput {
id: ID!
}
input RemoveAlwaysPremodUserInput {
id: ID!
}
type AlwaysPremodUserResponse implements Response {
errors: [UserError!]
}
type RemoveAlwaysPremodUserResponse implements Response {
errors: [UserError!]
}
input SuspendUserInput {
id: ID!
message: String!
@@ -1545,6 +1579,14 @@ type RootMutation {
# Mutation is restricted.
unsuspendUser(input: UnsuspendUserInput!): UnsuspendUserResponse
# Sets the always premod status on a given user. Requires the `MODERATOR` role.
# Mutation is restricted.
alwaysPremodUser(input: AlwaysPremodUserInput!): AlwaysPremodUserResponse
# Sets the always premod status on a given user. Requires the `MODERATOR` role.
# Mutation is restricted.
removeAlwaysPremodUser(input: RemoveAlwaysPremodUserInput!): RemoveAlwaysPremodUserResponse
# Sets the ban status on a given user. Requires the `MODERATOR` role.
# Mutation is restricted.
banUser(input: BanUserInput!): BanUsersResponse
+1
View File
@@ -136,6 +136,7 @@ de:
code_of_conduct_summary_desc: 'Verfassen Sie eine Einleitung, die über jedem Kommentarbereich erscheint. Nützlich z.B. für Community-Richtlinien.'
include_question_here: 'Stellen Sie Ihre Frage hier:'
include_text: 'Fügen Sie Ihren Text hier ein.'
include_an_icon: 'Fügen Sie ein Icon hinzu'
moderate: Moderieren
moderation_settings: Moderations-Einstellungen
open: Öffnen
+16 -1
View File
@@ -3,6 +3,13 @@ en:
sort_comments: 'Sort Comments'
view_options: 'View Options'
already_flagged_username: 'You have already flagged this username.'
alwayspremoddialog:
are_you_sure: 'Are you sure you would like to always premoderate {0}?'
always_premod_user: 'Always premoderate user?'
cancel: Cancel
note: 'Note: {0}'
note_always_premod_user: 'Always premoderating this user will place all of their comments in the Pre-Moderate queue.'
yes_always_premod_user: 'Yes, always premoderate user'
bandialog:
are_you_sure: 'Are you sure you would like to ban {0}?'
ban_user: 'Ban User?'
@@ -64,6 +71,7 @@ en:
admin: Administrator
ads_marketing: 'This looks like an ad/marketing'
all: 'All'
always_premod: 'Always premoderated'
are_you_sure: 'Are you sure you would like to ban {0}?'
ban_user: 'Ban User?'
banned: Banned
@@ -139,6 +147,7 @@ en:
hours: Hours
code_of_conduct_summary: 'Summary of your Code of Conduct'
code_of_conduct_summary_desc: 'This message will appear above every comments stream on your site. Click here to learn more about writing a good code.'
include_an_icon: 'Include an Icon'
include_question_here: 'Write your question here:'
include_text: 'Include your text here.'
moderate: Moderate
@@ -250,7 +259,7 @@ en:
EMAIL_REQUIRED: 'An email address is required'
EMAIL_VERIFICATION_TOKEN_INVALID: 'Email verification token is invalid.'
INCORRECT_PASSWORD: 'Incorrect Password'
INVALID_ASSET_URL: 'Assert URL is invalid'
INVALID_ASSET_URL: 'Asset URL is invalid'
LOGIN_MAXIMUM_EXCEEDED: 'You have made too many unsuccessful password attempts. Please wait.'
network_error: 'Failed to connect to server. Check your internet connection and try again.'
NO_SPECIAL_CHARACTERS: 'Usernames can contain letters numbers and _ only'
@@ -381,6 +390,7 @@ en:
actions: Actions
all: all
all_streams: 'All Streams'
always_premod_user_actions: 'Always Premod User'
approve: Approve
approved: Approved
ban_user: Ban
@@ -527,6 +537,8 @@ en:
username_flags: 'flags for this username'
user_detail:
all: All
always_premod: 'Always Premod User'
always_premoded: 'Always premoderated'
ban: 'Ban User'
banned: Banned
email: Email
@@ -538,6 +550,7 @@ en:
reject_rate: 'Reject Rate'
reject_username: 'Reject Username'
rejected: Rejected
remove_always_premod: 'Remove Always Premoderate'
remove_ban: 'Remove Ban'
remove_suspension: 'Remove Suspension'
suspend: 'Suspend User'
@@ -551,12 +564,14 @@ en:
username_rejected: 'Username rejected'
user_history:
action: Action
always_premod_removed: 'Always premoderate removed'
ban_removed: 'Ban removed'
date: Date
suspended: 'Suspended, {0}'
suspension_removed: 'Suspension removed'
system: System
taken_by: 'Taken By'
user_always_premoded: 'User always premoderated'
user_banned: 'User banned'
username_status: 'Username {0}'
user_impersonating: 'This user is impersonating'
+43 -29
View File
@@ -3,26 +3,33 @@ es:
sort_comments: 'Ordenar comentarios'
view_options: 'Ver opciones'
already_flagged_username: 'Usted ya reportó a este usuario.'
bandialog:
are_you_sure: '¿Estás seguro que quieres suspender a {0}?'
ban_user: '¿Quieres suspender al Usuario?'
banned_user: 'Usuario Suspendido'
alwayspremoddialog:
are_you_sure: '¿Estás seguro que quieres pre-moderar a {0}?'
always_premod_user: '¿Pre-moderar al Usuario?'
cancel: Cancelar
email_message_ban: "Estimado/a {0},\n\nUsted o alguien con acceso a su cuenta ha violado los lineamientos de nuestra comunidad. Como consecuencia de esto, su cuenta fue bloqueada. No podrá realizar ni reportar más comentarios. Si usted piensa que esto ha sido un error, por favor contáctese con nosotros."
note: 'Nota: {0}'
note_ban_user: 'Suspender a este usuario no le va a permitir (al usuario) borrar ni editar ni comentar.'
note_reject_comment: 'Suspender a este usuario también va a colocar este comentario en la cola de Rechazados.'
notify_ban_description: 'Esto notificará al usuario por correo electrónico que fueron suspendidos de la comunidad'
notify_ban_headline: 'Notificar al usuario de la suspensión'
note_always_premod_user: 'Pre-moderar a un usuario pondrá todos sus comentarios en la fila de Pre-Moderación.'
yes_always_premod_user: 'Sí, pre-moderar al usuario.'
bandialog:
are_you_sure: '¿Estás seguro que quieres prohibir a {0}?'
ban_user: '¿Quieres prohibir al Usuario?'
banned_user: 'Usuario prohibido'
cancel: Cancelar
email_message_ban: "Estimado/a {0},\n\nUsted o alguien con acceso a su cuenta ha violado los lineamientos de nuestra comunidad. Como consecuencia de esto, su cuenta fue prohibida. No podrá realizar ni reportar más comentarios. Si usted piensa que esto ha sido un error, por favor contáctese con nosotros."
note: 'Nota: {0}'
note_ban_user: 'Prohibir a este usuario no le va a permitir (al usuario) borrar ni editar ni comentar.'
note_reject_comment: 'Prohibir a este usuario también va a colocar este comentario en la cola de Rechazados.'
notify_ban_description: 'Esto notificará al usuario por correo electrónico que fue prohibido de la comunidad'
notify_ban_headline: 'Notificar al usuario de la prohibición'
send: Enviar
write_a_message: 'Escribe un mensaje'
yes_ban_user: 'Si, suspender al usuario'
yes_ban_user: 'Si, prohibir al usuario'
bio_offensive: 'Esta biografia es ofensiva'
cancel: Cancelar
characters_remaining: 'caracteres restantes'
comment:
anon: Anónimo
ban_user: 'Usuario Suspendido'
ban_user: 'Usuario prohibido'
comment: 'Publicar un comentario'
edited: Editado
flagged: Reportado
@@ -59,23 +66,24 @@ es:
community:
account_creation_date: 'Fecha de creación de la cuenta'
active: Activa
admin: Administrator
admin: Administrador
ads_marketing: 'Esto parece ser un publicidad/acción de comercialización'
all: 'Todos'
always_premod: 'Pre-moderado'
are_you_sure: '¿Estás seguro que quieres suspender a {0}?'
ban_user: '¿Quieres suspender al Usuario?'
banned: Suspendido
banned_user: 'Usuario suspendido'
ban_user: '¿Quieres prohibir al Usuario?'
banned: Prohibido
banned_user: 'Usuario prohibido'
cancel: Cancelar
commenter: Comentarista
dont_like_username: 'No me gusta este nombre de usuario'
filter_users: 'Filtrarr usuarios'
filter_users: 'Filtrar usuarios'
filter_role: Rol
flaggedaccounts: 'Nombres de usuario reportados'
flags: Reportes
impersonating: Impersonando
loading: 'Cargando resultados'
moderator: Moderator
moderator: Moderador
newsroom_role: 'Rol en la redacción'
no_flagged_accounts: 'No hay ningún nombre de usuario reportado en este momento.'
no_results: 'No se encontraron usuarios con ese nombre o correo.'
@@ -89,7 +97,7 @@ es:
status: Estado
suspended: Suspendido
username_and_email: 'Usuario y Correo'
yes_ban_user: 'Sí, suspendan el usuario'
yes_ban_user: 'Sí, prohiban el usuario'
configure:
access_message: 'Usted debe ser un administrador para acceder a esta página. Encuentre a otro administrador y actualice los permisos de su cuenta!'
apply: Aplicar
@@ -200,8 +208,8 @@ es:
seconds_plural: segundos
email:
banned:
body: 'De acuerdo con las guías de comunidad de The Coral Project, su cuenta a sido bloqueada. No podrá hacer comentarios, reportar o entrar en contacto con nuestra comunidad.'
subject: 'Su cuenta ha sido bloqueada'
body: 'De acuerdo con las guías de comunidad de The Coral Project, su cuenta a sido prohibida. No podrá hacer comentarios, reportar o entrar en contacto con nuestra comunidad.'
subject: 'Su cuenta ha sido prohibida'
confirm:
confirm_email: 'Confirmar Correo'
has_been_requested: 'Un correo de confirmación ha sido pedido para la siguiente cuenta:'
@@ -283,7 +291,7 @@ es:
username_spam: 'Contiene spam'
framework:
banned_account_body: 'Esto significa que no puedes gustar, marcar o escribir comentarios.'
banned_account_header: 'Tu cuenta se encuentra suspendida.'
banned_account_header: 'Tu cuenta se encuentra prohibida.'
changed_name:
msg: 'El cambio en su nombre de usuario está siendo revisado por nuestro equipo de moderación.'
comment: comentario
@@ -355,9 +363,10 @@ es:
actions: Acciones
all: todos
all_streams: 'Todos los Hilos'
always_premod_user_actions: 'Siempre Pre-moderar Usuario'
approve: Aprobar
approved: Aprobado
ban_user: Bloquear
ban_user: Prohibir
billion: B
close: Cerrar
empty_queue: '¡No hay más comentarios para moderar! Tiempo para un ☕️'
@@ -486,13 +495,16 @@ es:
username_flags: 'reportes para este nombre de usuario'
user_detail:
all: Todos
ban: 'Bloquear usuario'
banned: Baneado
always_premod: 'Siempre pre-moderar usuario'
always_premoded: 'Siempre pre-moderado'
ban: 'Prohibir usuario'
banned: Prohibido
email: 'Correo electrónico'
member_since: 'Miembro desde'
reject_rate: 'Promedio de rechazo'
rejected: Rechazado
remove_ban: 'Cancelar bloqueo'
remove_always_premod: 'Cancelar siempre pre-moderar'
remove_ban: 'Cancelar prohibición'
remove_suspension: 'Cancelar suspensión'
suspend: 'Suspender usuario'
suspended: Suspendido
@@ -503,13 +515,15 @@ es:
username_rejected: 'Usuario rechazado'
user_history:
action: Acción
ban_removed: 'Bloqueo cancelado'
always_premod_removed: 'Siempre pre-moderar cancelado'
ban_removed: 'Prohibición cancelada'
date: Fecha
suspended: 'Suspendido, {0}'
suspension_removed: 'Suspensión cancelada'
system: Sistema
taken_by: 'Está en uso'
user_banned: 'Usuario bloqueado'
user_always_premoded: 'Usuario siempre pre-moderado'
user_banned: 'Usuario prohibido'
username_status: 'Nombre de usuario {0}'
user_impersonating: 'Este usuario suplanta a alguien'
user_no_comment: 'No has dejado aún ningún comentario. ¡Únete a la conversación!'
@@ -523,6 +537,6 @@ es:
verify_password: 'La contraseña debe tener por lo menos 8 caracteres'
verify_username: 'Los nombres pueden contener letras números y _'
view_conversation: 'Ver Conversación'
your_account_has_been_banned: 'Su cuenta ha sido suspendida.'
your_account_has_been_suspended: 'Su cuenta ha sido temporalmente suspendida.'
your_account_has_been_banned: 'Su cuenta ha sido prohibida.'
your_account_has_been_suspended: 'Su cuenta ha sido suspendida.'
your_username_has_been_rejected: 'Su cuenta ha sido suspendida porque tu nombre de usuario ha sido considerado no apropiado para el espacio. Para recuperar la cuenta, por favor ingresar un nuevo nombre de usuario.'
+469
View File
@@ -0,0 +1,469 @@
he:
your_account_has_been_suspended: החשבון שלך הושעה באופן זמני.
your_account_has_been_banned: החשבון שלך הורחק.
your_username_has_been_rejected: החשבון שלך הושעה מפני ששם המשתמש שלך נחשב לא הולם. כדי לשחזר את החשבון שלך, הזן שם משתמש חדש.
embed_comments_tab: תגובות
bandialog:
are_you_sure: "האם אתה בטוח שאתה רוצה לאסור {0}?"
ban_user: "חסום משתמש?"
banned_user: "משתמש מורשה"
cancel: "בטל"
note: "הערה: {0}"
note_reject_comment: "חסימת משתמש זה תציב גם תגובה זו בתור נדחה."
note_ban_user: "חסימת משתמש זה לא תאפשר לו להגיב על תגובות או לדווח עליהן."
yes_ban_user: "כן. חסום משתמש"
write_a_message: "כתוב הודעה"
send: "שלח"
notify_ban_headline: "הודע למשתמש על האיסור"
notify_ban_description: 'פעולה זו תודיע למשתמש באימייל שהם נאסרו מהקהילה'
email_message_ban: "{0},\n\nמישהו עם גישה לחשבון שלך הפר את הנחיות הקהילה שלנו. כתוצאה מכך, החשבון שלך נאסר. לא תוכל עוד להגיב, לדווח או לדווח על תגובות. אם אתה חושב שהדבר נעשה בטעות, צור קשר עם צוות הקהילה שלנו."
bio_offensive: "ביו זה פוגע"
cancel: "בטל"
confirm_email:
click_to_confirm: 'לחץ למטה כדי לאשר את כתובת האימייל שלך'
confirm: "אשר"
password_reset:
mail_sent: 'אם יש לך חשבון רשום, נשלח קישור לאיפוס סיסמה לאותו דאימייל'
set_new_password: "שנה את סיסמתך"
new_password: "סיסמה חדשה"
new_password_help: "הסיסמה חייבת להיות לפחות 8 תווים"
confirm_new_password: "תאשר סיסמא חדשה"
change_password: "שנה סיסמא"
characters_remaining: "תווים נותרים"
comment:
anon: "אנונימי"
undo_reject: "בטל"
ban_user: "חסום משתמש"
comment: "פרסם תגובה"
edited: ערוך
flagged: "מסומנת"
view_context: "הצג הקשר"
comment_box:
post: "שלח"
cancel: "בטל"
reply: "תשיב"
comment: "פרסם תגובה"
name: "שם"
comment_post_notif: "התגובה שלך פורסמה."
comment_post_notif_premod: "תודה על הפרסום. צוות הפיקוח שלנו יבחן את התגובה שלך בקרוב."
comment_post_banned_word: "התגובה שלך מכילה מילה אחת או יותר שאינן מותרות, לכן היא לא תפורסם. אם אתה סבור שהודעה זו שגויה, צור קשר עם צוות הניהול שלנו."
characters_remaining: "תווים נותרים"
comment_history_blank:
info: 'תולדות של התגובות שלך יופיעו כאן'
title: 'לא כתבת שום תגובה'
comment_offensive: "תגובה זו פוגעת"
comment_singular: תגובה
comment_plural: תגובות
comment_post_banned_word: "התגובה שלך מכילה מילה אחת או יותר שאינן מותרות, לכן היא לא תפורסם. אם אתה סבור שהודעה זו שגויה, צור קשר עם צוות הניהול שלנו."
comment_post_notif: "התגובה שלך כבר פורסמה."
comment_post_notif_premod: "תודה על הפרסום. צוות הפיקוח שלנו יבחן את התגובה שלך בקרוב."
common:
copy: 'עותק'
error: 'אירעה שגיאה.'
reply: 'תשובה'
replies: 'תשובות'
reaction: 'ריאקציה'
reactions: 'ריאקציות'
story: 'כתבה'
flagged_usernames:
notify_approved: '{0} אישר את שם המשתמש {1}'
notify_rejected: '{0} דחה את שם המשתמש {1}'
notify_flagged: '{0} דיווח על שם המשתמש {1}'
notify_changed: 'המשתמש {0} שינה את שם המשתמש שלו ל {1}'
community:
account_creation_date: "תאריך היצירה של החשבון"
active: פעיל
admin: מנהל
ads_marketing: "זה נראה כמו מודעה / שיווק"
are_you_sure: "האם אתה בטוח שברצונך לאסור {0}?"
ban_user: "חסום משתמש?"
banned: אסור
banned_user: "משתמש מורשה"
cancel: בטל
dont_like_username: "לא אוהב את שם המשתמש"
flaggedaccounts: "שמות משתמש שדווחו"
flags: דגלים
impersonating: "התחזות"
loading: "טוען תוצאות"
moderator: מנהל
newsroom_role: "תפקיד בחדר החדשות"
no_flagged_accounts: "תור שמות המשתמש המדווחים ריק כעת."
no_results: "לא נמצאו משתמשים בשם המשתמש או בכתובת האימייל הזו. הם מסתתרים!"
offensive: "פוגע"
other: אחר
people: אנשים
role: "בחר תפקיד ..."
select_status: "בחר סטטוס ..."
spam_ads: "ספאם / מודעות"
staff: "צוות"
status: סטטוס
username_and_email: 'שם משתמש ואימייל'
yes_ban_user: "כן. חסום משתמש"
commenter: "מגיב"
configure:
apply: החל
banned_word_text: "הערות המכילות מילים או ביטויים אלה (לא תלויי רישיות) יוסרו באופן אוטומטי מזרם ההערות. הקלד מילה ולחץ על Enter או על Tab כדי להוסיף. אפשר להדביק רשימה מופרדת בפסיקים."
banned_words_title: "רשימת מילים אסורות"
close: "סגור"
close_after: "סגור הערות לאחר"
close_stream: "סגור את זרם ההערות"
close_stream_configuration: "זרם תגובות זה סגור כעת. על ידי פתיחת תגובה זו זרם תגובות חדשות ניתן להגיש ולהציג"
closed_comments_desc: "כתוב הודעה שתוצג כאשר זרם ההערות שלך ייסגר ולא תקבל עוד הערות."
closed_comments_label: "כתוב הודעה ..."
closed_stream_settings: "הודעת זרם סגור"
comment_count_error: "נא הכנס מספר תקף."
comment_count_header: "הגבל אורך תגובה"
comment_count_text_post: תווים
comment_count_text_pre: "תגובות יוגבלו"
comment_settings: הגדרות
comment_stream: "זרם תגובות"
comment_stream_will_close: "זרם ההערות ייסגר"
community: קהילה
configure: הגדר
copy_and_paste: "העתק והדבק קוד למטה לתוך CMS שלך כדי להטביע את תיבת התגובה לכתבות שלך"
custom_css_url: "כתובת האתר של ה- CSS המותאם אישית שלך"
custom_css_url_desc: "כתובת אתר של גיליון סגנונות CSS שתבטל את ברירת המחדל של סגנונות 'הזרמת זרם'. יכול להיות פנימי או חיצוני."
days: ימים
description: "כמנהל, תוכל להתאים אישית את ההגדרות עבור זרם ההערות עבור הסיפור הזה:"
domain_list_text: "הזן את הדומיינים שברצונך להרשות עבור Talk. כלומר, סביבות האחסון הזמני וההפקה המקומית שלך (לדוגמה localhost: 3000, staging.domain.com, domain.com)."
domain_list_title: "דומיינים מותרים"
edit_comment_timeframe_heading: "עריכת מסגרת זמן של תגובה"
edit_comment_timeframe_text_pre: "למשתמשים יהיו"
edit_comment_timeframe_text_post: "שניות כדי לערוך את התגובות שלהם."
embed_comment_stream: "הטמע את הזרם"
enable_premod_links_text: "על המתווכים לאשר כל תגובה המכילה קישור לפני פרסומה."
enable_pre_moderation: "אפשר התנהלות מראש"
enable_pre_moderation_text: "על המנחים לאשר כל הערה לפני פרסומה."
enable_premod_links: "תגובות המכילות קישורים צריך להיות מנוהל מראש"
enable_premod: "אפשר התנהלות מראש"
enable_premod_description: "על המנחים לאשר כל הערה לפני פרסומה."
enable_premod_links_description: "על המתווכים לאשר כל תגובה המכילה קישור לפני פרסומה."
enable_questionbox: "שאל את הקוראים שאלה"
enable_questionbox_description: "שאלה זו תופיע בחלק העליון של זרם תגובות זה. לשאול את הקוראים על בעיה מסוימת במאמר או להציג שאלות דיון וכו '"
hours: שעות
include_comment_stream: "כלול תיאור בזרם תגובות עבור הקוראים"
include_comment_stream_desc: "כתוב הודעה שתופיע בחלק העליון של זרם התגובה שלך. הוסף נושא להנחיות הקהילה וכו '."
include_text: "כלול את הטקסט שלך כאן."
include_question_here: "כתוב את השאלה שלך כאן:"
moderate: מתון
moderation_settings: "הגדרות פיקוח"
open: "פתח"
open_stream: "פתח את הזרם"
open_stream_configuration: "זרם תגובות זה פתוח כעת. על ידי סגירת זרם תגובות זה לא ניתן להגיש תגובות חדשות וכל התגובות הקודמות עדיין יוצגו."
organization_contact_email: "אימייל של הארגון"
require_email_verification: 'דרוש אימות אימייל'
require_email_verification_text: 'משתמשים חדשים חייבים לאמת את האימייל שלהם לפני שתגיב'
save_changes: "שמור שינויים"
shortcuts: קיצורי דרך
sign_out: "התנתק"
stories: כתבות
stream_settings: "הגדרות זרם"
suspect_word_title: "רשימת מילים חשוד"
suspect_word_text: "תגובות שמכילות מילים או ביטויים אלה (לא תלויי רישיות) יודגשו בזרם התגובות. הקלד מילה ולחץ על Enter או על Tab כדי להוסיף. אפשר להדביק רשימה מופרדת בפסיקים."
tech_settings: "הגדרות טכנולוגיה"
title: "הגדר זרם תגובות"
weeks: שבועות
wordlist: "מילים אסורות"
continue: "המשך"
createdisplay:
check_the_form: "טופס לא חוקי. בדוק את השדות"
continue: "המשך עם אותו שם משתמש ב- Facebook"
error_create: "שגיאה בעת שינוי שם המשתמש"
fake_comment_body: "זוהי תגובה לדוגמה. הקוראים יכולים לשתף את מחשבותיהם ואת דעותיהם עם צוות החדשות בקטע התגובות."
fake_comment_date: "לפני 1 דקה"
if_you_dont_change_your_name: "אם לא תשנה את שם המשתמש שלך בשלב זה שם התצוגה שלך ב- Facebook יופיע לצד כל ההערות שלך."
required_field: "שדה נדרש"
save: שמור
special_characters: "שמות משתמש יכולים להכיל מספרי אותיות ו- _ בלבד"
username: שם משתמש
write_your_username: "ערוך את שם המשתמש שלך"
your_username: "שם המשתמש שלך מופיע בכל תגובה שתפרסם."
done: בוצע
edit_comment:
body_input_label: "ערוך תגובה זו"
save_button: "שמור שינויים"
edit_window_expired: "לא ניתן עוד לערוך את ההערה הזו. פרק הזמן לביצוע זה פג. למה לא לכתוב עוד אחד?"
edit_window_expired_close: "סגור"
edit_window_timer_prefix: "פרק זמן זה לעריכה: "
second: "שנייה"
seconds_plural: "שניות"
minute: "דקה"
minutes_plural: "דקות"
email:
suspended:
subject: "חשבונך הושעה"
banned:
subject: "החשבון שלך הורחק"
body: "בהתאם להנחיות הקהילה של פרויקט אלמוגים, החשבון שלך נאסר. כעת אתה מורשה יותר להגיב, לדגל או ליצור מעורבות עם הקהילה שלנו."
confirm:
has_been_requested: 'התבקש אישור באימייל עבור החשבון הבא:'
to_confirm: "כדי לאשר את החשבון, בקר בקישור הבא:"
confirm_email: "אשר אימייל"
if_you_did_not: 'אם לא ביקשת זאת, תוכל להתעלם בבטחה מאימייל זה.'
subject: "אישור דואר אלקטרוני"
password_reset:
we_received_a_request: "קיבלנו בקשה לאפס את הסיסמה שלך. אם לא ביקשת שינוי זה, תוכל להתעלם מהודעת אימייל זו."
if_you_did: "אם עשית,"
please_click: "לחץ כאן כדי לאפס את הסיסמה"
embedlink:
copy: "העתק ללוח"
error:
COMMENT_PARENT_NOT_VISIBLE: "התגובה שאתה משיב לה הוסרה או אינה קיימת."
EMAIL_VERIFICATION_TOKEN_INVALID: "אסימון האימייל אינו חוקי."
PASSWORD_RESET_TOKEN_INVALID: "הקישור לאיפוס הסיסמה אינו חוקי."
COMMENT_TOO_SHORT: "התגובות צריכות להיות יותר מתו אחד, אנא שנה את תגובתך ונסה שוב."
NOT_AUTHORIZED: "אינך מורשה לבצע פעולה זו."
NO_SPECIAL_CHARACTERS: "שמות משתמש יכולים להכיל מספרי אותיות ו- _ בלבד"
PASSWORD_LENGTH: "הסיסמה קצרה מדי"
PROFANITY_ERROR: "שמות משתמש לא יכולים להכיל גסות. פנה למנהל המערכת אם אתה סבור שמדובר בטעות."
RATE_LIMIT_EXCEEDED: "חרגת מגבלת התעריף"
USERNAME_IN_USE: "שם משתמש כבר בשימוש"
USERNAME_REQUIRED: "חייב להזין שם משתמש"
EMAIL_NOT_VERIFIED: "כתובת האימייל לא אומתה"
EDIT_WINDOW_ENDED: "לא ניתן עוד לערוך את התגובה הזו. פרק הזמן לביצוע זה פג."
EDIT_USERNAME_NOT_AUTHORIZED: "אין לך הרשאה לעדכן את שם המשתמש שלך."
SAME_USERNAME_PROVIDED: "עליך לשלוח שם משתמש אחר."
EMAIL_IN_USE: 'כתובת האימייל כבר בשימוש'
EMAIL_REQUIRED: 'נדרשת כתובת אימייל'
LOGIN_MAXIMUM_EXCEEDED: "עשית יותר מדי ניסיונות סיסמה לא מוצלחים. המתן בבקשה."
PASSWORD_REQUIRED: "יש להזין סיסמה"
COMMENTING_CLOSED: "התגובה כבר סגורה"
NOT_FOUND: "זרם התגובה כבר סגור"
ALREADY_EXISTS: "המשאב כבר קיים"
INVALID_ASSET_URL: "כתובת האתר של הנכס אינה חוקית"
CANNOT_IGNORE_STAFF: "לא ניתן להתעלם מחברי צוות."
email: "אימייל לא חוקי"
confirm_password: "סיסמאות אינן תואמות. אנא בדוק שוב"
network_error: "נכשל נסיון להתחבר לשרת. בדוק את חיבור האינטרנט שלך ונסה שוב."
email_not_verified: "כתובת האימייל {0} לא אומתה."
email_password: "שילוב דואר אלקטרוני ו / או סיסמה שגוי."
organization_name: "שם הארגון חייב להכיל רק אותיות או מספרים."
password: "הסיסמה צריכה להיות לפחות 8 תווים"
username: "שמות משתמש יכולים להכיל מספרי אותיות ו- _ בלבד"
unexpected: "אירעה שגיאה לא צפויה. מצטער!"
required_field: "שדה חובה"
temporarily_suspended: "החשבון שלך מושעה כעת. הוא יופעל מחדש {0}. אנא צור איתנו קשר אם יש לך שאלות."
flag_comment: "דווח על תגובה"
flag_reason: "סיבה לדיווח (אופציונלי)"
flag_username: "דווח על שם משתמש"
framework:
banned_account_header: "החשבון שלך מוחרם כעת."
banned_account_body: "פירוש הדבר שאינך אוהב, לדווח או לכתוב תגובות."
comment: תגובה
comment_is_ignored: "תגובה זו מוסתרת מפני שהתעלמת ממשתמש זה."
comment_is_rejected: "דחית את התגובה הזו."
comment_is_hidden: "תגובה זו אינה זמינה."
comments: תגובות
configure_stream: "הגדר"
content_not_available: "תוכן זה אינו זמין"
edit_name:
button: שלח
error: "שמות משתמש יכולים להכיל מספרי אותיות ו- _ בלבד"
label: "שם משתמש חדש"
msg: "החשבון שלך מושעה כרגע מפני ששם המשתמש שלך נחשב לא הולם. כדי לשחזר את החשבון שלך, הזן שם משתמש חדש. אנא צור איתנו קשר אם יש לך שאלות."
changed_name:
msg: "שינוי שם המשתמש שלך נמצא בבדיקה על ידי צוות הניהול שלנו."
my_comments: "התגובות שלי"
my_profile: "הפרופיל שלי"
new_count: "הצג {0} עוד {1}"
profile: פרופיל
show_all_comments: "הצג את כל התגובות"
success_bio_update: "הביוגרפיה שלך עודכנה"
success_name_update: "שם המשתמש שלך עודכן"
success_update_settings: "השינויים שביצעת הוחלו על זרם התגובה בכתבה זה"
show_all_replies: הצג את כל התשובות
show_more_replies: הצג תשובות נוספות
view_more_comments: "הצג תגובות נוספות"
view_reply: "הצג תשובה"
from_settings_page: "בדף הפרופיל תוכל לראות את היסטוריית התגובות שלך."
like: לייק
loading_results: "טוען תוצאות"
marketing: "זה נראה כמו מודעה / שיווק"
moderate_this_stream: "נהל את הזרם הזה"
flags:
reasons:
user:
username_offensive: "פוגע"
username_nolike: "לא אוהב"
username_impersonating: "התחזות"
username_spam: "ספאם"
username_other: "אחר"
comment:
comment_offensive: "פוגע"
comment_spam: "ספאם"
comment_noagree: "לא מסכים"
comment_other: "אחר"
suspect_word: "מילה חשודה"
banned_word: "מילה אסורה"
body_count: "גוף התגובה עולה על אורך מרבי"
trust: "אמון"
links: "קישור"
modqueue:
account: "דגלים של החשבון"
actions: פעולות
all: הכל
all_streams: "כל הזרמים"
notify_edited: '{0} ערך תגובה "{1}"'
notify_accepted: '{0} קיבל תגובה "{1}"'
notify_rejected: '{0} דחה תגובה "{1}"'
notify_flagged: '{0} דגל תגובה "{1}"'
notify_reset: '{0} אפס את סטטוס התגובה "{1}"'
approve: "אישרו"
approved: "אושר"
ban_user: "חסום"
billion: ב
close: סגור
empty_queue: "אין תגובות נוספות כדי להתמתן! כולכם תקועים. לכי וליהנות קצת ☕️"
flagged: מסומנת
reported: דיווח
less_detail: "פחות פרטים"
likes: לייקס
million: מ
mod_faster: "מתון מהר יותר עם קיצורי מקשים"
moderate: "מתון ←"
more_detail: "פרטים נוספים"
new: חדש
newest_first: "הכי חדש קודם"
navigation: ניווט
next_comment: "עבור לתגובה הבאה"
toggle_search: "פתח חיפוש"
next_queue: "הפעל תורים"
oldest_first: "הכי עתיק קודם"
premod: מתינות מראש
prev_comment: "עבור לתגובה הקודמת"
reject: "דחה"
rejected: "נדחה"
reply: "תשיב"
select_stream: "בחר זרם"
shift_key: "⇧"
shortcuts: "קיצורי דרך"
sort: "מיין"
show_shortcuts: "הצג קיצורי דרך"
singleview: "מצב זן"
thismenu: "פתח את התפריט"
jump_to_queue: "קפיצה לתור ספציפי"
thousand: k
try_these: "נסה את אלה"
view_more_shortcuts: "הצג קיצורי דרך נוספים"
my_comment_history: "ההיסטוריה של התגובות שלי"
name: שם
no_agree_comment: "אני לא מסכים עם תגובה זו"
no_like_bio: "אני לא אוהב את הביוגרפיה הזאת"
no_like_username: "אני לא אוהב את שם המשתמש הזה"
already_flagged_username: "כבר סימנת שם משתמש זה."
other: אחר
permalink: שתף
personal_info: "תגובה זו מגלה מידע המאפשר זיהוי אישי"
post: שלח
profile: פרופיל
profile_settings: "הגדרות פרופיל"
reply: תשיב
report: דווח
report_notif: "תודה שדיווחת על תגובה זו. צוות ההתייחסות שלנו קיבל הודעה על כך ויבדוק אותו בקרוב."
report_notif_remove: "הדוח שלך הוסר."
reported: דווח
settings:
from_settings_page: "בדף הפרופיל תוכל לראות את היסטוריית התגובות שלך."
my_comment_history: "ההיסטוריה של התגובות שלי"
profile: פרופיל
profile_settings: "הגדרות פרופיל"
sign_in: "היכנס"
to_access: "כדי לגשת לפרופיל"
user_no_comment: "מעולם לא השארת תגובה. הצטרף לשיחה!"
stream:
all_comments: "כל התגובות"
temporarily_suspended: "בהתאם להנחיות הקהילה {0}, חשבונך הושעה באופן זמני. חזור לשיחה {1}."
comment_not_found: "תגובה זו הוסרה או אינה קיימת."
no_comments: "עדיין אין תגובות. האם אתה רוצה לכתוב אחד?"
no_comments_and_closed: "לא היו תגובות על כתבה זה."
step_1_header: "דווח על בעיה"
step_2_header: "עזור לנו להבין"
step_3_header: "תודה על הקלט שלך"
streams:
all: הכל
article: כתבה
closed: סגור
empty_result: "אין נכסים שמתאימים לחיפוש זה. אולי לנסות להרחיב את החיפוש שלך?"
filter_streams: "סינון זרמים"
newest: החדש ביותר
oldest: הוותיק ביותר
open: פתח
pubdate: "תאריך פרסום"
search: לחפש
sort_by: "מיין לפי"
status: "מצב זרם"
stream_status: "מצב זרם"
suspenduser:
title_suspend: "להשעות משתמש"
description_suspend: "אתה משעה את {0}. תגובה זו תעבור לתור נדחה, ו- {0} לא יהיה יכול ללייק, לדווח, להשיב או לפרסם עד להשלמת זמן ההשעיה."
select_duration: "בחר משך השעיה"
one_hour: "1 שעה"
hours: "{0} שעות"
days: "{0} ימים"
cancel: "בטל"
suspend_user: "להשעות משתמש"
email_message_suspend: "{0}, \n\n בהתאם להנחיות הקהילה {1}, חשבונך הושעה באופן זמני. במהלך ההשעיה, לא תוכל להגיב, לדגל או לשתף פעולה עם מפרסמים אחרים. חזור לשיחה {2}."
title_notify: "הודע למשתמש על השעיה זמנית"
notify_suspend_until: "המשתמש {0} הושעה באופן זמני. ההשעיה הזו תסתיים באופן אוטומטי {1}."
description_notify: "השעיית משתמש זה תשבית זמנית את החשבון שלו."
write_message: "לכתוב הודעה"
send: שלח
reject_username:
username: שם משתמש
no_cancel: "אין ביטול"
description_reject: "האם אתה רוצה לאסור את המשתמש הזה באופן זמני בגלל {0} שלו? פעולה זו תשעה את המשתמש הזה באופן זמני עד שיכתבו מחדש את {0}."
title_notify: "הודע למשתמש על השעיה זמנית"
description_notify: "השעיית משתמש זה תשבית זמנית את החשבון שלו."
title_reject: "שמנו לב שדחית שם משתמש"
suspend_user: "להשעות משתמש"
yes_suspend: "כן, להשעות"
email_message_reject: 'לאחרונה חבר בקהילה שלנו סימן את שם המשתמש שלך לבדיקה. בגלל התוכן של שם המשתמש שלך, שם המשתמש שלך נדחה. פירוש הדבר שאינך יכול עוד להגיב או לסמן תוכן עד שתשנה את שם המשתמש שלך. אנא שלח לנו אימייל אם יש לך שאלות או חששות.'
write_message: "לכתוב הודעה"
send: שלח
thank_you: "אנו מעריכים את בטיחותך ומשובך. מנחה יסקור את הדוח שלך."
user:
bio_flags: "דגלים עבור ביוגרפיה זו"
user_bio: "ביוגרפיה של המשתמש"
username_flags: "דגלים עבור שם משתמש זה"
user_detail:
remove_suspension: "הסר השעיה"
suspend: "להשעות משתמש"
remove_ban: "הסרת חסימה"
ban: "לחסום משתמש"
member_since: "חבר מאז"
email: 'אימייל'
total_comments: "סך הכל תגובות"
reject_rate: "שיעור דחייה"
reports: "דיווחים"
all: "כל"
rejected: "נדחה"
account_history: "היסטוריית החשבון"
user_impersonating: "משתמש זה מתחזה"
user_no_comment: "מעולם לא השארת תגובה. הצטרף לשיחה!"
username_offensive: "שם משתמש זה פוגע"
view_conversation: "הצג שיחה"
install:
initial:
description: "בואו נגדיר את קהילת Talk שלך בכמה שלבים קצרים בלבד."
submit: "תחל"
add_organization:
description: 'ספר לנו את שם הארגון שלך. פעולה זו תופיע באימייל בעת הזמנת חברי צוות חדשים.'
label: "שם ארגון"
save: "שמור"
create:
email: 'כתובת אימייל'
username: "שם משתמש"
password: "סיסמה"
confirm_password: "אשר סיסמה"
save: "שמור"
permitted_domains:
title: "דומיינים מותרים"
description: "הזן את הדומיינים שברצונך להרשות עבור Talk. כלומר, סביבות האחסון הזמני וההפקה המקומית שלך (לדוגמה localhost: 3000, staging.domain.com, domain.com)."
submit: "סיים את ההתקנה"
final:
description: "תודה שהתקנת את Talk! שלחנו הודעת אימייל לאימות כתובת האימייל שלך. בזמן שתסיים להגדיר את החשבון, תוכל להתחיל לעסוק עם הקוראים שלך כעת."
launch: "הפעל את Talk"
close: "סגור את המתקין"
admin_sidebar:
view_options: "הצג אפשרויות"
sort_comments: "מיין תגובות"
+374 -353
View File
@@ -1,556 +1,577 @@
nl_NL:
admin_sidebar:
sort_comments: 'Sorteer reacties'
view_options: 'Bekijk opties'
already_flagged_username: 'Je hebt deze gebruikersnaam al gemeld.'
sort_comments: "Sorteer reacties"
view_options: "Bekijk opties"
already_flagged_username: "Je hebt deze gebruikersnaam al gemeld."
bandialog:
are_you_sure: 'Weet je zeker dat je {0} wil verbannen?'
ban_user: 'Gebruiker verbannen?'
banned_user: 'Verbannen gebruiker'
are_you_sure: "Weet je zeker dat je {0} wil verbannen?"
ban_user: "Gebruiker verbannen?"
banned_user: "Verbannen gebruiker"
cancel: Annuleren
email_message_ban: "Beste {0},\n\nIemand met toegang tot je account heeft onze community richtlijnen overtreden. Om die reden is je account verbannen. Je kunt niet langer reageren, of reacties goedkeuren of rapporteren. Als je denkt dat dit berust op een vergissing, neem dan contact op met ons community team."
note: 'Opmerking: {0}'
note_ban_user: 'Door deze gebruiker te verbannen kan deze geen reactie meer wijzigen of verwijderen.'
note_reject_comment: 'Door deze gebruiker te verbannen verplaats je diens reactie ook naar de lijst met afgewezen reacties.'
notify_ban_description: 'Dit stelt de gebruiker via email op de hoogte verbannen te zijn van de community'
notify_ban_headline: 'Stel gebruiker op de hoogte van verbanning'
note: "Opmerking: {0}"
note_ban_user: "Door deze gebruiker te verbannen kan deze geen reactie meer wijzigen of verwijderen."
note_reject_comment: "Door deze gebruiker te verbannen verplaats je diens reactie ook naar de lijst met afgewezen reacties."
notify_ban_description: "Dit stelt de gebruiker via e-mail op de hoogte verbannen te zijn van de community"
notify_ban_headline: "Stel gebruiker op de hoogte van verbanning"
send: Versturen
write_a_message: 'Schrijf een bericht'
yes_ban_user: 'Ja, verban gebruiker'
bio_offensive: 'Deze biografie is aanstootgevend.'
write_a_message: "Schrijf een bericht"
yes_ban_user: "Ja, verban gebruiker"
bio_offensive: "Deze biografie is aanstootgevend."
cancel: Annuleren
characters_remaining: 'tekens resterend'
characters_remaining: "tekens resterend"
comment:
anon: Anoniem
ban_user: 'Verban gebruiker'
comment: 'Plaats een reactie'
ban_user: "Verban gebruiker"
comment: "Plaats een reactie"
edited: Gewijzigd
flagged: Gemarkeerd
undo_reject: 'Ongedaan maken'
view_context: 'Bekijk context'
undo_reject: "Ongedaan maken"
view_context: "Bekijk context"
comment_box:
cancel: Annuleren
characters_remaining: 'tekens resterend'
comment: 'Plaats een reactie'
comment_post_banned_word: 'Je reactie bevat een of meerdere termen die wij niet toestaan. Neem contact op wanneer je het er niet mee eens bent.'
comment_post_notif: 'Je reactie is geplaatst'
comment_post_notif_premod: 'Dank voor je reactie! Deze wordt zo snel mogelijk gemodereerd.'
characters_remaining: "tekens resterend"
comment: "Plaats een reactie"
comment_post_banned_word: "Je reactie bevat een of meerdere termen die wij niet toestaan. Neem contact op wanneer je het er niet mee eens bent."
comment_post_notif: "Je reactie is geplaatst"
comment_post_notif_premod: "Dank voor je reactie! Deze wordt zo snel mogelijk gemodereerd."
name: Naam
post: Plaats
reply: Beantwoord
comment_history_blank:
info: 'Reacties die je hebt geplaatst zullen hier verschijnen'
title: 'Je hebt nog geen reacties geplaatst'
comment_offensive: 'Deze reactie is aanstootgevend'
info: "Reacties die je hebt geplaatst zullen hier verschijnen"
title: "Je hebt nog geen reacties geplaatst"
comment_offensive: "Deze reactie is aanstootgevend"
comment_plural: Reacties
comment_post_banned_word: 'Je reactie bevat een of meerdere termen die wij niet toestaan. Neem contact op wanneer je het er niet mee eens bent.'
comment_post_notif: 'Je reactie is geplaatst.'
comment_post_notif_premod: 'Dank voor je reactie! Deze wordt zo snel mogelijk gemodereerd.'
comment_post_banned_word: "Je reactie bevat een of meerdere termen die wij niet toestaan. Neem contact op wanneer je het er niet mee eens bent."
comment_post_notif: "Je reactie is geplaatst."
comment_post_notif_premod: "Dank voor je reactie! Deze wordt zo snel mogelijk gemodereerd."
comment_singular: Reactie
common:
contains_link: 'Bevat link'
contains_link: "Bevat link"
copy: Kopieer
copied: Gekopieerd
notsupported: 'Niet ondersteund'
error: 'Er is een fout opgetreden.'
notsupported: "Niet ondersteund"
error: "Er is een fout opgetreden."
reaction: reactie
reactions: reacties
replies: antwoorden
reply: antwoord
replies: antwoorden
story: Verhaal
community:
account_creation_date: 'Aanmaakdatum account'
account_creation_date: "Aanmaakdatum account"
active: Actief
admin: Administrator
ads_marketing: 'Dit lijkt op een advertentie/marketing'
are_you_sure: 'Weet je zeker dat je {0} wil verbannen?'
ban_user: 'Verban gebruiker?'
ads_marketing: "Dit lijkt op een advertentie/marketing"
all: "Alle"
are_you_sure: "Weet je zeker dat je {0} wil verbannen?"
ban_user: "Verban gebruiker?"
banned: Verbannen
banned_user: 'Verbannen gebruiker'
banned_user: "Verbannen gebruiker"
cancel: Annuleren
commenter: Reageerder
dont_like_username: 'Keur gebruikersnaam af'
flaggedaccounts: 'Gerapporteerde gebruikersnamen'
dont_like_username: "Keur gebruikersnaam af"
filter_users: "Filter gebruikers"
filter_role: Rol
flaggedaccounts: "Gerapporteerde gebruikersnamen"
flags: Rapporteringen
impersonating: Imitatie
loading: 'Resultaten worden geladen'
loading: "Resultaten worden geladen"
moderator: Moderator
newsroom_role: 'Newsroom rol'
no_flagged_accounts: 'De lijst met gerapporteerde gebruikers is momenteel leeg.'
no_results: 'Geen accounts gevonden met deze gebruikersnaam of e-mailadres.'
newsroom_role: "Newsroom rol"
no_flagged_accounts: "De lijst met gerapporteerde gebruikers is momenteel leeg."
no_results: "Geen accounts gevonden met deze gebruikersnaam of e-mailadres."
offensive: Aanstootgevend
other: Anders
people: Gebruikers
role: 'Selecteer rol...'
select_status: 'Selecteer status...'
role: "Selecteer rol..."
select_status: "Selecteer status..."
spam_ads: Spam/Ads
staff: Staff
status: Status
suspended: Geschorst
username_and_email: 'Gebruikersnaam en e-mailadres'
yes_ban_user: 'Ja, verban gebruiker'
username_and_email: "Gebruikersnaam en e-mailadres"
yes_ban_user: "Ja, verban gebruiker"
configure:
access_message: 'Je moet een admin zijn om toegang te krijgen tot de configuratie instellingen. Vraag de dichtsbijzijnde Admin om toegang!'
access_message: "Je moet een admin zijn om toegang te krijgen tot de configuratie instellingen. Vraag de dichtsbijzijnde Admin om toegang!"
apply: Toepassen
banned_word_text: 'Reacties die deze woorden of zinnen bevatten (niet hoofdlettergevoelig) worden automatisch uit de conversatie verwijderd. Voer een woord in, en druk op enter of Tab om toe te passen. Je kunt ook een kommagescheiden lijst plakken.'
banned_words_title: 'Lijst met verbannen woorden'
banned_word_text: "Reacties die deze woorden of zinnen bevatten (niet hoofdlettergevoelig) worden automatisch uit de conversatie verwijderd. Voer een woord in, en druk op enter of Tab om toe te passen. Je kunt ook een kommagescheiden lijst plakken."
banned_words_title: "Lijst met verbannen woorden"
close: Sluiten
close_after: 'Reacties afsluiten na'
close_stream: 'Sluit conversatie'
close_stream_configuration: 'Deze conversatie is momenteel afgesloten. Door deze te heropenen kunnen nieuwe reacties worden toegevoegd en weergegeven.'
closed_comments_desc: 'Schrijf een bericht om weer te geven wanneer de conversatie is afgesloten.'
closed_comments_label: 'Schrijf een bericht...'
closed_stream_settings: 'Afgesloten conversatie bericht'
comment_count_error: 'Voer een geldig getal in.'
comment_count_header: 'Reactielengte beperken'
close_after: "Reacties afsluiten na"
close_stream: "Sluit conversatie"
close_stream_configuration: "Deze conversatie is momenteel afgesloten. Door deze te heropenen kunnen nieuwe reacties worden toegevoegd en weergegeven."
closed_comments_desc: "Schrijf een bericht om weer te geven wanneer de conversatie is afgesloten."
closed_comments_label: "Schrijf een bericht..."
closed_stream_settings: "Afgesloten conversatie bericht"
comment_count_error: "Voer een geldig getal in."
comment_count_header: "Reactielengte beperken"
comment_count_text_post: tekens
comment_count_text_pre: 'Reacties worden ingekort op'
comment_count_text_pre: "Reacties worden ingekort op"
comment_settings: Instellingen
comment_stream: Conversatie
comment_stream_will_close: 'Deze conversatie zal worden afgesloten.'
comment_stream_will_close: "Deze conversatie zal worden afgesloten."
community: Community
configure: Instellen
copy_and_paste: 'Kopieer en plak onderstaande code om je reactie-box in je artikel op te nemen.'
custom_css_url: 'Eigen CSS URL'
custom_css_url_desc: 'URL van CSS stylesheet die de standaard Embed Conversatie stylesheet overschrijft. Kan intern of extern zijn.'
copy_and_paste: "Kopieer en plak onderstaande code om je reactie-box in je artikel op te nemen."
custom_css_url: "Eigen CSS URL"
custom_css_url_desc: "URL van CSS stylesheet die de standaard Embed Conversatie stylesheet overschrijft. Kan intern of extern zijn."
days: Dagen
description: 'Als admin kun je de instellingen aanpassen voor de conversatie bij dit verhaal:'
disable_commenting_desc: 'Schrijf een bericht dat wordt weergeven wanneer reageren is afgesloten.'
disable_commenting_title: 'Reacties afsluiten voor de gehele site'
domain_list_text: 'Voer de domeinen in die je wil toestaan voor Talk, bijvoorbeeld je staging en productie-omgevingen (bijv. localhost:3000 staging.domeinnaam.com domeinnaam.com).'
domain_list_title: 'Toegestane domeinnamen'
edit_comment_timeframe_heading: 'Wijzig reactie tijdsduur'
edit_comment_timeframe_text_post: 'secondes om hun reactie te wijzigen.'
edit_comment_timeframe_text_pre: 'Gebruikers hebben'
embed_comment_stream: 'Embed conversatie'
enable_pre_moderation: 'Pre-moderatie inschakelen'
enable_pre_moderation_text: 'Moderators moeten elke reactie goedkeuren voordat deze is gepubliceerd.'
enable_premod: 'Pre-moderatie inschakelen'
enable_premod_description: 'Moderators moeten elke reactie goedkeuren voordat deze is gepubliceerd.'
enable_premod_links: 'Pre-Modereer reacties met een link'
enable_premod_links_description: 'Moderators moeten elke reactie met een link goedkeuren voordat deze is gepubliceerd.'
enable_premod_links_text: 'Moderators moeten elke reactie met een link goedkeuren voordat deze is gepubliceerd.'
enable_questionbox: 'Stel een vraag aan de lezers'
enable_questionbox_description: 'Deze vraag zal bovenaan de conversatie verschijnen. Vraag lezers naar een probleem in het artikel, poneer discussie vragen, enzovoort.'
description: "Als admin kun je de instellingen aanpassen voor de conversatie bij dit verhaal:"
disable_commenting_desc: "Schrijf een bericht dat wordt weergeven wanneer reageren is afgesloten."
disable_commenting_title: "Reacties afsluiten voor de gehele site"
domain_list_text: "Voer de domeinen in die je wil toestaan voor Talk, bijvoorbeeld je staging en productie-omgevingen (bijv. localhost:3000 staging.domeinnaam.com domeinnaam.com)."
domain_list_title: "Toegestane domeinnamen"
edit_comment_timeframe_heading: "Wijzig reactie tijdsduur"
edit_comment_timeframe_text_post: "secondes om hun reactie te wijzigen."
edit_comment_timeframe_text_pre: "Gebruikers hebben"
edit_info: "Wijzig info"
embed_comment_stream: "Embed conversatie"
enable_pre_moderation: "Pre-moderatie inschakelen"
enable_pre_moderation_text: "Moderators moeten elke reactie goedkeuren voordat deze is gepubliceerd."
enable_premod: "Pre-moderatie inschakelen"
enable_premod_description: "Moderators moeten elke reactie goedkeuren voordat deze is gepubliceerd."
enable_premod_links: "Pre-Modereer reacties met een link"
enable_premod_links_description: "Moderators moeten elke reactie met een link goedkeuren voordat deze is gepubliceerd."
enable_premod_links_text: "Moderators moeten elke reactie met een link goedkeuren voordat deze is gepubliceerd."
enable_questionbox: "Stel een vraag aan de lezers"
enable_questionbox_description: "Deze vraag zal bovenaan de conversatie verschijnen. Vraag lezers naar een probleem in het artikel, poneer discussie vragen, enzovoort."
hours: Uren
code_of_conduct_summary: 'Neem conversatie beschrijving op voor lezers.'
code_of_conduct_summary_desc: 'Schrijf een bericht voor boven je conversatie. Poneer een stelling, wijs op de community richtlijnen, etc.'
include_question_here: 'Schrijf je vraag hier:'
include_text: 'Schrijf hier je tekst.'
code_of_conduct_summary: "Neem conversatie beschrijving op voor lezers."
code_of_conduct_summary_desc: "Schrijf een bericht voor boven je conversatie. Poneer een stelling, wijs op de community richtlijnen, etc."
include_an_icon: 'Include an Icon'
include_question_here: "Schrijf je vraag hier:"
include_text: "Schrijf hier je tekst."
moderate: Modereer
moderation_settings: 'Moderatie instellingen'
moderation_settings: "Moderatie instellingen"
open: Open
open_stream: 'Open Stream'
open_stream_configuration: 'Deze converstatie is momenteel open. Door deze te sluiten kunnen geen nieuwe reacties meer worden geplaatst, maar de oude zullen nog steeds worden weergegeven.'
organization_contact_email: 'Organisatie Contact E-mailadres'
organization_info_copy: 'We gebruiken deze informatie in e-mail notificaties die door Talk worden verstuurd. Dit verbind de berichten met je organisatie en biedt gebruikers een manier om contact op te nemen mochten ze een probleem met hun account ondervinden.'
organization_info_copy_2: 'We raden aan om een algemeen e-mail account (bijvoorbeeld community@yournewsroom.com) te gebruiken voor dit doeleinde. Dit betekent dat dit adres onveranderd kan blijven en deze geen naam blootstelt die gebruikers kunnen gebruiken mocht hun account geblokkeerd worden.'
organization_information: 'Organisatie Informatie'
organization_name: 'Organisatie Naam'
suspect_or_forbidden_words_placeholder: 'Woord of uitdrukking'
product_guide_link: 'Product Handleiding'
report_bug_or_feedback: 'Rapporteer een bug of geef feedback'
require_email_verification: 'Maak e-mail verificatie vereist'
require_email_verification_text: 'Nieuwe gebruikers moeten hun e-mailadres verifiëren voordat ze door kunnen gaan.'
save_changes: 'Wijzigingen opslaan'
open_stream: "Open Stream"
open_stream_configuration: "Deze converstatie is momenteel open. Door deze te sluiten kunnen geen nieuwe reacties meer worden geplaatst, maar de oude zullen nog steeds worden weergegeven."
organization_contact_email: "Organisatie Contact E-mailadres"
organization_info_copy: "We gebruiken deze informatie in e-mail notificaties die door Talk worden verstuurd. Dit verbind de berichten met je organisatie en biedt gebruikers een manier om contact op te nemen mochten ze een probleem met hun account ondervinden."
organization_info_copy_2: "We raden aan om een algemeen e-mail account (bijvoorbeeld community@yournewsroom.com) te gebruiken voor dit doeleinde. Dit betekent dat dit adres onveranderd kan blijven en deze geen naam blootstelt die gebruikers kunnen gebruiken mocht hun account geblokkeerd worden."
organization_information: "Organisatie Informatie"
organization_name: "Organisatie Naam"
suspect_or_forbidden_words_placeholder: "Woord of uitdrukking"
product_guide_link: "Product Handleiding"
report_bug_or_feedback: "Rapporteer een bug of geef feedback"
require_email_verification: "Maak e-mail verificatie vereist"
require_email_verification_text: "Nieuwe gebruikers moeten hun e-mailadres verifiëren voordat ze door kunnen gaan."
save: "Opslaan"
save_changes: "Wijzigingen opslaan"
save_changes_dialog:
cancel: Annuleren
copy: 'Je hebt een of meerdere wijzigingen gedaan zonder op te slaan. Wil je je wijzigingen opslaan of ongedaan maken?'
discard: 'Ongedaan maken'
save_settings: 'Instellingen Opslaan'
unsaved_changes: 'Niet-opgeslagen wijzigingen'
copy: "Je hebt een of meerdere wijzigingen gedaan zonder op te slaan. Wil je je wijzigingen opslaan of ongedaan maken?"
discard: "Ongedaan maken"
save_settings: "Instellingen Opslaan"
unsaved_changes: "Niet-opgeslagen wijzigingen"
shortcuts: Sneltoetsen
sign_out: Uitloggen
stories: Conversaties
stream_settings: 'Conversatie instellingen'
suspect_word_text: 'Reacties die deze woorden of zinsdelen bevatten (niet hoofdlettergevoelig) zullen worden gemarkeerd in de conversatie. Type een woord en druk op enter of tab om toe te voegen. Je kunt optioneel een komma-gescheiden lijst plakken.'
suspect_word_title: 'Lijst met verdachte woorden'
tech_settings: 'Technische instellingen'
title: 'Conversatie configureren'
stream_settings: "Conversatie instellingen"
suspect_word_text: "Reacties die deze woorden of zinsdelen bevatten (niet hoofdlettergevoelig) zullen worden gemarkeerd in de conversatie. Type een woord en druk op enter of tab om toe te voegen. Je kunt optioneel een komma-gescheiden lijst plakken."
suspect_word_title: "Lijst met verdachte woorden"
tech_settings: "Technische instellingen"
title: "Conversatie configureren"
view_last_version: "Bekijk meest recente versie"
weeks: Weken
wordlist: 'Zwarte woordenlijst'
wordlist: "Zwarte woordenlijst"
confirm_email:
click_to_confirm: 'Klik hieronder om je e-mailadres te bevestigen.'
click_to_confirm: "Klik hieronder om je e-mailadres te bevestigen."
confirm: Bevestig
email_confirmation: "E-mailadres bevestiging"
continue: Doorgaan
createdisplay:
check_the_form: 'Ongeldig formulier. Kijk de invoer na.'
continue: 'Doorgaan met dezelfde Facebook gebruikersnaam'
error_create: 'Fout bij het wijzigen van de gebruikersnaam'
fake_comment_body: 'Dit is een voorbeeld reactie. Lezers kunnen hun gedachten en meningen delen met de Newsrooms in de reactie-sectie.'
fake_comment_date: '1 minuut geleden'
if_you_dont_change_your_name: 'Wanneer je gebruikersnaam niet verandert, zal je Facebook gebruikersnaam verschijnen bij al je reacties.'
required_field: 'Verplicht veld'
check_the_form: "Ongeldig formulier. Kijk de invoer na."
continue: "Doorgaan met dezelfde Facebook gebruikersnaam"
error_create: "Fout bij het wijzigen van de gebruikersnaam"
fake_comment_body: "Dit is een voorbeeld reactie. Lezers kunnen hun gedachten en meningen delen met de Newsrooms in de reactie-sectie."
fake_comment_date: "1 minuut geleden"
if_you_dont_change_your_name: "Wanneer je gebruikersnaam niet verandert, zal je Facebook gebruikersnaam verschijnen bij al je reacties."
required_field: "Verplicht veld"
save: Opslaan
special_characters: 'Gebruikersnamen kunnen alleen cijfers, letters en _ bevatten.'
special_characters: "Gebruikersnamen kunnen alleen cijfers, letters en _ bevatten."
username: Gebruikersnaam
write_your_username: 'Wijzig je gebruikersnaam'
your_username: 'Je gebruikersnaam verschijnt bij elke reactie die je plaatst.'
write_your_username: "Wijzig je gebruikersnaam"
your_username: "Je gebruikersnaam verschijnt bij elke reactie die je plaatst."
done: Klaar
edit_comment:
body_input_label: 'Wijzig deze reactie'
edit_window_expired: 'Je kunt deze reactie niet meer wijzigen. De tijdsduur hiervoor is verstreken.'
body_input_label: "Wijzig deze reactie"
edit_window_expired: "Je kunt deze reactie niet meer wijzigen. De tijdsduur hiervoor is verstreken."
edit_window_expired_close: Sluiten
edit_window_timer_prefix: 'Wijzig venster: '
edit_window_timer_prefix: "Wijzig venster: "
minute: minuut
minutes_plural: minuten
save_button: 'Wijzigingen opslaan'
save_button: "Wijzigingen opslaan"
second: seconde
seconds_plural: secondes
email:
banned:
body: 'In lijn met The Coral Project''s community richtlijnen is je account verbannen. Je kunt niet langer reageren, rapporteren of interacteren met onze community.'
subject: 'Je account is verbannen.'
body: "In lijn met The Coral Project's community richtlijnen is je account verbannen. Je kunt niet langer reageren, rapporteren of interacteren met onze community."
subject: "Je account is verbannen."
confirm:
confirm_email: 'Bevestig e-mail'
has_been_requested: 'Een e-mail bevestiging is aangevraagd voor het volgend account:'
if_you_did_not: 'Wanneer jij dit niet hebt aangevraagd, kun je deze e-mail negeren.'
subject: 'Email bevestiging'
to_confirm: 'Ga naar de volgende link om het account te bevestigen:'
confirm_email: "Bevestig e-mail"
has_been_requested: "Een e-mail bevestiging is aangevraagd voor het volgend account:"
if_you_did_not: "Wanneer jij dit niet hebt aangevraagd, kun je deze e-mail negeren."
subject: "Email bevestiging"
to_confirm: "Ga naar de volgende link om het account te bevestigen:"
password_change:
body: 'Het wachtwoord voor je account is gewijzigd.\n\nAls je deze wijziging niet hebt aangevraagd, neem dan contact met ons op: {0}'
subject: '{0} wachtwoord wijziging'
subject: "{0} wachtwoord wijziging"
password_reset:
if_you_did: 'Wanneer je dit zelf was,'
please_click: 'klik dan hier om je wachtwoord te veranderen'
we_received_a_request: 'We hebben een verzoek gekregen om je wachtwoord opnieuw in te stellen. Wanneer je dit niet zelf was, kun je deze mail negeren.'
if_you_did: "Wanneer je dit zelf was,"
please_click: "klik dan hier om je wachtwoord te veranderen"
subject: 'Wachtwoord veranderen'
we_received_a_request: "We hebben een verzoek gekregen om je wachtwoord opnieuw in te stellen. Wanneer je dit niet zelf was, kun je deze mail negeren."
suspended:
subject: 'Je account is tijdelijk geschorst.'
subject: "Je account is tijdelijk geschorst."
embed_comments_tab: Reacties
embedlink:
copy: 'Kopieer naar klembord'
copy: "Kopieer naar klembord"
copied: Gekopieerd
error:
ALREADY_EXISTS: 'Bron bestaat al'
AUTHENTICATION: 'Er is een fout opgetreden tijdens het aanmelden van je account'
CANNOT_IGNORE_STAFF: 'Kan geen Staff-leden negeren.'
COMMENT_PARENT_NOT_VISIBLE: 'De reactie waarop je probeert te reageren bestaat niet of is inmiddels verwijderd.'
COMMENT_TOO_SHORT: 'Reacties moeten meer dan één teken hebben. Herzie je reactie en probeer opnieuw.'
COMMENT_TOO_LONG: 'Tekst is te lang'
COMMENTING_CLOSED: 'Reageren is al afgesloten.'
COMMENTING_DISABLED: 'Reageren is momenteel uigeschakeld op deze site'
confirm_password: 'Wachtwoorden komen niet overeen. Controleer opnieuw.'
DELETION_NOT_SCHEDULED: 'Verwijdering was niet ingepland'
EDIT_USERNAME_NOT_AUTHORIZED: 'Je bent niet gemachtigd om je gebruikersnaam te wijzigen.'
EDIT_WINDOW_ENDED: 'Dit commentaar kan niet langer worden gewijzigd. Het tijdsbestek is verstreken.'
email: 'Geen geldig e-mailadres'
EMAIL_ALREADY_VERIFIED: 'E-mailadres is reeds geverifiëerd'
EMAIL_IN_USE: 'E-mailadres al in gebruik'
email_not_verified: 'E-mailadres {0} is niet geverifiëerd'
EMAIL_NOT_VERIFIED: 'E-mailadres is niet geverifiëerd'
email_password: 'E-mail en/of wachtwoord combinatie onjuist'
EMAIL_REQUIRED: 'Een e-mailadres is vereist'
EMAIL_VERIFICATION_TOKEN_INVALID: 'Ongeldig e-mail verificatie token'
INCORRECT_PASSWORD: 'Ongeldig wachtwoord'
INVALID_ASSET_URL: 'Ongeldige URL'
LOGIN_MAXIMUM_EXCEEDED: 'Je hebt te veel mislukte inlogpogingen gedaan. Even geduld aub.'
network_error: 'Kon geen verbinding maken met server. Controleer je internetverbinding en probeer het opnieuw.'
NO_SPECIAL_CHARACTERS: 'Gebruikersnamen kunnen alleen cijfers, letters en _ bevatten.'
NOT_AUTHORIZED: 'Je bent niet geauthoriseerd om dit te doen.'
NOT_FOUND: 'Bron niet gevonden'
organization_contact_email: 'Organisatie e-mailadres is niet geldig.'
organization_name: 'Organisatienaam kan alleen cijfers en letters bevatten.'
password: 'Wachtwoord moet minimaal 8 karakters lang zijn'
PAGE_NOT_AVAILABLE_ROLE: 'Deze pagina is enkel voor toegankelijk voor teamleden. Neem contact op met een admin als je toegang tot dit team wilt.'
PASSWORD_INCORRECT: 'Je huidige wachtwoord is incorrect ingevuld'
PASSWORD_LENGTH: 'Wachtwoord is te kort'
PASSWORD_REQUIRED: 'Je moet een wachtwoord invoeren.'
PASSWORD_RESET_TOKEN_INVALID: 'Je wachtwoord-herstel token is ongeldig.'
PROFANITY_ERROR: 'Gebruikersnamen mogen niet aanstootgevend zijn. Neem contact op met de administrator wanneer je denkt dat dit niet klopt.'
RATE_LIMIT_EXCEEDED: 'Gebruikslimiet overschreden'
required_field: 'Dit veld is verplicht'
SAME_USERNAME_PROVIDED: 'Je moet een andere gebruikersnaam invoeren.'
temporarily_suspended: 'Je account is momenteel geschorst. Deze zal worden gereactiveerd {0}. Neem s.v.p. contact met ons op voor vragen.'
unexpected: 'Onverwachte fout opgetreden. Sorry!'
username: 'Gebruikersnamen kunnen alleen cijfers, letters en _ bevatten.'
USERNAME_IN_USE: 'Gebruikersnaam al in gebruik'
USERNAME_REQUIRED: 'Gebruikersnaam is vereist'
flag_comment: 'Rapporteer reactie'
flag_reason: 'Reden voor rapporteren (optioneel)'
ALREADY_EXISTS: "Bron bestaat al"
AUTHENTICATION: "Er is een fout opgetreden tijdens het aanmelden van je account"
CANNOT_IGNORE_STAFF: "Kan geen Staff-leden negeren."
COMMENT_PARENT_NOT_VISIBLE: "De reactie waarop je probeert te reageren bestaat niet of is inmiddels verwijderd."
COMMENT_TOO_SHORT: "Reacties moeten meer dan één teken hebben. Herzie je reactie en probeer opnieuw."
COMMENT_TOO_LONG: "Tekst is te lang"
COMMENTING_CLOSED: "Reageren is al afgesloten."
COMMENTING_DISABLED: "Reageren is momenteel uigeschakeld op deze site"
confirm_password: "Wachtwoorden komen niet overeen. Controleer opnieuw."
DELETION_NOT_SCHEDULED: "Verwijdering was niet ingepland"
EDIT_USERNAME_NOT_AUTHORIZED: "Je bent niet gemachtigd om je gebruikersnaam te wijzigen."
EDIT_WINDOW_ENDED: "Dit commentaar kan niet langer worden gewijzigd. Het tijdsbestek is verstreken."
email: "Geen geldig e-mailadres"
EMAIL_ALREADY_VERIFIED: "E-mailadres is reeds geverifiëerd"
EMAIL_IN_USE: "E-mailadres al in gebruik"
email_not_verified: "E-mailadres {0} is niet geverifiëerd"
EMAIL_NOT_VERIFIED: "E-mailadres is niet geverifiëerd"
email_password: "E-mail en/of wachtwoord combinatie onjuist"
EMAIL_REQUIRED: "Een e-mailadres is vereist"
EMAIL_VERIFICATION_TOKEN_INVALID: "Ongeldig e-mail verificatie token"
INCORRECT_PASSWORD: "Ongeldig wachtwoord"
INVALID_ASSET_URL: "Ongeldige URL"
LOGIN_MAXIMUM_EXCEEDED: "Je hebt te veel mislukte inlogpogingen gedaan. Even geduld aub."
network_error: "Kon geen verbinding maken met server. Controleer je internetverbinding en probeer het opnieuw."
NO_SPECIAL_CHARACTERS: "Gebruikersnamen kunnen alleen cijfers, letters en _ bevatten."
NOT_AUTHORIZED: "Je bent niet geauthoriseerd om dit te doen."
NOT_FOUND: "Bron niet gevonden"
organization_contact_email: "Organisatie e-mailadres is niet geldig."
organization_name: "Organisatienaam kan alleen cijfers en letters bevatten."
password: "Wachtwoord moet minimaal 8 karakters lang zijn"
PAGE_NOT_AVAILABLE_ROLE: "Deze pagina is enkel voor toegankelijk voor teamleden. Neem contact op met een admin als je toegang tot dit team wilt."
PASSWORD_INCORRECT: "Je huidige wachtwoord is incorrect ingevuld"
PASSWORD_LENGTH: "Wachtwoord is te kort"
PASSWORD_REQUIRED: "Je moet een wachtwoord invoeren."
PASSWORD_RESET_TOKEN_INVALID: "Je wachtwoord-herstel token is ongeldig."
PROFANITY_ERROR: "Gebruikersnamen mogen niet aanstootgevend zijn. Neem contact op met de administrator wanneer je denkt dat dit niet klopt."
RATE_LIMIT_EXCEEDED: "Gebruikslimiet overschreden"
required_field: "Dit veld is verplicht"
SAME_USERNAME_PROVIDED: "Je moet een andere gebruikersnaam invoeren."
temporarily_suspended: "Je account is momenteel geschorst. Deze zal worden gereactiveerd {0}. Neem s.v.p. contact met ons op voor vragen."
unexpected: "Onverwachte fout opgetreden. Sorry!"
username: "Gebruikersnamen kunnen alleen cijfers, letters en _ bevatten."
USERNAME_IN_USE: "Gebruikersnaam al in gebruik"
USERNAME_REQUIRED: "Gebruikersnaam is vereist"
flag_comment: "Rapporteer reactie"
flag_reason: "Reden voor rapporteren (optioneel)"
flag_reasons:
username:
impersonating: 'Deze gebruiker doet zich voor als iemand anders'
nolike: 'Ik vind deze gebruikersnaam niet leuk'
offensive: 'Deze gebruikersnaam is aanstootgevend'
impersonating: "Deze gebruiker doet zich voor als iemand anders"
nolike: "Ik vind deze gebruikersnaam niet leuk"
offensive: "Deze gebruikersnaam is aanstootgevend"
other: Andere
spam: 'Dit lijkt op een advertentie/marketing'
flag_username: 'Rapporteer gebruikersnaam'
spam: "Dit lijkt op een advertentie/marketing"
flag_username: "Rapporteer gebruikersnaam"
flagged_usernames:
notify_approved: '{0} heeft gebruikersnaam {1} goedgekeurd'
notify_changed: 'gebruiker {0} heeft zijn/haar gebruikersnaam veranderd naar {1}'
notify_flagged: '{0} heeft gebruikersnaam {1} gerapporteerd'
notify_rejected: '{0} heeft gebruikersnaam {1} afgekeurd'
notify_approved: "{0} heeft gebruikersnaam {1} goedgekeurd"
notify_changed: "gebruiker {0} heeft zijn/haar gebruikersnaam veranderd naar {1}"
notify_flagged: "{0} heeft gebruikersnaam {1} gerapporteerd"
notify_rejected: "{0} heeft gebruikersnaam {1} afgekeurd"
flags:
reasons:
comment:
banned_word: 'Geblokeerd woord'
comment_noagree: 'Niet eens'
banned_word: "Geblokeerd woord"
comment_noagree: "Niet eens"
comment_offensive: Aanstootgevend
comment_other: Anders
comment_spam: Spam
links: Link
suspect_word: 'Verdacht woord'
suspect_word: "Verdacht woord"
trust: Karma
user:
username_impersonating: Impersonatie
username_nolike: 'Niet leuk'
username_nolike: "Niet leuk"
username_offensive: Aanstootgevend
username_other: Anders
username_spam: Spam
framework:
banned_account_body: 'Dit betekent dat je niet kunt reageren, liken of rapporteren.'
banned_account_header: 'Je account is momenteel verbannen.'
banned_account_body: "Dit betekent dat je niet kunt reageren, liken of rapporteren."
banned_account_header: "Je account is momenteel verbannen."
changed_name:
msg: 'De verandering van je gebruikersnaam wordt door ons moderatieteam gecontroleerd.'
msg: "De verandering van je gebruikersnaam wordt door ons moderatieteam gecontroleerd."
comment: reactie
comment_is_deleted: 'De reageerder heeft zijn account verwijderd.'
comment_is_hidden: 'Deze reactie is niet beschikbaar.'
comment_is_ignored: 'Deze reactie is verborgen omdat je de gebruiker negeert.'
comment_is_rejected: 'Je hebt deze reactie afgewezen.'
comment_is_deleted: "De reageerder heeft zijn account verwijderd."
comment_is_hidden: "Deze reactie is niet beschikbaar."
comment_is_ignored: "Deze reactie is verborgen omdat je de gebruiker negeert."
comment_is_rejected: "Je hebt deze reactie afgewezen."
comments: reacties
configure_stream: Configureren
content_not_available: 'Deze inhoud is niet beschikbaar'
content_not_available: "Deze inhoud is niet beschikbaar"
edit: Wijzig
edit_name:
button: Versturen
error: 'Gebruikersnamen kunnen alleen cijfers, letters en _ bevatten.'
label: 'Nieuwe gebruikersnaam'
msg: 'Je account is momenteel geschorst omdat je gebruikersnaam ongepast is bevonden. Om je account te herstellen, moet je je gebruikersnaam herstellen. Neem contact met ons op wanneer je vragen hebt.'
my_comments: 'Mijn reacties'
my_profile: 'Mijn profiel'
new_count: 'Bekijk {0} meer {1}'
error: "Gebruikersnamen kunnen alleen cijfers, letters en _ bevatten."
label: "Nieuwe gebruikersnaam"
msg: "Je account is momenteel geschorst omdat je gebruikersnaam ongepast is bevonden. Om je account te herstellen, moet je je gebruikersnaam herstellen. Neem contact met ons op wanneer je vragen hebt."
my_comments: "Mijn reacties"
my_profile: "Mijn profiel"
new_count: "Bekijk {0} meer {1}"
profile: Profiel
show_all_comments: 'Toon alle reacties'
show_all_replies: 'Toon alle reacties'
show_more_replies: 'Toon meer reacties'
success_bio_update: 'Je biografie is bijgewerkt.'
success_name_update: 'Je gebruikersnaam is bijgewerkt.'
success_update_settings: 'De conversatie is aangepast.'
view_more_comments: 'Bekijk meer reacties'
view_reply: 'Bekijk reactie'
from_settings_page: 'Vanuit de profielpagina kun je je reactiegeschiedenis bekijken.'
show_all_comments: "Toon alle reacties"
show_all_replies: "Toon alle reacties"
show_more_replies: "Toon meer reacties"
success_bio_update: "Je biografie is bijgewerkt."
success_name_update: "Je gebruikersnaam is bijgewerkt."
success_update_settings: "De conversatie is aangepast."
view_more_comments: "Bekijk meer reacties"
view_reply: "Bekijk reactie"
from_settings_page: "Vanuit de profielpagina kun je je reactiegeschiedenis bekijken."
install:
add_organization:
description: 'Vertel ons de naam van je organisatie. Deze zal te zien zijn in e-mails wanneer je nieuwe teamleden uitnodigt.'
description: "Vertel ons de naam van je organisatie. Deze zal te zien zijn in e-mails wanneer je nieuwe teamleden uitnodigt."
label: Organisatienaam
save: Opslaan
create:
confirm_password: 'Bevestig wachtwoord'
confirm_password: "Bevestig wachtwoord"
email: E-mailadres
organization_contact_email: "Organisatie Contact E-mailadres"
password: Wachtwoord
save: Opslaan
username: Gebruikersnaam
final:
close: 'Installatie afsluiten'
description: 'Dank voor het installeren van Talk! We hebben een bericht gestuurd om je e-mailadres te valideren. Terwijl je je account verder opzet, kun je alvast de interactie aangaan met je gebruikers.'
launch: 'Start Talk'
close: "Installatie afsluiten"
description: "Dank voor het installeren van Talk! We hebben een bericht gestuurd om je e-mailadres te valideren. Terwijl je je account verder opzet, kun je alvast de interactie aangaan met je gebruikers."
launch: "Start Talk"
initial:
description: 'Laten we je Talk-community opzetten met een paar simpele stappen.'
description: "Laten we je Talk-community opzetten met een paar simpele stappen."
submit: Begin
permitted_domains:
description: 'Voer de domeinen in die je wil toestaan voor Talk, bijvoorbeeld je staging en productie-omgevingen (bijv. localhost:3000 staging.domeinnaam.com domeinnaam.com)'
submit: 'Installatie afronden'
title: 'Toegestane domeinnamen'
description: "Voer de domeinen in die je wil toestaan voor Talk, bijvoorbeeld je staging en productie-omgevingen (bijv. localhost:3000 staging.domeinnaam.com domeinnaam.com)"
submit: "Installatie afronden"
title: "Toegestane domeinnamen"
like: Like
loading_results: 'Resultaten worden geladen'
loading_results: "Resultaten worden geladen"
login:
email_address: E-mailadres
forgot_password: 'Wachtwoord vergeten?'
go_back: 'Ga terug'
forgot_password: "Wachtwoord vergeten?"
go_back: "Ga terug"
sign_in: Inloggen
sign_in_button: Inloggen
sign_in_message: 'Log in om te communiceren met je community'
sign_in_message: "Log in om te communiceren met je community"
password: Wachtwoord
reset_password_send_button: 'Wachtwoord ophalen'
request_passowrd: 'Vraag een nieuwe aan.'
team_sign_in: 'Team login'
marketing: 'Dit lijkt op een advertentie/marketing'
moderate_this_stream: 'Modereer deze conversatie'
reset_password_send_button: "Wachtwoord ophalen"
request_passowrd: "Vraag een nieuwe aan."
team_sign_in: "Team login"
marketing: "Dit lijkt op een advertentie/marketing"
moderate_all_streams: "Modereer reacties op alle artikelen"
moderate_this_stream: "Modereer deze conversatie"
modqueue:
account: 'account meldingen'
account: "account meldingen"
actions: Acties
all: Alle
all_streams: 'Alle conversaties'
all_streams: "Alle conversaties"
approve: Goedkeuren
approved: Goedgekeurd
ban_user: Verban
ban_user_actions: "Verban gebruiker"
billion: G
close: Sluiten
empty_queue: 'Geen reacties meer te beoordelen!'
empty_queue: "Geen reacties meer te beoordelen!"
flagged: gemeld
jump_to_queue: 'Spring naar specifieke wachtrij'
less_detail: 'Minder detail'
jump_to_queue: "Spring naar specifieke wachtrij"
less_detail: "Minder detail"
likes: likes
million: M
mod_faster: 'Beoordeel sneller met sneltoetsen'
moderate: 'Beoordeel →'
more_detail: 'Meer detail'
mod_faster: "Beoordeel sneller met sneltoetsen"
moderate: "Beoordeel →"
more_detail: "Meer detail"
navigation: Navigatie
new: Nieuw
newest_first: 'Nieuwste eerst'
next_comment: 'Ga naar de volgende reactie'
next_queue: 'Verander wachtrij'
newest_first: "Nieuwste eerst"
next_comment: "Ga naar de volgende reactie"
next_queue: "Verander wachtrij"
notify_accepted: '{0} accepteerde reactie "{1}"'
notify_edited: '{0} wijzigde reactie "{1}"'
notify_flagged: '{0} heeft reactie "{1}" gerapporteerd'
notify_rejected: '{0} heeft reactie "{1}" afgewezen'
notify_reset: '{0} heeft de status van reactie "{1}" hersteld'
oldest_first: 'Oudste eerst'
oldest_first: "Oudste eerst"
premod: Pre-moderatie
prev_comment: 'Ga naar de vorige reactie'
reject: 'Wijs af'
prev_comment: "Ga naar de vorige reactie"
reject: "Wijs af"
rejected: Afgewezen
reply: Beantwoord
reported: gerapporteerd
select_stream: 'Selecteer conversatie'
select_stream: "Selecteer conversatie"
shift_key:
shortcuts: Sneltoetsen
show_shortcuts: 'Toon sneltoetsen'
show_shortcuts: "Toon sneltoetsen"
singleview: Zen-modus
sort: Sorteer
suspend: 'Schors gebruiker'
system_withheld: 'Achtergehouden door systeem'
thismenu: 'Open dit menu'
suspend: "Schors gebruiker"
system_withheld: "Achtergehouden door systeem"
thismenu: "Open dit menu"
thousand: k
toggle_search: 'Open zoekvenster'
try_these: 'Probeer deze'
view_more_shortcuts: 'Bekijk meer sneltoetsen'
my_comment_history: 'Mijn reactie geschiedenis'
toggle_search: "Open zoekvenster"
try_these: "Probeer deze"
view_more_shortcuts: "Bekijk meer sneltoetsen"
my_comment_history: "Mijn reactie geschiedenis"
name: Naam
no_agree_comment: 'Ik ben het niet eens met deze reactie'
no_like_bio: 'Ik vind deze biografie niet leuk'
no_like_username: 'Ik vind deze gebruikersnaam niet leuk'
no_agree_comment: "Ik ben het niet eens met deze reactie"
no_like_bio: "Ik vind deze biografie niet leuk"
no_like_username: "Ik vind deze gebruikersnaam niet leuk"
other: Ander
password_reset:
change_password: 'Verander wachtwoord'
change_password_help: 'Voer een nieuw wachtwoord in om mee in te loggen. Gebruik een veilig wachtwoord!'
confirm_new_password: 'Bevestig nieuw wachtwoord'
new_password: 'Nieuw wachtwoord'
new_password_help: 'Wachtwoord moet minimaal 8 karakters lang zijn.'
set_new_password: 'Verander je wachtwoord'
change_password: "Verander wachtwoord"
change_password_help: "Voer een nieuw wachtwoord in om mee in te loggen. Gebruik een veilig wachtwoord!"
confirm_new_password: "Bevestig nieuw wachtwoord"
mail_sent: "Wanneer je een account geregistreerd hebt, is er een wachtwoord-herstel link gestuurd naar dat e-mailadres"
new_password: "Nieuw wachtwoord"
new_password_help: "Wachtwoord moet minimaal 8 karakters lang zijn."
set_new_password: "Verander je wachtwoord"
permalink: Deel
personal_info: 'Deze reactie onthult persoonlijk identificeerbare gegevens.'
personal_info: "Deze reactie onthult persoonlijk identificeerbare gegevens."
post: Plaats
profile: Profiel
profile_settings: Instellingen
reject_username:
description_notify: 'Door de schorsing zal deze tijdelijk diens account niet kunnen gebruiken.'
description_reject: 'Wil je deze gebruiker tijdelijk schorsen om diens {0}? Dan wordt de gebruiker geschorst totdat deze diens {0} heeft herschreven.'
email_message_reject: 'Iemand anders uit de community heeft je gebruikersnaam gemeld ter controle. Vanwege de inhoud van je gebruikersnaam is je account geschorst. Dit betekent dat je niet langer kunt reageen, liken of inhoud melden totdat je je gebruikersnaam hebt veranderd. Stuur ons een e-mail wanneer je vragen of zorgen hebt.'
no_cancel: 'Geen annuleringsmogelijkheid'
description_notify: "Door de schorsing zal deze tijdelijk diens account niet kunnen gebruiken."
description_reject: "Wil je deze gebruiker tijdelijk schorsen om diens {0}? Dan wordt de gebruiker geschorst totdat deze diens {0} heeft herschreven."
email_message_reject: "Iemand anders uit de community heeft je gebruikersnaam gemeld ter controle. Vanwege de inhoud van je gebruikersnaam is je account geschorst. Dit betekent dat je niet langer kunt reageen, liken of inhoud melden totdat je je gebruikersnaam hebt veranderd. Stuur ons een e-mail wanneer je vragen of zorgen hebt."
no_cancel: "Geen annuleringsmogelijkheid"
send: Verstuur
suspend_user: 'Schors gebruiker'
title_notify: 'Breng de gebruiker op de hoogte van de schorsing.'
title_reject: 'We zagen dat je een gebruikersnaam hebt afgewezen'
suspend_user: "Schors gebruiker"
title_notify: "Breng de gebruiker op de hoogte van de schorsing."
title_reject: "We zagen dat je een gebruikersnaam hebt afgewezen"
username: gebruikersnaam
write_message: 'Schrijf een bericht'
yes_suspend: 'Ja, schors'
write_message: "Schrijf een bericht"
yes_suspend: "Ja, schors"
reject_username_dialog:
cancel: Annuleren
description: 'Help ons dit te begrijpen'
message: 'Reden voor rapporteren (Optioneel)'
description: "Help ons dit te begrijpen"
message: "Reden voor rapporteren (Optioneel)"
reason: Reden
reject_username: 'Gebruikersnaam afwijzen'
title: 'Gebruikersnaam afwijzen'
reject_username: "Gebruikersnaam afwijzen"
title: "Gebruikersnaam afwijzen"
reply: Beantwoord
report: Rapporteer
report_notif: 'Dank voor het rapporteren van deze reactie. Deze wordt zo snel mogelijk gemodereerd.'
report_notif_remove: 'Je melding is verwijderd.'
report_notif: "Dank voor het rapporteren van deze reactie. Deze wordt zo snel mogelijk gemodereerd."
report_notif_remove: "Je melding is verwijderd."
reported: Gerapporteerd
settings:
from_settings_page: 'Op je profielpagina kun je je reactie-geschiedenis zien.'
my_comment_history: 'Mijn reactie geschiedenis'
from_settings_page: "Op je profielpagina kun je je reactie-geschiedenis zien."
my_comment_history: "Mijn reactie geschiedenis"
profile: Profiel
profile_settings: 'Profiel instellingen'
profile_settings: "Profiel instellingen"
sign_in: Inloggen
to_access: 'om profiel te benaderen'
user_no_comment: 'Je hebt nog niet eerder gereageerd.'
step_1_header: 'Rapporteer een issue'
step_2_header: 'Help ons begrijpen'
step_3_header: 'Dankjewel voor je input'
to_access: "om profiel te benaderen"
user_no_comment: "Je hebt nog niet eerder gereageerd."
step_1_header: "Rapporteer een issue"
step_2_header: "Help ons begrijpen"
step_3_header: "Dankjewel voor je input"
stream:
all_comments: 'Alle reacties'
comment_not_found: 'Deze opmerking is verwijderd of bestaat niet.'
no_comments: 'Er zijn nog geen reacties. Schrijf er zelf eentje!'
no_comments_and_closed: 'Er waren geen reacties op dit artikel.'
temporarily_suspended: 'In overeenstemming met de community richtlijnen van {0} is je account tijdelijk geschorst. Keer terug naar de conversaties {1}.'
all_comments: "Alle reacties"
comment_not_found: "Deze opmerking is verwijderd of bestaat niet."
no_comments: "Er zijn nog geen reacties. Schrijf er zelf eentje!"
no_comments_and_closed: "Er waren geen reacties op dit artikel."
temporarily_suspended: "In overeenstemming met de community richtlijnen van {0} is je account tijdelijk geschorst. Keer terug naar de conversaties {1}."
streams:
all: Alle
article: Artikel
closed: Gesloten
empty_result: 'Niets gevonden bij deze zoekopdracht. Misschien moet je je zoekopdracht proberen te verbreden?'
filter_streams: 'Filter conversaties'
empty_result: "Niets gevonden bij deze zoekopdracht. Misschien moet je je zoekopdracht proberen te verbreden?"
filter_streams: "Filter conversaties"
most_recent_stories: "Meest recente artikelen"
newest: Nieuwste
no_results: "Geen resultaten"
oldest: Oudste
open: Open
pubdate: 'Publicatie datum'
pubdate: "Publicatie datum"
search: Zoeken
sort_by: 'Sorteer op'
status: 'Conversatie status'
stream_status: 'Conversatie status'
search_results: "Zoekresultaten"
sort_by: "Sorteer op"
status: "Conversatie status"
stream_status: "Conversatie status"
suspenduser:
cancel: Annuleren
days: '{0} dagen'
description_notify: 'Wanneer je de gebruiker schorst zal zijn/haar account tijdelijk worden uitgeschakeld.'
description_suspend: 'Je schorst {0}. Deze reactie wordt afgewezen, en {0} zal niet meer kunnen liken, rapporteren of reageren totdat de schorsingsduur verstreken is.'
day: "{0} days"
days: "{0} dagen"
description_notify: "Wanneer je de gebruiker schorst zal zijn/haar account tijdelijk worden uitgeschakeld."
description_suspend: "Je schorst {0}. Deze reactie wordt afgewezen, en {0} zal niet meer kunnen liken, rapporteren of reageren totdat de schorsingsduur verstreken is."
email_message_suspend: "Beste {0},\n\nIn overeenstemming met de community richtlijnen van {1} is je account tijdelijk geschorst. Tijdens deze schorsing kun je niet reageren, liken of interacteren met je collega-reageerders. Hervat het gesprek {2}."
hours: '{0} uur'
notify_suspend_until: 'Gebruiker {0} is tijdelijk geschorst. Deze schorsing houdt automatisch op {1}.'
one_hour: '1 uur'
select_duration: 'Selecteer schorsingsduur'
hour: "{0} hours"
hours: "{0} uur"
notify_suspend_until: "Gebruiker {0} is tijdelijk geschorst. Deze schorsing houdt automatisch op {1}."
one_hour: "1 uur"
select_duration: "Selecteer schorsingsduur"
send: Verstuur
suspend_user: 'Schors gebruiker'
title_notify: 'Breng de gebruiker op de hoogte van de schorsing.'
title_suspend: 'Schors gebruiker'
write_message: 'Schrijf een bericht'
thank_you: 'We waarderen je feedback. Een moderator zal je rapport bekijken.'
suspend_user: "Schors gebruiker"
title_notify: "Breng de gebruiker op de hoogte van de schorsing."
title_suspend: "Schors gebruiker"
write_message: "Schrijf een bericht"
thank_you: "We waarderen je feedback. Een moderator zal je rapport bekijken."
user:
bio_flags: 'Meldingen voor deze biografie'
user_bio: 'Gebruikers biografie'
username_flags: 'Meldingen voor deze gebruikersnaam'
bio_flags: "Meldingen voor deze biografie"
user_bio: "Gebruikers biografie"
username_flags: "Meldingen voor deze gebruikersnaam"
user_detail:
all: Alle
ban: 'Gebruiker verbannen'
ban: "Gebruiker verbannen"
banned: "Verbannen"
email: E-mailadres
id: ID
karma: Karma
karma_docs_link: 'https://docs.coralproject.net/talk/trust/#user-karma-score'
learn_more: 'Meer informatie'
member_since: 'Lid sinds'
reject_rate: 'Beoordeling verwijderen'
reject_username: 'Gebruikersnaam afwijzen'
karma_docs_link: "https://docs.coralproject.net/talk/trust/#user-karma-score"
learn_more: "Meer informatie"
member_since: "Lid sinds"
reject_rate: "Beoordeling verwijderen"
reject_username: "Gebruikersnaam afwijzen"
rejected: Afgewezen
remove_ban: 'Verbanning verwijderen'
remove_suspension: 'Schorsing opheffen'
suspend: 'Gebruiker schorsen'
remove_ban: "Verbanning verwijderen"
remove_suspension: "Schorsing opheffen"
suspend: "Gebruiker schorsen"
suspended: Geschorst
total_comments: 'Totaal aantal reacties'
total_comments: "Totaal aantal reacties"
unreliable: Onbetrouwbaar
user_history: Accountgeschiedenis
user_karma_score: 'Gebruiker Karma Score'
user_karma_score: "Gebruiker Karma Score"
username: Gebruikersnaam
username_needs_approval: 'Gebruikersnaam heeft goedkeuring nodig'
username_rejected: 'Gebruikersnaam afgewezen'
username_needs_approval: "Gebruikersnaam heeft goedkeuring nodig"
username_rejected: "Gebruikersnaam afgewezen"
user_history:
action: Actie
ban_removed: 'Schorsing opgeheven'
ban_removed: "Schorsing opgeheven"
date: Datum
suspended: 'Geschorst, {0}'
suspension_removed: 'Schorsing opgeheven'
suspended: "Geschorst, {0}"
suspension_removed: "Schorsing opgeheven"
system: Systeem
taken_by: 'Genomen door'
user_banned: 'Gebruiker geschorst'
username_status: 'Gebruikersnaam {0}'
user_impersonating: 'Deze gebruiker doet zich voor als iemand anders'
user_no_comment: 'Je hebt nog niet eerder gereageerd. Laat je mening horen!'
username_offensive: 'Dit is een aanstootgevende gebruikersnaam.'
taken_by: "Genomen door"
user_banned: "Gebruiker geschorst"
username_status: "Gebruikersnaam {0}"
user_impersonating: "Deze gebruiker doet zich voor als iemand anders"
user_no_comment: "Je hebt nog niet eerder gereageerd. Laat je mening horen!"
username_offensive: "Dit is een aanstootgevende gebruikersnaam."
validators:
confirm_email: 'E-mailadressen komen niet overeen. Controleer opnieuw.'
confirm_email: "E-mailadressen komen niet overeen. Controleer opnieuw."
confirm_password: Wachtwoorden komen niet overeen. Controleer opnieuw.
required: 'Dit veld is verplicht'
verify_email: 'Geen geldig e-mailadres'
verify_organization_name: 'Organisatienaam kan alleen cijfers en letters bevatten.'
verify_password: 'Wachtwoord moet minimaal 8 karakters lang zijn'
verify_username: 'Gebruikersnamen kunnen alleen cijfers, letters en _ bevatten.'
view_conversation: 'Bekijk conversatie'
your_account_has_been_banned: 'Je account is verbannen.'
your_account_has_been_suspended: 'Je account is tijdelijk geschorst.'
your_username_has_been_rejected: 'Je account is geschorst omdat we je gebruikersnaam ongepast vinden. Verander je gebruikersnaam om hem weer te activeren.'
required: "Dit veld is verplicht"
verify_email: "Geen geldig e-mailadres"
verify_organization_name: "Organisatienaam kan alleen cijfers en letters bevatten."
verify_password: "Wachtwoord moet minimaal 8 karakters lang zijn"
verify_username: "Gebruikersnamen kunnen alleen cijfers, letters en _ bevatten."
view_conversation: "Bekijk conversatie"
your_account_has_been_banned: "Je account is verbannen."
your_account_has_been_suspended: "Je account is tijdelijk geschorst."
your_username_has_been_rejected: "Je account is geschorst omdat we je gebruikersnaam ongepast vinden. Verander je gebruikersnaam om hem weer te activeren."
+576
View File
@@ -0,0 +1,576 @@
sr:
admin_sidebar:
sort_comments: 'Sortiranje komentara'
view_options: 'Opcije pregleda'
already_flagged_username: 'Već ste obilježili ovog korisnika'
bandialog:
are_you_sure: 'Jeste li sigurni da želite da banujete {0}?'
ban_user: 'Banuj korisnika'
banned_user: 'Banovan korisnik'
cancel: 'Otkaži'
email_message_ban: 'Poštovani {0},\n\nneko sa pristupom vašem nalogu je prekršio pravila komentarisanja. Zbog toga smo bili primorani da banujemo vaš nalog i više nećete moći da komentarišete, reagujete i prijavljujete komentare. Ukoliko smatrate da je došlo do greške, molim vas da kontaktirate naš tim'
note: 'Napomena: {0}'
note_ban_user: 'Banovanje ovog korisnika će onemogućiti komentarisanje, prijavljivanje i reagovanje na komentare.'
note_reject_comment: 'Banovanje ovog korisnika će staviti ovaj komentar na listu odbijeno'
notify_ban_description: 'Ovo će obavijestit korisnika putem e-maila da je njegov/njen nalog banovan'
notify_ban_headline: 'Obavijesti korisnika o banovanju'
send: 'Pošalji'
write_a_message: 'Napiši poruku'
yes_ban_user: 'Banuj koriniska'
bio_offensive: 'Ova biografija je neprimjerenog sadržaja.'
cancel: 'Otkaži'
characters_remaining: 'Preostali znakovi'
comment:
anon: 'Anoniman'
ban_user: 'Banuj korisnika'
comment: 'Postavi komentar'
edited: 'Izmijenjeno'
flagged: 'Obilježeno'
undo_reject: 'Prethodni korak'
view_context: 'Vidi kontekst'
comment_box:
cancel: 'Otkaži'
characters_remaining: 'Preostali znakovi'
comment: 'Postavi komentar'
comment_post_banned_word: 'Vaš komentar sadrži jednu ili više riječi koje nisu dozvoljene i neće biti objavljen. Ukoliko smatrate nije tako, molim vas kontaktirajte naš tim moderatora.'
comment_post_notif: 'Vaš komentar je postavljen'
comment_post_notif_premod: 'Hvala na objavi. Naš tim moderatora će ubrzo pregledati vaš komentar'
name: 'Ime'
post: 'Objava'
reply: 'Odgovori'
comment_history_blank:
info: 'Istorija vaših komentara će se prikazati ovdje'
title: 'Niste postavili nijedan komentar'
comment_offensive: 'Neprimjereno'
comment_plural: 'Komentari'
comment_post_banned_word: 'Vaš komentar sadrži jednu ili više riječi koje nisu dozvoljene i neće biti objavljen. Ukoliko smatrate nije tako, molim vas kontaktirajte naš tim moderatora.'
comment_post_notif: 'Vaš komentar je postavljen'
comment_post_notif_premod: 'Hvala na objavi. Naš tim moderatora će ubrzo pregledati vaš komentar'
comment_singular: 'Komentar'
common:
contains_link: 'Sadrži link'
copy: 'Kopiraj na tablu'
copied: 'Kopirano'
notsupported: 'Nije podržano'
error: 'Došlo je do greške'
reaction: 'Reakcija'
reactions: 'Reakcije'
reply: 'Odgovori'
replies: 'Odgovori'
story: 'Priča'
community:
account_creation_date: 'Datum kreiranja naloga'
active: 'Aktivan'
admin: 'Administrator'
ads_marketing: 'Ovo izgleda kao reklama'
all: 'Sve'
are_you_sure: 'Jeste li sigurni da želite da banujete {0}?'
ban_user: 'Banuj korisnika'
banned: 'Banovan'
banned_user: 'Banovan korisnik'
cancel: 'Otkaži'
commenter: 'Komentator'
dont_like_username: 'Ne sviđa mi se korisničko ime'
filter_users: 'Segmentiraj korisnike'
filter_role: 'Uloga'
flaggedaccounts: 'Prijavljena korisnička imena'
flags: 'Prijave'
impersonating: 'Korisnik se lažno predstavlja'
loading: 'Učitavanje rezultata'
moderator: 'Moderator'
newsroom_role: 'Uloga u redakciji'
no_flagged_accounts: 'Nema prijavljenih korisničkih naloga'
no_results: 'Nema rezultata'
offensive: 'Korisničko ime je neprimjereno'
other: 'Drugo'
people: 'Ljudi'
role: 'Izaberi ulogu'
select_status: 'Izaberi status'
spam_ads: 'Reklame'
staff: 'Član redakcije'
status: 'Status rasprave'
suspended: 'Suspendovan'
username_and_email: 'Korisničko ime i e-mail'
yes_ban_user: 'Banuj koriniska'
configure:
access_message: 'Morate biti administrator kako biste pristupili podešavanjima. Zamolite administratora da vam da tu ulogu'
apply: 'Primijeni'
banned_word_text: 'Komentari koji sadrže ove riječi ili fraze (a nijesu osjetljivi na veličinu slova) automatski će biti uklonjeni iz komentara. Unesite riječ i pritisnite Enter ili Tab da dodate. Opciono stavite listu sa odvojenu zarezima'
banned_words_title: 'Lista zabranjenih riječi'
close: 'Zatvori instalaciju'
close_after: 'Zatvori komentare poslije'
close_stream: 'Zatvori raspravu'
close_stream_configuration: 'Ova rasprava je trenutno zatvorena. Otvaranjem ove rasprave novi komentari mogu biti postavljani i prikazivani'
closed_comments_desc: 'Napišite poruku koja će se prikazati kada zatvorite vašu raspravu i kada ne prihvatate dalje komentare.'
closed_comments_label: 'Napiši poruku'
closed_stream_settings: 'Poruka za zatvaranje rasprave'
comment_count_error: 'Unesite validan broj'
comment_count_header: 'Ograniči dužinu komentara'
comment_count_text_post: 'Karakteri'
comment_count_text_pre: 'Komentari će biti ograničeni na'
comment_settings: 'Podešavanja'
comment_stream: 'Rasprava'
comment_stream_will_close: 'Rasprava će se zatvoriti'
community: 'Zajednica'
configure: 'Podesite'
copy_and_paste: 'Kopirajte i zalijepite ispod u CMS'
custom_css_url: 'Prilagođen CSS URL'
custom_css_url_desc: 'URL od CSS-a koji će da prepravi standardni stil ugrađivanja. Može biti interni ili eksterni?'
days: 'Dani'
description: 'Hvala što ste instalirali Talk! Poslali smo vam e-mail kako biste povrdili vašu e-mail adresu. Dok završavate podešavanje naloga, možete početi da komunicirate sa čitaocima.'
disable_commenting_desc: 'Napišite poruku koja će se prikazivati kada su komentari deaktivirani.'
disable_commenting_title: 'Deaktiviraj komentare na čitavom sajtu'
domain_list_text: 'Unesite domene koje biste želeli da dozvolite za Talk npr. vaše lokalno okruženje za postavljanje i proizvodnju (npr. localhost 3000 staging.domain.com domain.com)?'
domain_list_title: 'Dozvoljeni domeni'
edit_comment_timeframe_heading: 'Uredi vremenski okvir komentara'
edit_comment_timeframe_text_post: 'Sekunde za uređenje njihovih komentara'
edit_comment_timeframe_text_pre: 'Komentatori će imati'
edit_info: 'Uredi informacije'
embed_comment_stream: 'Ugradi raspravu'
enable_pre_moderation: 'Omogući moderiranje prije objave'
enable_pre_moderation_text: 'Moderatori moraju odobriti svaki komentar prije nego je objavljen'
enable_premod: 'Omogući moderiranje prije objave'
enable_premod_description: 'Moderatori moraju odobriti svaki komentar prije nego je objavljen'
enable_premod_links: 'Moderiraj komentare sa linkovima prije objave'
enable_premod_links_description: 'Moderatori moraju odobriti svaki komentar sa linkom prije nego je objavljen'
enable_premod_links_text: 'Moderatori moraju odobriti svaki komentar sa linkom prije nego je objavljen'
enable_questionbox: 'Pitaj čitaoce'
enable_questionbox_description: 'Ovo pitanje će se pojaviti na vrhu rasprave. Pitajte čitaoce o određenoj temi u članku ili postavite pitanja za diskusiju itd'
hours: 'Sati'
code_of_conduct_summary: 'Rezime Kodeksa Ponašanja'
code_of_conduct_summary_desc: 'Ova poruka će se pojaviti iznad svake rasprave na vašem sajtu. Kliknite ovdje da saznate više o pisanju dobrog koda.'
include_question_here: 'Napišite pitanje ovdje'
include_text: 'Ubacite tekst ovdje'
moderate: 'Moderiraj'
moderation_settings: 'Podešavanja moderacije'
open: 'Otvori'
open_stream: 'Otvori raspravu'
open_stream_configuration: 'Ovaj stream komentara trenutačno je otvoren. Zatvaranjem ovog komentarskog streama ne mogu se poslati novi komentari, a svi prethodni komentari i dalje će biti prikazani.'
organization_contact_email: 'Email organizacije nije validan'
organization_info_copy: 'Ove informacije se koriste u e-mailovima koje generiše Talk. Ovo povezuje poruke sa vašom organizacijom i pruža mogućnost korisnicima da vas kontaktiraju ako imaju problem sa svojim nalogom.'
organization_info_copy_2: 'Preporučujemo kreiranje generičkog email naloga (organizacija@organizacija.me) za ovu svrhu. Ovo znači da nalog može da traje a da ne izlaže konkretna imena ljudi koja bi bila podložna targetiranju korisnika ukoliko je njihov nalog blokian'
organization_information: 'Informacije o organizaciji'
organization_name: 'Ime organizacije može sadržati brojeve ili slova'
suspect_or_forbidden_words_placeholder: 'Riječ ili fraza'
product_guide_link: 'Priručnik'
report_bug_or_feedback: 'Prijavi grešku ili pošalji povratnu informaciju'
require_email_verification: 'Zahtijeva e-mail verifikaciju'
require_email_verification_text: 'Novi korisnici moraju verifikovati svoj e-mail prije mogućnosti postavljanja komentara'
save: 'Sačuvaj'
save_changes: 'Sačuvaj izmjene'
save_changes_dialog:
cancel: 'Otkaži'
copy: 'Kopiraj na tablu'
discard: 'Izbriši/Odbaci'
save_settings: 'Sačuvaj podešavanja'
unsaved_changes: 'Nesačuvane promjene'
shortcuts: 'Prečice'
sign_out: 'Odjavi se'
stories: 'Priče'
stream_settings: 'Podešavanje rasprave'
suspect_word_text: 'Komentari koji sadrže ove riječi ili fraze (a nijesu osjetljivi na veličinu slova) automatski će biti uklonjeni iz komentara. Unesite riječ i pritisnite Enter ili Tab da dodate. Opciono stavite listu sa odvojenu zarezima'
suspect_word_title: 'Lista sumnjivih riječi'
tech_settings: 'Tehnička podešavanja'
title: 'Niste postavili nijedan komentar'
view_last_version: 'Vidi poslednju verziju'
weeks: 'Nedelje'
wordlist: 'Banovane riječi'
confirm_email:
click_to_confirm: 'Kliknite ispod da potvrdite Vašu e-mail adresu'
confirm: 'Potvrdi'
email_confirmation: 'E-mail potvrda'
continue: 'Nastavi'
createdisplay:
check_the_form: 'Nevažeća forma. Molim vas provjerite polja'
continue: 'Nastavi'
error_create: 'Greška u promjeni korisničkog imena'
fake_comment_body: 'Ovo je primjer komentara. Čitaoci mogu da podijele stavove i komuniciraju sa redakcijom u sekciji komentara'
fake_comment_date: 'Prije minut'
if_you_dont_change_your_name: 'Ako ne promijenite svoje korisničko ime na ovom koraku, vaše ime na Facebook-u će se pojaviti zajedno sa svim Vašim komentarima'
required_field: 'Obavezno polje'
save: 'Sačuvaj'
special_characters: 'Korisničko ime može da sadrži slova, brojeve i'
username: 'Korisničko ime mora sadržati slova, brojeve I _ samo'
write_your_username: 'Izmijeni svoje korisničko ime'
your_username: 'Vaše korisničko ime se pojavljuje u svakom komentaru koji napišete'
done: 'Završeno'
edit_comment:
body_input_label: 'Izmijeni komentar'
edit_window_expired: 'Vrijeme je isteklo i ovaj komentar se više ne može izmijeniti. Zašto ne postavite novi komentar?'
edit_window_expired_close: 'Zatvori'
edit_window_timer_prefix: 'Uredi prozor'
minute: 'Minut'
minutes_plural: 'Minuti'
save_button: 'Sačuvaj izmjene'
second: 'Sekund'
seconds_plural: 'Sekunde'
email:
banned:
body: 'Svaš nalog je banovan. Više vam nije dozvoljeno da komentarišete, prijavljujete i budete dio zajednice'
subject: 'Potvrda e-maila'
confirm:
confirm_email: 'Email adrese se ne podudaraju, probajte ponovo'
has_been_requested: 'Potvrda e-mail adrese je neophodna za ovaj nalog'
if_you_did_not: 'Ukoliko niste ovo zahtijevali, ignorišite ovaj e mail.'
subject: 'Potvrda e-maila'
to_confirm: 'Da aktivirate nalog, posjetite sljedeći link:'
password_change:
body: 'Lozinka za vaš nalog je promjenjena.\n\nUkoliko niste vi zatražili ovu promjenu, molimo kontaktirajte nas {0}.'
subject: '{0} promena lozinke'
password_reset:
if_you_did: 'Ako jeste'
please_click: 'Kliknite ovdje da obnovite šifru'
subject: 'Potvrda e-maila'
we_received_a_request: 'Primili smo vaš zahtjev za obnovu šifre. Ukoliko niste tražili ovu promjenu, ignorišite ovaj mail.'
suspended:
subject: 'Potvrda e-maila'
embed_comments_tab: 'Komentari'
embedlink:
copy: 'Kopiraj na tablu'
copied: 'Kopirano'
error:
ALREADY_EXISTS: 'Resurs već postoji'
AUTHENTICATION: 'Došlo je do greške prilikom potvrde vašeg naloga.'
CANNOT_IGNORE_STAFF: 'Ne možete ignorisati članove redakcije.'
COMMENT_PARENT_NOT_VISIBLE: 'Komentar na koji odgovarate je uklonjen ili ne postoji'
COMMENT_TOO_SHORT: 'Komentar mora sadržati više od jednog znaka. Molimo vas izmijenite vaš komentar i pokušajte ponovo'
COMMENT_TOO_LONG: 'Komentar je predugačak'
COMMENTING_CLOSED: 'Komentarisanje je zatvoreno'
COMMENTING_DISABLED: 'Komentarisanje trenutno nije moguće na sajtu.'
confirm_password: 'Potvrdi šifru'
DELETION_NOT_SCHEDULED: 'Brisanje nije zakazano.'
EDIT_USERNAME_NOT_AUTHORIZED: 'Nemate dozvolu da izmijenite vaše korisiničko ime.'
EDIT_WINDOW_ENDED: 'Ne možete izmijeniti komentar, vrijeme je isteklo'
email: 'Molimo Vas unesite validan e-mail'
EMAIL_ALREADY_VERIFIED: 'E-mail adresa je već potvrđena.'
EMAIL_IN_USE: 'E-mail adresa je već u upotrebi'
email_not_verified: 'E-mail adresa nije potvrđena.'
EMAIL_NOT_VERIFIED: 'E-mail adresa nije potvrđena.'
email_password: 'E-mail i/ili šifra se ne podudaraju'
EMAIL_REQUIRED: 'Obavezna e-mail adresa'
EMAIL_VERIFICATION_TOKEN_INVALID: 'Šifra potvrde maila nije validna'
INCORRECT_PASSWORD: 'Pogrešna šifra'
INVALID_ASSET_URL: 'Istaknuti URL nije validan'
LOGIN_MAXIMUM_EXCEEDED: 'Ukucali ste pogrešnu šifru previše puta. Molimo sačekajte.'
network_error: 'Nemoguće povezivanje sa serverom. Provjerite konekciju i pokušajte ponovo'
NO_SPECIAL_CHARACTERS: 'Korisničko ime može samo sadržati slova, brojeve i _'
NOT_AUTHORIZED: 'Nemate dozvolu da sprovedete akciju'
NOT_FOUND: 'Podatak nije pronađen'
organization_contact_email: 'Email organizacije nije validan'
organization_name: 'Ime organizacije može sadržati brojeve ili slova'
password: 'Šifra mora sadržati minimum 8 karaktera'
PAGE_NOT_AVAILABLE_ROLE: 'Ovu stranicu mogu koristiti samo članovi redakcije. Molimo kontaktirajte administratora ukoliko želite da se priključite timu'
PASSWORD_INCORRECT: 'Pogrešno ste unijeli šifru'
PASSWORD_LENGTH: 'Šifra je prekratka'
PASSWORD_REQUIRED: 'Obavezno unijeti šifru'
PASSWORD_RESET_TOKEN_INVALID: 'Link za resetovanje šifre je nevažeći'
PROFANITY_ERROR: 'Korisničko ime ne može sadržati psovke. Kontaktirajte administratora ukoliko smatrate da je u pitanju greška'
RATE_LIMIT_EXCEEDED: 'Premašeno je ograničenje'
required_field: 'Obavezno polje'
SAME_USERNAME_PROVIDED: 'Morate izabrati drugo korisničko ime'
temporarily_suspended: 'U skladu sa pravilima naše zajednice, vaš nalog je privremeno suspendovan. Molimo vas da se ponovo uključite u razgovor.'
unexpected: 'Došlo je do greške. Izvinite.'
username: 'Korisničko ime mora sadržati isključivo slova, brojeve i _'
USERNAME_IN_USE: 'Korisničko ime je već u upotrebi'
USERNAME_REQUIRED: 'Morate unijeti korisničko ime'
flag_comment: 'Prijavi komentar'
flag_reason: 'Razlog prijave (opciono)'
flag_reasons:
username:
impersonating: 'Korisnik se lažno predstavlja'
nolike: 'Ne dopada mi se korisničko ime'
offensive: 'Korisničko ime je neprimjereno'
other: 'Drugo'
spam: 'Ovo izgleda kao reklama/marketing'
flag_username: 'Prijavi korisničko ime'
flagged_usernames:
notify_approved: '{0} je odobrio korisničko ime {1}'
notify_changed: 'Korisnik {0} je promijenio korisničko ime u {1}'
notify_flagged: '{0} je prijavio korisničko ime {1}'
notify_rejected: '{0} je odbio korisničko ime {1}'
flags:
reasons:
comment:
banned_word: 'Banovana riječ'
comment_noagree: 'Nisam saglasan'
comment_offensive: 'Neprimjereno'
comment_other: 'drugo'
comment_spam: 'spam'
links: 'link'
suspect_word: 'Neprimjerena riječ'
trust: 'karma'
user:
username_impersonating: 'Lažno predstavljanje'
username_nolike: 'ne dopada mi se'
username_offensive: 'Korisničko ime je neprimjereno.'
username_other: 'drugo'
username_spam: 'spam'
framework:
banned_account_body: 'To znači da ne možete reagovati, prijavljivati ili pisati komentare'
banned_account_header: 'Vaš nalog je trenutno banovan'
changed_name:
msg: 'Izmjena vašeg korisničkog imena prolazi provjeru našeg tima moderatora'
comment: 'Postavi komentar'
comment_is_deleted: 'Korisnik je izbrisao nalog'
comment_is_hidden: 'Komentar nije dostupan'
comment_is_ignored: 'Komentar je skriven, jer ste ignorisali korisnika'
comment_is_rejected: 'Odbili ste komentar'
comments: 'Komentari'
configure_stream: 'Podesi'
content_not_available: 'Sadržaj nije dostupan'
edit: 'Izmijeni'
edit_name:
button: 'Podnesi'
error: 'Došlo je do greške'
label: 'Novo korisničko ime'
msg: 'Izmjena vašeg korisničkog imena prolazi provjeru našeg tima moderatora'
my_comments: 'Moji komentari'
my_profile: 'Moj profil'
new_count: 'Vidi još {0} / {1}'
profile: 'Nalog'
show_all_comments: 'Prikaži sve komentare'
show_all_replies: 'Prikaži sve odgovore'
show_more_replies: 'Prikaži još odgovora'
success_bio_update: 'Vaša biografija je izmijenjena'
success_name_update: 'Vaše korisničko ime je izmijenjeno'
success_update_settings: 'Promjene koje ste unijeli su primijenjene na raspravu na ovom članku.'
view_more_comments: 'Vidi još komentara'
view_reply: 'vidi odgovor'
from_settings_page: 'Na profilu možete vidjeti istoriju komentara'
install:
add_organization:
description: 'Hvala što ste instalirali Talk! Poslali smo vam e-mail kako biste povrdili vašu e-mail adresu. Dok završavate podešavanje naloga, možete početi da komunicirate sa čitaocima.'
label: 'Novo korisničko ime'
save: 'Sačuvaj'
create:
confirm_password: 'Potvrdi šifru'
email: 'Molimo Vas unesite validan e-mail'
organization_contact_email: 'Email organizacije nije validan'
password: 'Šifra mora sadržati minimum 8 karaktera'
save: 'Sačuvaj'
username: 'Korisničko ime mora sadržati isključivo slova, brojeve i _'
final:
close: 'Zatvori instalaciju'
description: 'Hvala što ste instalirali Talk! Poslali smo vam e-mail kako biste povrdili vašu e-mail adresu. Dok završavate podešavanje naloga, možete početi da komunicirate sa čitaocima.'
launch: 'Pokreni Talk'
initial:
description: 'Hvala što ste instalirali Talk! Poslali smo vam e-mail kako biste povrdili vašu e-mail adresu. Dok završavate podešavanje naloga, možete početi da komunicirate sa čitaocima.'
submit: 'Počni'
permitted_domains:
description: 'Hvala što ste instalirali Talk! Poslali smo vam e-mail kako biste povrdili vašu e-mail adresu. Dok završavate podešavanje naloga, možete početi da komunicirate sa čitaocima.'
submit: 'Počni'
title: 'Niste postavili nijedan komentar'
like: 'Dopada mi se'
loading_results: 'rezultati se učitavaju'
login:
email_address: 'e-mail adresa'
forgot_password: 'Zaboravili ste šifru?'
go_back: 'Vrati se'
sign_in: 'Prijavi se'
sign_in_button: 'Dugme za prijavu'
sign_in_message: 'Prijavi se kako bi komunikacirao sa zajednicom'
password: 'Šifra mora sadržati minimum 8 karaktera'
reset_password_send_button: 'povrati šifru'
request_passowrd: 'Zahtijevaj novu šifru'
team_sign_in: 'Prijava tima'
marketing: 'Ovo izgleda kao reklama/marketing'
moderate_all_streams: 'Moderiraj komentare na svim pričama'
moderate_this_stream: 'Moderiraju ovu raspravu'
modqueue:
account: 'Prijave naloga'
actions: 'akcije'
all: 'Sve'
all_streams: 'Sve rasprave'
approve: 'Odobri'
approved: 'Odobreno'
ban_user: 'Banuj korisnika'
ban_user_actions: 'Banuj korisničke akcije'
billion: 'Milijardi'
close: 'Zatvori instalaciju'
empty_queue: 'Nema više komentara za moderiranje.'
flagged: 'Obilježeno'
jump_to_queue: 'Preskoči na red'
less_detail: 'Manje detalja'
likes: 'Sviđanja'
million: 'milion'
mod_faster: 'Moderiraj brže uz prečice na tastaturi'
moderate: 'Moderiraj'
more_detail: 'Više detalja'
navigation: 'navigacija'
new: 'novo'
newest_first: 'Prvo najnoviji'
next_comment: 'Idi na sljedeći komentar'
next_queue: 'Preskoči red'
notify_accepted: '{0} je prihvatio komentar "{1}"'
notify_edited: '{0} je izmjenio komentar "{1}"'
notify_flagged: '{0} je označio komentar "{1}"'
notify_rejected: '{0} je odbio komentar "{1}"'
notify_reset: '{0} je resetovao status komentara "{1}"'
oldest_first: 'Prvo najstariji'
premod: 'mod pre-moderacija'
prev_comment: 'idi na prethodni komentar'
reject: 'Odbij'
rejected: 'Odbijen'
reply: 'Odgovori'
reported: 'Prijavljen'
select_stream: 'Odaberi raspravu'
shift_key: '⇧'
shortcuts: 'Prečice'
show_shortcuts: 'Prikaži prečice'
singleview: 'Zen stanje'
sort: 'Sortiraj'
suspend: 'Suspenduj korisnika'
system_withheld: 'Zadržan u sistemu'
thismenu: 'Otvori meni'
thousand: 'hiljada'
toggle_search: 'Otvori pretragu'
try_these: 'Pokušaj ovo'
view_more_shortcuts: 'Vidi dodatne prečice'
my_comment_history: 'Istorija komentara'
name: 'Ime'
no_agree_comment: 'Nisam saglasan sa ovim komentarom'
no_like_bio: 'Ne dopada mi se ova biografija'
no_like_username: 'Ne dopada mi se ovo korisničko ime'
other: 'Drugo'
password_reset:
change_password: 'Promijeni šifru'
change_password_help: 'Unesite novu šifru za prijavu. Vodite računa da je šifra bezbjedna'
confirm_new_password: 'Potvrdite novu šifru'
mail_sent: 'Ukoliko imate registrovan nalog, link za resetovanje šifre je poslat na email'
new_password: 'Nova šifra'
new_password_help: 'Šifra mora sadržati minimum 8 znakova'
set_new_password: 'Promijeni šifru'
permalink: 'Podijeli'
personal_info: 'Ovaj komentar sadrži lične informacije'
post: 'Objava'
profile: 'Nalog'
profile_settings: 'Podešavanja naloga'
reject_username:
description_notify: 'Suspendovanje korisnika će im privremeno onemogućiti nalog'
description_reject: 'Da li želite da privremeno banujete ovog korisnika? Ukoliko to učinite, korisnik će biti suspendovan dok ne izmijeni'
email_message_reject: 'Član zajednice je zatražio provjeru vašeg korisničkog imena. Zbog tog sadržaja je vaše korisničko ime odbijeno. To znači da ne možete komentarisati, označavati i reagovati na komentare dok ne promijenite korisničko ime. Molimo da pošaljete e-mail ako imate komentare ili primjedbe.'
no_cancel: 'Ne poništavaj'
send: 'Pošalji'
suspend_user: 'Suspenduj korisnika'
title_notify: 'Obavijesti korisnika o privremenoj suspenziji'
title_reject: 'Primijetili smo da ste odbili korisničko ime'
username: 'Korisničko ime mora sadržati slova, brojeve I _ samo'
write_message: 'Napiši poruku'
yes_suspend: 'Potvrdi suspenziju'
reject_username_dialog:
cancel: 'Otkaži'
description: 'Hvala što ste instalirali Talk! Poslali smo vam e-mail kako biste povrdili vašu e-mail adresu. Dok završavate podešavanje naloga, možete početi da komunicirate sa čitaocima.'
message: 'Razlog prijave (opciono)'
reason: 'Razlog'
reject_username: 'Odbij korisničko ime'
title: 'Niste postavili nijedan komentar'
reply: 'Odgovori'
report: 'Prijavi'
report_notif: 'Hvala što ste prijavili komentar. Naš tim je obaviješten i provjera će biti izvršena brzo.'
report_notif_remove: 'Vaša prijava je uklonjena'
reported: 'Prijavljen'
settings:
from_settings_page: 'Na profilu možete vidjeti istoriju komentara'
my_comment_history: 'Istorija komentara'
profile: 'Nalog'
profile_settings: 'Podešavanja naloga'
sign_in: 'Prijavi se'
to_access: 'Pristupi nalogu'
user_no_comment: 'Nikada niste napisali komentar. Priključite se raspravi.'
step_1_header: 'Prijavi problem'
step_2_header: 'Pomozite nam da razumijemo'
step_3_header: 'Hvala na informaciji'
stream:
all_comments: 'Svi komentari'
comment_not_found: 'Komentar je uklonjen ili ne postoji'
no_comments: 'Još uvijek nema komentara. Zašto ne napišete nešto?'
no_comments_and_closed: 'Nema komenatara za ovaj članak'
temporarily_suspended: 'U skladu sa pravilima naše zajednice, vaš nalog je privremeno suspendovan. Molimo vas da se ponovo uključite u razgovor.'
streams:
all: 'Sve'
article: 'Priča'
closed: 'Zatvoreno'
empty_result: 'Nema rezultata pretrage. Pokušajte da proširite pretragu.'
filter_streams: 'Filteruj rasprave'
most_recent_stories: 'Najnovije priče'
newest: 'Najnovije'
no_results: 'Nema rezultata'
oldest: 'Najstarije'
open: 'Otvori'
pubdate: 'Datum objave'
search: 'Pretraga'
search_results: 'Rezultati pretrage'
sort_by: 'Sortiraj po'
status: 'Status rasprave'
stream_status: 'Status rasprave'
suspenduser:
cancel: 'Otkaži'
day: '{0} dana'
days: '{0} dana'
description_notify: 'Suspendovanje korisnika će im privremeno onemogućiti nalog'
description_suspend: 'Suspendujete {0}. Ovaj komentar će ići na spisak odbijenih komentare i neće moći da postavlja, odgovara i prijavljuje komentare dok ne istekne suspenzija.'
email_message_suspend: 'Poštovani {0},\n\nu skladu sa {1} pravilima komentarisanja, vaš nalog je trenutno suspendovan. Tokom suspenzije ne možete da komentarišete i imate interakciju sa ostalim komentatorima. Molimo da se vratite raspravi {2}.'
hour: '{0} sat'
hours: '{0} sati'
notify_suspend_until: 'Korisnik {0} je privremeno suspendovan. Suspenzija će se automatski okončati'
one_hour: 'Sat vremena'
select_duration: 'odaberi trajanje suspenzije'
send: 'Pošalji'
suspend_user: 'Suspenduj korisnika'
title_notify: 'Obavijesti korisnika o privremenoj suspenziji'
title_suspend: 'Suspenduj korisnika'
write_message: 'Napiši poruku'
thank_you: 'Cijenimo vašu povratnu reakciju i vašu bezbjedost. Moderator će ukoro pogledati vašu prijavu'
user:
bio_flags: 'Prijave za ovu biografiju.'
user_bio: 'Korisnička biografija'
username_flags: 'Prijave za ovo korisničko ime'
user_detail:
all: 'Sve'
ban: 'Banuj korisnika'
banned: 'Banovan'
email: 'Molimo Vas unesite validan e mail'
id: 'ID'
karma: 'karma'
karma_docs_link: 'https://docs.coralproject.net/talk/trust/#user-karma-score'
learn_more: 'Saznaj više'
member_since: 'Član od'
reject_rate: 'Odbijanja'
reject_username: 'Odbij korisničko ime'
rejected: 'Odbijen'
remove_ban: 'Ukloni ban'
remove_suspension: 'Ukloni suspenziju'
suspend: 'Suspenduj korisnika'
suspended: 'Suspendovan'
total_comments: 'Svi komentari'
unreliable: 'Nepouzdano'
user_history: 'Istorija korisnika'
user_karma_score: 'Karma poeni'
username: 'Korisničko ime mora sadržati isključivo slova, brojeve i _ '
username_needs_approval: 'Potrebno odobrenje korisničkog imena'
username_rejected: 'Korisničko ime odbijeno'
user_history:
action: 'Akcija'
ban_removed: 'Zabrana uklonjena'
date: 'Datum'
suspended: 'Suspendovan, {0}'
suspension_removed: 'Suspenzija uklonjena'
system: 'Sistem'
taken_by: 'Preduzeo'
user_banned: 'Korisnik banovan'
username_status: 'Korisnik {0}'
user_impersonating: 'Korisnik se lažno predstavlja'
user_no_comment: 'Nikada niste napisali komentar. Priključite se raspravi.'
username_offensive: 'Korisničko ime je neprimjereno.'
validators:
confirm_email: 'Email adrese se ne podudaraju, probajte ponovo'
confirm_password: 'Potvrdi šifru'
required: 'polje je obavezno'
verify_email: 'Unesite validan e mail'
verify_organization_name: 'Ime organizacije mora sadržati samo slova ili brojeve'
verify_password: 'Šifra mora imati makar 8 znakova'
verify_username: 'Korisničko ime može sadržati isključivo slova, brojeve i _'
view_conversation: 'Vidi razgovor'
your_account_has_been_banned: 'Vaš nalog je banovan'
your_account_has_been_suspended: 'Vaš nalog je privremeno suspendovan'
your_username_has_been_rejected: 'Vaš nalog je suspendovan jer je korisničko ime označeno kao neprikladno. Da povratite nalog, unesite novo korisničko ime'
+44
View File
@@ -0,0 +1,44 @@
const express = require('express');
const path = require('path');
const staticServer = require('express-static-gzip');
const { merge } = require('lodash');
const { EMBED_EXPIRY_TIME, STATIC_EXPIRY_TIME } = require('../config');
// EMBED_CACHE_CONTROL_HEADER is the header sent when the file is embed.js.
const EMBED_CACHE_CONTROL_HEADER = [
'public',
`max-age=${Math.floor(EMBED_EXPIRY_TIME / 1000)}`,
'immutable',
].join(', ');
// Define the options to be applied to all static files, the embed itself has a
// separate override.
const defaultOpts = {
maxAge: STATIC_EXPIRY_TIME,
immutable: true,
setHeaders: (res, path) => {
if (path.includes('/dist/embed.js')) {
// embed.js has a different max-age then the rest of the static files.
res.setHeader('Cache-Control', EMBED_CACHE_CONTROL_HEADER);
}
},
};
// Setup the configuration for the compression options on how to serve files.
const compressionOpts = {
indexFromEmptyFile: false,
enableBrotli: true,
customCompressions: [{ encodingName: 'deflate', fileExtension: 'zz' }],
};
// Serve the directories under ../dist.
const dist = path.resolve(path.join(__dirname, '../dist'));
/**
* middleware in production will serve compressed files if available, otherwise
* it will use express's static middleware.
*/
module.exports =
process.env.NODE_ENV === 'production'
? staticServer(dist, merge(compressionOpts, defaultOpts))
: express.static(dist, defaultOpts);
+4
View File
@@ -81,6 +81,10 @@ Asset.index(
}
);
// Indexes for listing the assets on the admin page.
Asset.index({ created_at: -1, publication_date: -1 }, { background: true });
Asset.index({ created_at: 1, publication_date: 1 }, { background: true });
/**
* Returns true if the asset is closed, false else.
*/
+45
View File
@@ -180,6 +180,30 @@ const User = new Schema(
},
],
},
// alwaysPremod stores the current user premod status as well as the history of
// changes.
alwaysPremod: {
// Status stores the current user premod status.
status: {
type: Boolean,
required: true,
default: false,
index: true,
},
history: [
{
// Status stores the historical premod status.
status: Boolean,
// assigned_by stores the user id of the user who assigned this status.
assigned_by: { type: String, default: null },
// created_at stores the date when this status was assigned.
created_at: { type: Date, default: Date.now },
},
],
},
},
// IgnoresUsers is an array of user id's that the current user is ignoring.
@@ -359,6 +383,27 @@ User.virtual('banned')
});
});
/**
* alwaysPremod returns true when the user is currently in always premod, and sets the alwaysPremod
* status locally.
*/
User.virtual('alwaysPremod')
.get(function() {
return this.status.alwaysPremod.status;
})
.set(function(status) {
this.status.alwaysPremod.status = status;
if (!this.status.alwaysPremod.history) {
this.status.alwaysPremod.history = [];
}
this.status.alwaysPremod.history.push({
status,
created_at: new Date(),
});
});
/**
* suspended returns true when the user is currently suspended, and sets the
* suspension status locally.
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "talk",
"version": "4.6.9",
"version": "4.8.2",
"description": "A better commenting experience from Mozilla, The New York Times, and the Washington Post. https://coralproject.net",
"main": "app.js",
"private": true,
@@ -58,6 +58,7 @@
"dependencies": {
"@coralproject/gql-merge": "^0.1.0",
"@coralproject/graphql-anywhere-optimized": "^0.1.0",
"@ungap/url-search-params": "^0.1.2",
"apollo-client": "^1.9.1",
"apollo-engine": "^0.8.1",
"apollo-server-express": "^1.2.0",
@@ -204,6 +205,7 @@
"style-loader": "^0.16.0",
"subscriptions-transport-ws": "^0.7.2",
"supports-color": "^4",
"throng": "^4.0.0",
"timeago.js": "^2.0.3",
"timekeeper": "^1.0.0",
"tlds": "^1.196.0",
@@ -211,7 +213,6 @@
"url-join": "^2.0.2",
"url-loader": "^0.6.0",
"url-parse": "^1.4.3",
"url-search-params": "^0.9.0",
"uuid": "^3.1.0",
"webpack": "^3.10.0",
"webpack-manifest-plugin": "^2.0.0-rc.2",
+1
View File
@@ -7,6 +7,7 @@ module.exports = {
EDIT_COMMENT: 'EDIT_COMMENT',
SET_USER_USERNAME_STATUS: 'SET_USER_USERNAME_STATUS',
SET_USER_BAN_STATUS: 'SET_USER_BAN_STATUS',
SET_USER_ALWAYS_PREMOD_STATUS: 'SET_USER_ALWAYS_PREMOD_STATUS',
SET_USER_SUSPENSION_STATUS: 'SET_USER_SUSPENSION_STATUS',
SET_COMMENT_STATUS: 'SET_COMMENT_STATUS',
ADD_COMMENT_TAG: 'ADD_COMMENT_TAG',
+1
View File
@@ -47,6 +47,7 @@ module.exports = (user, perm) => {
case types.SET_USER_USERNAME_STATUS:
case types.SET_USER_BAN_STATUS:
case types.SET_USER_SUSPENSION_STATUS:
case types.SET_USER_ALWAYS_PREMOD_STATUS:
case types.UPDATE_ASSET_SETTINGS:
case types.UPDATE_ASSET_STATUS:
return check(user, ['ADMIN', 'MODERATOR']);
@@ -42,6 +42,21 @@ en:
reasons:
comment:
spam_comment: "Detected Spam"
sr:
error:
COMMENT_IS_SPAM: |
Sadržaj ovog komentara liči na spam. Možete
urediti komentar, ili ga svejedno poslati moderatoru na odobrenje.
talk-plugin-akismet:
spam: "Spam"
spam_comment: "Spam"
detected: "Detected by Akismet"
still_spam: |
Hvala Vam. Naš tim moderatora će uskoro prgeldati vš komentar.
flags:
reasons:
comment:
spam_comment: "Detected Spam"
es:
error:
COMMENT_IS_SPAM: |
@@ -72,6 +87,36 @@ fr:
reasons:
comment:
spam_comment: "Detected Spam"
he:
error:
COMMENT_IS_SPAM: |
תגובה זו נראית כמו ספאם.
תוכל לערוך את התגובה או לשלוח אותה בכל מקרה לביקורת של מפקח.
talk-plugin-akismet:
spam: "ספאם"
spam_comment: "ספאם"
detected: "זוהה על ידי אקיזמט"
still_spam: |
תודה. צוות הפיקוח שלנו יבחן את התגובה שלך בקרוב.
flags:
reasons:
comment:
spam_comment: "זוהה ספאם"
it:
error:
COMMENT_IS_SPAM: |
Il linguaggio in questo commento sembra spam. Puoi
modificare il commento o sottometterlo alla revisione dei moderatori.
talk-plugin-akismet:
spam: "Spam"
spam_comment: "Spam"
detected: "Rilevato da Akismet"
still_spam: |
Grazie. Il nostro team di moderatori revisionerà il tuo commento a breve.
flags:
reasons:
comment:
spam_comment: "Rilevata spam"
nl_NL:
error:
COMMENT_IS_SPAM: |
+194 -45
View File
@@ -99,6 +99,51 @@ da:
username: Username
write_your_username: "Edit your username"
your_username: "Your username appears on every comment you post."
de:
talk-plugin-auth:
login:
email_verify_cta: "Bitte bestätigen Sie Ihre E-Mail-Adresse."
request_new_verify_email: "E-Mail-Bestätigung erneut anfordern"
verify_email: "Danke, dass Sie ein Konto eingerichtet haben! Wir haben eine Nachricht an Ihre E-Mail-Adresse geschickt, mit der Sie Ihr Konto bestätigen können."
verify_email2: "Sie müssen ihr Konto bestätigen, bevor Sie beginnen können."
not_you: "Nicht Ihr Name?"
logged_in_as: "Angemeldet als"
facebook_sign_in: "Mit Facebook anmelden"
facebook_sign_up: "Mit Facebook registrieren"
logout: "Abmelden"
sign_in: "Anmelden"
sign_in_to_join: "Anmelden, um zu diskutieren"
or: "Oder"
email: "E-Mail-Adresse"
password: "Passwort"
forgot_your_pass: "Passwort vergessen?"
need_an_account: "Brauchen Sie ein Konto?"
register: "Registrieren"
sign_up: "Registrieren"
confirm_password: "Passwort bestätigen"
username: "Nutzername"
already_have_an_account: "Konto bereits vorhanden?"
recover_password: "Passwort zurücksetzen"
email_in_use: "E-Mail-Adresse bereits vergeben"
email_or_username_in_use: "E-Mail-Adresse oder Nutzername bereits vergeben"
required_field: "Pflichtfeld"
passwords_dont_match: "Passwörter nicht identisch."
special_characters: "Nutzernamen dürfen nur Buchstaben, Zahlen und _ enthalten"
sign_in_to_comment: "Zum Kommentieren anmelden"
check_the_form: "Ungültige Eingabe. Bitte prüfen Sie Ihre Felder"
set_username_dialog:
check_the_form: "Ungültige Eingabe. Bitte prüfen Sie Ihre Felder"
continue: "Mit diesem Facebook-Profilnamen fortfahren"
error_create: "Fehler bei Änderung des Nutzernamens"
fake_comment_body: "Dies ist ein Beispiel-Kommentar. Leser können im Kommentarbereich Meinungen und Gedanken mit der Redaktion austauschen."
fake_comment_date: "Vor 1 Minute"
if_you_dont_change_your_name: "Wenn Sie Ihren Nutzernamen an diesem Punkt nicht ändern, wird Ihr Facebook-Name mit Ihren Kommentaren angezeigt."
required_field: "Pflichtfeld"
save: Speichern
special_characters: "Nutzernamen dürfen nur Buchstaben, Zahlen und _ enthalten"
username: Nutzername
write_your_username: "Nutzername bearbeiten"
your_username: "Ihr Nutzername erscheint an jedem Ihrer veröffentlichten Kommentare."
en:
talk-plugin-auth:
login:
@@ -152,51 +197,6 @@ en:
cancel: "Cancel"
edit: "Edit"
changed_password_msg: "Your password has been successfully changed"
de:
talk-plugin-auth:
login:
email_verify_cta: "Bitte bestätigen Sie Ihre E-Mail-Adresse."
request_new_verify_email: "E-Mail-Bestätigung erneut anfordern"
verify_email: "Danke, dass Sie ein Konto eingerichtet haben! Wir haben eine Nachricht an Ihre E-Mail-Adresse geschickt, mit der Sie Ihr Konto bestätigen können."
verify_email2: "Sie müssen ihr Konto bestätigen, bevor Sie beginnen können."
not_you: "Nicht Ihr Name?"
logged_in_as: "Angemeldet als"
facebook_sign_in: "Mit Facebook anmelden"
facebook_sign_up: "Mit Facebook registrieren"
logout: "Abmelden"
sign_in: "Anmelden"
sign_in_to_join: "Anmelden, um zu diskutieren"
or: "Oder"
email: "E-Mail-Adresse"
password: "Passwort"
forgot_your_pass: "Passwort vergessen?"
need_an_account: "Brauchen Sie ein Konto?"
register: "Registrieren"
sign_up: "Registrieren"
confirm_password: "Passwort bestätigen"
username: "Nutzername"
already_have_an_account: "Konto bereits vorhanden?"
recover_password: "Passwort zurücksetzen"
email_in_use: "E-Mail-Adresse bereits vergeben"
email_or_username_in_use: "E-Mail-Adresse oder Nutzername bereits vergeben"
required_field: "Pflichtfeld"
passwords_dont_match: "Passwörter nicht identisch."
special_characters: "Nutzernamen dürfen nur Buchstaben, Zahlen und _ enthalten"
sign_in_to_comment: "Zum Kommentieren anmelden"
check_the_form: "Ungültige Eingabe. Bitte prüfen Sie Ihre Felder"
set_username_dialog:
check_the_form: "Ungültige Eingabe. Bitte prüfen Sie Ihre Felder"
continue: "Mit diesem Facebook-Profilnamen fortfahren"
error_create: "Fehler bei Änderung des Nutzernamens"
fake_comment_body: "Dies ist ein Beispiel-Kommentar. Leser können im Kommentarbereich Meinungen und Gedanken mit der Redaktion austauschen."
fake_comment_date: "Vor 1 Minute"
if_you_dont_change_your_name: "Wenn Sie Ihren Nutzernamen an diesem Punkt nicht ändern, wird Ihr Facebook-Name mit Ihren Kommentaren angezeigt."
required_field: "Pflichtfeld"
save: Speichern
special_characters: "Nutzernamen dürfen nur Buchstaben, Zahlen und _ enthalten"
username: Nutzername
write_your_username: "Nutzername bearbeiten"
your_username: "Ihr Nutzername erscheint an jedem Ihrer veröffentlichten Kommentare."
es:
talk-plugin-auth:
login:
@@ -296,6 +296,102 @@ fr:
username: "Nom d'utilisateur"
write_your_username: "Modifier votre nom d'utilisateur"
your_username: "Votre nom d'utilisateur apparaît sur chaque commentaire que vous publiez."
he:
talk-plugin-auth:
login:
email_verify_cta: "אנא אמת את כתובת האימייל שלך."
request_new_verify_email: 'בקש אימייל נוסף'
verify_email: 'תודה שיצרת חשבון! שלחנו אימייל לכתובת שסיפקת כדי לאמת את חשבונך.'
verify_email2: "עליך לאמת את חשבונך לפני שתעסוק בקהילה."
not_you: "לא אתה?"
logged_in_as: "נכנס בתור"
logout: "התנתק"
sign_in: "היכנס"
sign_in_to_join: "היכנס כדי להצטרף לשיחה"
or: "או"
email: "כתובת אימייל"
password: "סיסמה"
forgot_your_pass: "שכחת את הסיסמה?"
need_an_account: "צריך חשבון?"
register: "הירשם"
sign_up: "הירשם"
confirm_password: "אשר את הסיסמה שלך"
username: "שם משתמש"
already_have_an_account: "כבר יש לך חשבון?"
recover_password: "שחזור סיסמה"
email_in_use: "אימייל כבר תפוס"
email_or_username_in_use: "אימייל או שם משתמש כבר תפוס"
required_field: "חובה למלא את הערך הזה"
passwords_dont_match: "הסיסמאות אינן תואמות."
special_characters: "שמות משתמש יכולים להכיל אותיות, מספרים ו- _ בלבד"
sign_in_to_comment: "היכנס כדי להגיב"
check_the_form: "טופס לא חוקי. אנא, בדוק את השדות"
set_username_dialog:
check_the_form: "טופס לא חוקי. אנא, בדוק את השדות"
continue: "המשך עם אותו שם משתמש בפייסבוק"
error_create: "שגיאה בעת שינוי שם המשתמש"
fake_comment_body: "זוהי תגובה לדוגמה. הקוראים יכולים לשתף את המחשבות שלהם ואת דעות עם חדר החדשות בסעיף התגובות"
fake_comment_date: "לפני דקה אחת"
if_you_dont_change_your_name: "אם לא תשנה את שם המשתמש שלך בשלב זה שם התצוגה שלך בפייסבוק יופיע לצד כל תגובות שלך."
required_field: "חובה למלא את הערך הזה"
save: "שמור"
special_characters: "שמות משתמש יכולים להכיל אותיות, מספרים ו- _ בלבד"
username: "שם משתמש"
write_your_username: "ערוך את שם המשתמש שלך"
your_username: "שם המשתמש שלך מופיע בכל תגובה שתפרסם."
it:
talk-plugin-auth:
login:
email_verify_cta: "Perfavore verifica il tuo indirizzo email."
request_new_verify_email: "Richiedi un'altra email"
verify_email: "Grazie per aver creato un account! Abbiamo inviato una email all'indirizzo che ci hai fornito per verificare il tuo account."
verify_email2: "Devi verificare il tuo account prima di poter interagire con la community."
not_you: "Non sei tu?"
logged_in_as: "Registrato come"
logout: "Esci"
sign_in: "Accedi"
sign_in_to_join: "Accedi per partecipare alla conversazione"
or: "o"
email: "Indirizzo email"
password: "Password"
password_error: "La password deve essere lunga almeno 8 caratteri."
forgot_your_pass: "Hai dimenticato la password?"
need_an_account: "Vuoi un account?"
register: "Registra"
sign_up: "Registrati"
confirm_password: "Conferma password"
username: "Username"
already_have_an_account: "Hai già un account?"
recover_password: "Recupera password"
email_in_use: "Indirizzo email già in uso"
email_or_username_in_use: "Indirizzo email o username già in uso"
required_field: "Questo è un campo obbligatorio"
passwords_dont_match: "Le password non coincidono."
special_characters: "Gli username possono contenere solo lettere, numeri e _"
sign_in_to_comment: "Accedi per commentare"
check_the_form: "Modulo non valido. Perfavore ricontrolla i campi"
set_username_dialog:
check_the_form: "Modulo non valido. Perfavore ricontrolla i campi"
continue: "Continua con lo stesso username di Facebook"
error_create: "Errore durante la modifica dell'username"
fake_comment_body: "Questo è un esempio di commento. I lettori possono condividere i loro pensieri e opinioni con le redazioni nella sezione dei commenti."
fake_comment_date: "1 minuto fa"
if_you_dont_change_your_name: "Se non modifichi il tuo username in questo momento il tuo nome su Facebook comparirà accanto a tutti i tuoi commenti."
required_field: "Campo obbligatorio"
save: Salva
special_characters: "Gli usernames possono contenere solo lettere, numeri e _"
username: Username
write_your_username: "Modifica il tuo username"
your_username: "Il tuo username comparirà in tutti i tuoi commenti che pubblicherai."
change_password:
change_password: "Modifica password"
passwords_dont_match: "Le passwords non coincidono"
required_field: "Questo campo è obbligatorio"
forgot_password: "Hai dimenticato la password?"
save: "Salva"
cancel: "Annulla"
edit: "Modifica"
changed_password_msg: "La tua password è stata modificata con successo"
nl_NL:
talk-plugin-auth:
login:
@@ -394,6 +490,59 @@ pt_BR:
username: Nome de usuário
write_your_username: "Edite seu nome de usuário"
your_username: "Seu nome de usuário aparece em cada comentário feito."
sr:
talk-plugin-auth:
login:
email_verify_cta: "Molimo potvrdite vašu e-mail adresu."
request_new_verify_email: "Zatraži novu email poruku"
verify_email: "Hvala Vam što ste napravili nalog! Poslali smo e-mail poruku za potvrdu naloga na adresu koju ste uneli."
verify_email2: "Morate potvrditi svoj nalog pre nego što se uključite u raspravu."
not_you: "Niste Vi?"
logged_in_as: "Prijavljeni ste kao"
logout: "Odjava"
sign_in: "Prijava"
sign_in_to_join: "Prijavite se da biste se uključili u raspravu"
or: "Ili"
email: "E-mail adresa"
password: "Lozinka"
password_error: "Lozinka mora sadržati najmanje 8 karaktera."
forgot_your_pass: "Zaboravili ste lozinku?"
need_an_account: "Nemate nalog?"
register: "Registrujte se"
sign_up: "Prijavite se"
confirm_password: "Potvrdite lozinku"
username: "Korisničko ime"
already_have_an_account: "Već imate nalog?"
recover_password: "Oporavite lozinku"
email_in_use: "E-mail adresa je već u upotrebi"
email_or_username_in_use: "E-mail adresa ili korisničko ime su već u upotrebi"
required_field: "Ovo polje je obavezno"
passwords_dont_match: "Lozinke se ne poklapaju."
special_characters: "Korisničko ime može sadržati isključivo slova, brojeve ili _"
sign_in_to_comment: "Prijava za komentarisanje"
check_the_form: "Neispravan formular. Molimo, proverite polja"
set_username_dialog:
check_the_form: "Neispravan formular. Molimo, proverite polja"
continue: "Nastavite sa istim Facebook imenom"
error_create: "Greška pri promeni korisničkog imena"
fake_comment_body: "Ovo je jedan ogledni komentar. Čitaoci mogu da dele svoje stavove i mišljenja sa uredništvom u sekciji sa komentarima."
fake_comment_date: "Pre jedan minut"
if_you_dont_change_your_name: "Ukoliko ne promenite korisničko ime u ovom koraku vaše Facebook ime će se pojavljivati uz vaše komentare."
required_field: "Obavezno polje"
save: Snimi
special_characters: "Korisničko ime može sadržati isključivo slova, brojeve ili _"
username: Korisničko ime
write_your_username: "Uredi svoje korisničko ime"
your_username: "Vaše korisničko ime prikazuje se uz svaki komentar koji pošaljete."
change_password:
change_password: "Promeni lozinku"
passwords_dont_match: "Lozinke se ne poklapaju"
required_field: "Polje je obavezno"
forgot_password: "Zaboravili ste lozinku?"
save: "Snimi"
cancel: "Poništi"
edit: "Uredi"
changed_password_msg: "Vaša lozinka je uspešno promenjena"
zh_CN:
talk-plugin-auth:
login:
@@ -2,19 +2,25 @@ ar:
talk-plugin-author-menu:
da:
talk-plugin-author-menu:
en:
talk-plugin-author-menu:
de:
talk-plugin-author-menu:
en:
talk-plugin-author-menu:
es:
talk-plugin-author-menu:
fr:
talk-plugin-author-menu:
he:
talk-plugin-author-menu:
it:
talk-plugin-author-menu:
nl_NL:
talk-plugin-author-menu:
pt_BR:
talk-plugin-author-menu:
sr:
talk-plugin-author-menu:
zh_CN:
talk-plugin-author-menu:
zh_TW:
talk-plugin-author-menu:
talk-plugin-author-menu:
@@ -29,6 +29,8 @@ Configuration:
guide. This is only required while the `talk-plugin-facebook-auth` plugin is
enabled.
_NOTE: FabceBook auth requires your site to use `https` (SSL) not `http`. If your site is not `https` you can not use this plugin!_
## GDPR Compliance
In order to facilitate compliance with the
@@ -18,6 +18,14 @@ fr:
talk-plugin-facebook-auth:
sign_in: "Connectez-vous avec Facebook"
sign_up: "Inscrivez-vous avec Facebook"
he:
talk-plugin-facebook-auth:
sign_in: "התחבר עם פייסבוק"
sign_up: "הרשם עם פייסבוק"
it:
talk-plugin-facebook-auth:
sign_in: "Accedi con Facebook"
sign_up: "Registrati con Facebook"
nl_NL:
talk-plugin-facebook-auth:
sign_in: "Inloggen met Facebook"
@@ -28,21 +28,6 @@ da:
are_you_sure: Are you sure you would like to feature this comment?
cancel: Cancel
yes_feature_comment: Yes, feature comment
en:
talk-plugin-featured-comments:
un_feature: Un-Feature
feature: Feature
featured: Featured
featured_comments: Featured Comments
go_to_conversation: Go to conversation
tooltip_description: Comments selected by our team as worth reading
notify_self_featured: 'The comment from {0} is now featured and approved'
notify_featured: '{0} featured and approved comment "{1}"'
notify_unfeatured: '{0} unfeatured comment "{1}"'
feature_comment: Feature comment?
are_you_sure: Are you sure you would like to feature this comment?
cancel: Cancel
yes_feature_comment: Yes, feature comment
de:
talk-plugin-featured-comments:
un_feature: Empfehlung aufheben
@@ -58,6 +43,21 @@ de:
are_you_sure: Sind Sie sicher, dass Sie diesen Kommentar empfehlen möchten?
cancel: Abbrechen
yes_feature_comment: Ja, empfehlen
en:
talk-plugin-featured-comments:
un_feature: Un-Feature
feature: Feature
featured: Featured
featured_comments: Featured Comments
go_to_conversation: Go to conversation
tooltip_description: Comments selected by our team as worth reading
notify_self_featured: 'The comment from {0} is now featured and approved'
notify_featured: '{0} featured and approved comment "{1}"'
notify_unfeatured: '{0} unfeatured comment "{1}"'
feature_comment: Feature comment?
are_you_sure: Are you sure you would like to feature this comment?
cancel: Cancel
yes_feature_comment: Yes, feature comment
es:
talk-plugin-featured-comments:
un_feature: Desmarcar
@@ -85,17 +85,47 @@ fr:
are_you_sure: Are you sure you would like to feature this comment?
cancel: Cancel
yes_feature_comment: Yes, feature comment
he:
talk-plugin-featured-comments:
un_feature: תסיר המלצה
feature: ממליץ
featured: מומלצים
featured_comments: תגובות מומלצות
go_to_conversation: עבור אל השיחה
tooltip_description: תגובות שנבחרו על ידי הצוות שלנו כקריאה שווה
notify_self_featured: 'ההערה מ {0} מומלצת ומאושרת כעת'
notify_featured: '"{0} המליץ ואושר תגובה {1}"'
notify_unfeatured: '{0} הוסר את ההמלצה מתגובה "{1}"'
feature_comment: ממליץ תגובה?
are_you_sure: האם אתה בטוח שברצונך להמליץ את התגובה הזו?
cancel: בטל
yes_feature_comment: כן, ממליץ תגובה
it:
talk-plugin-featured-comments:
un_feature: Rimuovi dal primo piano
feature: Metti in primo piano
featured: Messo in primo piano
featured_comments: Commenti in primo piano
go_to_conversation: Vai alla conversazione
tooltip_description: Commenti selezionati dal tuo team come meritevoli di essere letti
notify_self_featured: 'Il commento da {0} è ora in primo piano e approvato'
notify_featured: '{0} ha messo in primo piano e approvato il commento "{1}"'
notify_unfeatured: '{0} ha rimosso dal primo piano il commento "{1}"'
feature_comment: Metti in primo piano il commento?
are_you_sure: Sei sicuro di voler mettere in primo piano questo commento?
cancel: Annulla
yes_feature_comment: Sì, metti il commento in primo piano
nl_NL:
talk-plugin-featured-comments:
un_feature: Uitlichting opheffen.
un_feature: Uitlichten ongedaan maken.
feature: Uitlichten
featured: Uitgelicht
featured_comments: Uitgelichte reacties
go_to_conversation: Ga naar conversatie
tooltip_description: Reacties die ons team de moeite waard vind om te lezen.
go_to_conversation: Ga naar discussie
tooltip_description: Reacties die ons team de moeite waard vindt om te lezen.
notify_self_featured: 'De reactie van {0} is nu uitgelicht en goedgekeurd'
notify_featured: '{0} heeft de volgende reactie uitgelicht en goedgekeurd: "{1}"'
notify_unfeatured: '{0} hief de uitlichting op van reactie "{1}"'
notify_unfeatured: '{0} hef de uitlichting op van de reactie "{1}"'
feature_comment: Reactie uitlichten?
are_you_sure: Weet je zeker dat je deze reactie wil uitlichten?
cancel: Annuleren
@@ -115,6 +145,21 @@ pt_BR:
are_you_sure: Você tem certeza que deseja destacar esse comentário?
cancel: Cancelar
yes_feature_comment: Sim, destacar comentário
sr:
talk-plugin-featured-comments:
un_feature: Skini sa izdvojenih
feature: Označi kao izdvojen
featured: Izdvojen
featured_comments: Izdvojeni komentari
go_to_conversation: Idi na raspravu
tooltip_description: Komentari izdvojeni od strane redakcije kao posebno vredni pažnje
notify_self_featured: 'Komentar od {0} je sada izdvojen i odobren'
notify_featured: '{0} je izdvojio i odobrio komentar "{1}"'
notify_unfeatured: '{0} je skinuo sa izdvojenih komentara "{1}"'
feature_comment: Izdvoj komentar?
are_you_sure: Sigurni ste da želite da izdvojite ovaj komentar?
cancel: Poništi
yes_feature_comment: Da, izdvoj komentar
zh_CN:
talk-plugin-featured-comments:
un_feature: "取消精选"
@@ -3,28 +3,37 @@ ar:
flags: تقارير
da:
talk-plugin-flag-details:
flags: Reports
en:
talk-plugin-flag-details:
flags: Reports
flags: Reports
de:
talk-plugin-flag-details:
flags: Markierungen
en:
talk-plugin-flag-details:
flags: Reports
es:
talk-plugin-flag-details:
flags: Reportes
fr:
talk-plugin-flag-details:
flags: Reports
he:
talk-plugin-flag-details:
flags: דיווחים
it:
talk-plugin-flag-details:
flags: Rapporti
nl_NL:
talk-plugin-flag-details:
flags: Meldingen
pt_BR:
talk-plugin-flag-details:
flags: Reports
sr:
talk-plugin-flag-details:
flags: Reporteri
zh_CN:
talk-plugin-flag-details:
flags: "报告"
zh_TW:
talk-plugin-flag-details:
flags: 標記
flags: 標記
@@ -14,6 +14,14 @@ fr:
talk-plugin-google-auth:
sign_in: "Connectez-vous avec Google"
sign_up: "Inscrivez-vous avec Google"
he:
talk-plugin-google-auth:
sign_in: "התחבר עם גוגל"
sign_up: "הרשם עם גוגל"
it:
talk-plugin-google-auth:
sign_in: "Accedi con Google"
sign_up: "Registrati con Google"
nl_NL:
talk-plugin-google-auth:
sign_in: "Inloggen met Google"
+1 -1
View File
@@ -4,6 +4,6 @@
"main": "index.js",
"license": "MIT",
"dependencies": {
"passport-google-oauth2": "^0.1.6"
"passport-google-oauth2": "^0.2.0"
}
}
@@ -24,6 +24,17 @@ da:
notify_success: |
You are now ignoring {0}. You can undo this action from My Profile.
confirmation_title: Ignore {0}?
de:
talk-plugin-ignore-user:
blank_info: Sie ignorieren derzeit keine Nutzer
section_title: Ignorierte Nutzer
section_info: Weil Sie die folgenden Nutzer ignorieren, sind deren Kommentare versteckt.
stop_ignoring: Ignorieren beenden
ignore_user: Nutzer ignorieren
cancel: Abbrechen
confirmation: Wenn Sie Nutzer ignorieren, werden deren Kommentare auf der Seite für Sie unsichtbar. Diese Einstellung können Sie unter Mein Profil ändern.
notify_success: Sie ignorieren jetzt {0}. Sie können diese Einstellung unter Mein Profil wieder aufheben.
confirmation_title: "{0} ignorieren?"
en:
talk-plugin-ignore-user:
blank_info: You are currently not ignoring any users
@@ -38,17 +49,6 @@ en:
notify_success: |
You are now ignoring {0}. You can undo this action from My Profile.
confirmation_title: Ignore {0}?
de:
talk-plugin-ignore-user:
blank_info: Sie ignorieren derzeit keine Nutzer
section_title: Ignorierte Nutzer
section_info: Weil Sie die folgenden Nutzer ignorieren, sind deren Kommentare versteckt.
stop_ignoring: Ignorieren beenden
ignore_user: Nutzer ignorieren
cancel: Abbrechen
confirmation: Wenn Sie Nutzer ignorieren, werden deren Kommentare auf der Seite für Sie unsichtbar. Diese Einstellung können Sie unter Mein Profil ändern.
notify_success: Sie ignorieren jetzt {0}. Sie können diese Einstellung unter Mein Profil wieder aufheben.
confirmation_title: "{0} ignorieren?"
es:
talk-plugin-ignore-user:
section_title: "Usuarios ignorados"
@@ -76,8 +76,36 @@ fr:
notify_success: |
You are now ignoring {0}. You can undo this action from My Profile.
confirmation_title: Ignore {0}?
he:
talk-plugin-ignore-user:
blank_info: בשלב זה אינך מתעלם ממשתמשים
section_title: משתמשים שהתעלמו מהם
section_info: מכיוון שהתעלמת מהמגיבים הבאים, ההערות שלהם מוסתרות.
stop_ignoring: הפסק להתעלם
ignore_user: התעלם מהמשתמש
cancel: בטל
confirmation: |
כאשר תתעלם ממשתמש, כל התגובות שכתבו באתר יוסתרו ממך. תוכל לבטל זאת מאוחר יותר מהפרופיל שלי.
notify_success: |
כעת אתה מתעלם {0}. תוכל לבטל את הפעולה הזו מהפרופיל שלי.
confirmation_title: "התעלם {0}?"
it:
talk-plugin-ignore-user:
blank_info: In questo momento non stai ignorando alcun utente
section_title: Utenti ignorati
section_info: Perché stai ignorando i seguenti utenti, i loro commenti saranno nascosti.
stop_ignoring: Non ignorare più
ignore_user: Ignora utente
cancel: Annulla
confirmation: |
Quando ignori un utente, tutti i loro commenti saranno nascosti. Puoi
annullarlo successivamente da Mio Profilo.
notify_success: |
Stai ignorando {0}. Puoi annullare questa azione da Mio Profilo.
confirmation_title: Ignora {0}?
nl_NL:
talk-plugin-ignore-user:
blank_info: Momenteel negeer je geen gebruikers
section_title: Genegeerde gebruikers
section_info: Omdat je de volgende reageerders negeert, worden hun reacties verborgen.
stop_ignoring: Stop met negeren
@@ -103,6 +131,20 @@ pt_BR:
notify_success: |
Agora você está ignorando {0}. Você pode desfazer essa ação em Meu Perfil.
confirmation_title: Ignorar {0}?
sr:
talk-plugin-ignore-user:
blank_info: Trenutno ne ignorišete ni jednog korisnika
section_title: Ignorisani korisnici
section_info: Pošto ste ignorisali sledeće komentatore, njihovi komentari su sakriveni.
stop_ignoring: Prestani sa ignorisanjem
ignore_user: Ignoriši korisnika
cancel: Poništi
confirmation: |
Kada ignorišete nekog korisnika, svi njegovi komentari na sajtu biće skriveni od vas. Ovo podešavanje možete
uvek isključiti u prikazu Moj profil.
notify_success: |
Sada ignorišete {0}. Možete poništiti ovu radnju iz prikaza Moj profil.
confirmation_title: Ignoriši {0}?
zh_CN:
talk-plugin-ignore-user:
section_title: "被忽略用户"
@@ -6,14 +6,14 @@ da:
talk-plugin-like:
like: Like
liked: Liked
en:
talk-plugin-like:
like: Like
liked: Liked
de:
talk-plugin-like:
like: Gefällt mir
liked: Gefällt mir
en:
talk-plugin-like:
like: Like
liked: Liked
es:
talk-plugin-like:
like: Me Gusta
@@ -22,6 +22,14 @@ fr:
talk-plugin-like:
like: Like
liked: Liked
he:
talk-plugin-like:
like: לייק
liked: לייקד
it:
talk-plugin-like:
like: Mi piace
liked: Piaciuto
nl_NL:
talk-plugin-like:
like: Like
@@ -30,6 +38,10 @@ pt_BR:
talk-plugin-like:
like: Like
liked: Liked
sr:
talk-plugin-like:
like: Sviđa mi se
liked: Sviđa vam se
zh_CN:
talk-plugin-like:
like: "喜欢"
@@ -150,6 +150,82 @@ en:
description_2: "You can change your account settings by visiting"
path: "My Profile > Settings"
alert: "Email Added!"
sr:
email:
email_change_original:
subject: Promena e-maila
body: Vaša e-mail adresa je promenjena iz {0} u {1}. Ukoliko niste zatražili ovu izmenu, molimo kontaktirajte {2}.
error:
NO_LOCAL_PROFILE: Nijedna postojeća e-mail adresa nije povezana sa ovim nalogom.
LOCAL_PROFILE: E-mail adresa je već povezana sa ovim nalogom.
INCORRECT_PASSWORD: Lozinka koju ste uneli je neispravna.
talk-plugin-local-auth:
change_password:
change_password: "Promenite lozinku"
passwords_dont_match: "Lozinke se ne poklapaju"
required_field: "Ovo polje je obavezno"
forgot_password: "Zaboravili ste lozinku?"
old_password: "Stara lozinka"
new_password: "Nova lozinka"
confirm_new_password: "Potvrdite novu lozinku"
save: "Snimi"
cancel: "Poništi"
edit: "Uredi"
changed_password_msg: "Promena lozinke - Vša lozinka je uspešno promenjena"
forgot_password_sent: "Zaboravljena lozinka - poslali smo Vam e-mail za povraćaj lozinke"
change_username:
change_username_note: "Korisničko ime može biti promenjeno jednom u 14 dana."
is_not_eligible: "Trenutno ne možete promeniti korisničko ime."
save: "Snimi"
edit_profile: "Uredi profil"
cancel: "Poništi"
confirm_username_change: "Potvrdi promenu korisničkog imena"
description: "Pokušavate da promenite svoje korisničko ime. Novo korisničko ime će se pojaviti na svim vašim prethodnim i novim komentarima."
old_username: "Staro korisničko ime"
new_username: "Novo korisničko ime"
re_enter: "Ponovo unesite korisničko ime"
bottom_note: "Napomena: Nećete moći ponovo da menjate svoje korisničko ime narednih 14 dana"
confirm_changes: "Potvrdi izmene"
username_does_not_match: "Korisničko ime ne postoji"
cant_be_equal: "Vaše novo {0} mora se razlikovati od prethodnog"
changed_username_success_msg: "Korisničko ime je promenjeno - Vaše korisničko ime je uspešno promenjeno. Nećete moći ponovo da ga menjate narednih 14 dana."
change_username_attempt: "Koriničko ime ne može biti promenjeno. Korisničko ime može biti promenjeno samo jednom u 14 dana."
change_email:
confirm_email_change: "Potvrdi promenu e-maila"
description: "Pokušavate da promenite e-mail adresu. Vaša nova e-mail adresa biće korišćena za prijavljivanje i primanje obaveštenja o nalogu."
old_email: "Stara e-mail adresa"
new_email: "Nova e-mail adresa"
enter_password: "Unesite lozinku"
incorrect_password: "Pogrešna lozinka"
confirm_change: "Potvrdi izmenu"
cancel: "Poništi"
change_email_msg: "E-mail adresa promenjena. Ova e-mail adresa biće korišćena za prijavljivanje i primanje obaveštenja."
add_email:
add_email_address: "Dodaj e-mail adresu"
enter_email_address: "Unesi e-mail adresu:"
invalid_email_address: "Pogrešna e-mail adresa"
confirm_email_address: "Potvrdi e-mail adresu:"
email_does_not_match: "Email adrese se ne poklapaju"
insert_password: "Unesi lozinku:"
confirm_password: "Potvrdi lozinku:"
required_field: "Ovo polje je obavezno"
done: "Gotovo"
content:
title: "Dodaj e-mail adresu"
description: "For your added security, we require users to add an email address to their accounts. Your email address will be used to:"
item_1: "Receive updates regarding any changes to your account (email address, username, password, etc.)"
item_2: "Omogućuje vam da preuzmete (download) svoje komentare."
item_3: "Send comment notifications that you have chosen to receive."
verify:
title: "Potvrdite e-mail adresu"
description: "Poslali smo e-mail na {0} da potvrdite ssvoj nalog. Morate potvrditi e-mail adresu da bi se mogla koristiti za potvrde promene naloga i obaveštenja."
added:
title: "Email adresa dodata"
description: "Vaša e-mail adresa je dodata u nalog."
subtitle: "Želite da promenite e-mail adresu?"
description_2: "Možete urediti svoj nalog ovde:"
path: "Moj profil > Podešavanja"
alert: "E-mail dodat"
pt_BR:
email:
email_change_original:
@@ -376,6 +452,82 @@ es:
description_2: "Puedes cambiar la configuración de tu cuenta visitando"
path: "Mi perfil > Configuración"
alert: "¡Correo electrónico agregado!"
it:
email:
email_change_original:
subject: Modifica email
body: La tua email è stata cambiata da {0} a {1}. Se non hai richiesto questa modifica, perfavore contatta {2}.
error:
NO_LOCAL_PROFILE: Nessun indirizzo email esistente è associato a questo account.
LOCAL_PROFILE: Un indirizzo email è già associato a questo account.
INCORRECT_PASSWORD: La password fornita non è corretta.
talk-plugin-local-auth:
change_password:
change_password: "Cambia password"
passwords_dont_match: "Le password non coincidono"
required_field: "Questo campo è obbligatorio"
forgot_password: "Dimenticato la password?"
old_password: "Password vecchia"
new_password: "Password nuova"
confirm_new_password: "Conferma la nuova password"
save: "Salva"
cancel: "Annulla"
edit: "Modifica"
changed_password_msg: "Password modificata - La tua password è stata modificata con successo"
forgot_password_sent: "Password dimenticata - Ti abbiamo inviato una email per recuperare la tua password"
change_username:
change_username_note: "Gli username possono essere modificati solo una volta ogni 14 giorni."
is_not_eligible: "In questo momento non puoi cambiare il tuo username."
save: "Salva"
edit_profile: "Modifica Profilo"
cancel: "Annulla"
confirm_username_change: "Conferma cambio dell'username"
description: "Stai cercando di cambiare il tuo username. Il tuo nuovo username apparirà in tutti i tuoi commenti passati e futuri."
old_username: "Username vecchio"
new_username: "Username nuovo"
re_enter: "Ri-scrivi il nuovo username"
bottom_note: "Nota: non potrai più cambiare il tuo username per i prossimi 14 giorni"
confirm_changes: "Conferma modifiche"
username_does_not_match: "Gli username non coincidono"
cant_be_equal: "{0} non può essere uguale al corrente"
changed_username_success_msg: "Username cambiato - Il tuo username è stato modificato con successo. Non potrai più cambiarlo per i prossimi 14 giorni."
change_username_attempt: "L'username non può essere aggiornato. Gli username possono essre cambiati una sola volta ogni 14 giorni."
change_email:
confirm_email_change: "Conferma la modifica dell'indirizzo email"
description: "Stai cercando di modificare il tuo indirizzo email. Il tuo nuovo indirizzo email sarà usato per il login e per ricevere notifiche relative all'account."
old_email: "Indirizzo email vecchio"
new_email: "Indirizzo email nuovo"
enter_password: "Inserisci password"
incorrect_password: "Password incorretta"
confirm_change: "Conferma modifica"
cancel: "Annulla"
change_email_msg: "Indirizzo email modificato. Questo indirizzo email sarà usato per il login e per ricevere notifiche relative all'account."
add_email:
add_email_address: "Aggiungi indirizzo email"
enter_email_address: "Inserisci indirizzo email:"
invalid_email_address: "Indirizzo email non valido"
confirm_email_address: "Conferma indirizzo email:"
email_does_not_match: "Gli indirizzi email non coincidono"
insert_password: "Inserisci la password:"
confirm_password: "Conferma la password:"
required_field: "Questo campo è obbligatorio"
done: "Finito"
content:
title: "Aggiungi indirizzo email"
description: "Per questioni di sicurezza, richiediamo agli utenti di aggiungere un indirizzo email associato ai loro account. Il tuo indirizzo email sarà usato per:"
item_1: "Ricevere aggiornamenti riguardo modifiche relative al tuo account (indirizzo email, username, password, etc.)"
item_2: "Permetterti di scaricare i tuoi commenti."
item_3: "Inviare le notifiche che hai deciso di ricevere."
verify:
title: "Verifica il tuo indirizzo email"
description: "Abbiamo inviato una email a {0} per verificare il tuo account. Devi verificare il tuo indirizzo email così che potrà essere usato per confermare modifiche relative al tuo account e notifiche."
added:
title: "Indirizzo email aggiunto"
description: "Il tuo indirizzo email è stato aggiunto al tuo account."
subtitle: "Vuoi modificare il tuo indirizzo email?"
description_2: "Puoi modificare le impostazioni del tuo account visitando"
path: "Mio Profilo > Impostazioni"
alert: "Email aggiunta!"
nl_NL:
email:
email_change_original:
@@ -5,15 +5,15 @@ ar:
da:
talk-plugin-love:
love: Love
loved: Loved
en:
talk-plugin-love:
love: Love
loved: Loved
loved: Loved
de:
talk-plugin-love:
love: Ich liebe es
loved: Ich liebe es
en:
talk-plugin-love:
love: Love
loved: Loved
es:
talk-plugin-love:
love: Amo
@@ -22,6 +22,14 @@ fr:
talk-plugin-love:
love: Love
loved: Loved
he:
talk-plugin-love:
love: אוהב
loved: אהבתי
it:
talk-plugin-love:
love: Amo
loved: Amato
nl_NL:
talk-plugin-love:
love: Love
@@ -30,6 +38,10 @@ pt_BR:
talk-plugin-love:
love: Love
loved: Loved
sr:
talk-plugin-love:
love: Volim ovo
loved: Volite ovo
zh_CN:
talk-plugin-love:
love: " 比心"
@@ -3,25 +3,34 @@ ar:
member_since: "عضو منذ"
da:
talk-plugin-member-since:
member_since: "Member Since"
en:
talk-plugin-member-since:
member_since: "Member Since"
member_since: "Member Since"
de:
talk-plugin-member-since:
member_since: "Mitglied seit"
en:
talk-plugin-member-since:
member_since: "Member Since"
es:
talk-plugin-member-since:
member_since: "Miembro desde"
fr:
talk-plugin-member-since:
member_since: "Member Since"
he:
talk-plugin-member-since:
member_since: "חבר מאז"
it:
talk-plugin-member-since:
member_since: "Membro dal"
nl_NL:
talk-plugin-member-since:
member_since: "Lid sinds"
pt_BR:
talk-plugin-member-since:
member_since: "Membro desde"
sr:
talk-plugin-member-since:
member_since: "Član od"
zh_CN:
talk-plugin-member-since:
member_since: "成员加入日期"
@@ -70,6 +70,30 @@ fr:
ban_user_dialog_cancel: "Cancel"
ban_user_dialog_yes: "Yes. Ban user"
ban_user_dialog_headline: "Ban User?"
he:
talk-plugin-moderation-actions:
reject_comment: "דחה"
approve_comment: "אשר"
approved_comment: "מאושרת"
moderation_actions: "פעולות מתווך"
ban_user: "חסום משתמש"
ban_user_dialog_sub: "האם אתה בטוח שאתה רוצה לאסור את המשתמש הזה?"
ban_user_dialog_copy: "הערה: חסימת משתמש זה תציב גם תגובה זו בתור נדחה."
ban_user_dialog_cancel: "בטל"
ban_user_dialog_yes: "כן. חסום משתמש"
ban_user_dialog_headline: "חסום משתמש?"
it:
talk-plugin-moderation-actions:
reject_comment: "Rifiuta"
approve_comment: "Approva"
approved_comment: "Approvato"
moderation_actions: "Azioni di moderazione"
ban_user: "Bandisci utente"
ban_user_dialog_sub: "Sei sicuro di voler bandire questo utente?"
ban_user_dialog_copy: "Nota: Bandire questo utente metterà questo commento nella coda di commenti rifiutati."
ban_user_dialog_cancel: "Cancella"
ban_user_dialog_yes: "Sì. Bandisci utente"
ban_user_dialog_headline: "Bandisci utente?"
nl_NL:
talk-plugin-moderation-actions:
reject_comment: "Afkeuren"
@@ -1,12 +1,21 @@
ar:
talk-plugin-notifications-category-featured:
toggle_description: تعليقي تم تمييزه
de:
talk-plugin-notifications-category-featured:
toggle_description: Mein Kommentar wird empfohlen
en:
talk-plugin-notifications-category-featured:
toggle_description: My comment is featured
es:
talk-plugin-notifications-category-featured:
toggle_description: Mi comentario esta presentado
de:
he:
talk-plugin-notifications-category-featured:
toggle_description: Mein Kommentar wird empfohlen
toggle_description: התגובה שלי מובלטת
it:
talk-plugin-notifications-category-featured:
toggle_description: Il mio commento è stato messo in primo piano
nl_NL:
talk-plugin-notifications-category-featured:
toggle_description: Mijn bericht is uitgelicht
@@ -5,21 +5,45 @@ ar:
subject: "تميَزت واحدة من تعليقاتك على {0}"
body: "{0}\n
حدد أحد أعضاء فريقنا هذا التعليق ليتم عرضه كتعليق مميز للقراء الآخرين: {1}"
en:
talk-plugin-notifications:
categories:
featured:
subject: "One of your comments was featured on {0}"
body: "{0}\nA member of our team has selected this comment to be featured for other readers: {1}"
es:
talk-plugin-notifications:
categories:
featured:
subject: "Uno de tus comentarios apareció en {0}"
body: "{0}\nUn miembro de nuestro equipo ha seleccionado este comentario para ser presentado por otros lectores: {1}"
de:
talk-plugin-notifications:
categories:
featured:
subject: "Einer Ihrer Kommentare wurde auf {0} hervorgehoben"
body: "{0}\nEin Mitglied unseres Teams hat diesen Kommentar ausgewählt, er wird jetzt für andere Leser besonders hervorgehoben: {1}"
en:
talk-plugin-notifications:
categories:
featured:
subject: "One of your comments was featured on {0}"
body: "{0}\nA member of our team has selected this comment to be featured for other readers: {1}"
sr:
talk-plugin-notifications:
categories:
featured:
subject: "Jedan Vaš komentar je izdvojen na {0}"
body: "{0}\nČlan našeg tima je izabrao ovaj komentar da bude izdvojen za druge čitaoce: {1}"
es:
talk-plugin-notifications:
categories:
featured:
subject: "Uno de tus comentarios apareció en {0}"
body: "{0}\nUn miembro de nuestro equipo ha seleccionado este comentario para ser presentado por otros lectores: {1}"
he:
talk-plugin-notifications:
categories:
featured:
subject: "אחת מהתגובות שלך הוצגה ב {0}"
body: "{0} \n חבר בצוות שלנו בחר תגובה זו כך שתוצג עבור קוראים אחרים: {1}"
it:
talk-plugin-notifications:
categories:
featured:
subject: "Uno dei tuoi commenti è stato messo in primo piano su {0}"
body: "{0}\nUn membro del nostro team ha selezionato questo commento per essere messo in primo piano per altri lettori: {1}"
nl_NL:
talk-plugin-notifications:
categories:
featured:
subject: "Een van je reacties is uitgelicht in {0}"
body: "{0}\nDe redactie heeft deze reactie uitgelicht voor andere lezers: {1}"
@@ -0,0 +1,19 @@
---
title: talk-plugin-notifications-moderation-actions
permalink: /plugin/talk-plugin-notifications-moderation-actions/
layout: plugin
plugin:
name: talk-plugin-notifications-moderation-actions
depends:
- name: talk-plugin-notifications
provides:
- Server
- Client
---
When a comment that is initially withheld from publication and is then
approved or rejected, the user will receive a notification email.
## Configuration:
- `TALK_MODERATION_NOTIFICATION_TYPES`. This plugin requires values to be set. Available options: `APPROVED`, `REJECTED` as a single string (comma separated).
@@ -0,0 +1,3 @@
{
"extends": "@coralproject/eslint-config-talk/client"
}
@@ -0,0 +1,14 @@
import translations from './translations.yml';
import { t } from 'plugin-api/beta/client/services';
import { createSettingsToggle } from 'talk-plugin-notifications/client/api/factories';
const SettingsToggle = createSettingsToggle('onModeration', () =>
t('talk-plugin-notifications-category-moderation-actions.toggle_description')
);
export default {
slots: {
notificationSettings: [SettingsToggle],
},
translations,
};
@@ -0,0 +1,9 @@
en:
talk-plugin-notifications-category-moderation-actions:
toggle_description: My pending comments have been reviewed
es:
talk-plugin-notifications-category-moderation-actions:
toggle_description: Mis comentarios pendientes han sido revisados
it:
talk-plugin-notifications-category-moderation-actions:
toggle_description: I miei commenti in sospeso sono stati esaminati

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