aboutsummaryrefslogtreecommitdiffstats
path: root/apps/comments
diff options
context:
space:
mode:
Diffstat (limited to 'apps/comments')
-rw-r--r--apps/comments/activity/extension.php322
-rw-r--r--apps/comments/activity/listener.php128
-rw-r--r--apps/comments/appinfo/app.php53
-rw-r--r--apps/comments/appinfo/info.xml46
-rw-r--r--apps/comments/appinfo/routes.php12
-rw-r--r--apps/comments/composer/autoload.php25
-rw-r--r--apps/comments/composer/composer.json13
-rw-r--r--apps/comments/composer/composer.lock18
-rw-r--r--apps/comments/composer/composer/ClassLoader.php579
-rw-r--r--apps/comments/composer/composer/InstalledVersions.php359
-rw-r--r--apps/comments/composer/composer/LICENSE21
-rw-r--r--apps/comments/composer/composer/autoload_classmap.php28
-rw-r--r--apps/comments/composer/composer/autoload_namespaces.php9
-rw-r--r--apps/comments/composer/composer/autoload_psr4.php10
-rw-r--r--apps/comments/composer/composer/autoload_real.php37
-rw-r--r--apps/comments/composer/composer/autoload_static.php54
-rw-r--r--apps/comments/composer/composer/installed.json5
-rw-r--r--apps/comments/composer/composer/installed.php23
-rw-r--r--apps/comments/css/comments.css133
-rw-r--r--apps/comments/img/comments-dark.svg1
-rw-r--r--apps/comments/img/comments.svg1
-rw-r--r--apps/comments/js/app.js20
-rw-r--r--apps/comments/js/commentcollection.js167
-rw-r--r--apps/comments/js/commentmodel.js58
-rw-r--r--apps/comments/js/commentstabview.js435
-rw-r--r--apps/comments/js/commentsummarymodel.js65
-rw-r--r--apps/comments/js/filesplugin.js123
-rw-r--r--apps/comments/l10n/af_ZA.js6
-rw-r--r--apps/comments/l10n/af_ZA.json4
-rw-r--r--apps/comments/l10n/ar.js34
-rw-r--r--apps/comments/l10n/ar.json34
-rw-r--r--apps/comments/l10n/ast.js34
-rw-r--r--apps/comments/l10n/ast.json34
-rw-r--r--apps/comments/l10n/az.js8
-rw-r--r--apps/comments/l10n/az.json6
-rw-r--r--apps/comments/l10n/bg.js30
-rw-r--r--apps/comments/l10n/bg.json28
-rw-r--r--apps/comments/l10n/bg_BG.js8
-rw-r--r--apps/comments/l10n/bg_BG.json6
-rw-r--r--apps/comments/l10n/bn_BD.js8
-rw-r--r--apps/comments/l10n/bn_BD.json6
-rw-r--r--apps/comments/l10n/bn_IN.js7
-rw-r--r--apps/comments/l10n/bn_IN.json5
-rw-r--r--apps/comments/l10n/bs.js8
-rw-r--r--apps/comments/l10n/bs.json6
-rw-r--r--apps/comments/l10n/ca.js34
-rw-r--r--apps/comments/l10n/ca.json34
-rw-r--r--apps/comments/l10n/cs.js36
-rw-r--r--apps/comments/l10n/cs.json34
-rw-r--r--apps/comments/l10n/cs_CZ.js23
-rw-r--r--apps/comments/l10n/cs_CZ.json21
-rw-r--r--apps/comments/l10n/cy_GB.js7
-rw-r--r--apps/comments/l10n/cy_GB.json5
-rw-r--r--apps/comments/l10n/da.js43
-rw-r--r--apps/comments/l10n/da.json43
-rw-r--r--apps/comments/l10n/de.js43
-rw-r--r--apps/comments/l10n/de.json43
-rw-r--r--apps/comments/l10n/de_AT.js7
-rw-r--r--apps/comments/l10n/de_AT.json5
-rw-r--r--apps/comments/l10n/de_DE.js45
-rw-r--r--apps/comments/l10n/de_DE.json45
-rw-r--r--apps/comments/l10n/el.js38
-rw-r--r--apps/comments/l10n/el.json38
-rw-r--r--apps/comments/l10n/en_GB.js43
-rw-r--r--apps/comments/l10n/en_GB.json43
-rw-r--r--apps/comments/l10n/eo.js21
-rw-r--r--apps/comments/l10n/eo.json19
-rw-r--r--apps/comments/l10n/es.js45
-rw-r--r--apps/comments/l10n/es.json45
-rw-r--r--apps/comments/l10n/es_AR.js7
-rw-r--r--apps/comments/l10n/es_AR.json5
-rw-r--r--apps/comments/l10n/es_CL.js6
-rw-r--r--apps/comments/l10n/es_CL.json4
-rw-r--r--apps/comments/l10n/es_CO.js35
-rw-r--r--apps/comments/l10n/es_CO.json33
-rw-r--r--apps/comments/l10n/es_EC.js31
-rw-r--r--apps/comments/l10n/es_EC.json29
-rw-r--r--apps/comments/l10n/es_MX.js36
-rw-r--r--apps/comments/l10n/es_MX.json36
-rw-r--r--apps/comments/l10n/et_EE.js41
-rw-r--r--apps/comments/l10n/et_EE.json41
-rw-r--r--apps/comments/l10n/eu.js34
-rw-r--r--apps/comments/l10n/eu.json34
-rw-r--r--apps/comments/l10n/fa.js36
-rw-r--r--apps/comments/l10n/fa.json36
-rw-r--r--apps/comments/l10n/fi.js34
-rw-r--r--apps/comments/l10n/fi.json32
-rw-r--r--apps/comments/l10n/fi_FI.js23
-rw-r--r--apps/comments/l10n/fi_FI.json21
-rw-r--r--apps/comments/l10n/fil.js6
-rw-r--r--apps/comments/l10n/fil.json4
-rw-r--r--apps/comments/l10n/fr.js45
-rw-r--r--apps/comments/l10n/fr.json45
-rw-r--r--apps/comments/l10n/ga.js36
-rw-r--r--apps/comments/l10n/ga.json34
-rw-r--r--apps/comments/l10n/gl.js34
-rw-r--r--apps/comments/l10n/gl.json34
-rw-r--r--apps/comments/l10n/he.js39
-rw-r--r--apps/comments/l10n/he.json39
-rw-r--r--apps/comments/l10n/hi.js7
-rw-r--r--apps/comments/l10n/hi.json5
-rw-r--r--apps/comments/l10n/hr.js26
-rw-r--r--apps/comments/l10n/hr.json26
-rw-r--r--apps/comments/l10n/hu.js36
-rw-r--r--apps/comments/l10n/hu.json34
-rw-r--r--apps/comments/l10n/hu_HU.js21
-rw-r--r--apps/comments/l10n/hu_HU.json19
-rw-r--r--apps/comments/l10n/hy.js7
-rw-r--r--apps/comments/l10n/hy.json5
-rw-r--r--apps/comments/l10n/ia.js7
-rw-r--r--apps/comments/l10n/ia.json5
-rw-r--r--apps/comments/l10n/id.js35
-rw-r--r--apps/comments/l10n/id.json35
-rw-r--r--apps/comments/l10n/is.js43
-rw-r--r--apps/comments/l10n/is.json43
-rw-r--r--apps/comments/l10n/it.js45
-rw-r--r--apps/comments/l10n/it.json45
-rw-r--r--apps/comments/l10n/ja.js43
-rw-r--r--apps/comments/l10n/ja.json43
-rw-r--r--apps/comments/l10n/ka.js32
-rw-r--r--apps/comments/l10n/ka.json30
-rw-r--r--apps/comments/l10n/ka_GE.js7
-rw-r--r--apps/comments/l10n/ka_GE.json5
-rw-r--r--apps/comments/l10n/km.js7
-rw-r--r--apps/comments/l10n/km.json5
-rw-r--r--apps/comments/l10n/kn.js7
-rw-r--r--apps/comments/l10n/kn.json5
-rw-r--r--apps/comments/l10n/ko.js43
-rw-r--r--apps/comments/l10n/ko.json43
-rw-r--r--apps/comments/l10n/ku_IQ.js7
-rw-r--r--apps/comments/l10n/ku_IQ.json5
-rw-r--r--apps/comments/l10n/lb.js7
-rw-r--r--apps/comments/l10n/lb.json5
-rw-r--r--apps/comments/l10n/lt_LT.js29
-rw-r--r--apps/comments/l10n/lt_LT.json29
-rw-r--r--apps/comments/l10n/lv.js8
-rw-r--r--apps/comments/l10n/lv.json6
-rw-r--r--apps/comments/l10n/mk.js35
-rw-r--r--apps/comments/l10n/mk.json35
-rw-r--r--apps/comments/l10n/mn.js6
-rw-r--r--apps/comments/l10n/mn.json4
-rw-r--r--apps/comments/l10n/ms_MY.js7
-rw-r--r--apps/comments/l10n/ms_MY.json5
-rw-r--r--apps/comments/l10n/my_MM.js6
-rw-r--r--apps/comments/l10n/my_MM.json4
-rw-r--r--apps/comments/l10n/nb.js36
-rw-r--r--apps/comments/l10n/nb.json34
-rw-r--r--apps/comments/l10n/nb_NO.js21
-rw-r--r--apps/comments/l10n/nb_NO.json19
-rw-r--r--apps/comments/l10n/nds.js6
-rw-r--r--apps/comments/l10n/nds.json4
-rw-r--r--apps/comments/l10n/nl.js47
-rw-r--r--apps/comments/l10n/nl.json47
-rw-r--r--apps/comments/l10n/nn_NO.js7
-rw-r--r--apps/comments/l10n/nn_NO.json5
-rw-r--r--apps/comments/l10n/oc.js26
-rw-r--r--apps/comments/l10n/oc.json26
-rw-r--r--apps/comments/l10n/pa.js6
-rw-r--r--apps/comments/l10n/pa.json4
-rw-r--r--apps/comments/l10n/pl.js45
-rw-r--r--apps/comments/l10n/pl.json45
-rw-r--r--apps/comments/l10n/pt_BR.js47
-rw-r--r--apps/comments/l10n/pt_BR.json47
-rw-r--r--apps/comments/l10n/pt_PT.js38
-rw-r--r--apps/comments/l10n/pt_PT.json38
-rw-r--r--apps/comments/l10n/ro.js29
-rw-r--r--apps/comments/l10n/ro.json29
-rw-r--r--apps/comments/l10n/ru.js45
-rw-r--r--apps/comments/l10n/ru.json45
-rw-r--r--apps/comments/l10n/sc.js31
-rw-r--r--apps/comments/l10n/sc.json29
-rw-r--r--apps/comments/l10n/si_LK.js7
-rw-r--r--apps/comments/l10n/si_LK.json5
-rw-r--r--apps/comments/l10n/sk.js36
-rw-r--r--apps/comments/l10n/sk.json34
-rw-r--r--apps/comments/l10n/sk_SK.js8
-rw-r--r--apps/comments/l10n/sk_SK.json6
-rw-r--r--apps/comments/l10n/sl.js45
-rw-r--r--apps/comments/l10n/sl.json45
-rw-r--r--apps/comments/l10n/sq.js23
-rw-r--r--apps/comments/l10n/sq.json21
-rw-r--r--apps/comments/l10n/sr.js43
-rw-r--r--apps/comments/l10n/sr.json43
-rw-r--r--apps/comments/l10n/sr@latin.js7
-rw-r--r--apps/comments/l10n/sr@latin.json5
-rw-r--r--apps/comments/l10n/sv.js43
-rw-r--r--apps/comments/l10n/sv.json43
-rw-r--r--apps/comments/l10n/sw.js36
-rw-r--r--apps/comments/l10n/sw.json34
-rw-r--r--apps/comments/l10n/ta_LK.js7
-rw-r--r--apps/comments/l10n/ta_LK.json5
-rw-r--r--apps/comments/l10n/te.js7
-rw-r--r--apps/comments/l10n/te.json5
-rw-r--r--apps/comments/l10n/th_TH.js17
-rw-r--r--apps/comments/l10n/th_TH.json15
-rw-r--r--apps/comments/l10n/tr.js43
-rw-r--r--apps/comments/l10n/tr.json43
-rw-r--r--apps/comments/l10n/ug.js34
-rw-r--r--apps/comments/l10n/ug.json34
-rw-r--r--apps/comments/l10n/uk.js45
-rw-r--r--apps/comments/l10n/uk.json45
-rw-r--r--apps/comments/l10n/ur_PK.js7
-rw-r--r--apps/comments/l10n/ur_PK.json5
-rw-r--r--apps/comments/l10n/vi.js28
-rw-r--r--apps/comments/l10n/vi.json28
-rw-r--r--apps/comments/l10n/zh_CN.js43
-rw-r--r--apps/comments/l10n/zh_CN.json43
-rw-r--r--apps/comments/l10n/zh_HK.js33
-rw-r--r--apps/comments/l10n/zh_HK.json33
-rw-r--r--apps/comments/l10n/zh_TW.js45
-rw-r--r--apps/comments/l10n/zh_TW.json45
-rw-r--r--apps/comments/lib/Activity/Filter.php50
-rw-r--r--apps/comments/lib/Activity/Listener.php88
-rw-r--r--apps/comments/lib/Activity/Provider.php198
-rw-r--r--apps/comments/lib/Activity/Setting.php53
-rw-r--r--apps/comments/lib/AppInfo/Application.php62
-rw-r--r--apps/comments/lib/Capabilities.php24
-rw-r--r--apps/comments/lib/Collaboration/CommentersSorter.php92
-rw-r--r--apps/comments/lib/Controller/NotificationsController.php103
-rw-r--r--apps/comments/lib/Listener/CommentsEntityEventListener.php35
-rw-r--r--apps/comments/lib/Listener/CommentsEventListener.php63
-rw-r--r--apps/comments/lib/Listener/LoadAdditionalScripts.php27
-rw-r--r--apps/comments/lib/Listener/LoadSidebarScripts.php40
-rw-r--r--apps/comments/lib/MaxAutoCompleteResultsInitialState.php27
-rw-r--r--apps/comments/lib/Notification/Listener.php84
-rw-r--r--apps/comments/lib/Notification/Notifier.php177
-rw-r--r--apps/comments/lib/Search/CommentsSearchProvider.php71
-rw-r--r--apps/comments/lib/Search/LegacyProvider.php97
-rw-r--r--apps/comments/lib/Search/Result.php105
-rw-r--r--apps/comments/openapi.json46
-rw-r--r--apps/comments/openapi.json.license2
-rw-r--r--apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts179
-rw-r--r--apps/comments/src/actions/inlineUnreadCommentsAction.ts46
-rw-r--r--apps/comments/src/comments-activity-tab.ts78
-rw-r--r--apps/comments/src/comments-app.js15
-rw-r--r--apps/comments/src/comments-tab.js60
-rw-r--r--apps/comments/src/components/Comment.vue384
-rw-r--r--apps/comments/src/init.ts8
-rw-r--r--apps/comments/src/logger.js11
-rw-r--r--apps/comments/src/mixins/CommentMixin.js115
-rw-r--r--apps/comments/src/mixins/CommentView.ts76
-rw-r--r--apps/comments/src/services/CommentsInstance.js55
-rw-r--r--apps/comments/src/services/DavClient.js27
-rw-r--r--apps/comments/src/services/DeleteComment.js20
-rw-r--r--apps/comments/src/services/EditComment.js32
-rw-r--r--apps/comments/src/services/GetComments.ts67
-rw-r--r--apps/comments/src/services/NewComment.js50
-rw-r--r--apps/comments/src/services/ReadComments.ts38
-rw-r--r--apps/comments/src/store/deletedCommentLimbo.js28
-rw-r--r--apps/comments/src/utils/cancelableRequest.js36
-rw-r--r--apps/comments/src/utils/davUtils.js12
-rw-r--r--apps/comments/src/utils/decodeHtmlEntities.js17
-rw-r--r--apps/comments/src/views/ActivityCommentAction.vue54
-rw-r--r--apps/comments/src/views/ActivityCommentEntry.vue71
-rw-r--r--apps/comments/src/views/Comments.vue279
-rw-r--r--apps/comments/tests/Unit/Activity/ListenerTest.php159
-rw-r--r--apps/comments/tests/Unit/AppInfo/ApplicationTest.php62
-rw-r--r--apps/comments/tests/Unit/Collaboration/CommentersSorterTest.php136
-rw-r--r--apps/comments/tests/Unit/Controller/NotificationsTest.php214
-rw-r--r--apps/comments/tests/Unit/EventHandlerTest.php87
-rw-r--r--apps/comments/tests/Unit/Notification/ListenerTest.php195
-rw-r--r--apps/comments/tests/Unit/Notification/NotifierTest.php554
-rw-r--r--apps/comments/tests/js/commentscollectionSpec.js148
-rw-r--r--apps/comments/tests/js/commentstabviewSpec.js452
-rw-r--r--apps/comments/tests/js/filespluginSpec.js102
265 files changed, 8960 insertions, 3760 deletions
diff --git a/apps/comments/activity/extension.php b/apps/comments/activity/extension.php
deleted file mode 100644
index 6bf7cae5882..00000000000
--- a/apps/comments/activity/extension.php
+++ /dev/null
@@ -1,322 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Comments\Activity;
-
-use OCP\Activity\IExtension;
-use OCP\Activity\IManager;
-use OCP\Comments\ICommentsManager;
-use OCP\Comments\NotFoundException;
-use OCP\IL10N;
-use OCP\IURLGenerator;
-use OCP\L10N\IFactory;
-
-/**
- * Class Extension
- *
- * @package OCA\Comments\Activity
- */
-class Extension implements IExtension {
- const APP_NAME = 'comments';
-
- const ADD_COMMENT_SUBJECT = 'add_comment_subject';
- const ADD_COMMENT_MESSAGE = 'add_comment_message';
-
- /** @var IFactory */
- protected $languageFactory;
-
- /** @var IManager */
- protected $activityManager;
-
- /** @var ICommentsManager */
- protected $commentsManager;
-
- /** @var IURLGenerator */
- protected $URLGenerator;
-
- /**
- * @param IFactory $languageFactory
- * @param IManager $activityManager
- * @param ICommentsManager $commentsManager
- * @param IURLGenerator $URLGenerator
- */
- public function __construct(IFactory $languageFactory, IManager $activityManager, ICommentsManager $commentsManager, IURLGenerator $URLGenerator) {
- $this->languageFactory = $languageFactory;
- $this->activityManager = $activityManager;
- $this->commentsManager = $commentsManager;
- $this->URLGenerator = $URLGenerator;
- }
-
- protected function getL10N($languageCode = null) {
- return $this->languageFactory->get(self::APP_NAME, $languageCode);
- }
-
- /**
- * The extension can return an array of additional notification types.
- * If no additional types are to be added false is to be returned
- *
- * @param string $languageCode
- * @return array|false
- */
- public function getNotificationTypes($languageCode) {
- $l = $this->getL10N($languageCode);
-
- return array(
- self::APP_NAME => (string) $l->t('<strong>Comments</strong> for files'),
- );
- }
-
- /**
- * For a given method additional types to be displayed in the settings can be returned.
- * In case no additional types are to be added false is to be returned.
- *
- * @param string $method
- * @return array|false
- */
- public function getDefaultTypes($method) {
- return $method === self::METHOD_STREAM ? [self::APP_NAME] : false;
- }
-
- /**
- * A string naming the css class for the icon to be used can be returned.
- * If no icon is known for the given type false is to be returned.
- *
- * @param string $type
- * @return string|false
- */
- public function getTypeIcon($type) {
- switch ($type) {
- case self::APP_NAME:
- return 'icon-comment';
- }
-
- return false;
- }
-
- /**
- * The extension can translate a given message to the requested languages.
- * If no translation is available false is to be returned.
- *
- * @param string $app
- * @param string $text
- * @param array $params
- * @param boolean $stripPath
- * @param boolean $highlightParams
- * @param string $languageCode
- * @return string|false
- */
- public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
- if ($app !== self::APP_NAME) {
- return false;
- }
-
- $l = $this->getL10N($languageCode);
-
- if ($this->activityManager->isFormattingFilteredObject()) {
- $translation = $this->translateShort($text, $l, $params);
- if ($translation !== false) {
- return $translation;
- }
- }
-
- return $this->translateLong($text, $l, $params);
- }
-
- /**
- * @param string $text
- * @param IL10N $l
- * @param array $params
- * @return bool|string
- */
- protected function translateShort($text, IL10N $l, array $params) {
-
- switch ($text) {
- case self::ADD_COMMENT_SUBJECT:
- if ($this->authorIsCurrentUser($params[0])) {
- return (string) $l->t('You commented');
- }
- return (string) $l->t('%1$s commented', $params);
- case self::ADD_COMMENT_MESSAGE:
- return $this->convertParameterToComment($params[0], 120);
- }
-
- return false;
- }
-
- /**
- * @param string $text
- * @param IL10N $l
- * @param array $params
- * @return bool|string
- */
- protected function translateLong($text, IL10N $l, array $params) {
-
- switch ($text) {
- case self::ADD_COMMENT_SUBJECT:
- if ($this->authorIsCurrentUser($params[0])) {
- return (string) $l->t('You commented on %2$s', $params);
- }
- return (string) $l->t('%1$s commented on %2$s', $params);
- case self::ADD_COMMENT_MESSAGE:
- return $this->convertParameterToComment($params[0]);
- }
-
- return false;
- }
-
- /**
- * Check if the author is the current user
- *
- * @param string $user Parameter e.g. `<user display-name="admin">admin</user>`
- * @return bool
- */
- protected function authorIsCurrentUser($user) {
- try {
- return strip_tags($user) === $this->activityManager->getCurrentUserId();
- } catch (\UnexpectedValueException $e) {
- // FIXME this is awkward, but we have no access to the current user in emails
- return false;
- }
- }
-
- /**
- * The extension can define the type of parameters for translation
- *
- * Currently known types are:
- * * file => will strip away the path of the file and add a tooltip with it
- * * username => will add the avatar of the user
- *
- * @param string $app
- * @param string $text
- * @return array|false
- */
- public function getSpecialParameterList($app, $text) {
- if ($app === self::APP_NAME) {
- switch ($text) {
- case self::ADD_COMMENT_SUBJECT:
- return [
- 0 => 'username',
- 1 => 'file',
- ];
- }
- }
-
- return false;
- }
-
- /**
- * The extension can define the parameter grouping by returning the index as integer.
- * In case no grouping is required false is to be returned.
- *
- * @param array $activity
- * @return integer|false
- */
- public function getGroupParameter($activity) {
- return false;
- }
-
- /**
- * The extension can define additional navigation entries. The array returned has to contain two keys 'top'
- * and 'apps' which hold arrays with the relevant entries.
- * If no further entries are to be added false is no be returned.
- *
- * @return array|false
- */
- public function getNavigation() {
- $l = $this->getL10N();
- return [
- 'apps' => [],
- 'top' => [
- self::APP_NAME => [
- 'id' => self::APP_NAME,
- 'name' => (string) $l->t('Comments'),
- 'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::APP_NAME]),
- ],
- ],
- ];
- }
-
- /**
- * The extension can check if a custom filter (given by a query string like filter=abc) is valid or not.
- *
- * @param string $filterValue
- * @return boolean
- */
- public function isFilterValid($filterValue) {
- return $filterValue === self::APP_NAME;
- }
-
- /**
- * The extension can filter the types based on the filter if required.
- * In case no filter is to be applied false is to be returned unchanged.
- *
- * @param array $types
- * @param string $filter
- * @return array|false
- */
- public function filterNotificationTypes($types, $filter) {
- if ($filter === self::APP_NAME) {
- return array_intersect($types, [self::APP_NAME]);
- }
- return false;
- }
-
- /**
- * For a given filter the extension can specify the sql query conditions including parameters for that query.
- * In case the extension does not know the filter false is to be returned.
- * The query condition and the parameters are to be returned as array with two elements.
- * E.g. return array('`app` = ? and `message` like ?', array('mail', 'ownCloud%'));
- *
- * @param string $filter
- * @return array|false
- */
- public function getQueryForFilter($filter) {
- return false;
- }
-
- /**
- * @param string $parameter
- * @return string
- */
- protected function convertParameterToComment($parameter, $maxLength = 0) {
- if (preg_match('/^\<parameter\>(\d*)\<\/parameter\>$/', $parameter, $matches)) {
- try {
- $comment = $this->commentsManager->get((int) $matches[1]);
- $message = $comment->getMessage();
- $message = str_replace("\n", '<br />', str_replace(['<', '>'], ['&lt;', '&gt;'], $message));
-
- if ($maxLength && isset($message[$maxLength + 20])) {
- $findSpace = strpos($message, ' ', $maxLength);
- if ($findSpace !== false && $findSpace < $maxLength + 20) {
- return substr($message, 0, $findSpace) . '…';
- }
- return substr($message, 0, $maxLength + 20) . '…';
- }
-
- return $message;
- } catch (NotFoundException $e) {
- return '';
- }
- }
-
- return '';
- }
-}
diff --git a/apps/comments/activity/listener.php b/apps/comments/activity/listener.php
deleted file mode 100644
index 7c6970df837..00000000000
--- a/apps/comments/activity/listener.php
+++ /dev/null
@@ -1,128 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Comments\Activity;
-
-use OCP\Activity\IManager;
-use OCP\App\IAppManager;
-use OCP\Comments\CommentsEvent;
-use OCP\Files\Config\IMountProviderCollection;
-use OCP\Files\IRootFolder;
-use OCP\Files\Node;
-use OCP\IUser;
-use OCP\IUserSession;
-use OCP\Share;
-
-class Listener {
- /** @var IManager */
- protected $activityManager;
- /** @var IUserSession */
- protected $session;
- /** @var \OCP\App\IAppManager */
- protected $appManager;
- /** @var \OCP\Files\Config\IMountProviderCollection */
- protected $mountCollection;
- /** @var \OCP\Files\IRootFolder */
- protected $rootFolder;
-
- /**
- * Listener constructor.
- *
- * @param IManager $activityManager
- * @param IUserSession $session
- * @param IAppManager $appManager
- * @param IMountProviderCollection $mountCollection
- * @param IRootFolder $rootFolder
- */
- public function __construct(IManager $activityManager,
- IUserSession $session,
- IAppManager $appManager,
- IMountProviderCollection $mountCollection,
- IRootFolder $rootFolder) {
- $this->activityManager = $activityManager;
- $this->session = $session;
- $this->appManager = $appManager;
- $this->mountCollection = $mountCollection;
- $this->rootFolder = $rootFolder;
- }
-
- /**
- * @param CommentsEvent $event
- */
- public function commentEvent(CommentsEvent $event) {
- if ($event->getComment()->getObjectType() !== 'files'
- || !in_array($event->getEvent(), [CommentsEvent::EVENT_ADD])
- || !$this->appManager->isInstalled('activity')) {
- // Comment not for file, not adding a comment or no activity-app enabled (save the energy)
- return;
- }
-
- // Get all mount point owners
- $cache = $this->mountCollection->getMountCache();
- $mounts = $cache->getMountsForFileId($event->getComment()->getObjectId());
- if (empty($mounts)) {
- return;
- }
-
- $users = [];
- foreach ($mounts as $mount) {
- $owner = $mount->getUser()->getUID();
- $ownerFolder = $this->rootFolder->getUserFolder($owner);
- $nodes = $ownerFolder->getById($event->getComment()->getObjectId());
- if (!empty($nodes)) {
- /** @var Node $node */
- $node = array_shift($nodes);
- $path = $node->getPath();
- if (strpos($path, '/' . $owner . '/files/') === 0) {
- $path = substr($path, strlen('/' . $owner . '/files'));
- }
- // Get all users that have access to the mount point
- $users = array_merge($users, Share::getUsersSharingFile($path, $owner, true, true));
- }
- }
-
- $actor = $this->session->getUser();
- if ($actor instanceof IUser) {
- $actor = $actor->getUID();
- } else {
- $actor = '';
- }
-
- $activity = $this->activityManager->generateEvent();
- $activity->setApp(Extension::APP_NAME)
- ->setType(Extension::APP_NAME)
- ->setAuthor($actor)
- ->setObject($event->getComment()->getObjectType(), $event->getComment()->getObjectId())
- ->setMessage(Extension::ADD_COMMENT_MESSAGE, [
- $event->getComment()->getId(),
- ]);
-
- foreach ($users as $user => $path) {
- $activity->setAffectedUser($user);
-
- $activity->setSubject(Extension::ADD_COMMENT_SUBJECT, [
- $actor,
- $path,
- ]);
- $this->activityManager->publish($activity);
- }
- }
-}
diff --git a/apps/comments/appinfo/app.php b/apps/comments/appinfo/app.php
deleted file mode 100644
index cd1ccb2d7d3..00000000000
--- a/apps/comments/appinfo/app.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-$eventDispatcher = \OC::$server->getEventDispatcher();
-$eventDispatcher->addListener(
- 'OCA\Files::loadAdditionalScripts',
- function() {
- \OCP\Util::addScript('oc-backbone-webdav');
- \OCP\Util::addScript('comments', 'app');
- \OCP\Util::addScript('comments', 'commentmodel');
- \OCP\Util::addScript('comments', 'commentcollection');
- \OCP\Util::addScript('comments', 'commentsummarymodel');
- \OCP\Util::addScript('comments', 'commentstabview');
- \OCP\Util::addScript('comments', 'filesplugin');
- \OCP\Util::addStyle('comments', 'comments');
- }
-);
-
-$activityManager = \OC::$server->getActivityManager();
-$activityManager->registerExtension(function() {
- $application = new \OCP\AppFramework\App('comments');
- /** @var \OCA\Comments\Activity\Extension $extension */
- $extension = $application->getContainer()->query('OCA\Comments\Activity\Extension');
- return $extension;
-});
-
-$managerListener = function(\OCP\Comments\CommentsEvent $event) use ($activityManager) {
- $application = new \OCP\AppFramework\App('comments');
- /** @var \OCA\Comments\Activity\Listener $listener */
- $listener = $application->getContainer()->query('OCA\Comments\Activity\Listener');
- $listener->commentEvent($event);
-};
-
-$eventDispatcher->addListener(\OCP\Comments\CommentsEvent::EVENT_ADD, $managerListener);
diff --git a/apps/comments/appinfo/info.xml b/apps/comments/appinfo/info.xml
index c61b4a0fc7c..dc5af1a70a0 100644
--- a/apps/comments/appinfo/info.xml
+++ b/apps/comments/appinfo/info.xml
@@ -1,16 +1,46 @@
<?xml version="1.0"?>
-<info>
+<!--
+ - SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ - SPDX-License-Identifier: AGPL-3.0-only
+ -->
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>comments</id>
<name>Comments</name>
+ <summary>Files app plugin to add comments to files</summary>
<description>Files app plugin to add comments to files</description>
- <licence>AGPL</licence>
- <author>Arthur Schiwon, Vincent Petry</author>
- <default_enable/>
- <version>0.3.0</version>
- <dependencies>
- <owncloud min-version="9.1" max-version="9.1" />
- </dependencies>
+ <version>1.22.0</version>
+ <licence>agpl</licence>
+ <author>Arthur Schiwon</author>
+ <author>Vincent Petry</author>
<types>
<logging/>
</types>
+ <category>office</category>
+ <category>social</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="32" max-version="32"/>
+ </dependencies>
+
+ <activity>
+ <settings>
+ <setting>OCA\Comments\Activity\Setting</setting>
+ </settings>
+
+ <filters>
+ <filter>OCA\Comments\Activity\Filter</filter>
+ </filters>
+
+ <providers>
+ <provider>OCA\Comments\Activity\Provider</provider>
+ </providers>
+ </activity>
+
+ <collaboration>
+ <plugins>
+ <plugin type="autocomplete-sort">OCA\Comments\Collaboration\CommentersSorter</plugin>
+ </plugins>
+ </collaboration>
</info>
diff --git a/apps/comments/appinfo/routes.php b/apps/comments/appinfo/routes.php
new file mode 100644
index 00000000000..903f1b2168c
--- /dev/null
+++ b/apps/comments/appinfo/routes.php
@@ -0,0 +1,12 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+return [
+ 'routes' => [
+ ['name' => 'Notifications#view', 'url' => '/notifications/view/{id}', 'verb' => 'GET'],
+ ]
+];
diff --git a/apps/comments/composer/autoload.php b/apps/comments/composer/autoload.php
new file mode 100644
index 00000000000..2bbfd4fbebe
--- /dev/null
+++ b/apps/comments/composer/autoload.php
@@ -0,0 +1,25 @@
+<?php
+
+// autoload.php @generated by Composer
+
+if (PHP_VERSION_ID < 50600) {
+ if (!headers_sent()) {
+ header('HTTP/1.1 500 Internal Server Error');
+ }
+ $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
+ if (!ini_get('display_errors')) {
+ if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+ fwrite(STDERR, $err);
+ } elseif (!headers_sent()) {
+ echo $err;
+ }
+ }
+ trigger_error(
+ $err,
+ E_USER_ERROR
+ );
+}
+
+require_once __DIR__ . '/composer/autoload_real.php';
+
+return ComposerAutoloaderInitComments::getLoader();
diff --git a/apps/comments/composer/composer.json b/apps/comments/composer/composer.json
new file mode 100644
index 00000000000..40fe9ae34be
--- /dev/null
+++ b/apps/comments/composer/composer.json
@@ -0,0 +1,13 @@
+{
+ "config" : {
+ "vendor-dir": ".",
+ "optimize-autoloader": true,
+ "classmap-authoritative": true,
+ "autoloader-suffix": "Comments"
+ },
+ "autoload" : {
+ "psr-4": {
+ "OCA\\Comments\\": "../lib/"
+ }
+ }
+}
diff --git a/apps/comments/composer/composer.lock b/apps/comments/composer/composer.lock
new file mode 100644
index 00000000000..fd0bcbcb753
--- /dev/null
+++ b/apps/comments/composer/composer.lock
@@ -0,0 +1,18 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "d751713988987e9331980363e24189ce",
+ "packages": [],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": [],
+ "plugin-api-version": "2.1.0"
+}
diff --git a/apps/comments/composer/composer/ClassLoader.php b/apps/comments/composer/composer/ClassLoader.php
new file mode 100644
index 00000000000..7824d8f7eaf
--- /dev/null
+++ b/apps/comments/composer/composer/ClassLoader.php
@@ -0,0 +1,579 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ * Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ * $loader = new \Composer\Autoload\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @see https://www.php-fig.org/psr/psr-0/
+ * @see https://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ /** @var \Closure(string):void */
+ private static $includeFile;
+
+ /** @var string|null */
+ private $vendorDir;
+
+ // PSR-4
+ /**
+ * @var array<string, array<string, int>>
+ */
+ private $prefixLengthsPsr4 = array();
+ /**
+ * @var array<string, list<string>>
+ */
+ private $prefixDirsPsr4 = array();
+ /**
+ * @var list<string>
+ */
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ /**
+ * List of PSR-0 prefixes
+ *
+ * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
+ *
+ * @var array<string, array<string, list<string>>>
+ */
+ private $prefixesPsr0 = array();
+ /**
+ * @var list<string>
+ */
+ private $fallbackDirsPsr0 = array();
+
+ /** @var bool */
+ private $useIncludePath = false;
+
+ /**
+ * @var array<string, string>
+ */
+ private $classMap = array();
+
+ /** @var bool */
+ private $classMapAuthoritative = false;
+
+ /**
+ * @var array<string, bool>
+ */
+ private $missingClasses = array();
+
+ /** @var string|null */
+ private $apcuPrefix;
+
+ /**
+ * @var array<string, self>
+ */
+ private static $registeredLoaders = array();
+
+ /**
+ * @param string|null $vendorDir
+ */
+ public function __construct($vendorDir = null)
+ {
+ $this->vendorDir = $vendorDir;
+ self::initializeIncludeClosure();
+ }
+
+ /**
+ * @return array<string, list<string>>
+ */
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
+ }
+
+ return array();
+ }
+
+ /**
+ * @return array<string, list<string>>
+ */
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ /**
+ * @return list<string>
+ */
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ /**
+ * @return list<string>
+ */
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ /**
+ * @return array<string, string> Array of classname => path
+ */
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param array<string, string> $classMap Class to filename map
+ *
+ * @return void
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param list<string>|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @return void
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ $paths = (array) $paths;
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param list<string>|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return void
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ $paths = (array) $paths;
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param list<string>|string $paths The PSR-0 base directories
+ *
+ * @return void
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param list<string>|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return void
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ *
+ * @return void
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ *
+ * @return void
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ *
+ * @return void
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ *
+ * @return void
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+
+ if (null === $this->vendorDir) {
+ return;
+ }
+
+ if ($prepend) {
+ self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
+ } else {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ self::$registeredLoaders[$this->vendorDir] = $this;
+ }
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ *
+ * @return void
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+
+ if (null !== $this->vendorDir) {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ }
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return true|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ $includeFile = self::$includeFile;
+ $includeFile($file);
+
+ return true;
+ }
+
+ return null;
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ return false;
+ }
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if (false === $file && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
+ // Remember that this class does not exist.
+ $this->missingClasses[$class] = true;
+ }
+
+ return $file;
+ }
+
+ /**
+ * Returns the currently registered loaders keyed by their corresponding vendor directories.
+ *
+ * @return array<string, self>
+ */
+ public static function getRegisteredLoaders()
+ {
+ return self::$registeredLoaders;
+ }
+
+ /**
+ * @param string $class
+ * @param string $ext
+ * @return string|false
+ */
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath . '\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ if (file_exists($file = $dir . $pathEnd)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+
+ return false;
+ }
+
+ /**
+ * @return void
+ */
+ private static function initializeIncludeClosure()
+ {
+ if (self::$includeFile !== null) {
+ return;
+ }
+
+ /**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ *
+ * @param string $file
+ * @return void
+ */
+ self::$includeFile = \Closure::bind(static function($file) {
+ include $file;
+ }, null, null);
+ }
+}
diff --git a/apps/comments/composer/composer/InstalledVersions.php b/apps/comments/composer/composer/InstalledVersions.php
new file mode 100644
index 00000000000..51e734a774b
--- /dev/null
+++ b/apps/comments/composer/composer/InstalledVersions.php
@@ -0,0 +1,359 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ * Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer;
+
+use Composer\Autoload\ClassLoader;
+use Composer\Semver\VersionParser;
+
+/**
+ * This class is copied in every Composer installed project and available to all
+ *
+ * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
+ *
+ * To require its presence, you can require `composer-runtime-api ^2.0`
+ *
+ * @final
+ */
+class InstalledVersions
+{
+ /**
+ * @var mixed[]|null
+ * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
+ */
+ private static $installed;
+
+ /**
+ * @var bool|null
+ */
+ private static $canGetVendors;
+
+ /**
+ * @var array[]
+ * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
+ */
+ private static $installedByVendor = array();
+
+ /**
+ * Returns a list of all package names which are present, either by being installed, replaced or provided
+ *
+ * @return string[]
+ * @psalm-return list<string>
+ */
+ public static function getInstalledPackages()
+ {
+ $packages = array();
+ foreach (self::getInstalled() as $installed) {
+ $packages[] = array_keys($installed['versions']);
+ }
+
+ if (1 === \count($packages)) {
+ return $packages[0];
+ }
+
+ return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
+ }
+
+ /**
+ * Returns a list of all package names with a specific type e.g. 'library'
+ *
+ * @param string $type
+ * @return string[]
+ * @psalm-return list<string>
+ */
+ public static function getInstalledPackagesByType($type)
+ {
+ $packagesByType = array();
+
+ foreach (self::getInstalled() as $installed) {
+ foreach ($installed['versions'] as $name => $package) {
+ if (isset($package['type']) && $package['type'] === $type) {
+ $packagesByType[] = $name;
+ }
+ }
+ }
+
+ return $packagesByType;
+ }
+
+ /**
+ * Checks whether the given package is installed
+ *
+ * This also returns true if the package name is provided or replaced by another package
+ *
+ * @param string $packageName
+ * @param bool $includeDevRequirements
+ * @return bool
+ */
+ public static function isInstalled($packageName, $includeDevRequirements = true)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (isset($installed['versions'][$packageName])) {
+ return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks whether the given package satisfies a version constraint
+ *
+ * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
+ *
+ * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
+ *
+ * @param VersionParser $parser Install composer/semver to have access to this class and functionality
+ * @param string $packageName
+ * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
+ * @return bool
+ */
+ public static function satisfies(VersionParser $parser, $packageName, $constraint)
+ {
+ $constraint = $parser->parseConstraints((string) $constraint);
+ $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
+
+ return $provided->matches($constraint);
+ }
+
+ /**
+ * Returns a version constraint representing all the range(s) which are installed for a given package
+ *
+ * It is easier to use this via isInstalled() with the $constraint argument if you need to check
+ * whether a given version of a package is installed, and not just whether it exists
+ *
+ * @param string $packageName
+ * @return string Version constraint usable with composer/semver
+ */
+ public static function getVersionRanges($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ $ranges = array();
+ if (isset($installed['versions'][$packageName]['pretty_version'])) {
+ $ranges[] = $installed['versions'][$packageName]['pretty_version'];
+ }
+ if (array_key_exists('aliases', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
+ }
+ if (array_key_exists('replaced', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
+ }
+ if (array_key_exists('provided', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
+ }
+
+ return implode(' || ', $ranges);
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
+ */
+ public static function getVersion($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['version'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['version'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
+ */
+ public static function getPrettyVersion($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['pretty_version'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['pretty_version'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
+ */
+ public static function getReference($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['reference'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['reference'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
+ */
+ public static function getInstallPath($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @return array
+ * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
+ */
+ public static function getRootPackage()
+ {
+ $installed = self::getInstalled();
+
+ return $installed[0]['root'];
+ }
+
+ /**
+ * Returns the raw installed.php data for custom implementations
+ *
+ * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
+ * @return array[]
+ * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
+ */
+ public static function getRawData()
+ {
+ @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
+
+ if (null === self::$installed) {
+ // only require the installed.php file if this file is loaded from its dumped location,
+ // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
+ if (substr(__DIR__, -8, 1) !== 'C') {
+ self::$installed = include __DIR__ . '/installed.php';
+ } else {
+ self::$installed = array();
+ }
+ }
+
+ return self::$installed;
+ }
+
+ /**
+ * Returns the raw data of all installed.php which are currently loaded for custom implementations
+ *
+ * @return array[]
+ * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
+ */
+ public static function getAllRawData()
+ {
+ return self::getInstalled();
+ }
+
+ /**
+ * Lets you reload the static array from another file
+ *
+ * This is only useful for complex integrations in which a project needs to use
+ * this class but then also needs to execute another project's autoloader in process,
+ * and wants to ensure both projects have access to their version of installed.php.
+ *
+ * A typical case would be PHPUnit, where it would need to make sure it reads all
+ * the data it needs from this class, then call reload() with
+ * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
+ * the project in which it runs can then also use this class safely, without
+ * interference between PHPUnit's dependencies and the project's dependencies.
+ *
+ * @param array[] $data A vendor/composer/installed.php data set
+ * @return void
+ *
+ * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
+ */
+ public static function reload($data)
+ {
+ self::$installed = $data;
+ self::$installedByVendor = array();
+ }
+
+ /**
+ * @return array[]
+ * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
+ */
+ private static function getInstalled()
+ {
+ if (null === self::$canGetVendors) {
+ self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
+ }
+
+ $installed = array();
+
+ if (self::$canGetVendors) {
+ foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
+ if (isset(self::$installedByVendor[$vendorDir])) {
+ $installed[] = self::$installedByVendor[$vendorDir];
+ } elseif (is_file($vendorDir.'/composer/installed.php')) {
+ /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
+ $required = require $vendorDir.'/composer/installed.php';
+ $installed[] = self::$installedByVendor[$vendorDir] = $required;
+ if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
+ self::$installed = $installed[count($installed) - 1];
+ }
+ }
+ }
+ }
+
+ if (null === self::$installed) {
+ // only require the installed.php file if this file is loaded from its dumped location,
+ // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
+ if (substr(__DIR__, -8, 1) !== 'C') {
+ /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
+ $required = require __DIR__ . '/installed.php';
+ self::$installed = $required;
+ } else {
+ self::$installed = array();
+ }
+ }
+
+ if (self::$installed !== array()) {
+ $installed[] = self::$installed;
+ }
+
+ return $installed;
+ }
+}
diff --git a/apps/comments/composer/composer/LICENSE b/apps/comments/composer/composer/LICENSE
new file mode 100644
index 00000000000..f27399a042d
--- /dev/null
+++ b/apps/comments/composer/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/apps/comments/composer/composer/autoload_classmap.php b/apps/comments/composer/composer/autoload_classmap.php
new file mode 100644
index 00000000000..22f95a934d7
--- /dev/null
+++ b/apps/comments/composer/composer/autoload_classmap.php
@@ -0,0 +1,28 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(__DIR__);
+$baseDir = $vendorDir;
+
+return array(
+ 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
+ 'OCA\\Comments\\Activity\\Filter' => $baseDir . '/../lib/Activity/Filter.php',
+ 'OCA\\Comments\\Activity\\Listener' => $baseDir . '/../lib/Activity/Listener.php',
+ 'OCA\\Comments\\Activity\\Provider' => $baseDir . '/../lib/Activity/Provider.php',
+ 'OCA\\Comments\\Activity\\Setting' => $baseDir . '/../lib/Activity/Setting.php',
+ 'OCA\\Comments\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
+ 'OCA\\Comments\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
+ 'OCA\\Comments\\Collaboration\\CommentersSorter' => $baseDir . '/../lib/Collaboration/CommentersSorter.php',
+ 'OCA\\Comments\\Controller\\NotificationsController' => $baseDir . '/../lib/Controller/NotificationsController.php',
+ 'OCA\\Comments\\Listener\\CommentsEntityEventListener' => $baseDir . '/../lib/Listener/CommentsEntityEventListener.php',
+ 'OCA\\Comments\\Listener\\CommentsEventListener' => $baseDir . '/../lib/Listener/CommentsEventListener.php',
+ 'OCA\\Comments\\Listener\\LoadAdditionalScripts' => $baseDir . '/../lib/Listener/LoadAdditionalScripts.php',
+ 'OCA\\Comments\\Listener\\LoadSidebarScripts' => $baseDir . '/../lib/Listener/LoadSidebarScripts.php',
+ 'OCA\\Comments\\MaxAutoCompleteResultsInitialState' => $baseDir . '/../lib/MaxAutoCompleteResultsInitialState.php',
+ 'OCA\\Comments\\Notification\\Listener' => $baseDir . '/../lib/Notification/Listener.php',
+ 'OCA\\Comments\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php',
+ 'OCA\\Comments\\Search\\CommentsSearchProvider' => $baseDir . '/../lib/Search/CommentsSearchProvider.php',
+ 'OCA\\Comments\\Search\\LegacyProvider' => $baseDir . '/../lib/Search/LegacyProvider.php',
+ 'OCA\\Comments\\Search\\Result' => $baseDir . '/../lib/Search/Result.php',
+);
diff --git a/apps/comments/composer/composer/autoload_namespaces.php b/apps/comments/composer/composer/autoload_namespaces.php
new file mode 100644
index 00000000000..3f5c9296251
--- /dev/null
+++ b/apps/comments/composer/composer/autoload_namespaces.php
@@ -0,0 +1,9 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(__DIR__);
+$baseDir = $vendorDir;
+
+return array(
+);
diff --git a/apps/comments/composer/composer/autoload_psr4.php b/apps/comments/composer/composer/autoload_psr4.php
new file mode 100644
index 00000000000..2db1b8decc4
--- /dev/null
+++ b/apps/comments/composer/composer/autoload_psr4.php
@@ -0,0 +1,10 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(__DIR__);
+$baseDir = $vendorDir;
+
+return array(
+ 'OCA\\Comments\\' => array($baseDir . '/../lib'),
+);
diff --git a/apps/comments/composer/composer/autoload_real.php b/apps/comments/composer/composer/autoload_real.php
new file mode 100644
index 00000000000..7f9d22ca0a2
--- /dev/null
+++ b/apps/comments/composer/composer/autoload_real.php
@@ -0,0 +1,37 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInitComments
+{
+ private static $loader;
+
+ public static function loadClassLoader($class)
+ {
+ if ('Composer\Autoload\ClassLoader' === $class) {
+ require __DIR__ . '/ClassLoader.php';
+ }
+ }
+
+ /**
+ * @return \Composer\Autoload\ClassLoader
+ */
+ public static function getLoader()
+ {
+ if (null !== self::$loader) {
+ return self::$loader;
+ }
+
+ spl_autoload_register(array('ComposerAutoloaderInitComments', 'loadClassLoader'), true, true);
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
+ spl_autoload_unregister(array('ComposerAutoloaderInitComments', 'loadClassLoader'));
+
+ require __DIR__ . '/autoload_static.php';
+ call_user_func(\Composer\Autoload\ComposerStaticInitComments::getInitializer($loader));
+
+ $loader->setClassMapAuthoritative(true);
+ $loader->register(true);
+
+ return $loader;
+ }
+}
diff --git a/apps/comments/composer/composer/autoload_static.php b/apps/comments/composer/composer/autoload_static.php
new file mode 100644
index 00000000000..7e553f8e2e2
--- /dev/null
+++ b/apps/comments/composer/composer/autoload_static.php
@@ -0,0 +1,54 @@
+<?php
+
+// autoload_static.php @generated by Composer
+
+namespace Composer\Autoload;
+
+class ComposerStaticInitComments
+{
+ public static $prefixLengthsPsr4 = array (
+ 'O' =>
+ array (
+ 'OCA\\Comments\\' => 13,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'OCA\\Comments\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/../lib',
+ ),
+ );
+
+ public static $classMap = array (
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+ 'OCA\\Comments\\Activity\\Filter' => __DIR__ . '/..' . '/../lib/Activity/Filter.php',
+ 'OCA\\Comments\\Activity\\Listener' => __DIR__ . '/..' . '/../lib/Activity/Listener.php',
+ 'OCA\\Comments\\Activity\\Provider' => __DIR__ . '/..' . '/../lib/Activity/Provider.php',
+ 'OCA\\Comments\\Activity\\Setting' => __DIR__ . '/..' . '/../lib/Activity/Setting.php',
+ 'OCA\\Comments\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
+ 'OCA\\Comments\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
+ 'OCA\\Comments\\Collaboration\\CommentersSorter' => __DIR__ . '/..' . '/../lib/Collaboration/CommentersSorter.php',
+ 'OCA\\Comments\\Controller\\NotificationsController' => __DIR__ . '/..' . '/../lib/Controller/NotificationsController.php',
+ 'OCA\\Comments\\Listener\\CommentsEntityEventListener' => __DIR__ . '/..' . '/../lib/Listener/CommentsEntityEventListener.php',
+ 'OCA\\Comments\\Listener\\CommentsEventListener' => __DIR__ . '/..' . '/../lib/Listener/CommentsEventListener.php',
+ 'OCA\\Comments\\Listener\\LoadAdditionalScripts' => __DIR__ . '/..' . '/../lib/Listener/LoadAdditionalScripts.php',
+ 'OCA\\Comments\\Listener\\LoadSidebarScripts' => __DIR__ . '/..' . '/../lib/Listener/LoadSidebarScripts.php',
+ 'OCA\\Comments\\MaxAutoCompleteResultsInitialState' => __DIR__ . '/..' . '/../lib/MaxAutoCompleteResultsInitialState.php',
+ 'OCA\\Comments\\Notification\\Listener' => __DIR__ . '/..' . '/../lib/Notification/Listener.php',
+ 'OCA\\Comments\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php',
+ 'OCA\\Comments\\Search\\CommentsSearchProvider' => __DIR__ . '/..' . '/../lib/Search/CommentsSearchProvider.php',
+ 'OCA\\Comments\\Search\\LegacyProvider' => __DIR__ . '/..' . '/../lib/Search/LegacyProvider.php',
+ 'OCA\\Comments\\Search\\Result' => __DIR__ . '/..' . '/../lib/Search/Result.php',
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInitComments::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInitComments::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInitComments::$classMap;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/apps/comments/composer/composer/installed.json b/apps/comments/composer/composer/installed.json
new file mode 100644
index 00000000000..f20a6c47c6d
--- /dev/null
+++ b/apps/comments/composer/composer/installed.json
@@ -0,0 +1,5 @@
+{
+ "packages": [],
+ "dev": false,
+ "dev-package-names": []
+}
diff --git a/apps/comments/composer/composer/installed.php b/apps/comments/composer/composer/installed.php
new file mode 100644
index 00000000000..1a66c7f2416
--- /dev/null
+++ b/apps/comments/composer/composer/installed.php
@@ -0,0 +1,23 @@
+<?php return array(
+ 'root' => array(
+ 'name' => '__root__',
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'reference' => 'b1797842784b250fb01ed5e3bf130705eb94751b',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../',
+ 'aliases' => array(),
+ 'dev' => false,
+ ),
+ 'versions' => array(
+ '__root__' => array(
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'reference' => 'b1797842784b250fb01ed5e3bf130705eb94751b',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
+ ),
+);
diff --git a/apps/comments/css/comments.css b/apps/comments/css/comments.css
deleted file mode 100644
index a9b72252e88..00000000000
--- a/apps/comments/css/comments.css
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-#commentsTabView .newCommentForm {
- margin-bottom: 20px;
-}
-
-#commentsTabView .newCommentForm .message {
- width: 90%;
- resize: vertical;
-}
-
-#commentsTabView .newCommentForm .submitLoading {
- background-position: left;
-}
-
-#commentsTabView .comment {
- margin-bottom: 30px;
-}
-
-#commentsTabView .comment .avatar {
- width: 28px;
- height: 28px;
- line-height: 28px;
-}
-
-#commentsTabView .comment {
- position: relative;
- z-index: 1;
-}
-
-#commentsTabView .comment.collapsed .message {
- white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
- white-space: -webkit-pre-wrap; /*Chrome & Safari */
- white-space: -pre-wrap; /* Opera 4-6 */
- white-space: -o-pre-wrap; /* Opera 7 */
- white-space: pre-wrap; /* css-3 */
- word-wrap: break-word; /* Internet Explorer 5.5+ */
- word-break: break-all;
- white-space: normal;
-}
-
-#commentsTabView .comment.collapsed .message {
- max-height: 70px;
- overflow: hidden;
-}
-
-#commentsTabView .comment .message-overlay {
- display: none;
-}
-
-#commentsTabView .comment.collapsed .message-overlay {
- display: block;
- position: absolute;
- z-index: 2;
- height: 50px;
- pointer-events: none;
- left: 0;
- right: 0;
- bottom: 0;
- background: -moz-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1));
- background: -webkit-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1));
- background: -o-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1));
- background: -ms-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1));
- background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1));
- filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');
- background-repeat: no-repeat;
-}
-
-#commentsTabView .authorRow>div {
- display: inline-block;
- vertical-align: middle;
-}
-
-#commentsTabView .comment .authorRow {
- margin-bottom: 5px;
- position: relative;
-}
-
-#commentsTabView .comment .author {
- font-weight: bold;
-}
-
-#commentsTabView .comment .date {
- position: absolute;
- right: 0;
-}
-
-#commentsTabView .comment .action {
- opacity: 0;
- vertical-align: middle;
- display: inline-block;
-}
-
-#commentsTabView .comment:hover .action {
- opacity: 0.3;
-}
-
-#commentsTabView .comment .action:hover {
- opacity: 1;
-}
-
-#commentsTabView .comment .action.delete {
- position: absolute;
- right: 0;
-}
-
-#commentsTabView .comment.disabled {
- opacity: 0.3;
-}
-
-#commentsTabView .comment.disabled .action {
- visibility: hidden;
-}
-
-#commentsTabView .message.error {
- color: #e9322d;
- border-color: #e9322d;
- -webkit-box-shadow: 0 0 6px #f8b9b7;
- -moz-box-shadow: 0 0 6px #f8b9b7;
- box-shadow: 0 0 6px #f8b9b7;
-}
-
-.app-files .action-comment {
- padding: 16px 14px;
-}
diff --git a/apps/comments/img/comments-dark.svg b/apps/comments/img/comments-dark.svg
new file mode 100644
index 00000000000..b0732c747fe
--- /dev/null
+++ b/apps/comments/img/comments-dark.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px"><path d="M240-384h480v-72H240v72Zm0-132h480v-72H240v72Zm0-132h480v-72H240v72Zm-72 408q-29.7 0-50.85-21.15Q96-282.3 96-312v-480q0-29.7 21.15-50.85Q138.3-864 168-864h624q29.7 0 50.85 21.15Q864-821.7 864-792v696L720-240H168Z"/></svg> \ No newline at end of file
diff --git a/apps/comments/img/comments.svg b/apps/comments/img/comments.svg
new file mode 100644
index 00000000000..d4e4573bf91
--- /dev/null
+++ b/apps/comments/img/comments.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#fff"><path d="M240-384h480v-72H240v72Zm0-132h480v-72H240v72Zm0-132h480v-72H240v72Zm-72 408q-29.7 0-50.85-21.15Q96-282.3 96-312v-480q0-29.7 21.15-50.85Q138.3-864 168-864h624q29.7 0 50.85 21.15Q864-821.7 864-792v696L720-240H168Z"/></svg> \ No newline at end of file
diff --git a/apps/comments/js/app.js b/apps/comments/js/app.js
deleted file mode 100644
index 547059393a5..00000000000
--- a/apps/comments/js/app.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2016 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
- if (!OCA.Comments) {
- /**
- * @namespace
- */
- OCA.Comments = {};
- }
-
-})();
-
diff --git a/apps/comments/js/commentcollection.js b/apps/comments/js/commentcollection.js
deleted file mode 100644
index a15039cf484..00000000000
--- a/apps/comments/js/commentcollection.js
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function(OC, OCA) {
-
- /**
- * @class OCA.Comments.CommentCollection
- * @classdesc
- *
- * Collection of comments assigned to a file
- *
- */
- var CommentCollection = OC.Backbone.Collection.extend(
- /** @lends OCA.Comments.CommentCollection.prototype */ {
-
- sync: OC.Backbone.davSync,
-
- model: OCA.Comments.CommentModel,
-
- /**
- * Object type
- *
- * @type string
- */
- _objectType: 'files',
-
- /**
- * Object id
- *
- * @type string
- */
- _objectId: null,
-
- /**
- * True if there are no more page results left to fetch
- *
- * @type bool
- */
- _endReached: false,
-
- /**
- * Number of comments to fetch per page
- *
- * @type int
- */
- _limit : 20,
-
- /**
- * Initializes the collection
- *
- * @param {string} [options.objectType] object type
- * @param {string} [options.objectId] object id
- */
- initialize: function(models, options) {
- options = options || {};
- if (options.objectType) {
- this._objectType = options.objectType;
- }
- if (options.objectId) {
- this._objectId = options.objectId;
- }
- },
-
- url: function() {
- return OC.linkToRemote('dav') + '/comments/' +
- encodeURIComponent(this._objectType) + '/' +
- encodeURIComponent(this._objectId) + '/';
- },
-
- setObjectId: function(objectId) {
- this._objectId = objectId;
- },
-
- hasMoreResults: function() {
- return !this._endReached;
- },
-
- reset: function() {
- this._endReached = false;
- this._summaryModel = null;
- return OC.Backbone.Collection.prototype.reset.apply(this, arguments);
- },
-
- /**
- * Fetch the next set of results
- */
- fetchNext: function(options) {
- var self = this;
- if (!this.hasMoreResults()) {
- return null;
- }
-
- var body = '<?xml version="1.0" encoding="utf-8" ?>\n' +
- '<oc:filter-comments xmlns:D="DAV:" xmlns:oc="http://owncloud.org/ns">\n' +
- // load one more so we know there is more
- ' <oc:limit>' + (this._limit + 1) + '</oc:limit>\n' +
- ' <oc:offset>' + this.length + '</oc:offset>\n' +
- '</oc:filter-comments>\n';
-
- options = options || {};
- var success = options.success;
- options = _.extend({
- remove: false,
- parse: true,
- data: body,
- davProperties: CommentCollection.prototype.model.prototype.davProperties,
- success: function(resp) {
- if (resp.length <= self._limit) {
- // no new entries, end reached
- self._endReached = true;
- } else {
- // remove last entry, for next page load
- resp = _.initial(resp);
- }
- if (!self.set(resp, options)) {
- return false;
- }
- if (success) {
- success.apply(null, arguments);
- }
- self.trigger('sync', 'REPORT', self, options);
- }
- }, options);
-
- return this.sync('REPORT', this, options);
- },
-
- /**
- * Returns the matching summary model
- *
- * @return {OCA.Comments.CommentSummaryModel} summary model
- */
- getSummaryModel: function() {
- if (!this._summaryModel) {
- this._summaryModel = new OCA.Comments.CommentSummaryModel({
- id: this._objectId,
- objectType: this._objectType
- });
- }
- return this._summaryModel;
- },
-
- /**
- * Updates the read marker for this comment thread
- *
- * @param {Date} [date] optional date, defaults to now
- * @param {Object} [options] backbone options
- */
- updateReadMarker: function(date, options) {
- options = options || {};
-
- return this.getSummaryModel().save({
- readMarker: (date || new Date()).toUTCString()
- }, options);
- }
- });
-
- OCA.Comments.CommentCollection = CommentCollection;
-})(OC, OCA);
-
diff --git a/apps/comments/js/commentmodel.js b/apps/comments/js/commentmodel.js
deleted file mode 100644
index 89492707b61..00000000000
--- a/apps/comments/js/commentmodel.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function(OC, OCA) {
- var NS_OWNCLOUD = 'http://owncloud.org/ns';
- /**
- * @class OCA.Comments.CommentModel
- * @classdesc
- *
- * Comment
- *
- */
- var CommentModel = OC.Backbone.Model.extend(
- /** @lends OCA.Comments.CommentModel.prototype */ {
- sync: OC.Backbone.davSync,
-
- defaults: {
- actorType: 'users',
- objectType: 'files'
- },
-
- davProperties: {
- 'id': '{' + NS_OWNCLOUD + '}id',
- 'message': '{' + NS_OWNCLOUD + '}message',
- 'actorType': '{' + NS_OWNCLOUD + '}actorType',
- 'actorId': '{' + NS_OWNCLOUD + '}actorId',
- 'actorDisplayName': '{' + NS_OWNCLOUD + '}actorDisplayName',
- 'creationDateTime': '{' + NS_OWNCLOUD + '}creationDateTime',
- 'objectType': '{' + NS_OWNCLOUD + '}objectType',
- 'objectId': '{' + NS_OWNCLOUD + '}objectId',
- 'isUnread': '{' + NS_OWNCLOUD + '}isUnread'
- },
-
- parse: function(data) {
- return {
- id: data.id,
- message: data.message,
- actorType: data.actorType,
- actorId: data.actorId,
- actorDisplayName: data.actorDisplayName,
- creationDateTime: data.creationDateTime,
- objectType: data.objectType,
- objectId: data.objectId,
- isUnread: (data.isUnread === 'true')
- };
- }
- });
-
- OCA.Comments.CommentModel = CommentModel;
-})(OC, OCA);
-
diff --git a/apps/comments/js/commentstabview.js b/apps/comments/js/commentstabview.js
deleted file mode 100644
index 415ec2a9be5..00000000000
--- a/apps/comments/js/commentstabview.js
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/* global Handlebars, escapeHTML */
-
-(function(OC, OCA) {
- var TEMPLATE =
- '<ul class="comments">' +
- '</ul>' +
- '<div class="empty hidden">{{emptyResultLabel}}</div>' +
- '<input type="button" class="showMore hidden" value="{{moreLabel}}"' +
- ' name="show-more" id="show-more" />' +
- '<div class="loading hidden" style="height: 50px"></div>';
-
- var EDIT_COMMENT_TEMPLATE =
- '<div class="newCommentRow comment" data-id="{{id}}">' +
- ' <div class="authorRow">' +
- ' {{#if avatarEnabled}}' +
- ' <div class="avatar" data-username="{{actorId}}"></div>' +
- ' {{/if}}' +
- ' <div class="author">{{actorDisplayName}}</div>' +
- '{{#if isEditMode}}' +
- ' <a href="#" class="action delete icon icon-delete has-tooltip" title="{{deleteTooltip}}"></a>' +
- '{{/if}}' +
- ' </div>' +
- ' <form class="newCommentForm">' +
- ' <textarea class="message" placeholder="{{newMessagePlaceholder}}">{{{message}}}</textarea>' +
- ' <input class="submit" type="submit" value="{{submitText}}" />' +
- '{{#if isEditMode}}' +
- ' <input class="cancel" type="button" value="{{cancelText}}" />' +
- '{{/if}}' +
- ' <div class="submitLoading icon-loading-small hidden"></div>'+
- ' </form>' +
- '</div>';
-
- var COMMENT_TEMPLATE =
- '<li class="comment{{#if isUnread}} unread{{/if}}{{#if isLong}} collapsed{{/if}}" data-id="{{id}}">' +
- ' <div class="authorRow">' +
- ' {{#if avatarEnabled}}' +
- ' <div class="avatar" {{#if actorId}}data-username="{{actorId}}"{{/if}}> </div>' +
- ' {{/if}}' +
- ' <div class="author">{{actorDisplayName}}</div>' +
- '{{#if isUserAuthor}}' +
- ' <a href="#" class="action edit icon icon-rename has-tooltip" title="{{editTooltip}}"></a>' +
- '{{/if}}' +
- ' <div class="date has-tooltip" title="{{altDate}}">{{date}}</div>' +
- ' </div>' +
- ' <div class="message">{{{formattedMessage}}}</div>' +
- '{{#if isLong}}' +
- ' <div class="message-overlay"></div>' +
- '{{/if}}' +
- '</li>';
-
- /**
- * @memberof OCA.Comments
- */
- var CommentsTabView = OCA.Files.DetailTabView.extend(
- /** @lends OCA.Comments.CommentsTabView.prototype */ {
- id: 'commentsTabView',
- className: 'tab commentsTabView',
-
- events: {
- 'submit .newCommentForm': '_onSubmitComment',
- 'click .showMore': '_onClickShowMore',
- 'click .action.edit': '_onClickEditComment',
- 'click .action.delete': '_onClickDeleteComment',
- 'click .cancel': '_onClickCloseComment',
- 'click .comment': '_onClickComment'
- },
-
- _commentMaxLength: 1000,
-
- initialize: function() {
- OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments);
- this.collection = new OCA.Comments.CommentCollection();
- this.collection.on('request', this._onRequest, this);
- this.collection.on('sync', this._onEndRequest, this);
- this.collection.on('add', this._onAddModel, this);
-
- this._avatarsEnabled = !!OC.config.enable_avatars;
-
- this._commentMaxThreshold = this._commentMaxLength * 0.9;
-
- // TODO: error handling
- _.bindAll(this, '_onTypeComment');
- },
-
- template: function(params) {
- if (!this._template) {
- this._template = Handlebars.compile(TEMPLATE);
- }
- var currentUser = OC.getCurrentUser();
- return this._template(_.extend({
- avatarEnabled: this._avatarsEnabled,
- actorId: currentUser.uid,
- actorDisplayName: currentUser.displayName
- }, params));
- },
-
- editCommentTemplate: function(params) {
- if (!this._editCommentTemplate) {
- this._editCommentTemplate = Handlebars.compile(EDIT_COMMENT_TEMPLATE);
- }
- var currentUser = OC.getCurrentUser();
- return this._editCommentTemplate(_.extend({
- avatarEnabled: this._avatarsEnabled,
- actorId: currentUser.uid,
- actorDisplayName: currentUser.displayName,
- newMessagePlaceholder: t('comments', 'Type in a new comment...'),
- deleteTooltip: t('comments', 'Delete comment'),
- submitText: t('comments', 'Post'),
- cancelText: t('comments', 'Cancel')
- }, params));
- },
-
- commentTemplate: function(params) {
- if (!this._commentTemplate) {
- this._commentTemplate = Handlebars.compile(COMMENT_TEMPLATE);
- }
-
- params = _.extend({
- avatarEnabled: this._avatarsEnabled,
- editTooltip: t('comments', 'Edit comment'),
- isUserAuthor: OC.getCurrentUser().uid === params.actorId,
- isLong: this._isLong(params.message)
- }, params);
-
- if (params.actorType === 'deleted_users') {
- // makes the avatar a X
- params.actorId = null;
- params.actorDisplayName = t('comments', '[Deleted user]');
- }
-
- return this._commentTemplate(params);
- },
-
- getLabel: function() {
- return t('comments', 'Comments');
- },
-
- setFileInfo: function(fileInfo) {
- if (fileInfo) {
- this.model = fileInfo;
- this.render();
- this.collection.setObjectId(fileInfo.id);
- // reset to first page
- this.collection.reset([], {silent: true});
- this.nextPage();
- } else {
- this.model = null;
- this.render();
- this.collection.reset();
- }
- },
-
- render: function() {
- this.$el.html(this.template({
- emptyResultLabel: t('comments', 'No other comments available'),
- moreLabel: t('comments', 'More comments...')
- }));
- this.$el.find('.comments').before(this.editCommentTemplate({}));
- this.$el.find('.has-tooltip').tooltip();
- this.$container = this.$el.find('ul.comments');
- if (this._avatarsEnabled) {
- this.$el.find('.avatar').avatar(OC.getCurrentUser().uid, 28);
- }
- this.delegateEvents();
- this.$el.find('textarea').on('keyup input change', this._onTypeComment);
- },
-
- _formatItem: function(commentModel) {
- var timestamp = new Date(commentModel.get('creationDateTime')).getTime();
- var data = _.extend({
- date: OC.Util.relativeModifiedDate(timestamp),
- altDate: OC.Util.formatDate(timestamp),
- formattedMessage: this._formatMessage(commentModel.get('message'))
- }, commentModel.attributes);
- return data;
- },
-
- _toggleLoading: function(state) {
- this._loading = state;
- this.$el.find('.loading').toggleClass('hidden', !state);
- },
-
- _onRequest: function(type) {
- if (type === 'REPORT') {
- this._toggleLoading(true);
- this.$el.find('.showMore').addClass('hidden');
- }
- },
-
- _onEndRequest: function(type) {
- var fileInfoModel = this.model;
- this._toggleLoading(false);
- this.$el.find('.empty').toggleClass('hidden', !!this.collection.length);
- this.$el.find('.showMore').toggleClass('hidden', !this.collection.hasMoreResults());
-
- if (type !== 'REPORT') {
- return;
- }
-
- // find first unread comment
- var firstUnreadComment = this.collection.findWhere({isUnread: true});
- if (firstUnreadComment) {
- // update read marker
- this.collection.updateReadMarker(
- null,
- {
- success: function() {
- fileInfoModel.set('commentsUnread', 0);
- }
- }
- );
- }
- },
-
- _onAddModel: function(model, collection, options) {
- var $el = $(this.commentTemplate(this._formatItem(model)));
- if (!_.isUndefined(options.at) && collection.length > 1) {
- this.$container.find('li').eq(options.at).before($el);
- } else {
- this.$container.append($el);
- }
-
- this._postRenderItem($el);
- },
-
- _postRenderItem: function($el) {
- $el.find('.has-tooltip').tooltip();
- if(this._avatarsEnabled) {
- $el.find('.avatar').each(function() {
- var $this = $(this);
- $this.avatar($this.attr('data-username'), 28);
- });
- }
- },
-
- /**
- * Convert a message to be displayed in HTML,
- * converts newlines to <br> tags.
- */
- _formatMessage: function(message) {
- return escapeHTML(message).replace(/\n/g, '<br/>');
- },
-
- nextPage: function() {
- if (this._loading || !this.collection.hasMoreResults()) {
- return;
- }
-
- this.collection.fetchNext();
- },
-
- _onClickEditComment: function(ev) {
- ev.preventDefault();
- var $comment = $(ev.target).closest('.comment');
- var commentId = $comment.data('id');
- var commentToEdit = this.collection.get(commentId);
- var $formRow = $(this.editCommentTemplate(_.extend({
- isEditMode: true,
- submitText: t('comments', 'Save')
- }, commentToEdit.attributes)));
-
- $comment.addClass('hidden').removeClass('collapsed');
- // spawn form
- $comment.after($formRow);
- $formRow.data('commentEl', $comment);
- $formRow.find('textarea').on('keyup input change', this._onTypeComment);
-
- // copy avatar element from original to avoid flickering
- $formRow.find('.avatar').replaceWith($comment.find('.avatar').clone());
- $formRow.find('.has-tooltip').tooltip();
-
- return false;
- },
-
- _onTypeComment: function(ev) {
- var $field = $(ev.target);
- var len = $field.val().length;
- var $submitButton = $field.data('submitButtonEl');
- if (!$submitButton) {
- $submitButton = $field.closest('form').find('.submit');
- $field.data('submitButtonEl', $submitButton);
- }
- $field.tooltip('hide');
- if (len > this._commentMaxThreshold) {
- $field.attr('data-original-title', t('comments', 'Allowed characters {count} of {max}', {count: len, max: this._commentMaxLength}));
- $field.tooltip({trigger: 'manual'});
- $field.tooltip('show');
- $field.addClass('error');
- }
-
- var limitExceeded = (len > this._commentMaxLength);
- $field.toggleClass('error', limitExceeded);
- $submitButton.prop('disabled', limitExceeded);
- },
-
- _onClickComment: function(ev) {
- var $row = $(ev.target);
- if (!$row.is('.comment')) {
- $row = $row.closest('.comment');
- }
- $row.removeClass('collapsed');
- },
-
- _onClickCloseComment: function(ev) {
- ev.preventDefault();
- var $row = $(ev.target).closest('.comment');
- $row.data('commentEl').removeClass('hidden');
- $row.remove();
- return false;
- },
-
- _onClickDeleteComment: function(ev) {
- ev.preventDefault();
- var $comment = $(ev.target).closest('.comment');
- var commentId = $comment.data('id');
- var $loading = $comment.find('.submitLoading');
-
- $comment.addClass('disabled');
- $loading.removeClass('hidden');
- this.collection.get(commentId).destroy({
- success: function() {
- $comment.data('commentEl').remove();
- $comment.remove();
- },
- error: function(msg) {
- $loading.addClass('hidden');
- $comment.removeClass('disabled');
- OC.Notification.showTemporary(msg);
- }
- });
-
-
- return false;
- },
-
- _onClickShowMore: function(ev) {
- ev.preventDefault();
- this.nextPage();
- },
-
- _onSubmitComment: function(e) {
- var self = this;
- var $form = $(e.target);
- var commentId = $form.closest('.comment').data('id');
- var currentUser = OC.getCurrentUser();
- var $submit = $form.find('.submit');
- var $loading = $form.find('.submitLoading');
- var $textArea = $form.find('textarea');
- var message = $textArea.val().trim();
- e.preventDefault();
-
- if (!message.length || message.length > this._commentMaxLength) {
- return;
- }
-
- $textArea.prop('disabled', true);
- $submit.addClass('hidden');
- $loading.removeClass('hidden');
-
- if (commentId) {
- // edit mode
- var comment = this.collection.get(commentId);
- comment.save({
- message: $textArea.val()
- }, {
- success: function(model) {
- var $row = $form.closest('.comment');
- $submit.removeClass('hidden');
- $loading.addClass('hidden');
- $row.data('commentEl')
- .removeClass('hidden')
- .find('.message')
- .html(self._formatMessage(model.get('message')));
- $row.remove();
- },
- error: function(msg) {
- $submit.removeClass('hidden');
- $loading.addClass('hidden');
- $textArea.prop('disabled', false);
-
- OC.Notification.showTemporary(msg);
- }
- });
- } else {
- this.collection.create({
- actorId: currentUser.uid,
- actorDisplayName: currentUser.displayName,
- actorType: 'users',
- verb: 'comment',
- message: $textArea.val(),
- creationDateTime: (new Date()).toUTCString()
- }, {
- at: 0,
- // wait for real creation before adding
- wait: true,
- success: function() {
- $submit.removeClass('hidden');
- $loading.addClass('hidden');
- $textArea.val('').prop('disabled', false);
- },
- error: function(msg) {
- $submit.removeClass('hidden');
- $loading.addClass('hidden');
- $textArea.prop('disabled', false);
-
- OC.Notification.showTemporary(msg);
- }
- });
- }
-
- return false;
- },
-
- /**
- * Returns whether the given message is long and needs
- * collapsing
- */
- _isLong: function(message) {
- return message.length > 250 || (message.match(/\n/g) || []).length > 1;
- }
- });
-
- OCA.Comments.CommentsTabView = CommentsTabView;
-})(OC, OCA);
-
diff --git a/apps/comments/js/commentsummarymodel.js b/apps/comments/js/commentsummarymodel.js
deleted file mode 100644
index d405315ca1f..00000000000
--- a/apps/comments/js/commentsummarymodel.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function(OC, OCA) {
- var NS_OWNCLOUD = 'http://owncloud.org/ns';
- /**
- * @class OCA.Comments.CommentSummaryModel
- * @classdesc
- *
- * Model containing summary information related to comments
- * like the read marker.
- *
- */
- var CommentSummaryModel = OC.Backbone.Model.extend(
- /** @lends OCA.Comments.CommentSummaryModel.prototype */ {
- sync: OC.Backbone.davSync,
-
- /**
- * Object type
- *
- * @type string
- */
- _objectType: 'files',
-
- /**
- * Object id
- *
- * @type string
- */
- _objectId: null,
-
- davProperties: {
- 'readMarker': '{' + NS_OWNCLOUD + '}readMarker'
- },
-
- /**
- * Initializes the summary model
- *
- * @param {string} [options.objectType] object type
- * @param {string} [options.objectId] object id
- */
- initialize: function(attrs, options) {
- options = options || {};
- if (options.objectType) {
- this._objectType = options.objectType;
- }
- },
-
- url: function() {
- return OC.linkToRemote('dav') + '/comments/' +
- encodeURIComponent(this._objectType) + '/' +
- encodeURIComponent(this.id) + '/';
- }
- });
-
- OCA.Comments.CommentSummaryModel = CommentSummaryModel;
-})(OC, OCA);
-
diff --git a/apps/comments/js/filesplugin.js b/apps/comments/js/filesplugin.js
deleted file mode 100644
index ec201d1d3f7..00000000000
--- a/apps/comments/js/filesplugin.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2016 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/* global Handlebars */
-
-(function() {
- var TEMPLATE_COMMENTS_UNREAD =
- '<a class="action action-comment permanent" title="{{countMessage}}" href="#">' +
- '<img class="svg" src="{{iconUrl}}"/>' +
- '</a>';
-
- OCA.Comments = _.extend({}, OCA.Comments);
- if (!OCA.Comments) {
- /**
- * @namespace
- */
- OCA.Comments = {};
- }
-
- /**
- * @namespace
- */
- OCA.Comments.FilesPlugin = {
- ignoreLists: [
- 'files_trashbin',
- 'files.public'
- ],
-
- _formatCommentCount: function(count) {
- if (!this._commentsUnreadTemplate) {
- this._commentsUnreadTemplate = Handlebars.compile(TEMPLATE_COMMENTS_UNREAD);
- }
- return this._commentsUnreadTemplate({
- count: count,
- countMessage: t('comments', '{count} unread comments', {count: count}),
- iconUrl: OC.imagePath('core', 'actions/comment')
- });
- },
-
- attach: function(fileList) {
- var self = this;
- if (this.ignoreLists.indexOf(fileList.id) >= 0) {
- return;
- }
-
- fileList.registerTabView(new OCA.Comments.CommentsTabView('commentsTabView'));
-
- var NS_OC = 'http://owncloud.org/ns';
-
- var oldGetWebdavProperties = fileList._getWebdavProperties;
- fileList._getWebdavProperties = function() {
- var props = oldGetWebdavProperties.apply(this, arguments);
- props.push('{' + NS_OC + '}comments-unread');
- return props;
- };
-
- fileList.filesClient.addFileInfoParser(function(response) {
- var data = {};
- var props = response.propStat[0].properties;
- var commentsUnread = props['{' + NS_OC + '}comments-unread'];
- if (!_.isUndefined(commentsUnread) && commentsUnread !== '') {
- data.commentsUnread = parseInt(commentsUnread, 10);
- }
- return data;
- });
-
- fileList.$el.addClass('has-comments');
- var oldCreateRow = fileList._createRow;
- fileList._createRow = function(fileData) {
- var $tr = oldCreateRow.apply(this, arguments);
- if (fileData.commentsUnread) {
- $tr.attr('data-comments-unread', fileData.commentsUnread);
- }
- return $tr;
- };
-
- // register "comment" action for reading comments
- fileList.fileActions.registerAction({
- name: 'Comment',
- displayName: t('comments', 'Comment'),
- mime: 'all',
- permissions: OC.PERMISSION_READ,
- type: OCA.Files.FileActions.TYPE_INLINE,
- render: function(actionSpec, isDefault, context) {
- var $file = context.$file;
- var unreadComments = $file.data('comments-unread');
- if (unreadComments) {
- var $actionLink = $(self._formatCommentCount(unreadComments));
- context.$file.find('a.name>span.fileactions').append($actionLink);
- return $actionLink;
- }
- return '';
- },
- actionHandler: function(fileName, context) {
- context.$file.find('.action-comment').tooltip('hide');
- // open sidebar in comments section
- context.fileList.showDetailsView(fileName, 'commentsTabView');
- }
- });
-
- // add attribute to "elementToFile"
- var oldElementToFile = fileList.elementToFile;
- fileList.elementToFile = function($el) {
- var fileInfo = oldElementToFile.apply(this, arguments);
- var commentsUnread = $el.data('comments-unread');
- if (commentsUnread) {
- fileInfo.commentsUnread = commentsUnread;
- }
- return fileInfo;
- };
- }
- };
-
-})();
-
-OC.Plugins.register('OCA.Files.FileList', OCA.Comments.FilesPlugin);
diff --git a/apps/comments/l10n/af_ZA.js b/apps/comments/l10n/af_ZA.js
deleted file mode 100644
index 0f841f8ec48..00000000000
--- a/apps/comments/l10n/af_ZA.js
+++ /dev/null
@@ -1,6 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Kanselleer"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/af_ZA.json b/apps/comments/l10n/af_ZA.json
deleted file mode 100644
index 81ad64aac33..00000000000
--- a/apps/comments/l10n/af_ZA.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{ "translations": {
- "Cancel" : "Kanselleer"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/ar.js b/apps/comments/l10n/ar.js
index ec211e25e43..725c42c1cb4 100644
--- a/apps/comments/l10n/ar.js
+++ b/apps/comments/l10n/ar.js
@@ -1,8 +1,36 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "إلغاء",
- "Save" : "حفظ",
- "Comment" : "تعليق"
+ "Comments" : "تعليقات",
+ "You commented" : "قمت بكتابة تعليق",
+ "{author} commented" : "{author} علّق",
+ "You commented on %1$s" : "لقد علقت على %1$s",
+ "You commented on {file}" : "علقت على {file}",
+ "%1$s commented on %2$s" : "%1$s كتب تعليق على %2$s",
+ "{author} commented on {file}" : "{author} علّق على {file}",
+ "<strong>Comments</strong> for files" : "<strong>تعليقات</strong> على الملفات",
+ "Files" : "الملفّات",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "تمت الإشارة إليك في \"{file}\"، في تعليقٍ من قِبَل حسابٍ تمّ حذفه سلفاً",
+ "{user} mentioned you in a comment on \"{file}\"" : "أشار إليك {user} في تعليق على {file}",
+ "Files app plugin to add comments to files" : "المكوِّن الإضافي لتطبيق الملفات لإضافة تعليقات إلى الملفات",
+ "Edit comment" : "تعديل التعليق",
+ "Delete comment" : "حذف التعليق",
+ "Cancel edit" : "إلغاء التعديل",
+ "New comment" : "تعليق جديد",
+ "Write a comment …" : "أكتُب تعليق ...",
+ "Post comment" : "أضف تعليق",
+ "@ for mentions, : for emoji, / for smart picker" : "@ للإشارات : للإيموجي / للاقط الذكي",
+ "Could not reload comments" : "تعذّرت إعادة تحميل التعليقات",
+ "Failed to mark comments as read" : "فشل في تعيين ملاحظات كمقرؤة",
+ "Unable to load the comments list" : "تعذر تحميل قائمة التعليقات",
+ "No comments yet, start the conversation!" : "لا توجد تعليقات, ابدأ النقاش الآن!",
+ "No more messages" : "لامزيد من الرسائل",
+ "Retry" : "أعد المحاولة",
+ "_1 new comment_::_{unread} new comments_" : ["1 تعليق جديد","1 تعليق جديد","{unread} تعليقات جديدة","{unread} تعليقات جديدة","{unread} تعليقات جديدة","{unread} تعليقات جديدة"],
+ "Comment" : "تعليق",
+ "An error occurred while trying to edit the comment" : "حدث خطأ أثناء محاولة تعديل التعليق",
+ "Comment deleted" : "التعليق محذوف",
+ "An error occurred while trying to delete the comment" : "حدث خطأ أثناء محاولة حذف التعليق",
+ "An error occurred while trying to create the comment" : "حدث خطأ أثناء محاولة إنشاء التعليق"
},
"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;");
diff --git a/apps/comments/l10n/ar.json b/apps/comments/l10n/ar.json
index 8f601e76e16..4438e60ebf3 100644
--- a/apps/comments/l10n/ar.json
+++ b/apps/comments/l10n/ar.json
@@ -1,6 +1,34 @@
{ "translations": {
- "Cancel" : "إلغاء",
- "Save" : "حفظ",
- "Comment" : "تعليق"
+ "Comments" : "تعليقات",
+ "You commented" : "قمت بكتابة تعليق",
+ "{author} commented" : "{author} علّق",
+ "You commented on %1$s" : "لقد علقت على %1$s",
+ "You commented on {file}" : "علقت على {file}",
+ "%1$s commented on %2$s" : "%1$s كتب تعليق على %2$s",
+ "{author} commented on {file}" : "{author} علّق على {file}",
+ "<strong>Comments</strong> for files" : "<strong>تعليقات</strong> على الملفات",
+ "Files" : "الملفّات",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "تمت الإشارة إليك في \"{file}\"، في تعليقٍ من قِبَل حسابٍ تمّ حذفه سلفاً",
+ "{user} mentioned you in a comment on \"{file}\"" : "أشار إليك {user} في تعليق على {file}",
+ "Files app plugin to add comments to files" : "المكوِّن الإضافي لتطبيق الملفات لإضافة تعليقات إلى الملفات",
+ "Edit comment" : "تعديل التعليق",
+ "Delete comment" : "حذف التعليق",
+ "Cancel edit" : "إلغاء التعديل",
+ "New comment" : "تعليق جديد",
+ "Write a comment …" : "أكتُب تعليق ...",
+ "Post comment" : "أضف تعليق",
+ "@ for mentions, : for emoji, / for smart picker" : "@ للإشارات : للإيموجي / للاقط الذكي",
+ "Could not reload comments" : "تعذّرت إعادة تحميل التعليقات",
+ "Failed to mark comments as read" : "فشل في تعيين ملاحظات كمقرؤة",
+ "Unable to load the comments list" : "تعذر تحميل قائمة التعليقات",
+ "No comments yet, start the conversation!" : "لا توجد تعليقات, ابدأ النقاش الآن!",
+ "No more messages" : "لامزيد من الرسائل",
+ "Retry" : "أعد المحاولة",
+ "_1 new comment_::_{unread} new comments_" : ["1 تعليق جديد","1 تعليق جديد","{unread} تعليقات جديدة","{unread} تعليقات جديدة","{unread} تعليقات جديدة","{unread} تعليقات جديدة"],
+ "Comment" : "تعليق",
+ "An error occurred while trying to edit the comment" : "حدث خطأ أثناء محاولة تعديل التعليق",
+ "Comment deleted" : "التعليق محذوف",
+ "An error occurred while trying to delete the comment" : "حدث خطأ أثناء محاولة حذف التعليق",
+ "An error occurred while trying to create the comment" : "حدث خطأ أثناء محاولة إنشاء التعليق"
},"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/ast.js b/apps/comments/l10n/ast.js
index 716facf525d..0ee30bdbb53 100644
--- a/apps/comments/l10n/ast.js
+++ b/apps/comments/l10n/ast.js
@@ -1,8 +1,36 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "Encaboxar",
- "Save" : "Guardar",
- "Comment" : "Comentariu"
+ "Comments" : "Comentarios",
+ "You commented" : "Comentesti",
+ "{author} commented" : "{author} comentó",
+ "You commented on %1$s" : "Comentesti en: %1$s",
+ "You commented on {file}" : "Comentesti en: {file}",
+ "%1$s commented on %2$s" : "%1$s comentó en: %2$s",
+ "{author} commented on {file}" : "{author} comentó en: {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> pa ficheros",
+ "Files" : "Ficheros",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Mentáronte en «{file}», nun comentariu d'una cuenta que ta desaniciada",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mentóte nun comentariu de: «{file}»",
+ "Files app plugin to add comments to files" : "Plugin de l'aplicación Ficheros p'amestar comentarios a los ficheros",
+ "Edit comment" : "Editar el comentariu",
+ "Delete comment" : "Desaniciar el comentariu",
+ "Cancel edit" : "Anular la edición",
+ "New comment" : "Comentariu nuevu",
+ "Write a comment …" : "Escribi un comentariu…",
+ "Post comment" : "Espublizar el comentariu",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pa les menciones, : pa los fustaxes, / pal selector intelixente",
+ "Could not reload comments" : "Nun se pudieron recargar los comentarios",
+ "Failed to mark comments as read" : "Nun se pudieron marcar los comentarios como lleíos",
+ "Unable to load the comments list" : "Nun ye posible cargar la llista de comentarios",
+ "No comments yet, start the conversation!" : "Nun hai comentarios, ¡anicia una conversación!",
+ "No more messages" : "Nun hai más mensaxes",
+ "Retry" : "Retentar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentariu nuevu","{unread} comentarios nuevos"],
+ "Comment" : "Comentariu",
+ "An error occurred while trying to edit the comment" : "Prodúxose un error mentanto se tentaba d'editar el comentariu",
+ "Comment deleted" : "Desanicióse'l comentariu",
+ "An error occurred while trying to delete the comment" : "Prodúxose un error mentanto se tentaba de desaniciar el comentariu",
+ "An error occurred while trying to create the comment" : "Prodúxose un error mentanto se tentaba de crear el comentariu"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/ast.json b/apps/comments/l10n/ast.json
index 30dd7e23077..43193924d64 100644
--- a/apps/comments/l10n/ast.json
+++ b/apps/comments/l10n/ast.json
@@ -1,6 +1,34 @@
{ "translations": {
- "Cancel" : "Encaboxar",
- "Save" : "Guardar",
- "Comment" : "Comentariu"
+ "Comments" : "Comentarios",
+ "You commented" : "Comentesti",
+ "{author} commented" : "{author} comentó",
+ "You commented on %1$s" : "Comentesti en: %1$s",
+ "You commented on {file}" : "Comentesti en: {file}",
+ "%1$s commented on %2$s" : "%1$s comentó en: %2$s",
+ "{author} commented on {file}" : "{author} comentó en: {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> pa ficheros",
+ "Files" : "Ficheros",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Mentáronte en «{file}», nun comentariu d'una cuenta que ta desaniciada",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mentóte nun comentariu de: «{file}»",
+ "Files app plugin to add comments to files" : "Plugin de l'aplicación Ficheros p'amestar comentarios a los ficheros",
+ "Edit comment" : "Editar el comentariu",
+ "Delete comment" : "Desaniciar el comentariu",
+ "Cancel edit" : "Anular la edición",
+ "New comment" : "Comentariu nuevu",
+ "Write a comment …" : "Escribi un comentariu…",
+ "Post comment" : "Espublizar el comentariu",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pa les menciones, : pa los fustaxes, / pal selector intelixente",
+ "Could not reload comments" : "Nun se pudieron recargar los comentarios",
+ "Failed to mark comments as read" : "Nun se pudieron marcar los comentarios como lleíos",
+ "Unable to load the comments list" : "Nun ye posible cargar la llista de comentarios",
+ "No comments yet, start the conversation!" : "Nun hai comentarios, ¡anicia una conversación!",
+ "No more messages" : "Nun hai más mensaxes",
+ "Retry" : "Retentar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentariu nuevu","{unread} comentarios nuevos"],
+ "Comment" : "Comentariu",
+ "An error occurred while trying to edit the comment" : "Prodúxose un error mentanto se tentaba d'editar el comentariu",
+ "Comment deleted" : "Desanicióse'l comentariu",
+ "An error occurred while trying to delete the comment" : "Prodúxose un error mentanto se tentaba de desaniciar el comentariu",
+ "An error occurred while trying to create the comment" : "Prodúxose un error mentanto se tentaba de crear el comentariu"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/az.js b/apps/comments/l10n/az.js
deleted file mode 100644
index 75428f67cc5..00000000000
--- a/apps/comments/l10n/az.js
+++ /dev/null
@@ -1,8 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Dayandır",
- "Save" : "Saxla",
- "Comment" : "Komentariya"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/az.json b/apps/comments/l10n/az.json
deleted file mode 100644
index c54d6648c59..00000000000
--- a/apps/comments/l10n/az.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{ "translations": {
- "Cancel" : "Dayandır",
- "Save" : "Saxla",
- "Comment" : "Komentariya"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/bg.js b/apps/comments/l10n/bg.js
new file mode 100644
index 00000000000..a645c5a543f
--- /dev/null
+++ b/apps/comments/l10n/bg.js
@@ -0,0 +1,30 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Коментари",
+ "You commented" : "Вие коментирахте",
+ "{author} commented" : "{author} коментира",
+ "You commented on %1$s" : "Ти коментира за %1$s",
+ "You commented on {file}" : "Ти коментира за {file}",
+ "%1$s commented on %2$s" : "%1$s коментиран за %2$s",
+ "{author} commented on {file}" : "{author} коментира за {file}",
+ "<strong>Comments</strong> for files" : "<strong>Коментари</strong> за файлове",
+ "Files" : "Файлове",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} ви спомена в коментар за “{file}”",
+ "Files app plugin to add comments to files" : "Добавка на приложението Файлове за добавяне на коментари към файловете",
+ "Edit comment" : "Редактирай коментра",
+ "Delete comment" : "Изтрий коментар",
+ "Cancel edit" : "Отказ на редактиране",
+ "Post comment" : "Публикуване на коментар",
+ "Unable to load the comments list" : "Списъкът с коментари не може да се зареди",
+ "No comments yet, start the conversation!" : "Все още няма коментари, започнете разговор!",
+ "No more messages" : " Няма повече съобщения",
+ "Retry" : "Опитай отново",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} нови коментари","{unread} нови коментари"],
+ "Comment" : "Коментар",
+ "An error occurred while trying to edit the comment" : "Възникна грешка при опит за редактиране на коментара",
+ "Comment deleted" : " Изтрит е коментар",
+ "An error occurred while trying to delete the comment" : "Възникна грешка при опит за изтриване на коментара",
+ "An error occurred while trying to create the comment" : "Възникна грешка при опит за създаване на коментар"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/bg.json b/apps/comments/l10n/bg.json
new file mode 100644
index 00000000000..5bb763dbc5d
--- /dev/null
+++ b/apps/comments/l10n/bg.json
@@ -0,0 +1,28 @@
+{ "translations": {
+ "Comments" : "Коментари",
+ "You commented" : "Вие коментирахте",
+ "{author} commented" : "{author} коментира",
+ "You commented on %1$s" : "Ти коментира за %1$s",
+ "You commented on {file}" : "Ти коментира за {file}",
+ "%1$s commented on %2$s" : "%1$s коментиран за %2$s",
+ "{author} commented on {file}" : "{author} коментира за {file}",
+ "<strong>Comments</strong> for files" : "<strong>Коментари</strong> за файлове",
+ "Files" : "Файлове",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} ви спомена в коментар за “{file}”",
+ "Files app plugin to add comments to files" : "Добавка на приложението Файлове за добавяне на коментари към файловете",
+ "Edit comment" : "Редактирай коментра",
+ "Delete comment" : "Изтрий коментар",
+ "Cancel edit" : "Отказ на редактиране",
+ "Post comment" : "Публикуване на коментар",
+ "Unable to load the comments list" : "Списъкът с коментари не може да се зареди",
+ "No comments yet, start the conversation!" : "Все още няма коментари, започнете разговор!",
+ "No more messages" : " Няма повече съобщения",
+ "Retry" : "Опитай отново",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} нови коментари","{unread} нови коментари"],
+ "Comment" : "Коментар",
+ "An error occurred while trying to edit the comment" : "Възникна грешка при опит за редактиране на коментара",
+ "Comment deleted" : " Изтрит е коментар",
+ "An error occurred while trying to delete the comment" : "Възникна грешка при опит за изтриване на коментара",
+ "An error occurred while trying to create the comment" : "Възникна грешка при опит за създаване на коментар"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/bg_BG.js b/apps/comments/l10n/bg_BG.js
deleted file mode 100644
index e63aedf80db..00000000000
--- a/apps/comments/l10n/bg_BG.js
+++ /dev/null
@@ -1,8 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Отказ",
- "Save" : "Запазване",
- "Comment" : "Коментар"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/bg_BG.json b/apps/comments/l10n/bg_BG.json
deleted file mode 100644
index 78ad0b57d4c..00000000000
--- a/apps/comments/l10n/bg_BG.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{ "translations": {
- "Cancel" : "Отказ",
- "Save" : "Запазване",
- "Comment" : "Коментар"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/bn_BD.js b/apps/comments/l10n/bn_BD.js
deleted file mode 100644
index fcff25b8402..00000000000
--- a/apps/comments/l10n/bn_BD.js
+++ /dev/null
@@ -1,8 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "বাতিল",
- "Save" : "সংরক্ষণ",
- "Comment" : "মন্তব্য"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/bn_BD.json b/apps/comments/l10n/bn_BD.json
deleted file mode 100644
index 81cd8fe1a48..00000000000
--- a/apps/comments/l10n/bn_BD.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{ "translations": {
- "Cancel" : "বাতিল",
- "Save" : "সংরক্ষণ",
- "Comment" : "মন্তব্য"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/bn_IN.js b/apps/comments/l10n/bn_IN.js
deleted file mode 100644
index 7b479dc0264..00000000000
--- a/apps/comments/l10n/bn_IN.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "বাতিল করা",
- "Save" : "সেভ"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/bn_IN.json b/apps/comments/l10n/bn_IN.json
deleted file mode 100644
index 9df2ea07062..00000000000
--- a/apps/comments/l10n/bn_IN.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "বাতিল করা",
- "Save" : "সেভ"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/bs.js b/apps/comments/l10n/bs.js
deleted file mode 100644
index b1f98fedfa6..00000000000
--- a/apps/comments/l10n/bs.js
+++ /dev/null
@@ -1,8 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Odustani",
- "Save" : "Spremi",
- "Comment" : "Komentar"
-},
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/apps/comments/l10n/bs.json b/apps/comments/l10n/bs.json
deleted file mode 100644
index d73df1a46c6..00000000000
--- a/apps/comments/l10n/bs.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{ "translations": {
- "Cancel" : "Odustani",
- "Save" : "Spremi",
- "Comment" : "Komentar"
-},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/ca.js b/apps/comments/l10n/ca.js
index a0d508f0afd..a8f3ce6d136 100644
--- a/apps/comments/l10n/ca.js
+++ b/apps/comments/l10n/ca.js
@@ -1,8 +1,36 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "Cancel·la",
- "Save" : "Desa",
- "Comment" : "Comentari"
+ "Comments" : "Comentaris",
+ "You commented" : "Heu escrit un comentari",
+ "{author} commented" : "{author} ha escrit un comentari",
+ "You commented on %1$s" : "Heu escrit un comentari a %1$s",
+ "You commented on {file}" : "Heu escrit un comentari a {file}",
+ "%1$s commented on %2$s" : "%1$s ha escrit un comentari a %2$s",
+ "{author} commented on {file}" : "{author} ha escrit un comentari a {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentaris</strong> per a fitxers",
+ "Files" : "Fitxers",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Se us ha esmentat a «{file}» en un comentari d'un compte que s'ha suprimit",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} us ha esmentat en un comentari a «{file}»",
+ "Files app plugin to add comments to files" : "Connector de l'aplicació Fitxers per a afegir comentaris als fitxers",
+ "Edit comment" : "Edita el comentari",
+ "Delete comment" : "Suprimeix el comentari",
+ "Cancel edit" : "Cancel·la l'edició",
+ "New comment" : "Comentari nou",
+ "Write a comment …" : "Escriviu un comentari…",
+ "Post comment" : "Publica el comentari",
+ "@ for mentions, : for emoji, / for smart picker" : "@ per a mencions, : per a emojis, / per al selector intel·ligent",
+ "Could not reload comments" : "No s'han pogut tornar a carregar els comentaris",
+ "Failed to mark comments as read" : "No s'han pogut marcar els comentaris com a llegits",
+ "Unable to load the comments list" : "No s'ha pogut carregar la llista de comentaris",
+ "No comments yet, start the conversation!" : "Encara no hi ha cap comentari. Enceteu la conversa!",
+ "No more messages" : "No hi ha més missatges",
+ "Retry" : "Torna-ho a provar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentari nou","{unread} comentaris nous"],
+ "Comment" : "Comentari",
+ "An error occurred while trying to edit the comment" : "S'ha produït un error en intentar editar el comentari",
+ "Comment deleted" : "S'ha suprimit el comentari",
+ "An error occurred while trying to delete the comment" : "S'ha produït un error en intentar suprimir el comentari",
+ "An error occurred while trying to create the comment" : "S'ha produït un error en intentar crear el comentari"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/ca.json b/apps/comments/l10n/ca.json
index 2bfdc24610b..d1f4ce2c7fe 100644
--- a/apps/comments/l10n/ca.json
+++ b/apps/comments/l10n/ca.json
@@ -1,6 +1,34 @@
{ "translations": {
- "Cancel" : "Cancel·la",
- "Save" : "Desa",
- "Comment" : "Comentari"
+ "Comments" : "Comentaris",
+ "You commented" : "Heu escrit un comentari",
+ "{author} commented" : "{author} ha escrit un comentari",
+ "You commented on %1$s" : "Heu escrit un comentari a %1$s",
+ "You commented on {file}" : "Heu escrit un comentari a {file}",
+ "%1$s commented on %2$s" : "%1$s ha escrit un comentari a %2$s",
+ "{author} commented on {file}" : "{author} ha escrit un comentari a {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentaris</strong> per a fitxers",
+ "Files" : "Fitxers",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Se us ha esmentat a «{file}» en un comentari d'un compte que s'ha suprimit",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} us ha esmentat en un comentari a «{file}»",
+ "Files app plugin to add comments to files" : "Connector de l'aplicació Fitxers per a afegir comentaris als fitxers",
+ "Edit comment" : "Edita el comentari",
+ "Delete comment" : "Suprimeix el comentari",
+ "Cancel edit" : "Cancel·la l'edició",
+ "New comment" : "Comentari nou",
+ "Write a comment …" : "Escriviu un comentari…",
+ "Post comment" : "Publica el comentari",
+ "@ for mentions, : for emoji, / for smart picker" : "@ per a mencions, : per a emojis, / per al selector intel·ligent",
+ "Could not reload comments" : "No s'han pogut tornar a carregar els comentaris",
+ "Failed to mark comments as read" : "No s'han pogut marcar els comentaris com a llegits",
+ "Unable to load the comments list" : "No s'ha pogut carregar la llista de comentaris",
+ "No comments yet, start the conversation!" : "Encara no hi ha cap comentari. Enceteu la conversa!",
+ "No more messages" : "No hi ha més missatges",
+ "Retry" : "Torna-ho a provar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentari nou","{unread} comentaris nous"],
+ "Comment" : "Comentari",
+ "An error occurred while trying to edit the comment" : "S'ha produït un error en intentar editar el comentari",
+ "Comment deleted" : "S'ha suprimit el comentari",
+ "An error occurred while trying to delete the comment" : "S'ha produït un error en intentar suprimir el comentari",
+ "An error occurred while trying to create the comment" : "S'ha produït un error en intentar crear el comentari"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/cs.js b/apps/comments/l10n/cs.js
new file mode 100644
index 00000000000..1c8d69c14e5
--- /dev/null
+++ b/apps/comments/l10n/cs.js
@@ -0,0 +1,36 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Komentáře",
+ "You commented" : "Okomentovali jste",
+ "{author} commented" : "{author} okomentoval(a)",
+ "You commented on %1$s" : "Okomentovali jste %1$s",
+ "You commented on {file}" : "Okomentovali jste {file}",
+ "%1$s commented on %2$s" : "%1$s okomentoval(a) %2$s",
+ "{author} commented on {file}" : "{author} okomentoval(a) {file}",
+ "<strong>Comments</strong> for files" : "<strong>Komentáře</strong> k souborům",
+ "Files" : "Soubory",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Byli jste zmíněni u souboru „{file}“, v komentáři od účtu, který byl později smazán",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} vás zmínil(a) v komentáři u „{file}“",
+ "Files app plugin to add comments to files" : "Zásuvný modul do aplikace Soubory pro přidávání komentářů k souborům",
+ "Edit comment" : "Upravit komentář",
+ "Delete comment" : "Smazat komentář",
+ "Cancel edit" : "Zrušit úpravu",
+ "New comment" : "Nový komentář",
+ "Write a comment …" : "Napsat komentář…",
+ "Post comment" : "Odeslat komentář",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pro zmínění, : pro emotikony, / pro inteligentní výběr",
+ "Could not reload comments" : "Znovunačtení komentářů se nezdařilo",
+ "Failed to mark comments as read" : "Nepodařilo se označit komentáře jako přečtené",
+ "Unable to load the comments list" : "Nedaří se načíst seznam komentářů",
+ "No comments yet, start the conversation!" : "Zatím bez komentářů, začněte konverzaci!",
+ "No more messages" : "Žádné další zprávy",
+ "Retry" : "Zkusit znovu",
+ "_1 new comment_::_{unread} new comments_" : ["Jeden nový komentář","{unread} nové komentáře","{unread} nových komentářů","{unread} nové komentáře"],
+ "Comment" : "Komentář",
+ "An error occurred while trying to edit the comment" : "Došlo k chybě při pokusu o úpravu komentáře",
+ "Comment deleted" : "Komentář smazán",
+ "An error occurred while trying to delete the comment" : "Došlo k chybě při pokusu o smazání komentáře",
+ "An error occurred while trying to create the comment" : "Došlo k chybě při pokusu o vytvoření komentáře"
+},
+"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;");
diff --git a/apps/comments/l10n/cs.json b/apps/comments/l10n/cs.json
new file mode 100644
index 00000000000..c933b71a7c6
--- /dev/null
+++ b/apps/comments/l10n/cs.json
@@ -0,0 +1,34 @@
+{ "translations": {
+ "Comments" : "Komentáře",
+ "You commented" : "Okomentovali jste",
+ "{author} commented" : "{author} okomentoval(a)",
+ "You commented on %1$s" : "Okomentovali jste %1$s",
+ "You commented on {file}" : "Okomentovali jste {file}",
+ "%1$s commented on %2$s" : "%1$s okomentoval(a) %2$s",
+ "{author} commented on {file}" : "{author} okomentoval(a) {file}",
+ "<strong>Comments</strong> for files" : "<strong>Komentáře</strong> k souborům",
+ "Files" : "Soubory",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Byli jste zmíněni u souboru „{file}“, v komentáři od účtu, který byl později smazán",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} vás zmínil(a) v komentáři u „{file}“",
+ "Files app plugin to add comments to files" : "Zásuvný modul do aplikace Soubory pro přidávání komentářů k souborům",
+ "Edit comment" : "Upravit komentář",
+ "Delete comment" : "Smazat komentář",
+ "Cancel edit" : "Zrušit úpravu",
+ "New comment" : "Nový komentář",
+ "Write a comment …" : "Napsat komentář…",
+ "Post comment" : "Odeslat komentář",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pro zmínění, : pro emotikony, / pro inteligentní výběr",
+ "Could not reload comments" : "Znovunačtení komentářů se nezdařilo",
+ "Failed to mark comments as read" : "Nepodařilo se označit komentáře jako přečtené",
+ "Unable to load the comments list" : "Nedaří se načíst seznam komentářů",
+ "No comments yet, start the conversation!" : "Zatím bez komentářů, začněte konverzaci!",
+ "No more messages" : "Žádné další zprávy",
+ "Retry" : "Zkusit znovu",
+ "_1 new comment_::_{unread} new comments_" : ["Jeden nový komentář","{unread} nové komentáře","{unread} nových komentářů","{unread} nové komentáře"],
+ "Comment" : "Komentář",
+ "An error occurred while trying to edit the comment" : "Došlo k chybě při pokusu o úpravu komentáře",
+ "Comment deleted" : "Komentář smazán",
+ "An error occurred while trying to delete the comment" : "Došlo k chybě při pokusu o smazání komentáře",
+ "An error occurred while trying to create the comment" : "Došlo k chybě při pokusu o vytvoření komentáře"
+},"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/cs_CZ.js b/apps/comments/l10n/cs_CZ.js
deleted file mode 100644
index 1b4e03102d4..00000000000
--- a/apps/comments/l10n/cs_CZ.js
+++ /dev/null
@@ -1,23 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "<strong>Comments</strong> for files" : "<strong>Komentáře</strong> souborů",
- "You commented" : "Okomentoval jste",
- "%1$s commented" : "%1$s okomentován",
- "You commented on %2$s" : "Okomentoval jste %2$s",
- "%1$s commented on %2$s" : "%1$s okomentoval %2$s",
- "Comments" : "Komentáře",
- "Type in a new comment..." : "Zadat nový komentář...",
- "Delete comment" : "Smazat komentář",
- "Post" : "Zveřejnit",
- "Cancel" : "Zrušit",
- "Edit comment" : "Upravit komentář",
- "[Deleted user]" : "[Smazaný uživatel]",
- "No other comments available" : "Nejsou dostupné žádné další komentáře",
- "More comments..." : "Více komentářů...",
- "Save" : "Uložit",
- "Allowed characters {count} of {max}" : "Povolených znaků {count} z {max}",
- "{count} unread comments" : "{count} nepřečtených komentářů",
- "Comment" : "Komentář"
-},
-"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;");
diff --git a/apps/comments/l10n/cs_CZ.json b/apps/comments/l10n/cs_CZ.json
deleted file mode 100644
index 5ca994542bf..00000000000
--- a/apps/comments/l10n/cs_CZ.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Komentáře</strong> souborů",
- "You commented" : "Okomentoval jste",
- "%1$s commented" : "%1$s okomentován",
- "You commented on %2$s" : "Okomentoval jste %2$s",
- "%1$s commented on %2$s" : "%1$s okomentoval %2$s",
- "Comments" : "Komentáře",
- "Type in a new comment..." : "Zadat nový komentář...",
- "Delete comment" : "Smazat komentář",
- "Post" : "Zveřejnit",
- "Cancel" : "Zrušit",
- "Edit comment" : "Upravit komentář",
- "[Deleted user]" : "[Smazaný uživatel]",
- "No other comments available" : "Nejsou dostupné žádné další komentáře",
- "More comments..." : "Více komentářů...",
- "Save" : "Uložit",
- "Allowed characters {count} of {max}" : "Povolených znaků {count} z {max}",
- "{count} unread comments" : "{count} nepřečtených komentářů",
- "Comment" : "Komentář"
-},"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/cy_GB.js b/apps/comments/l10n/cy_GB.js
deleted file mode 100644
index 4e1c6a57f6e..00000000000
--- a/apps/comments/l10n/cy_GB.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Diddymu",
- "Save" : "Cadw"
-},
-"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;");
diff --git a/apps/comments/l10n/cy_GB.json b/apps/comments/l10n/cy_GB.json
deleted file mode 100644
index 1ea3eafef30..00000000000
--- a/apps/comments/l10n/cy_GB.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "Diddymu",
- "Save" : "Cadw"
-},"pluralForm" :"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/da.js b/apps/comments/l10n/da.js
index 5725a7b57c6..23c4b9873e7 100644
--- a/apps/comments/l10n/da.js
+++ b/apps/comments/l10n/da.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> til filer",
+ "Comments" : "Kommentarer",
"You commented" : "Du kommenterede",
- "%1$s commented" : "%1$s kommenterede",
- "You commented on %2$s" : "Du kommenterede %2$s",
+ "{author} commented" : "{author} kommenterede",
+ "You commented on %1$s" : "Du kommenterede %1$s",
+ "You commented on {file}" : "Du kommenterede {file}",
"%1$s commented on %2$s" : "%1$s kommenterede %2$s",
- "Comments" : "Kommentarer",
- "Type in a new comment..." : "Indtast en ny kommentar...",
- "Delete comment" : "Slet kommentar",
- "Post" : "Indlæg",
- "Cancel" : "Annullér",
+ "{author} commented on {file}" : "{author} kommenterede {file}",
+ "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> for filer",
+ "Files" : "Filer",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Du blev nævnt på \"{file}\", i en kommentar af en konto, som siden er blevet slettet",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} nævnte dig i en kommentar til \"{file}\"",
+ "Files app plugin to add comments to files" : "Files app plugin til at tilføje kommentarer til filer",
"Edit comment" : "Rediger kommentar",
- "[Deleted user]" : "[Deleted user]",
- "No other comments available" : "Ingen andre kommentarer tilgængelige",
- "More comments..." : "Flere kommentarer...",
- "Save" : "Gem",
- "Allowed characters {count} of {max}" : "Tilladte tegn {count} af {max}",
- "{count} unread comments" : "{count} ulæste kommentarer",
- "Comment" : "Kommentér"
+ "Delete comment" : "Slet kommentar",
+ "Cancel edit" : "Annuller redigering",
+ "New comment" : "Ny kommentar",
+ "Write a comment …" : "Skriv kommentar…",
+ "Post comment" : "Skriv kommentar",
+ "@ for mentions, : for emoji, / for smart picker" : "\"@\" for at omtale, \":\" for emojis, \"/\" for Smart Vælger",
+ "Could not reload comments" : "Kunne ikke indlæse kommentarer",
+ "Failed to mark comments as read" : "Kunne ikke markere kommentarer som læst",
+ "Unable to load the comments list" : "Kan ikke indlæse kommentarlisten",
+ "No comments yet, start the conversation!" : "Ingen kommentarer endnu, start samtalen!",
+ "No more messages" : "Ikke flere beskeder",
+ "Retry" : "Prøv igen",
+ "_1 new comment_::_{unread} new comments_" : ["1 ny kommentar","{unread} nye kommentarer"],
+ "Comment" : "Kommenter",
+ "An error occurred while trying to edit the comment" : "Der opstod en fejl under forsøget på at redigere kommentaren",
+ "Comment deleted" : "Kommentar slettet",
+ "An error occurred while trying to delete the comment" : "Der opstod en fejl under forsøget på at slette kommentaren",
+ "An error occurred while trying to create the comment" : "Der opstod en fejl under forsøget på at oprette kommentaren"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/da.json b/apps/comments/l10n/da.json
index a7b12851157..4abcd817f3b 100644
--- a/apps/comments/l10n/da.json
+++ b/apps/comments/l10n/da.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> til filer",
+ "Comments" : "Kommentarer",
"You commented" : "Du kommenterede",
- "%1$s commented" : "%1$s kommenterede",
- "You commented on %2$s" : "Du kommenterede %2$s",
+ "{author} commented" : "{author} kommenterede",
+ "You commented on %1$s" : "Du kommenterede %1$s",
+ "You commented on {file}" : "Du kommenterede {file}",
"%1$s commented on %2$s" : "%1$s kommenterede %2$s",
- "Comments" : "Kommentarer",
- "Type in a new comment..." : "Indtast en ny kommentar...",
- "Delete comment" : "Slet kommentar",
- "Post" : "Indlæg",
- "Cancel" : "Annullér",
+ "{author} commented on {file}" : "{author} kommenterede {file}",
+ "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> for filer",
+ "Files" : "Filer",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Du blev nævnt på \"{file}\", i en kommentar af en konto, som siden er blevet slettet",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} nævnte dig i en kommentar til \"{file}\"",
+ "Files app plugin to add comments to files" : "Files app plugin til at tilføje kommentarer til filer",
"Edit comment" : "Rediger kommentar",
- "[Deleted user]" : "[Deleted user]",
- "No other comments available" : "Ingen andre kommentarer tilgængelige",
- "More comments..." : "Flere kommentarer...",
- "Save" : "Gem",
- "Allowed characters {count} of {max}" : "Tilladte tegn {count} af {max}",
- "{count} unread comments" : "{count} ulæste kommentarer",
- "Comment" : "Kommentér"
+ "Delete comment" : "Slet kommentar",
+ "Cancel edit" : "Annuller redigering",
+ "New comment" : "Ny kommentar",
+ "Write a comment …" : "Skriv kommentar…",
+ "Post comment" : "Skriv kommentar",
+ "@ for mentions, : for emoji, / for smart picker" : "\"@\" for at omtale, \":\" for emojis, \"/\" for Smart Vælger",
+ "Could not reload comments" : "Kunne ikke indlæse kommentarer",
+ "Failed to mark comments as read" : "Kunne ikke markere kommentarer som læst",
+ "Unable to load the comments list" : "Kan ikke indlæse kommentarlisten",
+ "No comments yet, start the conversation!" : "Ingen kommentarer endnu, start samtalen!",
+ "No more messages" : "Ikke flere beskeder",
+ "Retry" : "Prøv igen",
+ "_1 new comment_::_{unread} new comments_" : ["1 ny kommentar","{unread} nye kommentarer"],
+ "Comment" : "Kommenter",
+ "An error occurred while trying to edit the comment" : "Der opstod en fejl under forsøget på at redigere kommentaren",
+ "Comment deleted" : "Kommentar slettet",
+ "An error occurred while trying to delete the comment" : "Der opstod en fejl under forsøget på at slette kommentaren",
+ "An error occurred while trying to create the comment" : "Der opstod en fejl under forsøget på at oprette kommentaren"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/de.js b/apps/comments/l10n/de.js
index 0e51b02662a..dc964592b19 100644
--- a/apps/comments/l10n/de.js
+++ b/apps/comments/l10n/de.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Kommentare</strong> für Dateien",
+ "Comments" : "Kommentare",
"You commented" : "Du hast kommentiert",
- "%1$s commented" : "%1$s kommentierte",
- "You commented on %2$s" : "Du hast %2$s kommentiert",
+ "{author} commented" : "{author} kommentierte",
+ "You commented on %1$s" : "Du hast %1$s kommentiert",
+ "You commented on {file}" : "Du hast {file} kommentiert",
"%1$s commented on %2$s" : "%1$s kommentierte %2$s",
- "Comments" : "Kommentare",
- "Type in a new comment..." : "Bitte gib einen neuen Kommentar ein...",
- "Delete comment" : "Kommentar löschen",
- "Post" : "Speichern",
- "Cancel" : "Abbrechen",
+ "{author} commented on {file}" : "{author} hat {file} kommentiert",
+ "<strong>Comments</strong> for files" : "<strong>Kommentare</strong> für Dateien",
+ "Files" : "Dateien",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Du wurdest in einem Kommentar zu \"{file}\" von einem Konto erwähnt, das inzwischen gelöscht wurde.",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} hat dich in einem Kommentar zu \"{file}\" erwähnt",
+ "Files app plugin to add comments to files" : "Ein Plugin für die Dateien-App zum Kommentieren von Dateien",
"Edit comment" : "Kommentar bearbeiten",
- "[Deleted user]" : "[Gelöschter Benutzer]",
- "No other comments available" : "Keine anderen Kommentare vorhanden",
- "More comments..." : "Weitere Kommentare...",
- "Save" : "Speichern",
- "Allowed characters {count} of {max}" : "Erlaubte Zeichen {count} von {max}",
- "{count} unread comments" : "{count} ungelesene Kommentare",
- "Comment" : "Kommentar"
+ "Delete comment" : "Kommentar löschen",
+ "Cancel edit" : "Bearbeiten abbrechen",
+ "New comment" : "Neuer Kommentar",
+ "Write a comment …" : "Einen Kommentar schreiben …",
+ "Post comment" : "Kommentar veröffentlichen",
+ "@ for mentions, : for emoji, / for smart picker" : "@ für Erwähnungen, : für Emoji, / für Smart Picker",
+ "Could not reload comments" : "Kommentare konnten nicht erneut geladen werden",
+ "Failed to mark comments as read" : "Kommentare konnten nicht als gelesen markiert werden",
+ "Unable to load the comments list" : "Kommentarliste konnte nicht geladen werden",
+ "No comments yet, start the conversation!" : "Keine Kommentare bisher. Beginne die Diskussion!",
+ "No more messages" : "Keine weiteren Nachrichten",
+ "Retry" : "Wiederholen",
+ "_1 new comment_::_{unread} new comments_" : ["1 neuer Kommentar","[unread] neue Kommentare"],
+ "Comment" : "Kommentar",
+ "An error occurred while trying to edit the comment" : "Es ist ein Fehler beim Bearbeiten des Kommentars aufgetreten",
+ "Comment deleted" : "Kommentar gelöscht",
+ "An error occurred while trying to delete the comment" : "Es ist ein Fehler beim Löschen des Kommentars aufgetreten",
+ "An error occurred while trying to create the comment" : "Es ist ein Fehler beim Erstellen des Kommentars aufgetreten"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/de.json b/apps/comments/l10n/de.json
index 8dc0bdb0427..d0679199b23 100644
--- a/apps/comments/l10n/de.json
+++ b/apps/comments/l10n/de.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Kommentare</strong> für Dateien",
+ "Comments" : "Kommentare",
"You commented" : "Du hast kommentiert",
- "%1$s commented" : "%1$s kommentierte",
- "You commented on %2$s" : "Du hast %2$s kommentiert",
+ "{author} commented" : "{author} kommentierte",
+ "You commented on %1$s" : "Du hast %1$s kommentiert",
+ "You commented on {file}" : "Du hast {file} kommentiert",
"%1$s commented on %2$s" : "%1$s kommentierte %2$s",
- "Comments" : "Kommentare",
- "Type in a new comment..." : "Bitte gib einen neuen Kommentar ein...",
- "Delete comment" : "Kommentar löschen",
- "Post" : "Speichern",
- "Cancel" : "Abbrechen",
+ "{author} commented on {file}" : "{author} hat {file} kommentiert",
+ "<strong>Comments</strong> for files" : "<strong>Kommentare</strong> für Dateien",
+ "Files" : "Dateien",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Du wurdest in einem Kommentar zu \"{file}\" von einem Konto erwähnt, das inzwischen gelöscht wurde.",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} hat dich in einem Kommentar zu \"{file}\" erwähnt",
+ "Files app plugin to add comments to files" : "Ein Plugin für die Dateien-App zum Kommentieren von Dateien",
"Edit comment" : "Kommentar bearbeiten",
- "[Deleted user]" : "[Gelöschter Benutzer]",
- "No other comments available" : "Keine anderen Kommentare vorhanden",
- "More comments..." : "Weitere Kommentare...",
- "Save" : "Speichern",
- "Allowed characters {count} of {max}" : "Erlaubte Zeichen {count} von {max}",
- "{count} unread comments" : "{count} ungelesene Kommentare",
- "Comment" : "Kommentar"
+ "Delete comment" : "Kommentar löschen",
+ "Cancel edit" : "Bearbeiten abbrechen",
+ "New comment" : "Neuer Kommentar",
+ "Write a comment …" : "Einen Kommentar schreiben …",
+ "Post comment" : "Kommentar veröffentlichen",
+ "@ for mentions, : for emoji, / for smart picker" : "@ für Erwähnungen, : für Emoji, / für Smart Picker",
+ "Could not reload comments" : "Kommentare konnten nicht erneut geladen werden",
+ "Failed to mark comments as read" : "Kommentare konnten nicht als gelesen markiert werden",
+ "Unable to load the comments list" : "Kommentarliste konnte nicht geladen werden",
+ "No comments yet, start the conversation!" : "Keine Kommentare bisher. Beginne die Diskussion!",
+ "No more messages" : "Keine weiteren Nachrichten",
+ "Retry" : "Wiederholen",
+ "_1 new comment_::_{unread} new comments_" : ["1 neuer Kommentar","[unread] neue Kommentare"],
+ "Comment" : "Kommentar",
+ "An error occurred while trying to edit the comment" : "Es ist ein Fehler beim Bearbeiten des Kommentars aufgetreten",
+ "Comment deleted" : "Kommentar gelöscht",
+ "An error occurred while trying to delete the comment" : "Es ist ein Fehler beim Löschen des Kommentars aufgetreten",
+ "An error occurred while trying to create the comment" : "Es ist ein Fehler beim Erstellen des Kommentars aufgetreten"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/de_AT.js b/apps/comments/l10n/de_AT.js
deleted file mode 100644
index f92cad6bcde..00000000000
--- a/apps/comments/l10n/de_AT.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Abbrechen",
- "Save" : "Speichern"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/de_AT.json b/apps/comments/l10n/de_AT.json
deleted file mode 100644
index 45d2f9e21dd..00000000000
--- a/apps/comments/l10n/de_AT.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "Abbrechen",
- "Save" : "Speichern"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/de_DE.js b/apps/comments/l10n/de_DE.js
index 424ae79e10e..8a492c10bd3 100644
--- a/apps/comments/l10n/de_DE.js
+++ b/apps/comments/l10n/de_DE.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Kommentare</strong> für Dateien",
- "You commented" : "Durch dich kommentiert",
- "%1$s commented" : "%1$s kommentiert",
- "You commented on %2$s" : "Sie haben %2$s kommentiert",
- "%1$s commented on %2$s" : "%1$s kommentierte %2$s",
"Comments" : "Kommentare",
- "Type in a new comment..." : "Neuer Kommentar...",
- "Delete comment" : "Kommentar löschen",
- "Post" : "Speichern",
- "Cancel" : "Abbrechen",
+ "You commented" : "Sie haben kommentiert",
+ "{author} commented" : "{author} kommentierte",
+ "You commented on %1$s" : "Sie haben %1$s kommentiert",
+ "You commented on {file}" : "Sie haben {file} kommentiert",
+ "%1$s commented on %2$s" : "%1$s kommentierte %2$s",
+ "{author} commented on {file}" : "{author} hat {file} kommentiert",
+ "<strong>Comments</strong> for files" : "<strong>Kommentare</strong> für Dateien",
+ "Files" : "Dateien",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Sie wurden in einem Kommentar zu \"{file}\" von einem Konto erwähnt, das inzwischen gelöscht wurde.",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} hat Sie in einem Kommentar zu \"{file}\" erwähnt",
+ "Files app plugin to add comments to files" : "Ein Plugin für die Dateien-App zum Kommentieren von Dateien",
"Edit comment" : "Kommentar bearbeiten",
- "[Deleted user]" : "[gelöschter Benutzer]",
- "No other comments available" : "Keine anderen Kommentare verfügbar",
- "More comments..." : "Weitere Kommentare...",
- "Save" : "Speichern",
- "Allowed characters {count} of {max}" : "{count} von {max} Zeichen benutzt",
- "{count} unread comments" : "[count] ungelesene Kommentare",
- "Comment" : "Kommentar"
+ "Delete comment" : "Kommentar löschen",
+ "Cancel edit" : "Bearbeiten abbrechen",
+ "New comment" : "Neuer Kommentar",
+ "Write a comment …" : "Schreiben Sie einen Kommentar …",
+ "Post comment" : "Kommentar veröffentlichen",
+ "@ for mentions, : for emoji, / for smart picker" : "@ für Erwähnungen, : für Emoji, / für Smart Picker",
+ "Could not reload comments" : "Kommentare konnten nicht erneut geladen werden",
+ "Failed to mark comments as read" : "Kommentare konnten nicht als gelesen markiert werden",
+ "Unable to load the comments list" : "Kommentarliste kann nicht geladen werden",
+ "No comments yet, start the conversation!" : "Keine Kommentare bisher. Beginnen Sie die Diskussion!",
+ "No more messages" : "Keine weiteren Nachrichten",
+ "Retry" : "Wiederholen",
+ "_1 new comment_::_{unread} new comments_" : ["1 neuer Kommentar","[unread] neue Kommentare"],
+ "Comment" : "Kommentar",
+ "An error occurred while trying to edit the comment" : "Es ist ein Fehler beim Bearbeiten des Kommentars aufgetreten",
+ "Comment deleted" : "Kommentar gelöscht",
+ "An error occurred while trying to delete the comment" : "Es ist ein Fehler beim Löschen des Kommentars aufgetreten",
+ "An error occurred while trying to create the comment" : "Es ist ein Fehler beim Erstellen des Kommentars aufgetreten"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/de_DE.json b/apps/comments/l10n/de_DE.json
index 4fd810c7006..44f2bbd961d 100644
--- a/apps/comments/l10n/de_DE.json
+++ b/apps/comments/l10n/de_DE.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Kommentare</strong> für Dateien",
- "You commented" : "Durch dich kommentiert",
- "%1$s commented" : "%1$s kommentiert",
- "You commented on %2$s" : "Sie haben %2$s kommentiert",
- "%1$s commented on %2$s" : "%1$s kommentierte %2$s",
"Comments" : "Kommentare",
- "Type in a new comment..." : "Neuer Kommentar...",
- "Delete comment" : "Kommentar löschen",
- "Post" : "Speichern",
- "Cancel" : "Abbrechen",
+ "You commented" : "Sie haben kommentiert",
+ "{author} commented" : "{author} kommentierte",
+ "You commented on %1$s" : "Sie haben %1$s kommentiert",
+ "You commented on {file}" : "Sie haben {file} kommentiert",
+ "%1$s commented on %2$s" : "%1$s kommentierte %2$s",
+ "{author} commented on {file}" : "{author} hat {file} kommentiert",
+ "<strong>Comments</strong> for files" : "<strong>Kommentare</strong> für Dateien",
+ "Files" : "Dateien",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Sie wurden in einem Kommentar zu \"{file}\" von einem Konto erwähnt, das inzwischen gelöscht wurde.",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} hat Sie in einem Kommentar zu \"{file}\" erwähnt",
+ "Files app plugin to add comments to files" : "Ein Plugin für die Dateien-App zum Kommentieren von Dateien",
"Edit comment" : "Kommentar bearbeiten",
- "[Deleted user]" : "[gelöschter Benutzer]",
- "No other comments available" : "Keine anderen Kommentare verfügbar",
- "More comments..." : "Weitere Kommentare...",
- "Save" : "Speichern",
- "Allowed characters {count} of {max}" : "{count} von {max} Zeichen benutzt",
- "{count} unread comments" : "[count] ungelesene Kommentare",
- "Comment" : "Kommentar"
+ "Delete comment" : "Kommentar löschen",
+ "Cancel edit" : "Bearbeiten abbrechen",
+ "New comment" : "Neuer Kommentar",
+ "Write a comment …" : "Schreiben Sie einen Kommentar …",
+ "Post comment" : "Kommentar veröffentlichen",
+ "@ for mentions, : for emoji, / for smart picker" : "@ für Erwähnungen, : für Emoji, / für Smart Picker",
+ "Could not reload comments" : "Kommentare konnten nicht erneut geladen werden",
+ "Failed to mark comments as read" : "Kommentare konnten nicht als gelesen markiert werden",
+ "Unable to load the comments list" : "Kommentarliste kann nicht geladen werden",
+ "No comments yet, start the conversation!" : "Keine Kommentare bisher. Beginnen Sie die Diskussion!",
+ "No more messages" : "Keine weiteren Nachrichten",
+ "Retry" : "Wiederholen",
+ "_1 new comment_::_{unread} new comments_" : ["1 neuer Kommentar","[unread] neue Kommentare"],
+ "Comment" : "Kommentar",
+ "An error occurred while trying to edit the comment" : "Es ist ein Fehler beim Bearbeiten des Kommentars aufgetreten",
+ "Comment deleted" : "Kommentar gelöscht",
+ "An error occurred while trying to delete the comment" : "Es ist ein Fehler beim Löschen des Kommentars aufgetreten",
+ "An error occurred while trying to create the comment" : "Es ist ein Fehler beim Erstellen des Kommentars aufgetreten"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/el.js b/apps/comments/l10n/el.js
index 1ca7886fdc5..80b8c2b00fe 100644
--- a/apps/comments/l10n/el.js
+++ b/apps/comments/l10n/el.js
@@ -1,23 +1,31 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Σχόλια</strong> για αρχεία",
+ "Comments" : "Σχόλια",
"You commented" : "Σχολιάσατε",
- "%1$s commented" : "%1$s σχολίασε",
- "You commented on %2$s" : "Σχολιάσατε στο %2$s",
+ "{author} commented" : "Ο {author} σχολίασε",
+ "You commented on %1$s" : "Σχολιάσατε στο %1$s",
+ "You commented on {file}" : "Σχολιάσατε στο {file}",
"%1$s commented on %2$s" : "%1$s σχολίασε στο %2$s",
- "Comments" : "Σχόλια",
- "Type in a new comment..." : "Αυτό είναι ένα νέο σχόλιο...",
- "Delete comment" : "Διαγραφή σχολίου",
- "Post" : "Δημοσίευση",
- "Cancel" : "Άκυρο",
+ "{author} commented on {file}" : "Ο {author} σχολίασε στο {file}",
+ "<strong>Comments</strong> for files" : "<strong>Σχόλια</strong> για αρχεία",
+ "Files" : "Αρχεία",
+ "{user} mentioned you in a comment on \"{file}\"" : "Ο/η {user} σας ανέφερε σε σχόλιο στο “{file}”",
+ "Files app plugin to add comments to files" : "Επέκταση της εφαρμογής Αρχεία που επιτρέπει την προσθήκη σχολίων σε αρχεία",
"Edit comment" : "Επεξεργασία σχολίου",
- "[Deleted user]" : "[Διαγραφή χρήστη]",
- "No other comments available" : "Δεν υπάρχουν άλλα διαθέσιμα σχόλια",
- "More comments..." : "Περισσότερα σχόλια...",
- "Save" : "Αποθήκευση",
- "Allowed characters {count} of {max}" : "Επιτρεπόμενοι χαρακτήρες {count} από {max}",
- "{count} unread comments" : "{count} μη αναγνωσμένα σχόλια",
- "Comment" : "Σχόλιο"
+ "Delete comment" : "Διαγραφή σχολίου",
+ "Cancel edit" : "Ακύρωση επεξεργασίας",
+ "New comment" : "Νέο σχόλιο",
+ "Post comment" : "Αναρτήστε σχόλιο",
+ "Unable to load the comments list" : "Δεν είναι δυνατή η μεταφόρτωση της λίστας σχολίων.",
+ "No comments yet, start the conversation!" : "Δεν υπάρχουν σχόλια, ξεκινήστε την συζήτηση!",
+ "No more messages" : "Δεν υπάρχουν άλλα μηνύματα",
+ "Retry" : "Δοκιμή ξανά",
+ "_1 new comment_::_{unread} new comments_" : ["1 νέο σχόλιο","{unread} νέα σχόλια"],
+ "Comment" : "Σχόλιο",
+ "An error occurred while trying to edit the comment" : "Παρουσιάστηκε σφάλμα κατά την προσπάθεια επεξεργασίας του σχολίου",
+ "Comment deleted" : "Το σχόλιο διαγράφηκε",
+ "An error occurred while trying to delete the comment" : "Παρουσιάστηκε σφάλμα κατά την προσπάθεια διαγραφής του σχολίου",
+ "An error occurred while trying to create the comment" : "Παρουσιάστηκε σφάλμα κατά την προσπάθεια δημιουργίας του σχολίου"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/el.json b/apps/comments/l10n/el.json
index 234f6b79045..3c0c4a730e9 100644
--- a/apps/comments/l10n/el.json
+++ b/apps/comments/l10n/el.json
@@ -1,21 +1,29 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Σχόλια</strong> για αρχεία",
+ "Comments" : "Σχόλια",
"You commented" : "Σχολιάσατε",
- "%1$s commented" : "%1$s σχολίασε",
- "You commented on %2$s" : "Σχολιάσατε στο %2$s",
+ "{author} commented" : "Ο {author} σχολίασε",
+ "You commented on %1$s" : "Σχολιάσατε στο %1$s",
+ "You commented on {file}" : "Σχολιάσατε στο {file}",
"%1$s commented on %2$s" : "%1$s σχολίασε στο %2$s",
- "Comments" : "Σχόλια",
- "Type in a new comment..." : "Αυτό είναι ένα νέο σχόλιο...",
- "Delete comment" : "Διαγραφή σχολίου",
- "Post" : "Δημοσίευση",
- "Cancel" : "Άκυρο",
+ "{author} commented on {file}" : "Ο {author} σχολίασε στο {file}",
+ "<strong>Comments</strong> for files" : "<strong>Σχόλια</strong> για αρχεία",
+ "Files" : "Αρχεία",
+ "{user} mentioned you in a comment on \"{file}\"" : "Ο/η {user} σας ανέφερε σε σχόλιο στο “{file}”",
+ "Files app plugin to add comments to files" : "Επέκταση της εφαρμογής Αρχεία που επιτρέπει την προσθήκη σχολίων σε αρχεία",
"Edit comment" : "Επεξεργασία σχολίου",
- "[Deleted user]" : "[Διαγραφή χρήστη]",
- "No other comments available" : "Δεν υπάρχουν άλλα διαθέσιμα σχόλια",
- "More comments..." : "Περισσότερα σχόλια...",
- "Save" : "Αποθήκευση",
- "Allowed characters {count} of {max}" : "Επιτρεπόμενοι χαρακτήρες {count} από {max}",
- "{count} unread comments" : "{count} μη αναγνωσμένα σχόλια",
- "Comment" : "Σχόλιο"
+ "Delete comment" : "Διαγραφή σχολίου",
+ "Cancel edit" : "Ακύρωση επεξεργασίας",
+ "New comment" : "Νέο σχόλιο",
+ "Post comment" : "Αναρτήστε σχόλιο",
+ "Unable to load the comments list" : "Δεν είναι δυνατή η μεταφόρτωση της λίστας σχολίων.",
+ "No comments yet, start the conversation!" : "Δεν υπάρχουν σχόλια, ξεκινήστε την συζήτηση!",
+ "No more messages" : "Δεν υπάρχουν άλλα μηνύματα",
+ "Retry" : "Δοκιμή ξανά",
+ "_1 new comment_::_{unread} new comments_" : ["1 νέο σχόλιο","{unread} νέα σχόλια"],
+ "Comment" : "Σχόλιο",
+ "An error occurred while trying to edit the comment" : "Παρουσιάστηκε σφάλμα κατά την προσπάθεια επεξεργασίας του σχολίου",
+ "Comment deleted" : "Το σχόλιο διαγράφηκε",
+ "An error occurred while trying to delete the comment" : "Παρουσιάστηκε σφάλμα κατά την προσπάθεια διαγραφής του σχολίου",
+ "An error occurred while trying to create the comment" : "Παρουσιάστηκε σφάλμα κατά την προσπάθεια δημιουργίας του σχολίου"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/en_GB.js b/apps/comments/l10n/en_GB.js
index 04a366a4f6d..20843d54147 100644
--- a/apps/comments/l10n/en_GB.js
+++ b/apps/comments/l10n/en_GB.js
@@ -1,21 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Comments</strong> for files",
- "%1$s commented" : "%1$s commented",
- "%1$s commented on %2$s" : "%1$s commented on %2$s",
"Comments" : "Comments",
- "Type in a new comment..." : "Type in a new comment...",
- "Delete comment" : "Delete comment",
- "Post" : "Post",
- "Cancel" : "Cancel",
+ "You commented" : "You commented",
+ "{author} commented" : "{author} commented",
+ "You commented on %1$s" : "You commented on %1$s",
+ "You commented on {file}" : "You commented on {file}",
+ "%1$s commented on %2$s" : "%1$s commented on %2$s",
+ "{author} commented on {file}" : "{author} commented on {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comments</strong> for files",
+ "Files" : "Files",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "You were mentioned on \"{file}\", in a comment by an account that has since been deleted",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mentioned you in a comment on \"{file}\"",
+ "Files app plugin to add comments to files" : "Files app plugin to add comments to files",
"Edit comment" : "Edit comment",
- "[Deleted user]" : "[Deleted user]",
- "No other comments available" : "No other comments available",
- "More comments..." : "More comments...",
- "Save" : "Save",
- "Allowed characters {count} of {max}" : "Allowed characters {count} of {max}",
- "{count} unread comments" : "{count} unread comments",
- "Comment" : "Comment"
+ "Delete comment" : "Delete comment",
+ "Cancel edit" : "Cancel edit",
+ "New comment" : "New comment",
+ "Write a comment …" : "Write a comment …",
+ "Post comment" : "Post comment",
+ "@ for mentions, : for emoji, / for smart picker" : "@ for mentions, : for emoji, / for smart picker",
+ "Could not reload comments" : "Could not reload comments",
+ "Failed to mark comments as read" : "Failed to mark comments as read",
+ "Unable to load the comments list" : "Unable to load the comments list",
+ "No comments yet, start the conversation!" : "No comments yet, start the conversation!",
+ "No more messages" : "No more messages",
+ "Retry" : "Retry",
+ "_1 new comment_::_{unread} new comments_" : ["1 new comment","{unread} new comments"],
+ "Comment" : "Comment",
+ "An error occurred while trying to edit the comment" : "An error occurred while trying to edit the comment",
+ "Comment deleted" : "Comment deleted",
+ "An error occurred while trying to delete the comment" : "An error occurred while trying to delete the comment",
+ "An error occurred while trying to create the comment" : "An error occurred while trying to create the comment"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/en_GB.json b/apps/comments/l10n/en_GB.json
index c43c1f4a629..1d61dbdf9a6 100644
--- a/apps/comments/l10n/en_GB.json
+++ b/apps/comments/l10n/en_GB.json
@@ -1,19 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Comments</strong> for files",
- "%1$s commented" : "%1$s commented",
- "%1$s commented on %2$s" : "%1$s commented on %2$s",
"Comments" : "Comments",
- "Type in a new comment..." : "Type in a new comment...",
- "Delete comment" : "Delete comment",
- "Post" : "Post",
- "Cancel" : "Cancel",
+ "You commented" : "You commented",
+ "{author} commented" : "{author} commented",
+ "You commented on %1$s" : "You commented on %1$s",
+ "You commented on {file}" : "You commented on {file}",
+ "%1$s commented on %2$s" : "%1$s commented on %2$s",
+ "{author} commented on {file}" : "{author} commented on {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comments</strong> for files",
+ "Files" : "Files",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "You were mentioned on \"{file}\", in a comment by an account that has since been deleted",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mentioned you in a comment on \"{file}\"",
+ "Files app plugin to add comments to files" : "Files app plugin to add comments to files",
"Edit comment" : "Edit comment",
- "[Deleted user]" : "[Deleted user]",
- "No other comments available" : "No other comments available",
- "More comments..." : "More comments...",
- "Save" : "Save",
- "Allowed characters {count} of {max}" : "Allowed characters {count} of {max}",
- "{count} unread comments" : "{count} unread comments",
- "Comment" : "Comment"
+ "Delete comment" : "Delete comment",
+ "Cancel edit" : "Cancel edit",
+ "New comment" : "New comment",
+ "Write a comment …" : "Write a comment …",
+ "Post comment" : "Post comment",
+ "@ for mentions, : for emoji, / for smart picker" : "@ for mentions, : for emoji, / for smart picker",
+ "Could not reload comments" : "Could not reload comments",
+ "Failed to mark comments as read" : "Failed to mark comments as read",
+ "Unable to load the comments list" : "Unable to load the comments list",
+ "No comments yet, start the conversation!" : "No comments yet, start the conversation!",
+ "No more messages" : "No more messages",
+ "Retry" : "Retry",
+ "_1 new comment_::_{unread} new comments_" : ["1 new comment","{unread} new comments"],
+ "Comment" : "Comment",
+ "An error occurred while trying to edit the comment" : "An error occurred while trying to edit the comment",
+ "Comment deleted" : "Comment deleted",
+ "An error occurred while trying to delete the comment" : "An error occurred while trying to delete the comment",
+ "An error occurred while trying to create the comment" : "An error occurred while trying to create the comment"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/eo.js b/apps/comments/l10n/eo.js
deleted file mode 100644
index 515156d663b..00000000000
--- a/apps/comments/l10n/eo.js
+++ /dev/null
@@ -1,21 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "<strong>Comments</strong> for files" : "<strong>Komentoj</strong> por dosieroj",
- "%1$s commented" : "%1$s komentis",
- "%1$s commented on %2$s" : "%1$s komentis %2$s",
- "Comments" : "Komentoj",
- "Type in a new comment..." : "Tajpu novan komenton...",
- "Delete comment" : "Forigi komenton",
- "Post" : "Afiŝi",
- "Cancel" : "Nuligi",
- "Edit comment" : "Redakti komenton",
- "[Deleted user]" : "[Forigita uzanto]",
- "No other comments available" : "Neniu alia komento disponeblas",
- "More comments..." : "Pli da komentoj...",
- "Save" : "Konservi",
- "Allowed characters {count} of {max}" : "Permesataj karakteroj: {count} el {max}",
- "{count} unread comments" : "{count} nelegitaj komentoj",
- "Comment" : "Komento"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/eo.json b/apps/comments/l10n/eo.json
deleted file mode 100644
index 33b8109abb9..00000000000
--- a/apps/comments/l10n/eo.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Komentoj</strong> por dosieroj",
- "%1$s commented" : "%1$s komentis",
- "%1$s commented on %2$s" : "%1$s komentis %2$s",
- "Comments" : "Komentoj",
- "Type in a new comment..." : "Tajpu novan komenton...",
- "Delete comment" : "Forigi komenton",
- "Post" : "Afiŝi",
- "Cancel" : "Nuligi",
- "Edit comment" : "Redakti komenton",
- "[Deleted user]" : "[Forigita uzanto]",
- "No other comments available" : "Neniu alia komento disponeblas",
- "More comments..." : "Pli da komentoj...",
- "Save" : "Konservi",
- "Allowed characters {count} of {max}" : "Permesataj karakteroj: {count} el {max}",
- "{count} unread comments" : "{count} nelegitaj komentoj",
- "Comment" : "Komento"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/es.js b/apps/comments/l10n/es.js
index 02e45762e09..38edb32d713 100644
--- a/apps/comments/l10n/es.js
+++ b/apps/comments/l10n/es.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> en archivos",
+ "Comments" : "Comentarios",
"You commented" : "Has comentado",
- "%1$s commented" : "%1$s comentados",
- "You commented on %2$s" : "Has comentado en %2$s",
+ "{author} commented" : "{author} comentó",
+ "You commented on %1$s" : "Has comentado en %1$s",
+ "You commented on {file}" : "Has comentado en {file}",
"%1$s commented on %2$s" : "%1$s comentados en %2$s",
- "Comments" : "Comentarios",
- "Type in a new comment..." : "Ingrese un nuevo comentario...",
- "Delete comment" : "Borrar comentario",
- "Post" : "Publicar",
- "Cancel" : "Cancelar",
+ "{author} commented on {file}" : "{author} comentó en {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> para archivos",
+ "Files" : "Archivos",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Fue mencionado en \"{file}\", en un comentario realizado por un usuario que ha sido eliminado",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} le mencionó en un comentario en “{file}”",
+ "Files app plugin to add comments to files" : "Plugin de la app de Archivos para añadir comentarios a archivos.",
"Edit comment" : "Editar comentario",
- "[Deleted user]" : "[Usuario eliminado]",
- "No other comments available" : "No hay otros comentarios disponibles",
- "More comments..." : "Más comentarios...",
- "Save" : "Guardar",
- "Allowed characters {count} of {max}" : "Caracteres permitidos {count} de {max}",
- "{count} unread comments" : "{count} comentarios no leídos",
- "Comment" : "Comentario"
+ "Delete comment" : "Borrar comentario",
+ "Cancel edit" : "Cacelar edición",
+ "New comment" : "Comentario nuevo",
+ "Write a comment …" : "Escribir un comentario …",
+ "Post comment" : "Publicar comentario",
+ "@ for mentions, : for emoji, / for smart picker" : "@ para menciones, : para emoji, / para selector inteligente",
+ "Could not reload comments" : "No se pudieron recargar los comentarios",
+ "Failed to mark comments as read" : "Fallo al marcar los comentarios como leídos",
+ "Unable to load the comments list" : "No se pudo cargar la lista de comentarios",
+ "No comments yet, start the conversation!" : "¡No hay comentarios, empieza la conversación!",
+ "No more messages" : "No hay más mensajes",
+ "Retry" : "Reintentar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentario nuevo","{unread} comentarios nuevos","{unread} comentarios nuevos"],
+ "Comment" : "Comentar",
+ "An error occurred while trying to edit the comment" : "Ocurrió un error intentando editar el comentario",
+ "Comment deleted" : "Comentario borrado",
+ "An error occurred while trying to delete the comment" : "Ocurrió un error intentando borrar el comentario",
+ "An error occurred while trying to create the comment" : "Ocurrió un error intentando crear el comentario"
},
-"nplurals=2; plural=(n != 1);");
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/comments/l10n/es.json b/apps/comments/l10n/es.json
index 232fea3a18b..51ae29fc0fa 100644
--- a/apps/comments/l10n/es.json
+++ b/apps/comments/l10n/es.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> en archivos",
+ "Comments" : "Comentarios",
"You commented" : "Has comentado",
- "%1$s commented" : "%1$s comentados",
- "You commented on %2$s" : "Has comentado en %2$s",
+ "{author} commented" : "{author} comentó",
+ "You commented on %1$s" : "Has comentado en %1$s",
+ "You commented on {file}" : "Has comentado en {file}",
"%1$s commented on %2$s" : "%1$s comentados en %2$s",
- "Comments" : "Comentarios",
- "Type in a new comment..." : "Ingrese un nuevo comentario...",
- "Delete comment" : "Borrar comentario",
- "Post" : "Publicar",
- "Cancel" : "Cancelar",
+ "{author} commented on {file}" : "{author} comentó en {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> para archivos",
+ "Files" : "Archivos",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Fue mencionado en \"{file}\", en un comentario realizado por un usuario que ha sido eliminado",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} le mencionó en un comentario en “{file}”",
+ "Files app plugin to add comments to files" : "Plugin de la app de Archivos para añadir comentarios a archivos.",
"Edit comment" : "Editar comentario",
- "[Deleted user]" : "[Usuario eliminado]",
- "No other comments available" : "No hay otros comentarios disponibles",
- "More comments..." : "Más comentarios...",
- "Save" : "Guardar",
- "Allowed characters {count} of {max}" : "Caracteres permitidos {count} de {max}",
- "{count} unread comments" : "{count} comentarios no leídos",
- "Comment" : "Comentario"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
+ "Delete comment" : "Borrar comentario",
+ "Cancel edit" : "Cacelar edición",
+ "New comment" : "Comentario nuevo",
+ "Write a comment …" : "Escribir un comentario …",
+ "Post comment" : "Publicar comentario",
+ "@ for mentions, : for emoji, / for smart picker" : "@ para menciones, : para emoji, / para selector inteligente",
+ "Could not reload comments" : "No se pudieron recargar los comentarios",
+ "Failed to mark comments as read" : "Fallo al marcar los comentarios como leídos",
+ "Unable to load the comments list" : "No se pudo cargar la lista de comentarios",
+ "No comments yet, start the conversation!" : "¡No hay comentarios, empieza la conversación!",
+ "No more messages" : "No hay más mensajes",
+ "Retry" : "Reintentar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentario nuevo","{unread} comentarios nuevos","{unread} comentarios nuevos"],
+ "Comment" : "Comentar",
+ "An error occurred while trying to edit the comment" : "Ocurrió un error intentando editar el comentario",
+ "Comment deleted" : "Comentario borrado",
+ "An error occurred while trying to delete the comment" : "Ocurrió un error intentando borrar el comentario",
+ "An error occurred while trying to create the comment" : "Ocurrió un error intentando crear el comentario"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/es_AR.js b/apps/comments/l10n/es_AR.js
deleted file mode 100644
index 8219a7da10b..00000000000
--- a/apps/comments/l10n/es_AR.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Cancelar",
- "Save" : "Guardar"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/es_AR.json b/apps/comments/l10n/es_AR.json
deleted file mode 100644
index 366986893df..00000000000
--- a/apps/comments/l10n/es_AR.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "Cancelar",
- "Save" : "Guardar"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/es_CL.js b/apps/comments/l10n/es_CL.js
deleted file mode 100644
index 73af8976a2d..00000000000
--- a/apps/comments/l10n/es_CL.js
+++ /dev/null
@@ -1,6 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Cancelar"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/es_CL.json b/apps/comments/l10n/es_CL.json
deleted file mode 100644
index 56eca9b124c..00000000000
--- a/apps/comments/l10n/es_CL.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{ "translations": {
- "Cancel" : "Cancelar"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/es_CO.js b/apps/comments/l10n/es_CO.js
new file mode 100644
index 00000000000..b8516c1449b
--- /dev/null
+++ b/apps/comments/l10n/es_CO.js
@@ -0,0 +1,35 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Comentarios",
+ "You commented" : "Comentaste",
+ "{author} commented" : "{author} comentó",
+ "You commented on %1$s" : "Usted comentó en %1$s",
+ "You commented on {file}" : "Hiciste un comentario de {file}",
+ "%1$s commented on %2$s" : "%1$s comentó en %2$s",
+ "{author} commented on {file}" : "{author} comentó en {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> de los archivos",
+ "Files" : "Archivo",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Fue mencionado en \"{file}\", en un comentario realizado por un usuario que ha sido eliminado",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} le mencionó en un comentario en “{file}”",
+ "Files app plugin to add comments to files" : "Plugin de la aplicación de archivos para agregar comentarios a los archivos",
+ "Edit comment" : "Editar comentario",
+ "Delete comment" : "Borrar comentario",
+ "Cancel edit" : "Cancelar edición",
+ "New comment" : "Nuevo comentario",
+ "Write a comment …" : "Escribir un comentario …",
+ "Post comment" : "Publicar comentario",
+ "@ for mentions, : for emoji, / for smart picker" : "@ para menciones, : para emoticonos, / para selector inteligente",
+ "Could not reload comments" : "No se pudieron recargar los comentarios",
+ "Failed to mark comments as read" : "No se pudieron marcar los comentarios como leídos",
+ "Unable to load the comments list" : "No se puede cargar la lista de comentarios",
+ "No comments yet, start the conversation!" : "¡Aún no hay comentarios, inicia la conversación!",
+ "No more messages" : "No hay más mensajes",
+ "Retry" : "Reintentar",
+ "Comment" : "Comentario",
+ "An error occurred while trying to edit the comment" : "Ocurrió un error al intentar editar el comentario",
+ "Comment deleted" : "Comentario borrado",
+ "An error occurred while trying to delete the comment" : "Ocurrió un error intentando borrar el comentario",
+ "An error occurred while trying to create the comment" : "Ocurrió un error al intentar crear el comentario"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/comments/l10n/es_CO.json b/apps/comments/l10n/es_CO.json
new file mode 100644
index 00000000000..c212111b999
--- /dev/null
+++ b/apps/comments/l10n/es_CO.json
@@ -0,0 +1,33 @@
+{ "translations": {
+ "Comments" : "Comentarios",
+ "You commented" : "Comentaste",
+ "{author} commented" : "{author} comentó",
+ "You commented on %1$s" : "Usted comentó en %1$s",
+ "You commented on {file}" : "Hiciste un comentario de {file}",
+ "%1$s commented on %2$s" : "%1$s comentó en %2$s",
+ "{author} commented on {file}" : "{author} comentó en {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> de los archivos",
+ "Files" : "Archivo",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Fue mencionado en \"{file}\", en un comentario realizado por un usuario que ha sido eliminado",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} le mencionó en un comentario en “{file}”",
+ "Files app plugin to add comments to files" : "Plugin de la aplicación de archivos para agregar comentarios a los archivos",
+ "Edit comment" : "Editar comentario",
+ "Delete comment" : "Borrar comentario",
+ "Cancel edit" : "Cancelar edición",
+ "New comment" : "Nuevo comentario",
+ "Write a comment …" : "Escribir un comentario …",
+ "Post comment" : "Publicar comentario",
+ "@ for mentions, : for emoji, / for smart picker" : "@ para menciones, : para emoticonos, / para selector inteligente",
+ "Could not reload comments" : "No se pudieron recargar los comentarios",
+ "Failed to mark comments as read" : "No se pudieron marcar los comentarios como leídos",
+ "Unable to load the comments list" : "No se puede cargar la lista de comentarios",
+ "No comments yet, start the conversation!" : "¡Aún no hay comentarios, inicia la conversación!",
+ "No more messages" : "No hay más mensajes",
+ "Retry" : "Reintentar",
+ "Comment" : "Comentario",
+ "An error occurred while trying to edit the comment" : "Ocurrió un error al intentar editar el comentario",
+ "Comment deleted" : "Comentario borrado",
+ "An error occurred while trying to delete the comment" : "Ocurrió un error intentando borrar el comentario",
+ "An error occurred while trying to create the comment" : "Ocurrió un error al intentar crear el comentario"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/es_EC.js b/apps/comments/l10n/es_EC.js
new file mode 100644
index 00000000000..1a90e73546f
--- /dev/null
+++ b/apps/comments/l10n/es_EC.js
@@ -0,0 +1,31 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Comentarios",
+ "You commented" : "Comentaste",
+ "{author} commented" : "{author} comentó",
+ "You commented on %1$s" : "Usted comentó en %1$s",
+ "You commented on {file}" : "Hiciste un comentario de {file}",
+ "%1$s commented on %2$s" : "%1$s comentó en %2$s",
+ "{author} commented on {file}" : "{author} comentó en {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> de los archivos",
+ "Files" : "Archivo",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} te mencionó en un comentario en \"{file}\"",
+ "Files app plugin to add comments to files" : "Plugin de la aplicación de archivos para agregar comentarios a los archivos",
+ "Edit comment" : "Editar comentario",
+ "Delete comment" : "Borrar comentario",
+ "Cancel edit" : "Cancelar edición",
+ "Post comment" : "Publicar comentario",
+ "Failed to mark comments as read" : "Error al marcar los comentarios como leídos",
+ "Unable to load the comments list" : "No se puede cargar la lista de comentarios",
+ "No comments yet, start the conversation!" : "¡Aún no hay comentarios, inicia la conversación!",
+ "No more messages" : "No hay más mensajes",
+ "Retry" : "Reintentar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentario nuevo","{unread} comentarios nuevos","{unread} comentarios nuevos"],
+ "Comment" : "Comentario",
+ "An error occurred while trying to edit the comment" : "Ocurrió un error al intentar editar el comentario",
+ "Comment deleted" : "Comentario eliminado",
+ "An error occurred while trying to delete the comment" : "Ocurrió un error al intentar eliminar el comentario",
+ "An error occurred while trying to create the comment" : "Ocurrió un error al intentar crear el comentario"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/comments/l10n/es_EC.json b/apps/comments/l10n/es_EC.json
new file mode 100644
index 00000000000..23c9432df1a
--- /dev/null
+++ b/apps/comments/l10n/es_EC.json
@@ -0,0 +1,29 @@
+{ "translations": {
+ "Comments" : "Comentarios",
+ "You commented" : "Comentaste",
+ "{author} commented" : "{author} comentó",
+ "You commented on %1$s" : "Usted comentó en %1$s",
+ "You commented on {file}" : "Hiciste un comentario de {file}",
+ "%1$s commented on %2$s" : "%1$s comentó en %2$s",
+ "{author} commented on {file}" : "{author} comentó en {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> de los archivos",
+ "Files" : "Archivo",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} te mencionó en un comentario en \"{file}\"",
+ "Files app plugin to add comments to files" : "Plugin de la aplicación de archivos para agregar comentarios a los archivos",
+ "Edit comment" : "Editar comentario",
+ "Delete comment" : "Borrar comentario",
+ "Cancel edit" : "Cancelar edición",
+ "Post comment" : "Publicar comentario",
+ "Failed to mark comments as read" : "Error al marcar los comentarios como leídos",
+ "Unable to load the comments list" : "No se puede cargar la lista de comentarios",
+ "No comments yet, start the conversation!" : "¡Aún no hay comentarios, inicia la conversación!",
+ "No more messages" : "No hay más mensajes",
+ "Retry" : "Reintentar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentario nuevo","{unread} comentarios nuevos","{unread} comentarios nuevos"],
+ "Comment" : "Comentario",
+ "An error occurred while trying to edit the comment" : "Ocurrió un error al intentar editar el comentario",
+ "Comment deleted" : "Comentario eliminado",
+ "An error occurred while trying to delete the comment" : "Ocurrió un error al intentar eliminar el comentario",
+ "An error occurred while trying to create the comment" : "Ocurrió un error al intentar crear el comentario"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/es_MX.js b/apps/comments/l10n/es_MX.js
index ab04eea953e..30959ef751f 100644
--- a/apps/comments/l10n/es_MX.js
+++ b/apps/comments/l10n/es_MX.js
@@ -1,8 +1,36 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "Cancelar",
- "Save" : "Guardar",
- "Comment" : "Comentario"
+ "Comments" : "Comentarios",
+ "You commented" : "Comentaste",
+ "{author} commented" : "{author} comentó",
+ "You commented on %1$s" : "Usted comentó en %1$s",
+ "You commented on {file}" : "Hiciste un comentario de {file}",
+ "%1$s commented on %2$s" : "%1$s comentó en %2$s",
+ "{author} commented on {file}" : "{author} comentó en {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> de los archivos",
+ "Files" : "Archivo",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Fue mencionado en \"{file}\", en un comentario realizado por un usuario que ha sido eliminado",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} lo mencionó en un comentario en \"{file}\"",
+ "Files app plugin to add comments to files" : "Un complemento a la aplicación de Archivos para agregar comentarios a los archivos",
+ "Edit comment" : "Editar comentario",
+ "Delete comment" : "Borrar comentario",
+ "Cancel edit" : "Cancelar edición",
+ "New comment" : "Nuevo comentario",
+ "Write a comment …" : "Escribir un comentario …",
+ "Post comment" : "Publicar comentario",
+ "@ for mentions, : for emoji, / for smart picker" : "@ para menciones, : para emoticonos, / para selector inteligente",
+ "Could not reload comments" : "No se pudieron recargar los comentarios",
+ "Failed to mark comments as read" : "No se pudieron marcar los comentarios como leídos",
+ "Unable to load the comments list" : "No se puede cargar la lista de comentarios",
+ "No comments yet, start the conversation!" : "¡Aún no hay comentarios, inicia la conversación!",
+ "No more messages" : "No hay más mensajes",
+ "Retry" : "Reintentar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentario nuevo","{unread} nuevos comentarios","{unread} nuevos comentarios"],
+ "Comment" : "Comentario",
+ "An error occurred while trying to edit the comment" : "Ocurrió un error al intentar editar el comentario",
+ "Comment deleted" : "Comentario borrado",
+ "An error occurred while trying to delete the comment" : "Ocurrió un error intentando borrar el comentario",
+ "An error occurred while trying to create the comment" : "Ocurrió un error al intentar crear el comentario"
},
-"nplurals=2; plural=(n != 1);");
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/comments/l10n/es_MX.json b/apps/comments/l10n/es_MX.json
index 6f6df7e9c84..db42c396705 100644
--- a/apps/comments/l10n/es_MX.json
+++ b/apps/comments/l10n/es_MX.json
@@ -1,6 +1,34 @@
{ "translations": {
- "Cancel" : "Cancelar",
- "Save" : "Guardar",
- "Comment" : "Comentario"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
+ "Comments" : "Comentarios",
+ "You commented" : "Comentaste",
+ "{author} commented" : "{author} comentó",
+ "You commented on %1$s" : "Usted comentó en %1$s",
+ "You commented on {file}" : "Hiciste un comentario de {file}",
+ "%1$s commented on %2$s" : "%1$s comentó en %2$s",
+ "{author} commented on {file}" : "{author} comentó en {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> de los archivos",
+ "Files" : "Archivo",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Fue mencionado en \"{file}\", en un comentario realizado por un usuario que ha sido eliminado",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} lo mencionó en un comentario en \"{file}\"",
+ "Files app plugin to add comments to files" : "Un complemento a la aplicación de Archivos para agregar comentarios a los archivos",
+ "Edit comment" : "Editar comentario",
+ "Delete comment" : "Borrar comentario",
+ "Cancel edit" : "Cancelar edición",
+ "New comment" : "Nuevo comentario",
+ "Write a comment …" : "Escribir un comentario …",
+ "Post comment" : "Publicar comentario",
+ "@ for mentions, : for emoji, / for smart picker" : "@ para menciones, : para emoticonos, / para selector inteligente",
+ "Could not reload comments" : "No se pudieron recargar los comentarios",
+ "Failed to mark comments as read" : "No se pudieron marcar los comentarios como leídos",
+ "Unable to load the comments list" : "No se puede cargar la lista de comentarios",
+ "No comments yet, start the conversation!" : "¡Aún no hay comentarios, inicia la conversación!",
+ "No more messages" : "No hay más mensajes",
+ "Retry" : "Reintentar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentario nuevo","{unread} nuevos comentarios","{unread} nuevos comentarios"],
+ "Comment" : "Comentario",
+ "An error occurred while trying to edit the comment" : "Ocurrió un error al intentar editar el comentario",
+ "Comment deleted" : "Comentario borrado",
+ "An error occurred while trying to delete the comment" : "Ocurrió un error intentando borrar el comentario",
+ "An error occurred while trying to create the comment" : "Ocurrió un error al intentar crear el comentario"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/et_EE.js b/apps/comments/l10n/et_EE.js
index 5367fb240c0..f8e80d0e690 100644
--- a/apps/comments/l10n/et_EE.js
+++ b/apps/comments/l10n/et_EE.js
@@ -1,19 +1,36 @@
OC.L10N.register(
"comments",
{
- "%1$s commented on %2$s" : "%1$s kommenteeris %2$s",
"Comments" : "Kommentaarid",
- "Type in a new comment..." : "Kirjuta uus komentaar...",
- "Delete comment" : "Kustuta kommentaar",
- "Post" : "Postita",
- "Cancel" : "Loobu",
+ "You commented" : "Sa kommenteerisid",
+ "{author} commented" : "{author} kommenteeris",
+ "You commented on %1$s" : "Sa kommmenteerisid %1$s",
+ "You commented on {file}" : "Sa kommenteerisid faili {file}",
+ "%1$s commented on %2$s" : "%1$s kommenteeris %2$s",
+ "{author} commented on {file}" : "{author} kommenteeris faili {file}",
+ "<strong>Comments</strong> for files" : "<strong>Kommentaarid</strong> failidele",
+ "Files" : "Failid",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Sind mainiti \"{file}\" kommentaarides konto poolt, mis on nüüdseks kustutatud",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mainis sind faili \"{file}\" kommentaaris",
+ "Files app plugin to add comments to files" : "Failid rakenduse laiendus failidele kommentaaride lisamiseks",
"Edit comment" : "Muuda kommentaari",
- "[Deleted user]" : "[Kustutatud kasutaja]",
- "No other comments available" : "Ühtegi teist kommentaari pole saadaval",
- "More comments..." : "Veel kommentaare...",
- "Save" : "Salvesta",
- "Allowed characters {count} of {max}" : "Lubatud märkide arv {count}/{max}",
- "{count} unread comments" : "{count} lugemata kommentaari",
- "Comment" : "Kommentaar"
+ "Delete comment" : "Kustuta kommentaar",
+ "Cancel edit" : "Loobu muutmisest",
+ "New comment" : "Uus kommentaar",
+ "Write a comment …" : "Kirjuta kommentaar...",
+ "Post comment" : "Postita kommentaar",
+ "@ for mentions, : for emoji, / for smart picker" : "@ mainimiseks, : emojide jaoks, / nutika valija jaoks",
+ "Could not reload comments" : "Ei saanud kommentaare uuesti laadida",
+ "Failed to mark comments as read" : "Kommentaaride loetuks märkimine ebaõnnestus",
+ "Unable to load the comments list" : "Kommentaaride loendi laadimine ebaõnnestus",
+ "No comments yet, start the conversation!" : "Kommentaare veel pole, alusta vestlust!",
+ "No more messages" : "Rohkem teateid pole",
+ "Retry" : "Proovi uuesti",
+ "_1 new comment_::_{unread} new comments_" : ["1 uus kommentaar","{unread} uus kommentaar"],
+ "Comment" : "Kommentaar",
+ "An error occurred while trying to edit the comment" : "Kommentaari muutmisel tekkis tõrge",
+ "Comment deleted" : "Kommentaar kustutatud",
+ "An error occurred while trying to delete the comment" : "Kommentaari kustutamisel tekkis tõrge",
+ "An error occurred while trying to create the comment" : "Kommentaari lisamisel tekkis tõrge"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/et_EE.json b/apps/comments/l10n/et_EE.json
index b3e43be6f76..3c56525cb0c 100644
--- a/apps/comments/l10n/et_EE.json
+++ b/apps/comments/l10n/et_EE.json
@@ -1,17 +1,34 @@
{ "translations": {
- "%1$s commented on %2$s" : "%1$s kommenteeris %2$s",
"Comments" : "Kommentaarid",
- "Type in a new comment..." : "Kirjuta uus komentaar...",
- "Delete comment" : "Kustuta kommentaar",
- "Post" : "Postita",
- "Cancel" : "Loobu",
+ "You commented" : "Sa kommenteerisid",
+ "{author} commented" : "{author} kommenteeris",
+ "You commented on %1$s" : "Sa kommmenteerisid %1$s",
+ "You commented on {file}" : "Sa kommenteerisid faili {file}",
+ "%1$s commented on %2$s" : "%1$s kommenteeris %2$s",
+ "{author} commented on {file}" : "{author} kommenteeris faili {file}",
+ "<strong>Comments</strong> for files" : "<strong>Kommentaarid</strong> failidele",
+ "Files" : "Failid",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Sind mainiti \"{file}\" kommentaarides konto poolt, mis on nüüdseks kustutatud",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mainis sind faili \"{file}\" kommentaaris",
+ "Files app plugin to add comments to files" : "Failid rakenduse laiendus failidele kommentaaride lisamiseks",
"Edit comment" : "Muuda kommentaari",
- "[Deleted user]" : "[Kustutatud kasutaja]",
- "No other comments available" : "Ühtegi teist kommentaari pole saadaval",
- "More comments..." : "Veel kommentaare...",
- "Save" : "Salvesta",
- "Allowed characters {count} of {max}" : "Lubatud märkide arv {count}/{max}",
- "{count} unread comments" : "{count} lugemata kommentaari",
- "Comment" : "Kommentaar"
+ "Delete comment" : "Kustuta kommentaar",
+ "Cancel edit" : "Loobu muutmisest",
+ "New comment" : "Uus kommentaar",
+ "Write a comment …" : "Kirjuta kommentaar...",
+ "Post comment" : "Postita kommentaar",
+ "@ for mentions, : for emoji, / for smart picker" : "@ mainimiseks, : emojide jaoks, / nutika valija jaoks",
+ "Could not reload comments" : "Ei saanud kommentaare uuesti laadida",
+ "Failed to mark comments as read" : "Kommentaaride loetuks märkimine ebaõnnestus",
+ "Unable to load the comments list" : "Kommentaaride loendi laadimine ebaõnnestus",
+ "No comments yet, start the conversation!" : "Kommentaare veel pole, alusta vestlust!",
+ "No more messages" : "Rohkem teateid pole",
+ "Retry" : "Proovi uuesti",
+ "_1 new comment_::_{unread} new comments_" : ["1 uus kommentaar","{unread} uus kommentaar"],
+ "Comment" : "Kommentaar",
+ "An error occurred while trying to edit the comment" : "Kommentaari muutmisel tekkis tõrge",
+ "Comment deleted" : "Kommentaar kustutatud",
+ "An error occurred while trying to delete the comment" : "Kommentaari kustutamisel tekkis tõrge",
+ "An error occurred while trying to create the comment" : "Kommentaari lisamisel tekkis tõrge"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/eu.js b/apps/comments/l10n/eu.js
index 65c4b80558a..efa029c41ad 100644
--- a/apps/comments/l10n/eu.js
+++ b/apps/comments/l10n/eu.js
@@ -1,8 +1,36 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "Ezeztatu",
- "Save" : "Gorde",
- "Comment" : "Iruzkina"
+ "Comments" : "Iruzkinak",
+ "You commented" : "Iruzkindu duzu",
+ "{author} commented" : "{author}-(e)k iruzkindu du",
+ "You commented on %1$s" : "%1$s-en iruzkindu duzu",
+ "You commented on {file}" : "{file} fitxategian iruzkina egin duzu",
+ "%1$s commented on %2$s" : "%1$s-ek %2$s-en iruzkindu du",
+ "{author} commented on {file}" : "{author}-(e)k {file}-en iruzkina egin du",
+ "<strong>Comments</strong> for files" : "Fitxategientzako <strong>iruzkinak</strong>",
+ "Files" : "Fitxategiak",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "\"{file}\"-n aipatu zaituzte, dagoeneko ezabatu den kontu baten iruzkin batean",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} erabiltzaileak aipatu zaitu \"{file}\"-eko iruzkin batean",
+ "Files app plugin to add comments to files" : "Fitxategiak aplikazioko plugina, fitxategiei iruzkinak gehitzeko",
+ "Edit comment" : "Editatu iruzkina",
+ "Delete comment" : "Ezabatu iruzkina",
+ "Cancel edit" : "Utzi editatzeari",
+ "New comment" : "Iruzkin berria",
+ "Write a comment …" : "Idatzi iruzkin bat ...",
+ "Post comment" : "Argitaratu iruzkina",
+ "@ for mentions, : for emoji, / for smart picker" : "@ aipamenetarako, : emojientzako, / hautatzaile adimentsurako",
+ "Could not reload comments" : "Ezin izan dira iruzkinak freskatu",
+ "Failed to mark comments as read" : "Iruzkinak irakurritako gisa markatzeak huts egin du",
+ "Unable to load the comments list" : "Ezin da iruzkinen zerrenda kargatu",
+ "No comments yet, start the conversation!" : "Oraindik ez dago iruzkinik, izan zaitez lehena zerbait esanez!",
+ "No more messages" : "Ez da mezu gehiagorik",
+ "Retry" : "Saiatu berriro",
+ "_1 new comment_::_{unread} new comments_" : ["Iruzkin berri 1","{unread} iruzkin berri"],
+ "Comment" : "Iruzkindu",
+ "An error occurred while trying to edit the comment" : "Errorea gertatu da iruzkina editatzen saiatzean",
+ "Comment deleted" : "Iruzkina ezabatu da",
+ "An error occurred while trying to delete the comment" : "Errorea gertatu da iruzkina ezabatzen saiatzean",
+ "An error occurred while trying to create the comment" : "Errorea gertatu da iruzkina sortzen saiatzean"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/eu.json b/apps/comments/l10n/eu.json
index 746260d520c..9df5961d387 100644
--- a/apps/comments/l10n/eu.json
+++ b/apps/comments/l10n/eu.json
@@ -1,6 +1,34 @@
{ "translations": {
- "Cancel" : "Ezeztatu",
- "Save" : "Gorde",
- "Comment" : "Iruzkina"
+ "Comments" : "Iruzkinak",
+ "You commented" : "Iruzkindu duzu",
+ "{author} commented" : "{author}-(e)k iruzkindu du",
+ "You commented on %1$s" : "%1$s-en iruzkindu duzu",
+ "You commented on {file}" : "{file} fitxategian iruzkina egin duzu",
+ "%1$s commented on %2$s" : "%1$s-ek %2$s-en iruzkindu du",
+ "{author} commented on {file}" : "{author}-(e)k {file}-en iruzkina egin du",
+ "<strong>Comments</strong> for files" : "Fitxategientzako <strong>iruzkinak</strong>",
+ "Files" : "Fitxategiak",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "\"{file}\"-n aipatu zaituzte, dagoeneko ezabatu den kontu baten iruzkin batean",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} erabiltzaileak aipatu zaitu \"{file}\"-eko iruzkin batean",
+ "Files app plugin to add comments to files" : "Fitxategiak aplikazioko plugina, fitxategiei iruzkinak gehitzeko",
+ "Edit comment" : "Editatu iruzkina",
+ "Delete comment" : "Ezabatu iruzkina",
+ "Cancel edit" : "Utzi editatzeari",
+ "New comment" : "Iruzkin berria",
+ "Write a comment …" : "Idatzi iruzkin bat ...",
+ "Post comment" : "Argitaratu iruzkina",
+ "@ for mentions, : for emoji, / for smart picker" : "@ aipamenetarako, : emojientzako, / hautatzaile adimentsurako",
+ "Could not reload comments" : "Ezin izan dira iruzkinak freskatu",
+ "Failed to mark comments as read" : "Iruzkinak irakurritako gisa markatzeak huts egin du",
+ "Unable to load the comments list" : "Ezin da iruzkinen zerrenda kargatu",
+ "No comments yet, start the conversation!" : "Oraindik ez dago iruzkinik, izan zaitez lehena zerbait esanez!",
+ "No more messages" : "Ez da mezu gehiagorik",
+ "Retry" : "Saiatu berriro",
+ "_1 new comment_::_{unread} new comments_" : ["Iruzkin berri 1","{unread} iruzkin berri"],
+ "Comment" : "Iruzkindu",
+ "An error occurred while trying to edit the comment" : "Errorea gertatu da iruzkina editatzen saiatzean",
+ "Comment deleted" : "Iruzkina ezabatu da",
+ "An error occurred while trying to delete the comment" : "Errorea gertatu da iruzkina ezabatzen saiatzean",
+ "An error occurred while trying to create the comment" : "Errorea gertatu da iruzkina sortzen saiatzean"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/fa.js b/apps/comments/l10n/fa.js
index 2eed645ec36..3317f902043 100644
--- a/apps/comments/l10n/fa.js
+++ b/apps/comments/l10n/fa.js
@@ -1,8 +1,36 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "منصرف شدن",
- "Save" : "ذخیره",
- "Comment" : "نظر"
+ "Comments" : "نظرات",
+ "You commented" : "دیدگاه شما",
+ "{author} commented" : "{author} دیدگاهی گذاشت",
+ "You commented on %1$s" : "دیدگاهی برای %1$s ثبت کردید",
+ "You commented on {file}" : "دیدگاهی برای {file} ثبت کردید",
+ "%1$s commented on %2$s" : "%1$s دیدگاهی برای %2$s ثبت کرد",
+ "{author} commented on {file}" : "{author} دیدگاهی برای {file} ثبت کرد",
+ "<strong>Comments</strong> for files" : "<strong>دیدگاه‌های</strong> زیر پرونده‌ها ",
+ "Files" : "پرونده‌ها",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "شما در «{file}» و در دیدگاهی که توسط حسابی که بعدتر پاک شده است مورد اشاره قرار گرفته‌اید",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} در دیدگاهش زیر «{file}» به شما اشاره کرد",
+ "Files app plugin to add comments to files" : "افزونهٔ برنامهٔ Files برای افزودن دیدگاه به پرونده‌ها",
+ "Edit comment" : "ویرایش دیدگاه",
+ "Delete comment" : "حذف دیدگاه",
+ "Cancel edit" : "Cancel edit",
+ "New comment" : "دیدگاه جدید",
+ "Write a comment …" : "دیدگاهی بنویسید...",
+ "Post comment" : "فرستادن دیدگاه",
+ "@ for mentions, : for emoji, / for smart picker" : "@ برای اشاره، : برای شکلک، / برای انتخاب‌گر هوشمند",
+ "Could not reload comments" : "ناتوانی در دریافت دیدگاه‌ها",
+ "Failed to mark comments as read" : "ناتوانی در علامت زدن دیدگاه‌های به عنوان خوانده شده",
+ "Unable to load the comments list" : "ناتوانی در دریافت فهرست دیدگاه‌ها",
+ "No comments yet, start the conversation!" : "هنوز هیچ نظری ندارید ، مکالمه را شروع کنید!",
+ "No more messages" : "No more messages",
+ "Retry" : "تلاش دوباره",
+ "_1 new comment_::_{unread} new comments_" : ["1 new comment","{unread} دیدگاه جدید"],
+ "Comment" : "نظر",
+ "An error occurred while trying to edit the comment" : "خطایی در خلال تلاش برای ویرایش دیدگاه رخ داد",
+ "Comment deleted" : "دیدگاه حذف شد",
+ "An error occurred while trying to delete the comment" : "خطایی در خلال تلاش برای حذف دیدگاه رخ داد",
+ "An error occurred while trying to create the comment" : "خطایی در خلال تلاش برای ایجاد دیدگاه رخ داد"
},
-"nplurals=1; plural=0;");
+"nplurals=2; plural=(n > 1);");
diff --git a/apps/comments/l10n/fa.json b/apps/comments/l10n/fa.json
index 5b99e9f2896..59df258f222 100644
--- a/apps/comments/l10n/fa.json
+++ b/apps/comments/l10n/fa.json
@@ -1,6 +1,34 @@
{ "translations": {
- "Cancel" : "منصرف شدن",
- "Save" : "ذخیره",
- "Comment" : "نظر"
-},"pluralForm" :"nplurals=1; plural=0;"
+ "Comments" : "نظرات",
+ "You commented" : "دیدگاه شما",
+ "{author} commented" : "{author} دیدگاهی گذاشت",
+ "You commented on %1$s" : "دیدگاهی برای %1$s ثبت کردید",
+ "You commented on {file}" : "دیدگاهی برای {file} ثبت کردید",
+ "%1$s commented on %2$s" : "%1$s دیدگاهی برای %2$s ثبت کرد",
+ "{author} commented on {file}" : "{author} دیدگاهی برای {file} ثبت کرد",
+ "<strong>Comments</strong> for files" : "<strong>دیدگاه‌های</strong> زیر پرونده‌ها ",
+ "Files" : "پرونده‌ها",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "شما در «{file}» و در دیدگاهی که توسط حسابی که بعدتر پاک شده است مورد اشاره قرار گرفته‌اید",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} در دیدگاهش زیر «{file}» به شما اشاره کرد",
+ "Files app plugin to add comments to files" : "افزونهٔ برنامهٔ Files برای افزودن دیدگاه به پرونده‌ها",
+ "Edit comment" : "ویرایش دیدگاه",
+ "Delete comment" : "حذف دیدگاه",
+ "Cancel edit" : "Cancel edit",
+ "New comment" : "دیدگاه جدید",
+ "Write a comment …" : "دیدگاهی بنویسید...",
+ "Post comment" : "فرستادن دیدگاه",
+ "@ for mentions, : for emoji, / for smart picker" : "@ برای اشاره، : برای شکلک، / برای انتخاب‌گر هوشمند",
+ "Could not reload comments" : "ناتوانی در دریافت دیدگاه‌ها",
+ "Failed to mark comments as read" : "ناتوانی در علامت زدن دیدگاه‌های به عنوان خوانده شده",
+ "Unable to load the comments list" : "ناتوانی در دریافت فهرست دیدگاه‌ها",
+ "No comments yet, start the conversation!" : "هنوز هیچ نظری ندارید ، مکالمه را شروع کنید!",
+ "No more messages" : "No more messages",
+ "Retry" : "تلاش دوباره",
+ "_1 new comment_::_{unread} new comments_" : ["1 new comment","{unread} دیدگاه جدید"],
+ "Comment" : "نظر",
+ "An error occurred while trying to edit the comment" : "خطایی در خلال تلاش برای ویرایش دیدگاه رخ داد",
+ "Comment deleted" : "دیدگاه حذف شد",
+ "An error occurred while trying to delete the comment" : "خطایی در خلال تلاش برای حذف دیدگاه رخ داد",
+ "An error occurred while trying to create the comment" : "خطایی در خلال تلاش برای ایجاد دیدگاه رخ داد"
+},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/fi.js b/apps/comments/l10n/fi.js
new file mode 100644
index 00000000000..28a05c1659d
--- /dev/null
+++ b/apps/comments/l10n/fi.js
@@ -0,0 +1,34 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Kommentit",
+ "You commented" : "Kommentoit",
+ "{author} commented" : "{author} kommentoi",
+ "You commented on %1$s" : "Kommentoit %1$s",
+ "You commented on {file}" : "Kommentoit tiedostoa {file}",
+ "%1$s commented on %2$s" : "%1$s kommentoi kohdetta %2$s",
+ "{author} commented on {file}" : "{author} kommentoi tiedostoa {file}",
+ "<strong>Comments</strong> for files" : "Tiedostojen <strong>kommentit</strong>",
+ "Files" : "Tiedostot",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mainitsi sinut tiedoston \"{file}\" kommentissa",
+ "Edit comment" : "Muokkaa kommenttia",
+ "Delete comment" : "Poista kommentti",
+ "Cancel edit" : "Peruuta muokkaus",
+ "New comment" : "Uusi kommentti",
+ "Write a comment …" : "Kirjoita kommentti…",
+ "Post comment" : "Lähetä viesti",
+ "@ for mentions, : for emoji, / for smart picker" : "@ maininnoille, : emojille, / älykkäälle valitsimelle",
+ "Could not reload comments" : "Kommenttien lataus epäonnistui",
+ "Failed to mark comments as read" : "Kommenttien merkitseminen luetuksi epäonnistui",
+ "Unable to load the comments list" : "Kommenttilistaa ei voitu ladata",
+ "No comments yet, start the conversation!" : "Ei kommentteja vielä. Aloita keskustelu!",
+ "No more messages" : "Ei enempää viestejä",
+ "Retry" : "Yritä uudelleen",
+ "_1 new comment_::_{unread} new comments_" : ["1 uusi kommentti","{unread} uutta kommenttia"],
+ "Comment" : "Kommentti",
+ "An error occurred while trying to edit the comment" : "Kommenttia muokatessa tapahtui virhe",
+ "Comment deleted" : "Kommentti poistettu",
+ "An error occurred while trying to delete the comment" : "Kommenttia poistaessa tapahtui virhe",
+ "An error occurred while trying to create the comment" : "Kommenttia luodessa tapahtui virhe"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/fi.json b/apps/comments/l10n/fi.json
new file mode 100644
index 00000000000..a8943301573
--- /dev/null
+++ b/apps/comments/l10n/fi.json
@@ -0,0 +1,32 @@
+{ "translations": {
+ "Comments" : "Kommentit",
+ "You commented" : "Kommentoit",
+ "{author} commented" : "{author} kommentoi",
+ "You commented on %1$s" : "Kommentoit %1$s",
+ "You commented on {file}" : "Kommentoit tiedostoa {file}",
+ "%1$s commented on %2$s" : "%1$s kommentoi kohdetta %2$s",
+ "{author} commented on {file}" : "{author} kommentoi tiedostoa {file}",
+ "<strong>Comments</strong> for files" : "Tiedostojen <strong>kommentit</strong>",
+ "Files" : "Tiedostot",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mainitsi sinut tiedoston \"{file}\" kommentissa",
+ "Edit comment" : "Muokkaa kommenttia",
+ "Delete comment" : "Poista kommentti",
+ "Cancel edit" : "Peruuta muokkaus",
+ "New comment" : "Uusi kommentti",
+ "Write a comment …" : "Kirjoita kommentti…",
+ "Post comment" : "Lähetä viesti",
+ "@ for mentions, : for emoji, / for smart picker" : "@ maininnoille, : emojille, / älykkäälle valitsimelle",
+ "Could not reload comments" : "Kommenttien lataus epäonnistui",
+ "Failed to mark comments as read" : "Kommenttien merkitseminen luetuksi epäonnistui",
+ "Unable to load the comments list" : "Kommenttilistaa ei voitu ladata",
+ "No comments yet, start the conversation!" : "Ei kommentteja vielä. Aloita keskustelu!",
+ "No more messages" : "Ei enempää viestejä",
+ "Retry" : "Yritä uudelleen",
+ "_1 new comment_::_{unread} new comments_" : ["1 uusi kommentti","{unread} uutta kommenttia"],
+ "Comment" : "Kommentti",
+ "An error occurred while trying to edit the comment" : "Kommenttia muokatessa tapahtui virhe",
+ "Comment deleted" : "Kommentti poistettu",
+ "An error occurred while trying to delete the comment" : "Kommenttia poistaessa tapahtui virhe",
+ "An error occurred while trying to create the comment" : "Kommenttia luodessa tapahtui virhe"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/fi_FI.js b/apps/comments/l10n/fi_FI.js
deleted file mode 100644
index 741dea8252b..00000000000
--- a/apps/comments/l10n/fi_FI.js
+++ /dev/null
@@ -1,23 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "<strong>Comments</strong> for files" : "<strong>Kommentit</strong> tiedostoille",
- "You commented" : "Kommentoit",
- "%1$s commented" : "%1$s kommentoi",
- "You commented on %2$s" : "Kommentoit %2$s",
- "%1$s commented on %2$s" : "%1$s kommentoi kohdetta %2$s",
- "Comments" : "Kommentit",
- "Type in a new comment..." : "Kirjoita uusi kommentti...",
- "Delete comment" : "Poista kommentti",
- "Post" : "Lähetä",
- "Cancel" : "Peruuta",
- "Edit comment" : "Muokkaa kommenttia",
- "[Deleted user]" : "[Poistettu käyttäjä]",
- "No other comments available" : "Ei muita kommentteja saatavilla",
- "More comments..." : "Lisää kommentteja...",
- "Save" : "Tallenna",
- "Allowed characters {count} of {max}" : "Sallittujen merkkien määrä {count}/{max}",
- "{count} unread comments" : "{count} lukematonta kommenttia",
- "Comment" : "Kommentti"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/fi_FI.json b/apps/comments/l10n/fi_FI.json
deleted file mode 100644
index 52a9f1955ef..00000000000
--- a/apps/comments/l10n/fi_FI.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Kommentit</strong> tiedostoille",
- "You commented" : "Kommentoit",
- "%1$s commented" : "%1$s kommentoi",
- "You commented on %2$s" : "Kommentoit %2$s",
- "%1$s commented on %2$s" : "%1$s kommentoi kohdetta %2$s",
- "Comments" : "Kommentit",
- "Type in a new comment..." : "Kirjoita uusi kommentti...",
- "Delete comment" : "Poista kommentti",
- "Post" : "Lähetä",
- "Cancel" : "Peruuta",
- "Edit comment" : "Muokkaa kommenttia",
- "[Deleted user]" : "[Poistettu käyttäjä]",
- "No other comments available" : "Ei muita kommentteja saatavilla",
- "More comments..." : "Lisää kommentteja...",
- "Save" : "Tallenna",
- "Allowed characters {count} of {max}" : "Sallittujen merkkien määrä {count}/{max}",
- "{count} unread comments" : "{count} lukematonta kommenttia",
- "Comment" : "Kommentti"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/fil.js b/apps/comments/l10n/fil.js
deleted file mode 100644
index e3734cb6ceb..00000000000
--- a/apps/comments/l10n/fil.js
+++ /dev/null
@@ -1,6 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "I-cancel"
-},
-"nplurals=2; plural=(n > 1);");
diff --git a/apps/comments/l10n/fil.json b/apps/comments/l10n/fil.json
deleted file mode 100644
index a368f5adea8..00000000000
--- a/apps/comments/l10n/fil.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{ "translations": {
- "Cancel" : "I-cancel"
-},"pluralForm" :"nplurals=2; plural=(n > 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/fr.js b/apps/comments/l10n/fr.js
index fc065bd0db0..a1f24df6b80 100644
--- a/apps/comments/l10n/fr.js
+++ b/apps/comments/l10n/fr.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Commentaires</strong> pour les fichiers",
+ "Comments" : "Commentaires",
"You commented" : "Vous avez commenté",
- "%1$s commented" : "%1$s a commenté",
- "You commented on %2$s" : "Vous avez commenté %2$s",
+ "{author} commented" : "{author} a commenté",
+ "You commented on %1$s" : "Vous avez commenté %1$s",
+ "You commented on {file}" : "Vous avez commenté {file}",
"%1$s commented on %2$s" : "%1$s a commenté %2$s",
- "Comments" : "Commentaires",
- "Type in a new comment..." : "Écrire un nouveau commentaire...",
- "Delete comment" : "Supprimer le commentaire",
- "Post" : "Poster",
- "Cancel" : "Annuler",
+ "{author} commented on {file}" : "{author} a commenté sur {file}",
+ "<strong>Comments</strong> for files" : "<strong>Commentaires</strong> sur les fichiers",
+ "Files" : "Fichiers",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Vous avez été mentionné dans « {file} », dans un commentaire d'un compte qui a été supprimé depuis",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} vous a mentionné dans un commentaire sur « {file} »",
+ "Files app plugin to add comments to files" : "Plugin Fichiers app pour ajouter des commentaires aux fichiers",
"Edit comment" : "Modifier le commentaire",
- "[Deleted user]" : "[Utilisateur supprimé]",
- "No other comments available" : "Aucun autre commentaire",
- "More comments..." : "Plus de commentaires...",
- "Save" : "Enregistrer",
- "Allowed characters {count} of {max}" : "{count} sur {max} caractères autorisés",
- "{count} unread comments" : "{count} commentaires non lus",
- "Comment" : "Commenter"
+ "Delete comment" : "Supprimer le commentaire",
+ "Cancel edit" : "Annuler les modifications",
+ "New comment" : "Nouveau commentaire",
+ "Write a comment …" : "Écrire un commentaire…",
+ "Post comment" : "Publier le commentaire",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pour les mentions, : pour les émojis, / pour le sélecteur intelligent",
+ "Could not reload comments" : "Impossible de recharger les commentaires",
+ "Failed to mark comments as read" : "Les commentaires n'ont pas été marqués comme lus",
+ "Unable to load the comments list" : "Impossible de charger la liste des commentaires",
+ "No comments yet, start the conversation!" : "Il n'y a aucun commentaire, démarrez la conversation !",
+ "No more messages" : "Aucun autre message",
+ "Retry" : "Réessayer",
+ "_1 new comment_::_{unread} new comments_" : ["1 nouveau commentaire","{unread} nouveaux commentaires","{unread} nouveaux commentaires"],
+ "Comment" : "Commenter",
+ "An error occurred while trying to edit the comment" : "Une erreur s'est produite lors de la tentative de modification du commentaire",
+ "Comment deleted" : "Commentaire supprimé",
+ "An error occurred while trying to delete the comment" : "Une erreur s'est produite lors de la tentative de suppression du commentaire",
+ "An error occurred while trying to create the comment" : "Une erreur s'est produite lors de la tentative de création du commentaire"
},
-"nplurals=2; plural=(n > 1);");
+"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/comments/l10n/fr.json b/apps/comments/l10n/fr.json
index d69887540f9..861754c9719 100644
--- a/apps/comments/l10n/fr.json
+++ b/apps/comments/l10n/fr.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Commentaires</strong> pour les fichiers",
+ "Comments" : "Commentaires",
"You commented" : "Vous avez commenté",
- "%1$s commented" : "%1$s a commenté",
- "You commented on %2$s" : "Vous avez commenté %2$s",
+ "{author} commented" : "{author} a commenté",
+ "You commented on %1$s" : "Vous avez commenté %1$s",
+ "You commented on {file}" : "Vous avez commenté {file}",
"%1$s commented on %2$s" : "%1$s a commenté %2$s",
- "Comments" : "Commentaires",
- "Type in a new comment..." : "Écrire un nouveau commentaire...",
- "Delete comment" : "Supprimer le commentaire",
- "Post" : "Poster",
- "Cancel" : "Annuler",
+ "{author} commented on {file}" : "{author} a commenté sur {file}",
+ "<strong>Comments</strong> for files" : "<strong>Commentaires</strong> sur les fichiers",
+ "Files" : "Fichiers",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Vous avez été mentionné dans « {file} », dans un commentaire d'un compte qui a été supprimé depuis",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} vous a mentionné dans un commentaire sur « {file} »",
+ "Files app plugin to add comments to files" : "Plugin Fichiers app pour ajouter des commentaires aux fichiers",
"Edit comment" : "Modifier le commentaire",
- "[Deleted user]" : "[Utilisateur supprimé]",
- "No other comments available" : "Aucun autre commentaire",
- "More comments..." : "Plus de commentaires...",
- "Save" : "Enregistrer",
- "Allowed characters {count} of {max}" : "{count} sur {max} caractères autorisés",
- "{count} unread comments" : "{count} commentaires non lus",
- "Comment" : "Commenter"
-},"pluralForm" :"nplurals=2; plural=(n > 1);"
+ "Delete comment" : "Supprimer le commentaire",
+ "Cancel edit" : "Annuler les modifications",
+ "New comment" : "Nouveau commentaire",
+ "Write a comment …" : "Écrire un commentaire…",
+ "Post comment" : "Publier le commentaire",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pour les mentions, : pour les émojis, / pour le sélecteur intelligent",
+ "Could not reload comments" : "Impossible de recharger les commentaires",
+ "Failed to mark comments as read" : "Les commentaires n'ont pas été marqués comme lus",
+ "Unable to load the comments list" : "Impossible de charger la liste des commentaires",
+ "No comments yet, start the conversation!" : "Il n'y a aucun commentaire, démarrez la conversation !",
+ "No more messages" : "Aucun autre message",
+ "Retry" : "Réessayer",
+ "_1 new comment_::_{unread} new comments_" : ["1 nouveau commentaire","{unread} nouveaux commentaires","{unread} nouveaux commentaires"],
+ "Comment" : "Commenter",
+ "An error occurred while trying to edit the comment" : "Une erreur s'est produite lors de la tentative de modification du commentaire",
+ "Comment deleted" : "Commentaire supprimé",
+ "An error occurred while trying to delete the comment" : "Une erreur s'est produite lors de la tentative de suppression du commentaire",
+ "An error occurred while trying to create the comment" : "Une erreur s'est produite lors de la tentative de création du commentaire"
+},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/ga.js b/apps/comments/l10n/ga.js
new file mode 100644
index 00000000000..32438cb60ec
--- /dev/null
+++ b/apps/comments/l10n/ga.js
@@ -0,0 +1,36 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Tuairimí",
+ "You commented" : "Rinne tú trácht",
+ "{author} commented" : "Rinne {author} nóta tráchta",
+ "You commented on %1$s" : "Rinne tú trácht ar%1$s",
+ "You commented on {file}" : "Rinne tú trácht ar {file}",
+ "%1$s commented on %2$s" : "%1$s trácht ar %2$s",
+ "{author} commented on {file}" : "{author} trácht ar {file}",
+ "<strong>Comments</strong> for files" : "<strong>Tuairimí</strong> le haghaidh comhaid",
+ "Files" : "Comhaid",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Luadh thú ar \"{file}\", i nóta tráchta ó chuntas a scriosadh ó shin",
+ "{user} mentioned you in a comment on \"{file}\"" : "Luaigh {user} tú i nóta tráchta ar \"{file}\"",
+ "Files app plugin to add comments to files" : "Breiseán aip Comhaid chun tuairimí a chur le comhaid",
+ "Edit comment" : "Cuir trácht in eagar",
+ "Delete comment" : "Scrios nóta tráchta",
+ "Cancel edit" : "Cealaigh eagarthóireacht",
+ "New comment" : "Trácht nua",
+ "Write a comment …" : "Scríobh trácht…",
+ "Post comment" : "Post trácht",
+ "@ for mentions, : for emoji, / for smart picker" : "@ le haghaidh tagairtí, : le haghaidh emoji, / le haghaidh roghnóir cliste",
+ "Could not reload comments" : "Níorbh fhéidir na nótaí tráchta a athlódáil",
+ "Failed to mark comments as read" : "Theip ar nótaí tráchta a mharcáil mar léite",
+ "Unable to load the comments list" : "Ní féidir an liosta tuairimí a lódáil",
+ "No comments yet, start the conversation!" : "Gan trácht ar bith go fóill, cuir tús leis an gcomhrá!",
+ "No more messages" : "Níl a thuilleadh teachtaireachtaí",
+ "Retry" : "Bain triail eile as",
+ "_1 new comment_::_{unread} new comments_" : ["1 trácht nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua"],
+ "Comment" : "Trácht",
+ "An error occurred while trying to edit the comment" : "Tharla earráid agus an nóta tráchta á chur in eagar",
+ "Comment deleted" : "Trácht scriosta",
+ "An error occurred while trying to delete the comment" : "Tharla earráid agus an nóta tráchta á scriosadh",
+ "An error occurred while trying to create the comment" : "Tharla earráid agus an nóta tráchta á chruthú"
+},
+"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);");
diff --git a/apps/comments/l10n/ga.json b/apps/comments/l10n/ga.json
new file mode 100644
index 00000000000..4442145dea6
--- /dev/null
+++ b/apps/comments/l10n/ga.json
@@ -0,0 +1,34 @@
+{ "translations": {
+ "Comments" : "Tuairimí",
+ "You commented" : "Rinne tú trácht",
+ "{author} commented" : "Rinne {author} nóta tráchta",
+ "You commented on %1$s" : "Rinne tú trácht ar%1$s",
+ "You commented on {file}" : "Rinne tú trácht ar {file}",
+ "%1$s commented on %2$s" : "%1$s trácht ar %2$s",
+ "{author} commented on {file}" : "{author} trácht ar {file}",
+ "<strong>Comments</strong> for files" : "<strong>Tuairimí</strong> le haghaidh comhaid",
+ "Files" : "Comhaid",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Luadh thú ar \"{file}\", i nóta tráchta ó chuntas a scriosadh ó shin",
+ "{user} mentioned you in a comment on \"{file}\"" : "Luaigh {user} tú i nóta tráchta ar \"{file}\"",
+ "Files app plugin to add comments to files" : "Breiseán aip Comhaid chun tuairimí a chur le comhaid",
+ "Edit comment" : "Cuir trácht in eagar",
+ "Delete comment" : "Scrios nóta tráchta",
+ "Cancel edit" : "Cealaigh eagarthóireacht",
+ "New comment" : "Trácht nua",
+ "Write a comment …" : "Scríobh trácht…",
+ "Post comment" : "Post trácht",
+ "@ for mentions, : for emoji, / for smart picker" : "@ le haghaidh tagairtí, : le haghaidh emoji, / le haghaidh roghnóir cliste",
+ "Could not reload comments" : "Níorbh fhéidir na nótaí tráchta a athlódáil",
+ "Failed to mark comments as read" : "Theip ar nótaí tráchta a mharcáil mar léite",
+ "Unable to load the comments list" : "Ní féidir an liosta tuairimí a lódáil",
+ "No comments yet, start the conversation!" : "Gan trácht ar bith go fóill, cuir tús leis an gcomhrá!",
+ "No more messages" : "Níl a thuilleadh teachtaireachtaí",
+ "Retry" : "Bain triail eile as",
+ "_1 new comment_::_{unread} new comments_" : ["1 trácht nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua"],
+ "Comment" : "Trácht",
+ "An error occurred while trying to edit the comment" : "Tharla earráid agus an nóta tráchta á chur in eagar",
+ "Comment deleted" : "Trácht scriosta",
+ "An error occurred while trying to delete the comment" : "Tharla earráid agus an nóta tráchta á scriosadh",
+ "An error occurred while trying to create the comment" : "Tharla earráid agus an nóta tráchta á chruthú"
+},"pluralForm" :"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/gl.js b/apps/comments/l10n/gl.js
index e882611c3dc..364e95abc69 100644
--- a/apps/comments/l10n/gl.js
+++ b/apps/comments/l10n/gl.js
@@ -1,8 +1,36 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "Cancelar",
- "Save" : "Gardar",
- "Comment" : "Comentario"
+ "Comments" : "Comentarios",
+ "You commented" : "Vde. comentou",
+ "{author} commented" : "{author} comentou",
+ "You commented on %1$s" : "Vde. comentou en %1$s",
+ "You commented on {file}" : "Vde. comentou en {file}",
+ "%1$s commented on %2$s" : "%1$s comentados en %2$s",
+ "{author} commented on {file}" : "{author} comentou en {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> para ficheiros",
+ "Files" : "Ficheiros",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Mencionárono en «{file}», nun comentario dunha conta que xa foi eliminada",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mencionouno a Vde. nun comentario en «{file}»",
+ "Files app plugin to add comments to files" : "Complemento da aplicación de ficheiros para engadir comentarios aos ficheiros",
+ "Edit comment" : "Editar comentario",
+ "Delete comment" : "Eliminar comentario",
+ "Cancel edit" : "Cancelar a edición",
+ "New comment" : "Comentario novo",
+ "Write a comment …" : "Escriba un comentario…",
+ "Post comment" : "Publicar comentario",
+ "@ for mentions, : for emoji, / for smart picker" : "@ para mencións, : para «emoji», / para selector intelixente",
+ "Could not reload comments" : "Non foi posíbel volver cargar os comentarios",
+ "Failed to mark comments as read" : "Produciuse un fallo ao marcar os comentarios como lidos",
+ "Unable to load the comments list" : "Non é posíbel cargar a lista de comentarios",
+ "No comments yet, start the conversation!" : "Aínda non hai comentarios, comeza a conversa!",
+ "No more messages" : "Non hai máis mensaxes",
+ "Retry" : "Volver tentar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentario novo","{unread} comentarios novos"],
+ "Comment" : "Comentario",
+ "An error occurred while trying to edit the comment" : "Produciuse un erro cando tentaba editar o comentario",
+ "Comment deleted" : "Comentario eliminado",
+ "An error occurred while trying to delete the comment" : "Produciuse un erro cando tentaba eliminar o comentario",
+ "An error occurred while trying to create the comment" : "Produciuse un erro cando tentaba crear o comentario"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/gl.json b/apps/comments/l10n/gl.json
index 4f4e732bcf1..128f8e5251f 100644
--- a/apps/comments/l10n/gl.json
+++ b/apps/comments/l10n/gl.json
@@ -1,6 +1,34 @@
{ "translations": {
- "Cancel" : "Cancelar",
- "Save" : "Gardar",
- "Comment" : "Comentario"
+ "Comments" : "Comentarios",
+ "You commented" : "Vde. comentou",
+ "{author} commented" : "{author} comentou",
+ "You commented on %1$s" : "Vde. comentou en %1$s",
+ "You commented on {file}" : "Vde. comentou en {file}",
+ "%1$s commented on %2$s" : "%1$s comentados en %2$s",
+ "{author} commented on {file}" : "{author} comentou en {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarios</strong> para ficheiros",
+ "Files" : "Ficheiros",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Mencionárono en «{file}», nun comentario dunha conta que xa foi eliminada",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mencionouno a Vde. nun comentario en «{file}»",
+ "Files app plugin to add comments to files" : "Complemento da aplicación de ficheiros para engadir comentarios aos ficheiros",
+ "Edit comment" : "Editar comentario",
+ "Delete comment" : "Eliminar comentario",
+ "Cancel edit" : "Cancelar a edición",
+ "New comment" : "Comentario novo",
+ "Write a comment …" : "Escriba un comentario…",
+ "Post comment" : "Publicar comentario",
+ "@ for mentions, : for emoji, / for smart picker" : "@ para mencións, : para «emoji», / para selector intelixente",
+ "Could not reload comments" : "Non foi posíbel volver cargar os comentarios",
+ "Failed to mark comments as read" : "Produciuse un fallo ao marcar os comentarios como lidos",
+ "Unable to load the comments list" : "Non é posíbel cargar a lista de comentarios",
+ "No comments yet, start the conversation!" : "Aínda non hai comentarios, comeza a conversa!",
+ "No more messages" : "Non hai máis mensaxes",
+ "Retry" : "Volver tentar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentario novo","{unread} comentarios novos"],
+ "Comment" : "Comentario",
+ "An error occurred while trying to edit the comment" : "Produciuse un erro cando tentaba editar o comentario",
+ "Comment deleted" : "Comentario eliminado",
+ "An error occurred while trying to delete the comment" : "Produciuse un erro cando tentaba eliminar o comentario",
+ "An error occurred while trying to create the comment" : "Produciuse un erro cando tentaba crear o comentario"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/he.js b/apps/comments/l10n/he.js
index 640ec297dd3..e1d0256599a 100644
--- a/apps/comments/l10n/he.js
+++ b/apps/comments/l10n/he.js
@@ -1,23 +1,30 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>תגובות</strong> לקבצים",
+ "Comments" : "תגובות",
"You commented" : "הערות שלך",
- "%1$s commented" : "התקבלו תגובות %1$s",
- "You commented on %2$s" : "הערות שלך ב- %2$s",
+ "{author} commented" : "התקבלה תגובה מאת {author}",
+ "You commented on %1$s" : "הגבת על %1$s",
+ "You commented on {file}" : "הגבת על {file}",
"%1$s commented on %2$s" : "התקבלו תגובות %1$s ב- %2$s ",
- "Comments" : "תגובות",
- "Type in a new comment..." : "יש להכניס תגובה חדשה...",
- "Delete comment" : "מחיקת תגובה",
- "Post" : "פרסום",
- "Cancel" : "ביטול",
+ "{author} commented on {file}" : "נוספה תגובה על {file} מאת {author}",
+ "<strong>Comments</strong> for files" : "<strong>תגובות</strong> על קבצים",
+ "Files" : "קבצים",
+ "{user} mentioned you in a comment on \"{file}\"" : "אוזכרת על ידי {user} בהערה בתוך „{file}”",
+ "Files app plugin to add comments to files" : "תוסף ליישומון הקבצים כדי להוסיף הערות על קבצים",
"Edit comment" : "עריכת תגובה",
- "[Deleted user]" : "[משתמשים מוסרים]",
- "No other comments available" : "אין תגובות אחרות זמינות",
- "More comments..." : "תגובות נוספות...",
- "Save" : "שמירה",
- "Allowed characters {count} of {max}" : "תווים מותרים {count} מתוך {max}",
- "{count} unread comments" : "{count} תגובות שלא נקראו",
- "Comment" : "תגובה"
+ "Delete comment" : "מחיקת תגובה",
+ "Cancel edit" : "בטל עריכה",
+ "Post comment" : "פרסם תגובה",
+ "Unable to load the comments list" : "לא ניתן לטעון את רשימת התגובות",
+ "No comments yet, start the conversation!" : "אין תגובות עדיין, בואו נתחיל לקשקש!",
+ "No more messages" : "אין יותר הודעות",
+ "Retry" : "ניסיון חוזר",
+ "_1 new comment_::_{unread} new comments_" : ["הערה חדשה אחת","{unread} הערות חדשות","{unread} הערות חדשות"],
+ "Comment" : "תגובה",
+ "An error occurred while trying to edit the comment" : "אירעה שגיאה בניסיון לערוך את התגובה",
+ "Comment deleted" : "נמחקה הערה",
+ "An error occurred while trying to delete the comment" : "אירעה שגיאה בניסיון למחוק את התגובה",
+ "An error occurred while trying to create the comment" : "אירעה שגיאה בניסיון ליצור את התגובה"
},
-"nplurals=2; plural=(n != 1);");
+"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;");
diff --git a/apps/comments/l10n/he.json b/apps/comments/l10n/he.json
index 0f79918c472..c59bb70dfd1 100644
--- a/apps/comments/l10n/he.json
+++ b/apps/comments/l10n/he.json
@@ -1,21 +1,28 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>תגובות</strong> לקבצים",
+ "Comments" : "תגובות",
"You commented" : "הערות שלך",
- "%1$s commented" : "התקבלו תגובות %1$s",
- "You commented on %2$s" : "הערות שלך ב- %2$s",
+ "{author} commented" : "התקבלה תגובה מאת {author}",
+ "You commented on %1$s" : "הגבת על %1$s",
+ "You commented on {file}" : "הגבת על {file}",
"%1$s commented on %2$s" : "התקבלו תגובות %1$s ב- %2$s ",
- "Comments" : "תגובות",
- "Type in a new comment..." : "יש להכניס תגובה חדשה...",
- "Delete comment" : "מחיקת תגובה",
- "Post" : "פרסום",
- "Cancel" : "ביטול",
+ "{author} commented on {file}" : "נוספה תגובה על {file} מאת {author}",
+ "<strong>Comments</strong> for files" : "<strong>תגובות</strong> על קבצים",
+ "Files" : "קבצים",
+ "{user} mentioned you in a comment on \"{file}\"" : "אוזכרת על ידי {user} בהערה בתוך „{file}”",
+ "Files app plugin to add comments to files" : "תוסף ליישומון הקבצים כדי להוסיף הערות על קבצים",
"Edit comment" : "עריכת תגובה",
- "[Deleted user]" : "[משתמשים מוסרים]",
- "No other comments available" : "אין תגובות אחרות זמינות",
- "More comments..." : "תגובות נוספות...",
- "Save" : "שמירה",
- "Allowed characters {count} of {max}" : "תווים מותרים {count} מתוך {max}",
- "{count} unread comments" : "{count} תגובות שלא נקראו",
- "Comment" : "תגובה"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
+ "Delete comment" : "מחיקת תגובה",
+ "Cancel edit" : "בטל עריכה",
+ "Post comment" : "פרסם תגובה",
+ "Unable to load the comments list" : "לא ניתן לטעון את רשימת התגובות",
+ "No comments yet, start the conversation!" : "אין תגובות עדיין, בואו נתחיל לקשקש!",
+ "No more messages" : "אין יותר הודעות",
+ "Retry" : "ניסיון חוזר",
+ "_1 new comment_::_{unread} new comments_" : ["הערה חדשה אחת","{unread} הערות חדשות","{unread} הערות חדשות"],
+ "Comment" : "תגובה",
+ "An error occurred while trying to edit the comment" : "אירעה שגיאה בניסיון לערוך את התגובה",
+ "Comment deleted" : "נמחקה הערה",
+ "An error occurred while trying to delete the comment" : "אירעה שגיאה בניסיון למחוק את התגובה",
+ "An error occurred while trying to create the comment" : "אירעה שגיאה בניסיון ליצור את התגובה"
+},"pluralForm" :"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/hi.js b/apps/comments/l10n/hi.js
deleted file mode 100644
index ed49cce9227..00000000000
--- a/apps/comments/l10n/hi.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "रद्द करें ",
- "Save" : "सहेजें"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/hi.json b/apps/comments/l10n/hi.json
deleted file mode 100644
index f6b1d3d1b1b..00000000000
--- a/apps/comments/l10n/hi.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "रद्द करें ",
- "Save" : "सहेजें"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/hr.js b/apps/comments/l10n/hr.js
index d7aa807254c..00cd18cb7fb 100644
--- a/apps/comments/l10n/hr.js
+++ b/apps/comments/l10n/hr.js
@@ -1,7 +1,29 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "Odustanite",
- "Save" : "Spremi"
+ "Comments" : "Komentari",
+ "You commented" : "Vi ste komentirali",
+ "{author} commented" : "{author} je komentirao",
+ "You commented on %1$s" : "Vi ste komentirali %1$s",
+ "You commented on {file}" : "Komentirali ste {file}",
+ "%1$s commented on %2$s" : "%1$s je komentirao %2$s",
+ "{author} commented on {file}" : "{author} je komentirao {file}",
+ "<strong>Comments</strong> for files" : "<strong>Komentari</strong> za datoteke",
+ "Files" : "Datoteke",
+ "Files app plugin to add comments to files" : "Dodatak za aplikaciju Datoteke za dodavanje komentara na datoteke",
+ "Edit comment" : "Uredi komentar",
+ "Delete comment" : "Izbriši komentar",
+ "Cancel edit" : "Otkaži uređivanje",
+ "Post comment" : "Objavi komentar",
+ "Unable to load the comments list" : "Nije moguće učitati popis komentara",
+ "No comments yet, start the conversation!" : "Još nema komentara, započnite razgovor!",
+ "No more messages" : "Nema više poruka",
+ "Retry" : "Pokušaj ponovno",
+ "_1 new comment_::_{unread} new comments_" : ["1 novi komentar","{unread} novih komentara","{unread} novih komentara"],
+ "Comment" : "Komentar",
+ "An error occurred while trying to edit the comment" : "Došlo je do pogreške prilikom uređivanja komentara",
+ "Comment deleted" : "Komentar izbrisan",
+ "An error occurred while trying to delete the comment" : "Došlo je do pogreške prilikom brisanja komentara",
+ "An error occurred while trying to create the comment" : "Došlo je do pogreške prilikom stvaranja komentara"
},
"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;");
diff --git a/apps/comments/l10n/hr.json b/apps/comments/l10n/hr.json
index 78c71af4fd2..e6447eef1af 100644
--- a/apps/comments/l10n/hr.json
+++ b/apps/comments/l10n/hr.json
@@ -1,5 +1,27 @@
{ "translations": {
- "Cancel" : "Odustanite",
- "Save" : "Spremi"
+ "Comments" : "Komentari",
+ "You commented" : "Vi ste komentirali",
+ "{author} commented" : "{author} je komentirao",
+ "You commented on %1$s" : "Vi ste komentirali %1$s",
+ "You commented on {file}" : "Komentirali ste {file}",
+ "%1$s commented on %2$s" : "%1$s je komentirao %2$s",
+ "{author} commented on {file}" : "{author} je komentirao {file}",
+ "<strong>Comments</strong> for files" : "<strong>Komentari</strong> za datoteke",
+ "Files" : "Datoteke",
+ "Files app plugin to add comments to files" : "Dodatak za aplikaciju Datoteke za dodavanje komentara na datoteke",
+ "Edit comment" : "Uredi komentar",
+ "Delete comment" : "Izbriši komentar",
+ "Cancel edit" : "Otkaži uređivanje",
+ "Post comment" : "Objavi komentar",
+ "Unable to load the comments list" : "Nije moguće učitati popis komentara",
+ "No comments yet, start the conversation!" : "Još nema komentara, započnite razgovor!",
+ "No more messages" : "Nema više poruka",
+ "Retry" : "Pokušaj ponovno",
+ "_1 new comment_::_{unread} new comments_" : ["1 novi komentar","{unread} novih komentara","{unread} novih komentara"],
+ "Comment" : "Komentar",
+ "An error occurred while trying to edit the comment" : "Došlo je do pogreške prilikom uređivanja komentara",
+ "Comment deleted" : "Komentar izbrisan",
+ "An error occurred while trying to delete the comment" : "Došlo je do pogreške prilikom brisanja komentara",
+ "An error occurred while trying to create the comment" : "Došlo je do pogreške prilikom stvaranja komentara"
},"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/hu.js b/apps/comments/l10n/hu.js
new file mode 100644
index 00000000000..05b0f519e0b
--- /dev/null
+++ b/apps/comments/l10n/hu.js
@@ -0,0 +1,36 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Hozzászólások",
+ "You commented" : "Hozzászólt",
+ "{author} commented" : "{author} hozzászólt",
+ "You commented on %1$s" : "Hozzászólt ehhez: %1$s",
+ "You commented on {file}" : "Hozzászólt ehhez: {file}",
+ "%1$s commented on %2$s" : "%1$s hozzászólt ehhez: %2$s",
+ "{author} commented on {file}" : "{author} hozzászólt ehhez: {file}",
+ "<strong>Comments</strong> for files" : "<strong>Hozzászólások</strong> fájlokhoz",
+ "Files" : "Fájlok",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Megemlítették ennél: „{file}”, egy már törölt fiók hozzászólásában",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} megemlítette egy hozzászólásban ennél: „{file}”",
+ "Files app plugin to add comments to files" : "A Fájlok alkalmazás bővítménye, amellyel megjegyzések adhatóak a fájlokhoz",
+ "Edit comment" : "Hozzászólás szerkesztése",
+ "Delete comment" : "Hozzászólás törlése",
+ "Cancel edit" : "Változások elvetése",
+ "New comment" : "Új hozzászólás",
+ "Write a comment …" : "Hozzászólás írása…",
+ "Post comment" : "Hozzászólás közzététele",
+ "@ for mentions, : for emoji, / for smart picker" : "@ az említésekhez, : az emodzsikhoz, / az okos választóhoz",
+ "Could not reload comments" : "Nem sikerült a megjegyzések újratöltése.",
+ "Failed to mark comments as read" : "A hozzászólások olvasottnak jelölése sikertelen",
+ "Unable to load the comments list" : "A hozzászólások betöltése sikertelen",
+ "No comments yet, start the conversation!" : "Még nincsenek hozzászólások, kezdje el a beszélgetést!",
+ "No more messages" : "Nincs több üzenet",
+ "Retry" : "Újra",
+ "_1 new comment_::_{unread} new comments_" : ["1 új hozzászólás","{unread} új hozzászólás"],
+ "Comment" : "Hozzászólás",
+ "An error occurred while trying to edit the comment" : "Hiba történt a megjegyzés szerkesztése közben",
+ "Comment deleted" : "Hozzászólás törölve",
+ "An error occurred while trying to delete the comment" : "Hiba történt a megjegyzés törlése közben",
+ "An error occurred while trying to create the comment" : "Hiba történt a megjegyzés létrehozása közben"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/hu.json b/apps/comments/l10n/hu.json
new file mode 100644
index 00000000000..962f1c72c06
--- /dev/null
+++ b/apps/comments/l10n/hu.json
@@ -0,0 +1,34 @@
+{ "translations": {
+ "Comments" : "Hozzászólások",
+ "You commented" : "Hozzászólt",
+ "{author} commented" : "{author} hozzászólt",
+ "You commented on %1$s" : "Hozzászólt ehhez: %1$s",
+ "You commented on {file}" : "Hozzászólt ehhez: {file}",
+ "%1$s commented on %2$s" : "%1$s hozzászólt ehhez: %2$s",
+ "{author} commented on {file}" : "{author} hozzászólt ehhez: {file}",
+ "<strong>Comments</strong> for files" : "<strong>Hozzászólások</strong> fájlokhoz",
+ "Files" : "Fájlok",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Megemlítették ennél: „{file}”, egy már törölt fiók hozzászólásában",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} megemlítette egy hozzászólásban ennél: „{file}”",
+ "Files app plugin to add comments to files" : "A Fájlok alkalmazás bővítménye, amellyel megjegyzések adhatóak a fájlokhoz",
+ "Edit comment" : "Hozzászólás szerkesztése",
+ "Delete comment" : "Hozzászólás törlése",
+ "Cancel edit" : "Változások elvetése",
+ "New comment" : "Új hozzászólás",
+ "Write a comment …" : "Hozzászólás írása…",
+ "Post comment" : "Hozzászólás közzététele",
+ "@ for mentions, : for emoji, / for smart picker" : "@ az említésekhez, : az emodzsikhoz, / az okos választóhoz",
+ "Could not reload comments" : "Nem sikerült a megjegyzések újratöltése.",
+ "Failed to mark comments as read" : "A hozzászólások olvasottnak jelölése sikertelen",
+ "Unable to load the comments list" : "A hozzászólások betöltése sikertelen",
+ "No comments yet, start the conversation!" : "Még nincsenek hozzászólások, kezdje el a beszélgetést!",
+ "No more messages" : "Nincs több üzenet",
+ "Retry" : "Újra",
+ "_1 new comment_::_{unread} new comments_" : ["1 új hozzászólás","{unread} új hozzászólás"],
+ "Comment" : "Hozzászólás",
+ "An error occurred while trying to edit the comment" : "Hiba történt a megjegyzés szerkesztése közben",
+ "Comment deleted" : "Hozzászólás törölve",
+ "An error occurred while trying to delete the comment" : "Hiba történt a megjegyzés törlése közben",
+ "An error occurred while trying to create the comment" : "Hiba történt a megjegyzés létrehozása közben"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/hu_HU.js b/apps/comments/l10n/hu_HU.js
deleted file mode 100644
index b49d1456848..00000000000
--- a/apps/comments/l10n/hu_HU.js
+++ /dev/null
@@ -1,21 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "<strong>Comments</strong> for files" : "<strong>Hozzászólások</strong> a fájlokhoz",
- "%1$s commented" : "%1$s hozzászólt",
- "%1$s commented on %2$s" : "%1$s hozzászólt ehhez: %2$s",
- "Comments" : "Hozzászólások",
- "Type in a new comment..." : "Új hozzászólás írása...",
- "Delete comment" : "Hozzászólás törlése",
- "Post" : "Küldés",
- "Cancel" : "Mégsem",
- "Edit comment" : "Hozzászólás szerkesztése",
- "[Deleted user]" : "[Törölt felhasználó]",
- "No other comments available" : "Nincs több hozzászólás.",
- "More comments..." : "Több hozzászólás...",
- "Save" : "Mentés",
- "Allowed characters {count} of {max}" : "Engedélyezett karakterek: {count} / {max}",
- "{count} unread comments" : "{count} olvasatlan hozzászólás",
- "Comment" : "Hozzászólás"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/hu_HU.json b/apps/comments/l10n/hu_HU.json
deleted file mode 100644
index ceba0641915..00000000000
--- a/apps/comments/l10n/hu_HU.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Hozzászólások</strong> a fájlokhoz",
- "%1$s commented" : "%1$s hozzászólt",
- "%1$s commented on %2$s" : "%1$s hozzászólt ehhez: %2$s",
- "Comments" : "Hozzászólások",
- "Type in a new comment..." : "Új hozzászólás írása...",
- "Delete comment" : "Hozzászólás törlése",
- "Post" : "Küldés",
- "Cancel" : "Mégsem",
- "Edit comment" : "Hozzászólás szerkesztése",
- "[Deleted user]" : "[Törölt felhasználó]",
- "No other comments available" : "Nincs több hozzászólás.",
- "More comments..." : "Több hozzászólás...",
- "Save" : "Mentés",
- "Allowed characters {count} of {max}" : "Engedélyezett karakterek: {count} / {max}",
- "{count} unread comments" : "{count} olvasatlan hozzászólás",
- "Comment" : "Hozzászólás"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/hy.js b/apps/comments/l10n/hy.js
deleted file mode 100644
index 6e6fa514244..00000000000
--- a/apps/comments/l10n/hy.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Չեղարկել",
- "Save" : "Պահպանել"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/hy.json b/apps/comments/l10n/hy.json
deleted file mode 100644
index 1d692e6d00d..00000000000
--- a/apps/comments/l10n/hy.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "Չեղարկել",
- "Save" : "Պահպանել"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/ia.js b/apps/comments/l10n/ia.js
deleted file mode 100644
index ff148a13b8d..00000000000
--- a/apps/comments/l10n/ia.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Cancellar",
- "Save" : "Salveguardar"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/ia.json b/apps/comments/l10n/ia.json
deleted file mode 100644
index a71e73149f6..00000000000
--- a/apps/comments/l10n/ia.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "Cancellar",
- "Save" : "Salveguardar"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/id.js b/apps/comments/l10n/id.js
index 28965c9e91e..10e0fa73ee3 100644
--- a/apps/comments/l10n/id.js
+++ b/apps/comments/l10n/id.js
@@ -1,21 +1,28 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Komentar</strong> untuk berkas",
- "%1$s commented" : "%1$s dikomentari",
- "%1$s commented on %2$s" : "%1$s dikomentari pada %2$s",
"Comments" : "Komentar",
- "Type in a new comment..." : "Ketik di komentar baru...",
- "Delete comment" : "Hapus komentar",
- "Post" : "Posting",
- "Cancel" : "Batal",
+ "You commented" : "Anda berkomentar",
+ "{author} commented" : "{author} berkomentar",
+ "You commented on %1$s" : "Anda berkomentar pada %1$s",
+ "You commented on {file}" : "Anda berkomentar pada {file} ",
+ "%1$s commented on %2$s" : "%1$s dikomentari pada %2$s",
+ "{author} commented on {file}" : "{author} berkomentar pada {file}",
+ "<strong>Comments</strong> for files" : "<strong>komentar</strong> pada file",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} menyebut Anda dalam sebuah komentar pada \"{file}\" ",
+ "Files app plugin to add comments to files" : "Plugin aplikasi file untuk menambah komentar pada file",
"Edit comment" : "Sunting komentar",
- "[Deleted user]" : "[Hapus pengguna]",
- "No other comments available" : "Tidak ada komentar lainnya",
- "More comments..." : "Komentar lainya...",
- "Save" : "Simpan",
- "Allowed characters {count} of {max}" : "Karakter yang diizinkan {count} dari {max}",
- "{count} unread comments" : "{count} komentar belum dibaca",
- "Comment" : "Komentar"
+ "Delete comment" : "Hapus komentar",
+ "Cancel edit" : "Batal sunting",
+ "Post comment" : "Posting komentar",
+ "Unable to load the comments list" : "Tidak dapat memuat daftar komentar",
+ "No comments yet, start the conversation!" : "Belum ada yang berkomentar, mulailah perbincangan!",
+ "No more messages" : "Tidak ada pesan lagi",
+ "Retry" : "Ulangi",
+ "Comment" : "Komentar",
+ "An error occurred while trying to edit the comment" : "Terjadi kesalahan ketika mencoba menyunting komentar",
+ "Comment deleted" : "Komentar dihapus",
+ "An error occurred while trying to delete the comment" : "Terjadi kesalahan ketika mencoba untuk menghapus komentar",
+ "An error occurred while trying to create the comment" : "Terjadi kesalahan ketika mencoba untuk membuat komentar"
},
"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/id.json b/apps/comments/l10n/id.json
index f66594eca16..56ecdc58c2c 100644
--- a/apps/comments/l10n/id.json
+++ b/apps/comments/l10n/id.json
@@ -1,19 +1,26 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Komentar</strong> untuk berkas",
- "%1$s commented" : "%1$s dikomentari",
- "%1$s commented on %2$s" : "%1$s dikomentari pada %2$s",
"Comments" : "Komentar",
- "Type in a new comment..." : "Ketik di komentar baru...",
- "Delete comment" : "Hapus komentar",
- "Post" : "Posting",
- "Cancel" : "Batal",
+ "You commented" : "Anda berkomentar",
+ "{author} commented" : "{author} berkomentar",
+ "You commented on %1$s" : "Anda berkomentar pada %1$s",
+ "You commented on {file}" : "Anda berkomentar pada {file} ",
+ "%1$s commented on %2$s" : "%1$s dikomentari pada %2$s",
+ "{author} commented on {file}" : "{author} berkomentar pada {file}",
+ "<strong>Comments</strong> for files" : "<strong>komentar</strong> pada file",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} menyebut Anda dalam sebuah komentar pada \"{file}\" ",
+ "Files app plugin to add comments to files" : "Plugin aplikasi file untuk menambah komentar pada file",
"Edit comment" : "Sunting komentar",
- "[Deleted user]" : "[Hapus pengguna]",
- "No other comments available" : "Tidak ada komentar lainnya",
- "More comments..." : "Komentar lainya...",
- "Save" : "Simpan",
- "Allowed characters {count} of {max}" : "Karakter yang diizinkan {count} dari {max}",
- "{count} unread comments" : "{count} komentar belum dibaca",
- "Comment" : "Komentar"
+ "Delete comment" : "Hapus komentar",
+ "Cancel edit" : "Batal sunting",
+ "Post comment" : "Posting komentar",
+ "Unable to load the comments list" : "Tidak dapat memuat daftar komentar",
+ "No comments yet, start the conversation!" : "Belum ada yang berkomentar, mulailah perbincangan!",
+ "No more messages" : "Tidak ada pesan lagi",
+ "Retry" : "Ulangi",
+ "Comment" : "Komentar",
+ "An error occurred while trying to edit the comment" : "Terjadi kesalahan ketika mencoba menyunting komentar",
+ "Comment deleted" : "Komentar dihapus",
+ "An error occurred while trying to delete the comment" : "Terjadi kesalahan ketika mencoba untuk menghapus komentar",
+ "An error occurred while trying to create the comment" : "Terjadi kesalahan ketika mencoba untuk membuat komentar"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/is.js b/apps/comments/l10n/is.js
index c55ebf7ef85..d4b6327070b 100644
--- a/apps/comments/l10n/is.js
+++ b/apps/comments/l10n/is.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Athugasemdir</strong> við skrár",
+ "Comments" : "Athugasemdir",
"You commented" : "Þú settir inn athugasemd",
- "%1$s commented" : "%1$s setti inn athugasemd",
- "You commented on %2$s" : "Þú settir inn athugasemd við %2$s",
+ "{author} commented" : "{author} setti inn athugasemd",
+ "You commented on %1$s" : "Þú settir inn athugasemd við %1$s",
+ "You commented on {file}" : "Þú settir inn athugasemd við {file}",
"%1$s commented on %2$s" : "%1$s setti inn athugasemd um %2$s",
- "Comments" : "Athugasemdir",
- "Type in a new comment..." : "Skrifaðu inn nýja athugasemd...",
- "Delete comment" : "Eyða athugasemd",
- "Post" : "Senda",
- "Cancel" : "Hætta við",
+ "{author} commented on {file}" : "{author} setti inn athugasemd við {file}",
+ "<strong>Comments</strong> for files" : "<strong>Athugasemdir</strong> við skrár",
+ "Files" : "Skráaforrit",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Minnst var á þig í \"{file}\", í athugasemd frá notandaaðgangi sem síðan þá hefur verið eytt",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} minntist á þig í athugasemd við \"{file}\"",
+ "Files app plugin to add comments to files" : "Viðbót við skráaforrit til að bæta athugasemdum við skrár",
"Edit comment" : "Breyta athugasemd",
- "[Deleted user]" : "[Eyddur notandi]",
- "No other comments available" : "Engar aðrar athugasemdir eru tiltækar",
- "More comments..." : "Fleiri athugasemdir...",
- "Save" : "Vista",
- "Allowed characters {count} of {max}" : "Leyfður stafafjöldi {count} af {max}",
- "{count} unread comments" : "{count} ólesnar athugasemdir",
- "Comment" : "Athugasemd"
+ "Delete comment" : "Eyða athugasemd",
+ "Cancel edit" : "Hætta við breytingar",
+ "New comment" : "Ný athugasemd",
+ "Write a comment …" : "Skrifa athugasemd ...",
+ "Post comment" : "Senda inn athugasemd",
+ "@ for mentions, : for emoji, / for smart picker" : "@ til að minnast á, : fyrir tjáningartákn, / fyrir snjallveljara",
+ "Could not reload comments" : "Gat ekki endurlesið athugasemdir",
+ "Failed to mark comments as read" : "Tókst ekki að merkja athugasemdir sem lesnar",
+ "Unable to load the comments list" : "Gat ekki hlaðið inn lista yfir athugasemdir",
+ "No comments yet, start the conversation!" : "Engar athugasemdir ennþá, byrjaðu umræðuna!",
+ "No more messages" : "Engin fleiri skilaboð",
+ "Retry" : "Reyna aftur",
+ "_1 new comment_::_{unread} new comments_" : ["1 ný athugasemd","{unread} nýjar athugasemdir"],
+ "Comment" : "Athugasemd",
+ "An error occurred while trying to edit the comment" : "Villa átti sér stað við að breyta athugasemdinni",
+ "Comment deleted" : "Athugasemd var eytt",
+ "An error occurred while trying to delete the comment" : "Villa átti sér stað við að eyða athugasemdinni",
+ "An error occurred while trying to create the comment" : "Villa átti sér stað við að útbúa athugasemdina"
},
"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");
diff --git a/apps/comments/l10n/is.json b/apps/comments/l10n/is.json
index 1a73471addf..458a1704c3b 100644
--- a/apps/comments/l10n/is.json
+++ b/apps/comments/l10n/is.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Athugasemdir</strong> við skrár",
+ "Comments" : "Athugasemdir",
"You commented" : "Þú settir inn athugasemd",
- "%1$s commented" : "%1$s setti inn athugasemd",
- "You commented on %2$s" : "Þú settir inn athugasemd við %2$s",
+ "{author} commented" : "{author} setti inn athugasemd",
+ "You commented on %1$s" : "Þú settir inn athugasemd við %1$s",
+ "You commented on {file}" : "Þú settir inn athugasemd við {file}",
"%1$s commented on %2$s" : "%1$s setti inn athugasemd um %2$s",
- "Comments" : "Athugasemdir",
- "Type in a new comment..." : "Skrifaðu inn nýja athugasemd...",
- "Delete comment" : "Eyða athugasemd",
- "Post" : "Senda",
- "Cancel" : "Hætta við",
+ "{author} commented on {file}" : "{author} setti inn athugasemd við {file}",
+ "<strong>Comments</strong> for files" : "<strong>Athugasemdir</strong> við skrár",
+ "Files" : "Skráaforrit",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Minnst var á þig í \"{file}\", í athugasemd frá notandaaðgangi sem síðan þá hefur verið eytt",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} minntist á þig í athugasemd við \"{file}\"",
+ "Files app plugin to add comments to files" : "Viðbót við skráaforrit til að bæta athugasemdum við skrár",
"Edit comment" : "Breyta athugasemd",
- "[Deleted user]" : "[Eyddur notandi]",
- "No other comments available" : "Engar aðrar athugasemdir eru tiltækar",
- "More comments..." : "Fleiri athugasemdir...",
- "Save" : "Vista",
- "Allowed characters {count} of {max}" : "Leyfður stafafjöldi {count} af {max}",
- "{count} unread comments" : "{count} ólesnar athugasemdir",
- "Comment" : "Athugasemd"
+ "Delete comment" : "Eyða athugasemd",
+ "Cancel edit" : "Hætta við breytingar",
+ "New comment" : "Ný athugasemd",
+ "Write a comment …" : "Skrifa athugasemd ...",
+ "Post comment" : "Senda inn athugasemd",
+ "@ for mentions, : for emoji, / for smart picker" : "@ til að minnast á, : fyrir tjáningartákn, / fyrir snjallveljara",
+ "Could not reload comments" : "Gat ekki endurlesið athugasemdir",
+ "Failed to mark comments as read" : "Tókst ekki að merkja athugasemdir sem lesnar",
+ "Unable to load the comments list" : "Gat ekki hlaðið inn lista yfir athugasemdir",
+ "No comments yet, start the conversation!" : "Engar athugasemdir ennþá, byrjaðu umræðuna!",
+ "No more messages" : "Engin fleiri skilaboð",
+ "Retry" : "Reyna aftur",
+ "_1 new comment_::_{unread} new comments_" : ["1 ný athugasemd","{unread} nýjar athugasemdir"],
+ "Comment" : "Athugasemd",
+ "An error occurred while trying to edit the comment" : "Villa átti sér stað við að breyta athugasemdinni",
+ "Comment deleted" : "Athugasemd var eytt",
+ "An error occurred while trying to delete the comment" : "Villa átti sér stað við að eyða athugasemdinni",
+ "An error occurred while trying to create the comment" : "Villa átti sér stað við að útbúa athugasemdina"
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/it.js b/apps/comments/l10n/it.js
index 56660b5a779..e2aac0c0b86 100644
--- a/apps/comments/l10n/it.js
+++ b/apps/comments/l10n/it.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Commenti</strong> sui file",
+ "Comments" : "Commenti",
"You commented" : "Hai commentato",
- "%1$s commented" : "%1$s ha commentato",
- "You commented on %2$s" : "Hai commentato su %2$s",
+ "{author} commented" : "{author} ha commentato",
+ "You commented on %1$s" : "Hai commentato su %1$s",
+ "You commented on {file}" : "Hai commentato su {file}",
"%1$s commented on %2$s" : "%1$s ha commentato %2$s",
- "Comments" : "Commenti",
- "Type in a new comment..." : "Digita un nuovo commento...",
- "Delete comment" : "Elimina commento",
- "Post" : "Commento",
- "Cancel" : "Annulla",
+ "{author} commented on {file}" : "{author} ha commentato su {file}",
+ "<strong>Comments</strong> for files" : "<strong>Commenti</strong> sui file",
+ "Files" : "File",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Sei stato menzionato su \"{file}\", in un commento di un account che è stato eliminato",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} ti ha menzionato in un commento su \"{file}\"",
+ "Files app plugin to add comments to files" : "Estensione dell'applicazione File per aggiungere commenti ai file",
"Edit comment" : "Modifica commento",
- "[Deleted user]" : "[Utente eliminato]",
- "No other comments available" : "Non sono disponibili altri commenti",
- "More comments..." : "Altri commenti...",
- "Save" : "Salva",
- "Allowed characters {count} of {max}" : "Caratteri consentiti {count} di {max}",
- "{count} unread comments" : "{count} commenti non letti",
- "Comment" : "Commento"
+ "Delete comment" : "Elimina commento",
+ "Cancel edit" : "Annulla modifica",
+ "New comment" : "Nuovo commento",
+ "Write a comment …" : "Scrivi un commento...",
+ "Post comment" : "Pubblica commento",
+ "@ for mentions, : for emoji, / for smart picker" : "@ per menzioni, : per emoji, / per selettore intelligente",
+ "Could not reload comments" : "Impossibile ricaricare i commenti",
+ "Failed to mark comments as read" : "Impossibile segnare i commenti come letti",
+ "Unable to load the comments list" : "Impossibile caricare l'elenco dei commenti",
+ "No comments yet, start the conversation!" : "Ancora nessun commento, inizia la conversazione!",
+ "No more messages" : "Non ci sono altri messaggi",
+ "Retry" : "Riprova",
+ "_1 new comment_::_{unread} new comments_" : ["1 nuovo commento","{unread} nuovi commenti","{unread} nuovi commenti"],
+ "Comment" : "Commento",
+ "An error occurred while trying to edit the comment" : "Si è verificato un errore durante il tentativo di modificare il commento",
+ "Comment deleted" : "Commento eliminato",
+ "An error occurred while trying to delete the comment" : "Si è verificato un errore durante il tentativo di eliminare il commento",
+ "An error occurred while trying to create the comment" : "Si è verificato un errore durante il tentativo di creare il commento"
},
-"nplurals=2; plural=(n != 1);");
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/comments/l10n/it.json b/apps/comments/l10n/it.json
index 8d113baa6e4..09ba85ad60e 100644
--- a/apps/comments/l10n/it.json
+++ b/apps/comments/l10n/it.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Commenti</strong> sui file",
+ "Comments" : "Commenti",
"You commented" : "Hai commentato",
- "%1$s commented" : "%1$s ha commentato",
- "You commented on %2$s" : "Hai commentato su %2$s",
+ "{author} commented" : "{author} ha commentato",
+ "You commented on %1$s" : "Hai commentato su %1$s",
+ "You commented on {file}" : "Hai commentato su {file}",
"%1$s commented on %2$s" : "%1$s ha commentato %2$s",
- "Comments" : "Commenti",
- "Type in a new comment..." : "Digita un nuovo commento...",
- "Delete comment" : "Elimina commento",
- "Post" : "Commento",
- "Cancel" : "Annulla",
+ "{author} commented on {file}" : "{author} ha commentato su {file}",
+ "<strong>Comments</strong> for files" : "<strong>Commenti</strong> sui file",
+ "Files" : "File",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Sei stato menzionato su \"{file}\", in un commento di un account che è stato eliminato",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} ti ha menzionato in un commento su \"{file}\"",
+ "Files app plugin to add comments to files" : "Estensione dell'applicazione File per aggiungere commenti ai file",
"Edit comment" : "Modifica commento",
- "[Deleted user]" : "[Utente eliminato]",
- "No other comments available" : "Non sono disponibili altri commenti",
- "More comments..." : "Altri commenti...",
- "Save" : "Salva",
- "Allowed characters {count} of {max}" : "Caratteri consentiti {count} di {max}",
- "{count} unread comments" : "{count} commenti non letti",
- "Comment" : "Commento"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
+ "Delete comment" : "Elimina commento",
+ "Cancel edit" : "Annulla modifica",
+ "New comment" : "Nuovo commento",
+ "Write a comment …" : "Scrivi un commento...",
+ "Post comment" : "Pubblica commento",
+ "@ for mentions, : for emoji, / for smart picker" : "@ per menzioni, : per emoji, / per selettore intelligente",
+ "Could not reload comments" : "Impossibile ricaricare i commenti",
+ "Failed to mark comments as read" : "Impossibile segnare i commenti come letti",
+ "Unable to load the comments list" : "Impossibile caricare l'elenco dei commenti",
+ "No comments yet, start the conversation!" : "Ancora nessun commento, inizia la conversazione!",
+ "No more messages" : "Non ci sono altri messaggi",
+ "Retry" : "Riprova",
+ "_1 new comment_::_{unread} new comments_" : ["1 nuovo commento","{unread} nuovi commenti","{unread} nuovi commenti"],
+ "Comment" : "Commento",
+ "An error occurred while trying to edit the comment" : "Si è verificato un errore durante il tentativo di modificare il commento",
+ "Comment deleted" : "Commento eliminato",
+ "An error occurred while trying to delete the comment" : "Si è verificato un errore durante il tentativo di eliminare il commento",
+ "An error occurred while trying to create the comment" : "Si è verificato un errore durante il tentativo di creare il commento"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/ja.js b/apps/comments/l10n/ja.js
index ff20dcedbc6..60800bfb5f9 100644
--- a/apps/comments/l10n/ja.js
+++ b/apps/comments/l10n/ja.js
@@ -1,21 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "ファイルについての<strong>コメント</strong>",
- "%1$s commented" : "%1$s がコメントを追加",
- "%1$s commented on %2$s" : "%2$s について、%1$s がコメントしました",
"Comments" : "コメント",
- "Type in a new comment..." : "新しいコメントを入力...",
- "Delete comment" : "コメントを削除",
- "Post" : "追加",
- "Cancel" : "キャンセル",
+ "You commented" : "コメント済",
+ "{author} commented" : "{author} がコメントしました",
+ "You commented on %1$s" : "%1$s についてコメントしました",
+ "You commented on {file}" : "{file} にコメントしました",
+ "%1$s commented on %2$s" : "%2$s について、%1$s がコメントしました",
+ "{author} commented on {file}" : "{author} が{file} にコメントしました",
+ "<strong>Comments</strong> for files" : "ファイルへの<strong>コメント</strong>があったとき",
+ "Files" : "ファイル",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "あなたは \"{file}\" で、削除されたアカウントのコメントで言及されました",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} さんが \"{file}\" のコメント内であなたついて言及しました",
+ "Files app plugin to add comments to files" : "ファイルにコメントを追加するためのファイルアプリプラグイン",
"Edit comment" : "コメントを編集",
- "[Deleted user]" : "[削除済みユーザー]",
- "No other comments available" : "コメントはありません",
- "More comments..." : "コメントをさらに表示...",
- "Save" : "保存",
- "Allowed characters {count} of {max}" : "入力文字数 {count} / {max}",
- "{count} unread comments" : "未読コメント数 {count}",
- "Comment" : "コメント"
+ "Delete comment" : "コメントを削除",
+ "Cancel edit" : "編集をキャンセル",
+ "New comment" : "新しいコメント",
+ "Write a comment …" : "コメントを書く...",
+ "Post comment" : "コメントを投稿",
+ "@ for mentions, : for emoji, / for smart picker" : "メンションには@、絵文字には:、スマートピッカーには/",
+ "Could not reload comments" : "コメントをリロードできませんでした",
+ "Failed to mark comments as read" : "コメントを既読にすることができませんでした",
+ "Unable to load the comments list" : "コメントリストを読み込めませんでした",
+ "No comments yet, start the conversation!" : "まだコメントはありません、会話を開始してください!",
+ "No more messages" : "これ以上のメッセージはありません",
+ "Retry" : "再試行",
+ "_1 new comment_::_{unread} new comments_" : ["の未読のコメント {unread}"],
+ "Comment" : "コメント",
+ "An error occurred while trying to edit the comment" : "コメント編集中にエラーが発生しました",
+ "Comment deleted" : "コメントが削除されました",
+ "An error occurred while trying to delete the comment" : "コメントの削除中にエラーが発生しました",
+ "An error occurred while trying to create the comment" : "コメント中にエラーが発生しました"
},
"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/ja.json b/apps/comments/l10n/ja.json
index 603d2e3d49b..08014639e97 100644
--- a/apps/comments/l10n/ja.json
+++ b/apps/comments/l10n/ja.json
@@ -1,19 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "ファイルについての<strong>コメント</strong>",
- "%1$s commented" : "%1$s がコメントを追加",
- "%1$s commented on %2$s" : "%2$s について、%1$s がコメントしました",
"Comments" : "コメント",
- "Type in a new comment..." : "新しいコメントを入力...",
- "Delete comment" : "コメントを削除",
- "Post" : "追加",
- "Cancel" : "キャンセル",
+ "You commented" : "コメント済",
+ "{author} commented" : "{author} がコメントしました",
+ "You commented on %1$s" : "%1$s についてコメントしました",
+ "You commented on {file}" : "{file} にコメントしました",
+ "%1$s commented on %2$s" : "%2$s について、%1$s がコメントしました",
+ "{author} commented on {file}" : "{author} が{file} にコメントしました",
+ "<strong>Comments</strong> for files" : "ファイルへの<strong>コメント</strong>があったとき",
+ "Files" : "ファイル",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "あなたは \"{file}\" で、削除されたアカウントのコメントで言及されました",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} さんが \"{file}\" のコメント内であなたついて言及しました",
+ "Files app plugin to add comments to files" : "ファイルにコメントを追加するためのファイルアプリプラグイン",
"Edit comment" : "コメントを編集",
- "[Deleted user]" : "[削除済みユーザー]",
- "No other comments available" : "コメントはありません",
- "More comments..." : "コメントをさらに表示...",
- "Save" : "保存",
- "Allowed characters {count} of {max}" : "入力文字数 {count} / {max}",
- "{count} unread comments" : "未読コメント数 {count}",
- "Comment" : "コメント"
+ "Delete comment" : "コメントを削除",
+ "Cancel edit" : "編集をキャンセル",
+ "New comment" : "新しいコメント",
+ "Write a comment …" : "コメントを書く...",
+ "Post comment" : "コメントを投稿",
+ "@ for mentions, : for emoji, / for smart picker" : "メンションには@、絵文字には:、スマートピッカーには/",
+ "Could not reload comments" : "コメントをリロードできませんでした",
+ "Failed to mark comments as read" : "コメントを既読にすることができませんでした",
+ "Unable to load the comments list" : "コメントリストを読み込めませんでした",
+ "No comments yet, start the conversation!" : "まだコメントはありません、会話を開始してください!",
+ "No more messages" : "これ以上のメッセージはありません",
+ "Retry" : "再試行",
+ "_1 new comment_::_{unread} new comments_" : ["の未読のコメント {unread}"],
+ "Comment" : "コメント",
+ "An error occurred while trying to edit the comment" : "コメント編集中にエラーが発生しました",
+ "Comment deleted" : "コメントが削除されました",
+ "An error occurred while trying to delete the comment" : "コメントの削除中にエラーが発生しました",
+ "An error occurred while trying to create the comment" : "コメント中にエラーが発生しました"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/ka.js b/apps/comments/l10n/ka.js
new file mode 100644
index 00000000000..4d721d8441c
--- /dev/null
+++ b/apps/comments/l10n/ka.js
@@ -0,0 +1,32 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Comments",
+ "You commented" : "You commented",
+ "{author} commented" : "{author} commented",
+ "You commented on %1$s" : "You commented on %1$s",
+ "You commented on {file}" : "You commented on {file}",
+ "%1$s commented on %2$s" : "%1$s commented on %2$s",
+ "{author} commented on {file}" : "{author} commented on {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comments</strong> for files",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mentioned you in a comment on \"{file}\"",
+ "Files app plugin to add comments to files" : "Files app plugin to add comments to files",
+ "Edit comment" : "Edit comment",
+ "Delete comment" : "Delete comment",
+ "Cancel edit" : "Cancel edit",
+ "Post comment" : "Post comment",
+ "@ for mentions, : for emoji, / for smart picker" : "@ for mentions, : for emoji, / for smart picker",
+ "Could not reload comments" : "Could not reload comments",
+ "Failed to mark comments as read" : "Failed to mark comments as read",
+ "Unable to load the comments list" : "Unable to load the comments list",
+ "No comments yet, start the conversation!" : "No comments yet, start the conversation!",
+ "No more messages" : "No more messages",
+ "Retry" : "Retry",
+ "_1 new comment_::_{unread} new comments_" : ["1 new comment","{unread} new comments"],
+ "Comment" : "Comment",
+ "An error occurred while trying to edit the comment" : "An error occurred while trying to edit the comment",
+ "Comment deleted" : "Comment deleted",
+ "An error occurred while trying to delete the comment" : "An error occurred while trying to delete the comment",
+ "An error occurred while trying to create the comment" : "An error occurred while trying to create the comment"
+},
+"nplurals=2; plural=(n!=1);");
diff --git a/apps/comments/l10n/ka.json b/apps/comments/l10n/ka.json
new file mode 100644
index 00000000000..a8625a23f7a
--- /dev/null
+++ b/apps/comments/l10n/ka.json
@@ -0,0 +1,30 @@
+{ "translations": {
+ "Comments" : "Comments",
+ "You commented" : "You commented",
+ "{author} commented" : "{author} commented",
+ "You commented on %1$s" : "You commented on %1$s",
+ "You commented on {file}" : "You commented on {file}",
+ "%1$s commented on %2$s" : "%1$s commented on %2$s",
+ "{author} commented on {file}" : "{author} commented on {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comments</strong> for files",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mentioned you in a comment on \"{file}\"",
+ "Files app plugin to add comments to files" : "Files app plugin to add comments to files",
+ "Edit comment" : "Edit comment",
+ "Delete comment" : "Delete comment",
+ "Cancel edit" : "Cancel edit",
+ "Post comment" : "Post comment",
+ "@ for mentions, : for emoji, / for smart picker" : "@ for mentions, : for emoji, / for smart picker",
+ "Could not reload comments" : "Could not reload comments",
+ "Failed to mark comments as read" : "Failed to mark comments as read",
+ "Unable to load the comments list" : "Unable to load the comments list",
+ "No comments yet, start the conversation!" : "No comments yet, start the conversation!",
+ "No more messages" : "No more messages",
+ "Retry" : "Retry",
+ "_1 new comment_::_{unread} new comments_" : ["1 new comment","{unread} new comments"],
+ "Comment" : "Comment",
+ "An error occurred while trying to edit the comment" : "An error occurred while trying to edit the comment",
+ "Comment deleted" : "Comment deleted",
+ "An error occurred while trying to delete the comment" : "An error occurred while trying to delete the comment",
+ "An error occurred while trying to create the comment" : "An error occurred while trying to create the comment"
+},"pluralForm" :"nplurals=2; plural=(n!=1);"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/ka_GE.js b/apps/comments/l10n/ka_GE.js
deleted file mode 100644
index 6eb6c73569b..00000000000
--- a/apps/comments/l10n/ka_GE.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "უარყოფა",
- "Save" : "შენახვა"
-},
-"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/ka_GE.json b/apps/comments/l10n/ka_GE.json
deleted file mode 100644
index a70874ae50b..00000000000
--- a/apps/comments/l10n/ka_GE.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "უარყოფა",
- "Save" : "შენახვა"
-},"pluralForm" :"nplurals=1; plural=0;"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/km.js b/apps/comments/l10n/km.js
deleted file mode 100644
index 16f065c86b3..00000000000
--- a/apps/comments/l10n/km.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "បោះបង់",
- "Save" : "រក្សាទុក"
-},
-"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/km.json b/apps/comments/l10n/km.json
deleted file mode 100644
index 20de21d56a1..00000000000
--- a/apps/comments/l10n/km.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "បោះបង់",
- "Save" : "រក្សាទុក"
-},"pluralForm" :"nplurals=1; plural=0;"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/kn.js b/apps/comments/l10n/kn.js
deleted file mode 100644
index 97a48f9cb3e..00000000000
--- a/apps/comments/l10n/kn.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "ರದ್ದು",
- "Save" : "ಉಳಿಸಿ"
-},
-"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/kn.json b/apps/comments/l10n/kn.json
deleted file mode 100644
index 8a2b49fc262..00000000000
--- a/apps/comments/l10n/kn.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "ರದ್ದು",
- "Save" : "ಉಳಿಸಿ"
-},"pluralForm" :"nplurals=1; plural=0;"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/ko.js b/apps/comments/l10n/ko.js
index c1aafb01d9c..5b75a6eea40 100644
--- a/apps/comments/l10n/ko.js
+++ b/apps/comments/l10n/ko.js
@@ -1,21 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "파일에 <strong>댓글</strong> 남기기",
- "%1$s commented" : "%1$s 님의 댓글",
- "%1$s commented on %2$s" : "%2$s에 %1$s 님이 댓글 남김",
"Comments" : "댓글",
- "Type in a new comment..." : "새 댓글을 입력하십시오...",
- "Delete comment" : "댓글 삭제",
- "Post" : "게시",
- "Cancel" : "취소",
+ "You commented" : "댓글 남김",
+ "{author} commented" : "{author} 님이 댓글 남김",
+ "You commented on %1$s" : "%1$s에 댓글 남김",
+ "You commented on {file}" : "{file}에 댓글 남김",
+ "%1$s commented on %2$s" : "%2$s에 %1$s 님이 댓글 남김",
+ "{author} commented on {file}" : "{author} 님이 {file}에 댓글 남김",
+ "<strong>Comments</strong> for files" : "파일의 <strong>댓글</strong>",
+ "Files" : "파일",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "삭제된 계정이 게시한 “{file}”의 댓글에서 나를 언급함",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} 님이 “{file}”에 남긴 댓글에서 나를 언급함",
+ "Files app plugin to add comments to files" : "파일에 댓글을 남기는 파일 앱 플러그인",
"Edit comment" : "댓글 편집",
- "[Deleted user]" : "[삭제된 사용자]",
- "No other comments available" : "더 이상 댓글 없음",
- "More comments..." : "더 많은 댓글...",
- "Save" : "저장",
- "Allowed characters {count} of {max}" : "{count}/{max} 글자 사용 가능",
- "{count} unread comments" : "읽지 않은 댓글 {count}개",
- "Comment" : "설명"
+ "Delete comment" : "댓글 삭제",
+ "Cancel edit" : "편집 취소",
+ "New comment" : "새로운 댓글",
+ "Write a comment …" : "댓글 쓰기 ...",
+ "Post comment" : "댓글 게시",
+ "@ for mentions, : for emoji, / for smart picker" : "@을 입력해 언급, :을 입력해 이모지 추가, /을 입력해 스마트 피커를 사용하십시오.",
+ "Could not reload comments" : "댓글을 다시 불러올 수 없음",
+ "Failed to mark comments as read" : "댓글을 읽음 표시할 수 없음",
+ "Unable to load the comments list" : "댓글 목록을 불러올 수 없음",
+ "No comments yet, start the conversation!" : "아직 댓글이 없습니다. 대화를 시작하십시오!",
+ "No more messages" : "메시지 더 이상 없음",
+ "Retry" : "다시 시도",
+ "_1 new comment_::_{unread} new comments_" : ["새 댓글 {unread}개"],
+ "Comment" : "설명",
+ "An error occurred while trying to edit the comment" : "댓글을 편집하는 중 오류 발생",
+ "Comment deleted" : "댓글이 삭제됨",
+ "An error occurred while trying to delete the comment" : "댓글을 삭제하는 중 오류 발생",
+ "An error occurred while trying to create the comment" : "댓글을 작성하는 중 오류 발생"
},
"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/ko.json b/apps/comments/l10n/ko.json
index 5ccd0dc52eb..a8aed7edea4 100644
--- a/apps/comments/l10n/ko.json
+++ b/apps/comments/l10n/ko.json
@@ -1,19 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "파일에 <strong>댓글</strong> 남기기",
- "%1$s commented" : "%1$s 님의 댓글",
- "%1$s commented on %2$s" : "%2$s에 %1$s 님이 댓글 남김",
"Comments" : "댓글",
- "Type in a new comment..." : "새 댓글을 입력하십시오...",
- "Delete comment" : "댓글 삭제",
- "Post" : "게시",
- "Cancel" : "취소",
+ "You commented" : "댓글 남김",
+ "{author} commented" : "{author} 님이 댓글 남김",
+ "You commented on %1$s" : "%1$s에 댓글 남김",
+ "You commented on {file}" : "{file}에 댓글 남김",
+ "%1$s commented on %2$s" : "%2$s에 %1$s 님이 댓글 남김",
+ "{author} commented on {file}" : "{author} 님이 {file}에 댓글 남김",
+ "<strong>Comments</strong> for files" : "파일의 <strong>댓글</strong>",
+ "Files" : "파일",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "삭제된 계정이 게시한 “{file}”의 댓글에서 나를 언급함",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} 님이 “{file}”에 남긴 댓글에서 나를 언급함",
+ "Files app plugin to add comments to files" : "파일에 댓글을 남기는 파일 앱 플러그인",
"Edit comment" : "댓글 편집",
- "[Deleted user]" : "[삭제된 사용자]",
- "No other comments available" : "더 이상 댓글 없음",
- "More comments..." : "더 많은 댓글...",
- "Save" : "저장",
- "Allowed characters {count} of {max}" : "{count}/{max} 글자 사용 가능",
- "{count} unread comments" : "읽지 않은 댓글 {count}개",
- "Comment" : "설명"
+ "Delete comment" : "댓글 삭제",
+ "Cancel edit" : "편집 취소",
+ "New comment" : "새로운 댓글",
+ "Write a comment …" : "댓글 쓰기 ...",
+ "Post comment" : "댓글 게시",
+ "@ for mentions, : for emoji, / for smart picker" : "@을 입력해 언급, :을 입력해 이모지 추가, /을 입력해 스마트 피커를 사용하십시오.",
+ "Could not reload comments" : "댓글을 다시 불러올 수 없음",
+ "Failed to mark comments as read" : "댓글을 읽음 표시할 수 없음",
+ "Unable to load the comments list" : "댓글 목록을 불러올 수 없음",
+ "No comments yet, start the conversation!" : "아직 댓글이 없습니다. 대화를 시작하십시오!",
+ "No more messages" : "메시지 더 이상 없음",
+ "Retry" : "다시 시도",
+ "_1 new comment_::_{unread} new comments_" : ["새 댓글 {unread}개"],
+ "Comment" : "설명",
+ "An error occurred while trying to edit the comment" : "댓글을 편집하는 중 오류 발생",
+ "Comment deleted" : "댓글이 삭제됨",
+ "An error occurred while trying to delete the comment" : "댓글을 삭제하는 중 오류 발생",
+ "An error occurred while trying to create the comment" : "댓글을 작성하는 중 오류 발생"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/ku_IQ.js b/apps/comments/l10n/ku_IQ.js
deleted file mode 100644
index bbbe6f95bb1..00000000000
--- a/apps/comments/l10n/ku_IQ.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "لابردن",
- "Save" : "پاشکه‌وتکردن"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/ku_IQ.json b/apps/comments/l10n/ku_IQ.json
deleted file mode 100644
index 1a46f867235..00000000000
--- a/apps/comments/l10n/ku_IQ.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "لابردن",
- "Save" : "پاشکه‌وتکردن"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/lb.js b/apps/comments/l10n/lb.js
deleted file mode 100644
index f63640ac6f7..00000000000
--- a/apps/comments/l10n/lb.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Ofbriechen",
- "Save" : "Späicheren"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/lb.json b/apps/comments/l10n/lb.json
deleted file mode 100644
index c015c4dd2a8..00000000000
--- a/apps/comments/l10n/lb.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "Ofbriechen",
- "Save" : "Späicheren"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/lt_LT.js b/apps/comments/l10n/lt_LT.js
index ef4967e9fcc..c61f36f8af8 100644
--- a/apps/comments/l10n/lt_LT.js
+++ b/apps/comments/l10n/lt_LT.js
@@ -1,8 +1,29 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "Atšaukti",
- "Save" : "Išsaugoti",
- "Comment" : "Komentaras"
+ "Comments" : "Komentarai",
+ "You commented" : "Jūs pakomentavote",
+ "{author} commented" : "{author} pakomentavo",
+ "You commented on %1$s" : "Pakomentavote %1$s",
+ "You commented on {file}" : "Pakomentavote {file}",
+ "%1$s commented on %2$s" : "%1$s pakomentavo %2$s",
+ "{author} commented on {file}" : "{author} pakomentavo {file}",
+ "<strong>Comments</strong> for files" : "Failų <strong>komentarai</strong>",
+ "Files" : "Failai",
+ "Files app plugin to add comments to files" : "Failų programėlės įskiepis, skirtas prie failų pridėti komentarus",
+ "Edit comment" : "Taisyti komentarą",
+ "Delete comment" : "Ištrinti komentarą",
+ "Cancel edit" : "Atsisakyti taisymo",
+ "New comment" : "Naujas komentaras",
+ "Post comment" : "Paskelbti komentarą",
+ "Unable to load the comments list" : "Nepavyko įkelti komentarų sąrašo",
+ "No comments yet, start the conversation!" : "Komentarų kol kas nėra, pradėkite pokalbį!",
+ "Retry" : "Bandyti dar kartą",
+ "_1 new comment_::_{unread} new comments_" : ["1 neskaitytas komentaras","{unread} neskaityti komentarai","{unread} neskaitytų komentarų","{unread} neskaitytas komentaras"],
+ "Comment" : "Komentaras",
+ "An error occurred while trying to edit the comment" : "Bandant taisyti komentarą, įvyko klaida",
+ "Comment deleted" : "Komentaras ištrintas",
+ "An error occurred while trying to delete the comment" : "Bandant ištrinti komentarą, įvyko klaida",
+ "An error occurred while trying to create the comment" : "Bandant sukurti komentarą, įvyko klaida"
},
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);");
+"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);");
diff --git a/apps/comments/l10n/lt_LT.json b/apps/comments/l10n/lt_LT.json
index 59432d7b6b4..eed1892b83d 100644
--- a/apps/comments/l10n/lt_LT.json
+++ b/apps/comments/l10n/lt_LT.json
@@ -1,6 +1,27 @@
{ "translations": {
- "Cancel" : "Atšaukti",
- "Save" : "Išsaugoti",
- "Comment" : "Komentaras"
-},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"
+ "Comments" : "Komentarai",
+ "You commented" : "Jūs pakomentavote",
+ "{author} commented" : "{author} pakomentavo",
+ "You commented on %1$s" : "Pakomentavote %1$s",
+ "You commented on {file}" : "Pakomentavote {file}",
+ "%1$s commented on %2$s" : "%1$s pakomentavo %2$s",
+ "{author} commented on {file}" : "{author} pakomentavo {file}",
+ "<strong>Comments</strong> for files" : "Failų <strong>komentarai</strong>",
+ "Files" : "Failai",
+ "Files app plugin to add comments to files" : "Failų programėlės įskiepis, skirtas prie failų pridėti komentarus",
+ "Edit comment" : "Taisyti komentarą",
+ "Delete comment" : "Ištrinti komentarą",
+ "Cancel edit" : "Atsisakyti taisymo",
+ "New comment" : "Naujas komentaras",
+ "Post comment" : "Paskelbti komentarą",
+ "Unable to load the comments list" : "Nepavyko įkelti komentarų sąrašo",
+ "No comments yet, start the conversation!" : "Komentarų kol kas nėra, pradėkite pokalbį!",
+ "Retry" : "Bandyti dar kartą",
+ "_1 new comment_::_{unread} new comments_" : ["1 neskaitytas komentaras","{unread} neskaityti komentarai","{unread} neskaitytų komentarų","{unread} neskaitytas komentaras"],
+ "Comment" : "Komentaras",
+ "An error occurred while trying to edit the comment" : "Bandant taisyti komentarą, įvyko klaida",
+ "Comment deleted" : "Komentaras ištrintas",
+ "An error occurred while trying to delete the comment" : "Bandant ištrinti komentarą, įvyko klaida",
+ "An error occurred while trying to create the comment" : "Bandant sukurti komentarą, įvyko klaida"
+},"pluralForm" :"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/lv.js b/apps/comments/l10n/lv.js
deleted file mode 100644
index 78665af9a46..00000000000
--- a/apps/comments/l10n/lv.js
+++ /dev/null
@@ -1,8 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Atcelt",
- "Save" : "Saglabāt",
- "Comment" : "Komentārs"
-},
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);");
diff --git a/apps/comments/l10n/lv.json b/apps/comments/l10n/lv.json
deleted file mode 100644
index 0ad41e139cb..00000000000
--- a/apps/comments/l10n/lv.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{ "translations": {
- "Cancel" : "Atcelt",
- "Save" : "Saglabāt",
- "Comment" : "Komentārs"
-},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/mk.js b/apps/comments/l10n/mk.js
index 52277cc9222..9c73793ce49 100644
--- a/apps/comments/l10n/mk.js
+++ b/apps/comments/l10n/mk.js
@@ -1,9 +1,36 @@
OC.L10N.register(
"comments",
{
- "%1$s commented" : "%1$s коментиран",
- "Cancel" : "Откажи",
- "Save" : "Сними",
- "Comment" : "Коментар"
+ "Comments" : "Коментари",
+ "You commented" : "Kоментиравте",
+ "{author} commented" : "{author} коментираше",
+ "You commented on %1$s" : "Коментиравте на %1$s",
+ "You commented on {file}" : "Коментиравте на {file}",
+ "%1$s commented on %2$s" : "%1$s коментираше на %2$s",
+ "{author} commented on {file}" : "{author} коментираше на {file}",
+ "<strong>Comments</strong> for files" : "<strong>Коментари</strong> за датотеки",
+ "Files" : "Датотеки",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Бевте спомнати на “{file}”, во коментар од корисник кој сега е избришан",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} те спомна во коментар на датотеката “{file}”",
+ "Files app plugin to add comments to files" : "Додади додаток за коментирање на датотеки",
+ "Edit comment" : "Измени го коментарот",
+ "Delete comment" : "Избриши коментар",
+ "Cancel edit" : "Откажи ажурирање",
+ "New comment" : "Нов коментар",
+ "Write a comment …" : "Напиши коментар ...",
+ "Post comment" : "Објави коментар",
+ "@ for mentions, : for emoji, / for smart picker" : "@ за спомнување, : за емоција, / за паметен избор",
+ "Could not reload comments" : "Неможе да се вчитаат коментарите",
+ "Failed to mark comments as read" : "Неуспешно означување на коментарот како прочитан",
+ "Unable to load the comments list" : "Неможе да се вчита листата на коментари",
+ "No comments yet, start the conversation!" : "Сеуште нема коментари, започнете разговор!",
+ "No more messages" : "Нема повеќе пораки",
+ "Retry" : "Обидете се повторно",
+ "_1 new comment_::_{unread} new comments_" : ["1 нов коментар","{unread} нови коментари"],
+ "Comment" : "Коментар",
+ "An error occurred while trying to edit the comment" : "Настана грешка при обид за ажурирање на коментар",
+ "Comment deleted" : "Коментарот е избришан",
+ "An error occurred while trying to delete the comment" : "Настана грешка при обидот за бришење на коментар",
+ "An error occurred while trying to create the comment" : "Настана грешка при обидот за креирање на коментар"
},
"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;");
diff --git a/apps/comments/l10n/mk.json b/apps/comments/l10n/mk.json
index 9a3b69b499a..5cd8c7b1076 100644
--- a/apps/comments/l10n/mk.json
+++ b/apps/comments/l10n/mk.json
@@ -1,7 +1,34 @@
{ "translations": {
- "%1$s commented" : "%1$s коментиран",
- "Cancel" : "Откажи",
- "Save" : "Сними",
- "Comment" : "Коментар"
+ "Comments" : "Коментари",
+ "You commented" : "Kоментиравте",
+ "{author} commented" : "{author} коментираше",
+ "You commented on %1$s" : "Коментиравте на %1$s",
+ "You commented on {file}" : "Коментиравте на {file}",
+ "%1$s commented on %2$s" : "%1$s коментираше на %2$s",
+ "{author} commented on {file}" : "{author} коментираше на {file}",
+ "<strong>Comments</strong> for files" : "<strong>Коментари</strong> за датотеки",
+ "Files" : "Датотеки",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Бевте спомнати на “{file}”, во коментар од корисник кој сега е избришан",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} те спомна во коментар на датотеката “{file}”",
+ "Files app plugin to add comments to files" : "Додади додаток за коментирање на датотеки",
+ "Edit comment" : "Измени го коментарот",
+ "Delete comment" : "Избриши коментар",
+ "Cancel edit" : "Откажи ажурирање",
+ "New comment" : "Нов коментар",
+ "Write a comment …" : "Напиши коментар ...",
+ "Post comment" : "Објави коментар",
+ "@ for mentions, : for emoji, / for smart picker" : "@ за спомнување, : за емоција, / за паметен избор",
+ "Could not reload comments" : "Неможе да се вчитаат коментарите",
+ "Failed to mark comments as read" : "Неуспешно означување на коментарот како прочитан",
+ "Unable to load the comments list" : "Неможе да се вчита листата на коментари",
+ "No comments yet, start the conversation!" : "Сеуште нема коментари, започнете разговор!",
+ "No more messages" : "Нема повеќе пораки",
+ "Retry" : "Обидете се повторно",
+ "_1 new comment_::_{unread} new comments_" : ["1 нов коментар","{unread} нови коментари"],
+ "Comment" : "Коментар",
+ "An error occurred while trying to edit the comment" : "Настана грешка при обид за ажурирање на коментар",
+ "Comment deleted" : "Коментарот е избришан",
+ "An error occurred while trying to delete the comment" : "Настана грешка при обидот за бришење на коментар",
+ "An error occurred while trying to create the comment" : "Настана грешка при обидот за креирање на коментар"
},"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/mn.js b/apps/comments/l10n/mn.js
deleted file mode 100644
index 44deab30ac4..00000000000
--- a/apps/comments/l10n/mn.js
+++ /dev/null
@@ -1,6 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Save" : "Хадгалах"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/mn.json b/apps/comments/l10n/mn.json
deleted file mode 100644
index 09df2456611..00000000000
--- a/apps/comments/l10n/mn.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{ "translations": {
- "Save" : "Хадгалах"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/ms_MY.js b/apps/comments/l10n/ms_MY.js
deleted file mode 100644
index 37e8518632d..00000000000
--- a/apps/comments/l10n/ms_MY.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Batal",
- "Save" : "Simpan"
-},
-"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/ms_MY.json b/apps/comments/l10n/ms_MY.json
deleted file mode 100644
index dd6b20cbd7b..00000000000
--- a/apps/comments/l10n/ms_MY.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "Batal",
- "Save" : "Simpan"
-},"pluralForm" :"nplurals=1; plural=0;"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/my_MM.js b/apps/comments/l10n/my_MM.js
deleted file mode 100644
index 2fd6d1d1a9c..00000000000
--- a/apps/comments/l10n/my_MM.js
+++ /dev/null
@@ -1,6 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "ပယ်ဖျက်မည်"
-},
-"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/my_MM.json b/apps/comments/l10n/my_MM.json
deleted file mode 100644
index 28a85e87b39..00000000000
--- a/apps/comments/l10n/my_MM.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{ "translations": {
- "Cancel" : "ပယ်ဖျက်မည်"
-},"pluralForm" :"nplurals=1; plural=0;"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/nb.js b/apps/comments/l10n/nb.js
new file mode 100644
index 00000000000..dcc1127639a
--- /dev/null
+++ b/apps/comments/l10n/nb.js
@@ -0,0 +1,36 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Kommentarer",
+ "You commented" : "Du kommenterte",
+ "{author} commented" : "{author} kommenterte",
+ "You commented on %1$s" : "Du kommenterte på %1$s",
+ "You commented on {file}" : "Du kommenterte på {file}",
+ "%1$s commented on %2$s" : "%1$s kommenterte %2$s",
+ "{author} commented on {file}" : "{author} kommenterte på {file}",
+ "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> for filer",
+ "Files" : "Filer",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Du ble nevnt på \"{file}\", i en kommentar av en konto som siden har blitt slettet",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} nevnte deg i en kommentar til \"{file}\"",
+ "Files app plugin to add comments to files" : "Tillegg for å legge til kommentarer til filer",
+ "Edit comment" : "Rediger kommentar",
+ "Delete comment" : "Slett kommentar",
+ "Cancel edit" : "Avbryt endring",
+ "New comment" : "Ny kommentar",
+ "Write a comment …" : "Skriv en kommentar...",
+ "Post comment" : "Send kommentar",
+ "@ for mentions, : for emoji, / for smart picker" : "@ for nevner, : for emoji, / for smartvelger",
+ "Could not reload comments" : "Kunne ikke laste inn kommentarene på nytt",
+ "Failed to mark comments as read" : "Markering av kommentarer som lest feilet",
+ "Unable to load the comments list" : "Kan ikke laste inn kommentarlisten",
+ "No comments yet, start the conversation!" : "Ingen kommentarer enda, start diskusjonen!",
+ "No more messages" : "Ingen flere meldinger",
+ "Retry" : "Prøv igjen",
+ "_1 new comment_::_{unread} new comments_" : ["[uleste] nye kommentarer","{unread} nye kommentarer"],
+ "Comment" : "Kommentar",
+ "An error occurred while trying to edit the comment" : "Det oppsto en feil under forsøk på å redigere kommentaren",
+ "Comment deleted" : "Kommentar slettet",
+ "An error occurred while trying to delete the comment" : "Det oppsto en feil under forsøk på å slette kommentaren",
+ "An error occurred while trying to create the comment" : "Det oppsto en feil under forsøket på å opprette kommentaren"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/nb.json b/apps/comments/l10n/nb.json
new file mode 100644
index 00000000000..84c7337798d
--- /dev/null
+++ b/apps/comments/l10n/nb.json
@@ -0,0 +1,34 @@
+{ "translations": {
+ "Comments" : "Kommentarer",
+ "You commented" : "Du kommenterte",
+ "{author} commented" : "{author} kommenterte",
+ "You commented on %1$s" : "Du kommenterte på %1$s",
+ "You commented on {file}" : "Du kommenterte på {file}",
+ "%1$s commented on %2$s" : "%1$s kommenterte %2$s",
+ "{author} commented on {file}" : "{author} kommenterte på {file}",
+ "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> for filer",
+ "Files" : "Filer",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Du ble nevnt på \"{file}\", i en kommentar av en konto som siden har blitt slettet",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} nevnte deg i en kommentar til \"{file}\"",
+ "Files app plugin to add comments to files" : "Tillegg for å legge til kommentarer til filer",
+ "Edit comment" : "Rediger kommentar",
+ "Delete comment" : "Slett kommentar",
+ "Cancel edit" : "Avbryt endring",
+ "New comment" : "Ny kommentar",
+ "Write a comment …" : "Skriv en kommentar...",
+ "Post comment" : "Send kommentar",
+ "@ for mentions, : for emoji, / for smart picker" : "@ for nevner, : for emoji, / for smartvelger",
+ "Could not reload comments" : "Kunne ikke laste inn kommentarene på nytt",
+ "Failed to mark comments as read" : "Markering av kommentarer som lest feilet",
+ "Unable to load the comments list" : "Kan ikke laste inn kommentarlisten",
+ "No comments yet, start the conversation!" : "Ingen kommentarer enda, start diskusjonen!",
+ "No more messages" : "Ingen flere meldinger",
+ "Retry" : "Prøv igjen",
+ "_1 new comment_::_{unread} new comments_" : ["[uleste] nye kommentarer","{unread} nye kommentarer"],
+ "Comment" : "Kommentar",
+ "An error occurred while trying to edit the comment" : "Det oppsto en feil under forsøk på å redigere kommentaren",
+ "Comment deleted" : "Kommentar slettet",
+ "An error occurred while trying to delete the comment" : "Det oppsto en feil under forsøk på å slette kommentaren",
+ "An error occurred while trying to create the comment" : "Det oppsto en feil under forsøket på å opprette kommentaren"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/nb_NO.js b/apps/comments/l10n/nb_NO.js
deleted file mode 100644
index 5d3732da827..00000000000
--- a/apps/comments/l10n/nb_NO.js
+++ /dev/null
@@ -1,21 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> for filer",
- "%1$s commented" : "%1$s kommentert",
- "%1$s commented on %2$s" : "%1$s kommenterte %2$s",
- "Comments" : "Kommentarer",
- "Type in a new comment..." : "Skriv inn en ny kommentar...",
- "Delete comment" : "Slett kommentar",
- "Post" : "Send",
- "Cancel" : "Avbryt",
- "Edit comment" : "Rediger kommentar",
- "[Deleted user]" : "[Slettet bruker]",
- "No other comments available" : "Ingen andre kommentarer tilgjengelig",
- "More comments..." : "Flere kommentarer..",
- "Save" : "Lagre",
- "Allowed characters {count} of {max}" : "Antall tegn tillatt {count} av {max}",
- "{count} unread comments" : "{count} uleste kommentarer",
- "Comment" : "Kommentar"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/nb_NO.json b/apps/comments/l10n/nb_NO.json
deleted file mode 100644
index 80724fff6de..00000000000
--- a/apps/comments/l10n/nb_NO.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> for filer",
- "%1$s commented" : "%1$s kommentert",
- "%1$s commented on %2$s" : "%1$s kommenterte %2$s",
- "Comments" : "Kommentarer",
- "Type in a new comment..." : "Skriv inn en ny kommentar...",
- "Delete comment" : "Slett kommentar",
- "Post" : "Send",
- "Cancel" : "Avbryt",
- "Edit comment" : "Rediger kommentar",
- "[Deleted user]" : "[Slettet bruker]",
- "No other comments available" : "Ingen andre kommentarer tilgjengelig",
- "More comments..." : "Flere kommentarer..",
- "Save" : "Lagre",
- "Allowed characters {count} of {max}" : "Antall tegn tillatt {count} av {max}",
- "{count} unread comments" : "{count} uleste kommentarer",
- "Comment" : "Kommentar"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/nds.js b/apps/comments/l10n/nds.js
deleted file mode 100644
index 9fc7bc4cfe2..00000000000
--- a/apps/comments/l10n/nds.js
+++ /dev/null
@@ -1,6 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Abbrechen"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/nds.json b/apps/comments/l10n/nds.json
deleted file mode 100644
index 8c981f87994..00000000000
--- a/apps/comments/l10n/nds.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{ "translations": {
- "Cancel" : "Abbrechen"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/nl.js b/apps/comments/l10n/nl.js
index eb9faf55e1a..cb42f547b7c 100644
--- a/apps/comments/l10n/nl.js
+++ b/apps/comments/l10n/nl.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Reacties</strong> voor bestanden",
- "You commented" : "U heeft gereageerd",
- "%1$s commented" : "%1$s heeft gereageerd",
- "You commented on %2$s" : "U heeft gereageerd op %2$s",
- "%1$s commented on %2$s" : "%1$s heeft gereageerd op %2$s",
"Comments" : "Reacties",
- "Type in a new comment..." : "Type een nieuwe reactie...",
- "Delete comment" : "Verwijder reactie",
- "Post" : "Reageer",
- "Cancel" : "Annuleren",
- "Edit comment" : "Bewerk reactie",
- "[Deleted user]" : "[Verwijderde gebruiker]",
- "No other comments available" : "Geen andere reacties beschikbaar",
- "More comments..." : "Meer reacties...",
- "Save" : "Opslaan",
- "Allowed characters {count} of {max}" : "{count} van de {max} toegestane tekens",
- "{count} unread comments" : "{count} ongelezen reacties",
- "Comment" : "Reactie"
+ "You commented" : "Je reageerde",
+ "{author} commented" : "{author} reageerde",
+ "You commented on %1$s" : "Je reageerde op %1$s",
+ "You commented on {file}" : "Je reageerde op {file}",
+ "%1$s commented on %2$s" : "%1$s heeft gereageerd op %2$s",
+ "{author} commented on {file}" : "{author} reageerde op {file}",
+ "<strong>Comments</strong> for files" : "<strong>Reacties</strong> voor bestanden",
+ "Files" : "Bestanden",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Je werd genoemd op \"{file}\", in een opmerking van een account dat intussen is verwijderd",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} noemde jou in een reactie op \"{file}\"",
+ "Files app plugin to add comments to files" : "Bestanden app plugin om reacties aan bestanden toe te voegen",
+ "Edit comment" : "Reactie bewerken",
+ "Delete comment" : "Reactie verwijderen",
+ "Cancel edit" : "Bewerking annuleren",
+ "New comment" : "Nieuwe reactie",
+ "Write a comment …" : "Schrijf een reactie…",
+ "Post comment" : "Reactie plaatsen",
+ "@ for mentions, : for emoji, / for smart picker" : "@ voor vermeldingen, : voor emoji, / voor Smart Picker",
+ "Could not reload comments" : "Kon reactie niet opnieuw laden",
+ "Failed to mark comments as read" : "Kon reacties niet als gelezen markeren",
+ "Unable to load the comments list" : "Kan reactielijst niet laden",
+ "No comments yet, start the conversation!" : "Nog geen reacties, start de discussie!",
+ "No more messages" : "Geen berichten meer",
+ "Retry" : "Opnieuw proberen",
+ "_1 new comment_::_{unread} new comments_" : ["1 nieuwe reactie","{unread} nieuwe reacties"],
+ "Comment" : "Reactie",
+ "An error occurred while trying to edit the comment" : "Er is een fout opgetreden bij het bewerken van de reactie",
+ "Comment deleted" : "Reactie verwijderd",
+ "An error occurred while trying to delete the comment" : "Er is een fout opgetreden bij het verwijderen van de reactie",
+ "An error occurred while trying to create the comment" : "Er is een fout opgetreden bij het aanmaken van de reactie"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/nl.json b/apps/comments/l10n/nl.json
index d2a811207f6..6d660138be1 100644
--- a/apps/comments/l10n/nl.json
+++ b/apps/comments/l10n/nl.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Reacties</strong> voor bestanden",
- "You commented" : "U heeft gereageerd",
- "%1$s commented" : "%1$s heeft gereageerd",
- "You commented on %2$s" : "U heeft gereageerd op %2$s",
- "%1$s commented on %2$s" : "%1$s heeft gereageerd op %2$s",
"Comments" : "Reacties",
- "Type in a new comment..." : "Type een nieuwe reactie...",
- "Delete comment" : "Verwijder reactie",
- "Post" : "Reageer",
- "Cancel" : "Annuleren",
- "Edit comment" : "Bewerk reactie",
- "[Deleted user]" : "[Verwijderde gebruiker]",
- "No other comments available" : "Geen andere reacties beschikbaar",
- "More comments..." : "Meer reacties...",
- "Save" : "Opslaan",
- "Allowed characters {count} of {max}" : "{count} van de {max} toegestane tekens",
- "{count} unread comments" : "{count} ongelezen reacties",
- "Comment" : "Reactie"
+ "You commented" : "Je reageerde",
+ "{author} commented" : "{author} reageerde",
+ "You commented on %1$s" : "Je reageerde op %1$s",
+ "You commented on {file}" : "Je reageerde op {file}",
+ "%1$s commented on %2$s" : "%1$s heeft gereageerd op %2$s",
+ "{author} commented on {file}" : "{author} reageerde op {file}",
+ "<strong>Comments</strong> for files" : "<strong>Reacties</strong> voor bestanden",
+ "Files" : "Bestanden",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Je werd genoemd op \"{file}\", in een opmerking van een account dat intussen is verwijderd",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} noemde jou in een reactie op \"{file}\"",
+ "Files app plugin to add comments to files" : "Bestanden app plugin om reacties aan bestanden toe te voegen",
+ "Edit comment" : "Reactie bewerken",
+ "Delete comment" : "Reactie verwijderen",
+ "Cancel edit" : "Bewerking annuleren",
+ "New comment" : "Nieuwe reactie",
+ "Write a comment …" : "Schrijf een reactie…",
+ "Post comment" : "Reactie plaatsen",
+ "@ for mentions, : for emoji, / for smart picker" : "@ voor vermeldingen, : voor emoji, / voor Smart Picker",
+ "Could not reload comments" : "Kon reactie niet opnieuw laden",
+ "Failed to mark comments as read" : "Kon reacties niet als gelezen markeren",
+ "Unable to load the comments list" : "Kan reactielijst niet laden",
+ "No comments yet, start the conversation!" : "Nog geen reacties, start de discussie!",
+ "No more messages" : "Geen berichten meer",
+ "Retry" : "Opnieuw proberen",
+ "_1 new comment_::_{unread} new comments_" : ["1 nieuwe reactie","{unread} nieuwe reacties"],
+ "Comment" : "Reactie",
+ "An error occurred while trying to edit the comment" : "Er is een fout opgetreden bij het bewerken van de reactie",
+ "Comment deleted" : "Reactie verwijderd",
+ "An error occurred while trying to delete the comment" : "Er is een fout opgetreden bij het verwijderen van de reactie",
+ "An error occurred while trying to create the comment" : "Er is een fout opgetreden bij het aanmaken van de reactie"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/nn_NO.js b/apps/comments/l10n/nn_NO.js
deleted file mode 100644
index ce79cf242bc..00000000000
--- a/apps/comments/l10n/nn_NO.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Avbryt",
- "Save" : "Lagra"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/nn_NO.json b/apps/comments/l10n/nn_NO.json
deleted file mode 100644
index 51f3ed49364..00000000000
--- a/apps/comments/l10n/nn_NO.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "Avbryt",
- "Save" : "Lagra"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/oc.js b/apps/comments/l10n/oc.js
index 7311b7fd7a4..cee38c3d2ec 100644
--- a/apps/comments/l10n/oc.js
+++ b/apps/comments/l10n/oc.js
@@ -1,8 +1,28 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "Anullar",
- "Save" : "Enregistrar",
- "Comment" : "Comentar"
+ "Comments" : "Comentaris",
+ "You commented" : "Avètz comentat",
+ "{author} commented" : "{author} a comentat",
+ "You commented on %1$s" : "Comentèretz %1$s",
+ "You commented on {file}" : "Comentèretz {file}",
+ "%1$s commented on %2$s" : "%1$s comentèt %2$s",
+ "{author} commented on {file}" : "{author} comentèt {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentaris</strong> de fichièrs",
+ "Files app plugin to add comments to files" : "Extension d’aplication Fichièrs per apondre de comentaris als fichièrs",
+ "Edit comment" : "Modificar lo comentari",
+ "Delete comment" : "Suprimir lo comentari",
+ "Cancel edit" : "Anullar la modificacion",
+ "Post comment" : "Publicar lo comentari",
+ "Unable to load the comments list" : "Cargament impossible de la lista dels comentaris",
+ "No comments yet, start the conversation!" : "Cap de comentari pel moment, començat la conversacion !",
+ "No more messages" : "Pas mai de messatge",
+ "Retry" : "Tornar ensajar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentari novèl","{unread} comentaris novèls"],
+ "Comment" : "Comentar",
+ "An error occurred while trying to edit the comment" : "Error en ensajant de modificar lo comentari",
+ "Comment deleted" : "Comentari suprimit",
+ "An error occurred while trying to delete the comment" : "Error en ensajant de suprimir lo comentari",
+ "An error occurred while trying to create the comment" : "Error en ensajant de crear lo comentari"
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/comments/l10n/oc.json b/apps/comments/l10n/oc.json
index 21f0098bf30..5d4636fb27e 100644
--- a/apps/comments/l10n/oc.json
+++ b/apps/comments/l10n/oc.json
@@ -1,6 +1,26 @@
{ "translations": {
- "Cancel" : "Anullar",
- "Save" : "Enregistrar",
- "Comment" : "Comentar"
+ "Comments" : "Comentaris",
+ "You commented" : "Avètz comentat",
+ "{author} commented" : "{author} a comentat",
+ "You commented on %1$s" : "Comentèretz %1$s",
+ "You commented on {file}" : "Comentèretz {file}",
+ "%1$s commented on %2$s" : "%1$s comentèt %2$s",
+ "{author} commented on {file}" : "{author} comentèt {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentaris</strong> de fichièrs",
+ "Files app plugin to add comments to files" : "Extension d’aplication Fichièrs per apondre de comentaris als fichièrs",
+ "Edit comment" : "Modificar lo comentari",
+ "Delete comment" : "Suprimir lo comentari",
+ "Cancel edit" : "Anullar la modificacion",
+ "Post comment" : "Publicar lo comentari",
+ "Unable to load the comments list" : "Cargament impossible de la lista dels comentaris",
+ "No comments yet, start the conversation!" : "Cap de comentari pel moment, començat la conversacion !",
+ "No more messages" : "Pas mai de messatge",
+ "Retry" : "Tornar ensajar",
+ "_1 new comment_::_{unread} new comments_" : ["1 comentari novèl","{unread} comentaris novèls"],
+ "Comment" : "Comentar",
+ "An error occurred while trying to edit the comment" : "Error en ensajant de modificar lo comentari",
+ "Comment deleted" : "Comentari suprimit",
+ "An error occurred while trying to delete the comment" : "Error en ensajant de suprimir lo comentari",
+ "An error occurred while trying to create the comment" : "Error en ensajant de crear lo comentari"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/pa.js b/apps/comments/l10n/pa.js
deleted file mode 100644
index 98e2affcd12..00000000000
--- a/apps/comments/l10n/pa.js
+++ /dev/null
@@ -1,6 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "ਰੱਦ ਕਰੋ"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/pa.json b/apps/comments/l10n/pa.json
deleted file mode 100644
index 2472134c5f2..00000000000
--- a/apps/comments/l10n/pa.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{ "translations": {
- "Cancel" : "ਰੱਦ ਕਰੋ"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/pl.js b/apps/comments/l10n/pl.js
index 09142286773..918cfffa852 100644
--- a/apps/comments/l10n/pl.js
+++ b/apps/comments/l10n/pl.js
@@ -1,21 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Komentarze</strong> dla plików",
- "%1$s commented" : "%1$s skomentował",
- "%1$s commented on %2$s" : "%1$s skomentował %2$s",
"Comments" : "Komentarze",
- "Type in a new comment..." : "Wprowadź nowy komentarz...",
- "Delete comment" : "Skasuj komentarz",
- "Post" : "Zapisz",
- "Cancel" : "Anuluj",
+ "You commented" : "Skomentowałeś",
+ "{author} commented" : "{author} skomentował",
+ "You commented on %1$s" : "Skomentowałeś w %1$s",
+ "You commented on {file}" : "Skomentowałeś w {file}",
+ "%1$s commented on %2$s" : "%1$s skomentował %2$s",
+ "{author} commented on {file}" : "{author} skomentował w {file}",
+ "<strong>Comments</strong> for files" : "<strong>Komentarze</strong> dla plików",
+ "Files" : "Pliki",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Wspomniano o Tobie w „{file}” w komentarzu konta, które zostało już usunięte",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} wspomniał o Tobie w komentarzu do “{file}”",
+ "Files app plugin to add comments to files" : "Plugin umożliwiający dodawanie komentarzy w aplikacji Pliki",
"Edit comment" : "Edytuj komentarz",
- "[Deleted user]" : "[Usunięty użytkownik]",
- "No other comments available" : "Nie ma więcej komentarzy",
- "More comments..." : "Więcej komentarzy...",
- "Save" : "Zapisz",
- "Allowed characters {count} of {max}" : "Dozwolone znaki {count} z {max}",
- "{count} unread comments" : "{count} nieprzeczytanych komentarzy",
- "Comment" : "Komentarz"
+ "Delete comment" : "Usuń komentarz",
+ "Cancel edit" : "Anuluj edycję",
+ "New comment" : "Nowy komentarz",
+ "Write a comment …" : "Napisz komentarz…",
+ "Post comment" : "Wyślij komentarz",
+ "@ for mentions, : for emoji, / for smart picker" : "@ dla wzmianek, : dla emoji, / dla inteligentnego wybierania",
+ "Could not reload comments" : "Nie można ponownie wczytać komentarzy",
+ "Failed to mark comments as read" : "Nie udało się oznaczyć komentarzy jako przeczytane",
+ "Unable to load the comments list" : "Nie można załadować listy komentarzy",
+ "No comments yet, start the conversation!" : "Brak komentarzy, rozpocznij rozmowę!",
+ "No more messages" : "Nie ma więcej wiadomości",
+ "Retry" : "Powtórz",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} nowy komentarz","{unread} nowe komentarze","{unread} nowych komentarzy","{unread} nowe komentarze"],
+ "Comment" : "Komentarz",
+ "An error occurred while trying to edit the comment" : "Wystąpił błąd podczas próby edycji komentarza",
+ "Comment deleted" : "Komentarz usunięty",
+ "An error occurred while trying to delete the comment" : "Wystąpił błąd podczas próby usunięcia komentarza",
+ "An error occurred while trying to create the comment" : "Wystąpił błąd podczas próby utworzenia komentarza"
},
-"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
+"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);");
diff --git a/apps/comments/l10n/pl.json b/apps/comments/l10n/pl.json
index 92b9f66bf1c..a541f40224a 100644
--- a/apps/comments/l10n/pl.json
+++ b/apps/comments/l10n/pl.json
@@ -1,19 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Komentarze</strong> dla plików",
- "%1$s commented" : "%1$s skomentował",
- "%1$s commented on %2$s" : "%1$s skomentował %2$s",
"Comments" : "Komentarze",
- "Type in a new comment..." : "Wprowadź nowy komentarz...",
- "Delete comment" : "Skasuj komentarz",
- "Post" : "Zapisz",
- "Cancel" : "Anuluj",
+ "You commented" : "Skomentowałeś",
+ "{author} commented" : "{author} skomentował",
+ "You commented on %1$s" : "Skomentowałeś w %1$s",
+ "You commented on {file}" : "Skomentowałeś w {file}",
+ "%1$s commented on %2$s" : "%1$s skomentował %2$s",
+ "{author} commented on {file}" : "{author} skomentował w {file}",
+ "<strong>Comments</strong> for files" : "<strong>Komentarze</strong> dla plików",
+ "Files" : "Pliki",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Wspomniano o Tobie w „{file}” w komentarzu konta, które zostało już usunięte",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} wspomniał o Tobie w komentarzu do “{file}”",
+ "Files app plugin to add comments to files" : "Plugin umożliwiający dodawanie komentarzy w aplikacji Pliki",
"Edit comment" : "Edytuj komentarz",
- "[Deleted user]" : "[Usunięty użytkownik]",
- "No other comments available" : "Nie ma więcej komentarzy",
- "More comments..." : "Więcej komentarzy...",
- "Save" : "Zapisz",
- "Allowed characters {count} of {max}" : "Dozwolone znaki {count} z {max}",
- "{count} unread comments" : "{count} nieprzeczytanych komentarzy",
- "Comment" : "Komentarz"
-},"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
+ "Delete comment" : "Usuń komentarz",
+ "Cancel edit" : "Anuluj edycję",
+ "New comment" : "Nowy komentarz",
+ "Write a comment …" : "Napisz komentarz…",
+ "Post comment" : "Wyślij komentarz",
+ "@ for mentions, : for emoji, / for smart picker" : "@ dla wzmianek, : dla emoji, / dla inteligentnego wybierania",
+ "Could not reload comments" : "Nie można ponownie wczytać komentarzy",
+ "Failed to mark comments as read" : "Nie udało się oznaczyć komentarzy jako przeczytane",
+ "Unable to load the comments list" : "Nie można załadować listy komentarzy",
+ "No comments yet, start the conversation!" : "Brak komentarzy, rozpocznij rozmowę!",
+ "No more messages" : "Nie ma więcej wiadomości",
+ "Retry" : "Powtórz",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} nowy komentarz","{unread} nowe komentarze","{unread} nowych komentarzy","{unread} nowe komentarze"],
+ "Comment" : "Komentarz",
+ "An error occurred while trying to edit the comment" : "Wystąpił błąd podczas próby edycji komentarza",
+ "Comment deleted" : "Komentarz usunięty",
+ "An error occurred while trying to delete the comment" : "Wystąpił błąd podczas próby usunięcia komentarza",
+ "An error occurred while trying to create the comment" : "Wystąpił błąd podczas próby utworzenia komentarza"
+},"pluralForm" :"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/pt_BR.js b/apps/comments/l10n/pt_BR.js
index 9d143822a99..035edefd0bc 100644
--- a/apps/comments/l10n/pt_BR.js
+++ b/apps/comments/l10n/pt_BR.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Comentários</strong> por arquivos",
- "You commented" : "Você comentou",
- "%1$s commented" : "%1$s comentado",
- "You commented on %2$s" : "Você comentou em %2$s",
- "%1$s commented on %2$s" : "%1$s comentado em %2$s",
"Comments" : "Comentários",
- "Type in a new comment..." : "Digite um novo comentário...",
- "Delete comment" : "Apague o comentário",
- "Post" : "Postar",
- "Cancel" : "Cancelar",
+ "You commented" : "Você comentou",
+ "{author} commented" : "{author} comentou",
+ "You commented on %1$s" : "Você comentou em %1$s",
+ "You commented on {file}" : "Você comentou sobre {file}",
+ "%1$s commented on %2$s" : "%1$s comentaram em %2$s",
+ "{author} commented on {file}" : "{author} comentou em {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentários</strong> para arquivos",
+ "Files" : "Arquivos",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Você foi mencionado em \"{file}\", em um comentário de uma conta que já foi excluída",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mencionou você em um comentário sobre \"{file}\"",
+ "Files app plugin to add comments to files" : "Complemento do aplicativo Files para adicionar comentários",
"Edit comment" : "Editar comentário",
- "[Deleted user]" : "[Usuário eliminado]",
- "No other comments available" : "Nenhum outro comentário disponível",
- "More comments..." : "Mais comentários...",
- "Save" : "Salvar",
- "Allowed characters {count} of {max}" : "Caracteres permitidos {count} de {max}",
- "{count} unread comments" : "{count} comentários não lidos",
- "Comment" : "Comentário"
+ "Delete comment" : "Excluir comentário",
+ "Cancel edit" : "Cancelar edição",
+ "New comment" : "Novo comentário",
+ "Write a comment …" : "Escreva um comentário …",
+ "Post comment" : "Postar comentário",
+ "@ for mentions, : for emoji, / for smart picker" : "@ para menções, : para emoji, / para seletor inteligente",
+ "Could not reload comments" : "Não foi possível recarregar comentários",
+ "Failed to mark comments as read" : "Falha ao marcar comentários como lidos",
+ "Unable to load the comments list" : "Não foi possível carregar a lista de comentários",
+ "No comments yet, start the conversation!" : "Nenhum comentário ainda, inicie uma conversa!",
+ "No more messages" : "Sem mais mensagens",
+ "Retry" : "Tentar novamente",
+ "_1 new comment_::_{unread} new comments_" : ["1 novo comentário","{unread} novos comentários","{unread} novos comentários"],
+ "Comment" : "Comentar",
+ "An error occurred while trying to edit the comment" : "Ocorreu um erro ao tentar editar o comentário",
+ "Comment deleted" : "Comentário excluído",
+ "An error occurred while trying to delete the comment" : "Ocorreu um erro ao tentar excluir o comentário",
+ "An error occurred while trying to create the comment" : "Ocorreu um erro ao tentar criar o comentário"
},
-"nplurals=2; plural=(n > 1);");
+"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/comments/l10n/pt_BR.json b/apps/comments/l10n/pt_BR.json
index 10b32799a54..c1cb3d4c814 100644
--- a/apps/comments/l10n/pt_BR.json
+++ b/apps/comments/l10n/pt_BR.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Comentários</strong> por arquivos",
- "You commented" : "Você comentou",
- "%1$s commented" : "%1$s comentado",
- "You commented on %2$s" : "Você comentou em %2$s",
- "%1$s commented on %2$s" : "%1$s comentado em %2$s",
"Comments" : "Comentários",
- "Type in a new comment..." : "Digite um novo comentário...",
- "Delete comment" : "Apague o comentário",
- "Post" : "Postar",
- "Cancel" : "Cancelar",
+ "You commented" : "Você comentou",
+ "{author} commented" : "{author} comentou",
+ "You commented on %1$s" : "Você comentou em %1$s",
+ "You commented on {file}" : "Você comentou sobre {file}",
+ "%1$s commented on %2$s" : "%1$s comentaram em %2$s",
+ "{author} commented on {file}" : "{author} comentou em {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentários</strong> para arquivos",
+ "Files" : "Arquivos",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Você foi mencionado em \"{file}\", em um comentário de uma conta que já foi excluída",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} mencionou você em um comentário sobre \"{file}\"",
+ "Files app plugin to add comments to files" : "Complemento do aplicativo Files para adicionar comentários",
"Edit comment" : "Editar comentário",
- "[Deleted user]" : "[Usuário eliminado]",
- "No other comments available" : "Nenhum outro comentário disponível",
- "More comments..." : "Mais comentários...",
- "Save" : "Salvar",
- "Allowed characters {count} of {max}" : "Caracteres permitidos {count} de {max}",
- "{count} unread comments" : "{count} comentários não lidos",
- "Comment" : "Comentário"
-},"pluralForm" :"nplurals=2; plural=(n > 1);"
+ "Delete comment" : "Excluir comentário",
+ "Cancel edit" : "Cancelar edição",
+ "New comment" : "Novo comentário",
+ "Write a comment …" : "Escreva um comentário …",
+ "Post comment" : "Postar comentário",
+ "@ for mentions, : for emoji, / for smart picker" : "@ para menções, : para emoji, / para seletor inteligente",
+ "Could not reload comments" : "Não foi possível recarregar comentários",
+ "Failed to mark comments as read" : "Falha ao marcar comentários como lidos",
+ "Unable to load the comments list" : "Não foi possível carregar a lista de comentários",
+ "No comments yet, start the conversation!" : "Nenhum comentário ainda, inicie uma conversa!",
+ "No more messages" : "Sem mais mensagens",
+ "Retry" : "Tentar novamente",
+ "_1 new comment_::_{unread} new comments_" : ["1 novo comentário","{unread} novos comentários","{unread} novos comentários"],
+ "Comment" : "Comentar",
+ "An error occurred while trying to edit the comment" : "Ocorreu um erro ao tentar editar o comentário",
+ "Comment deleted" : "Comentário excluído",
+ "An error occurred while trying to delete the comment" : "Ocorreu um erro ao tentar excluir o comentário",
+ "An error occurred while trying to create the comment" : "Ocorreu um erro ao tentar criar o comentário"
+},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/pt_PT.js b/apps/comments/l10n/pt_PT.js
index 5c874329fcd..e3b5e0f070a 100644
--- a/apps/comments/l10n/pt_PT.js
+++ b/apps/comments/l10n/pt_PT.js
@@ -1,23 +1,27 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Comentários</strong> para ficheiros",
- "You commented" : "Comentou",
- "%1$s commented" : "%1$s comentou",
- "You commented on %2$s" : "Comentou %2$s",
- "%1$s commented on %2$s" : "%1$s comentou %2$s",
"Comments" : "Comentários",
- "Type in a new comment..." : "Escreva um novo comentário...",
- "Delete comment" : "Apagar comentário",
- "Post" : "Enviar",
- "Cancel" : "Cancelar",
+ "You commented" : "Comentou",
+ "{author} commented" : "{author} comentou",
+ "You commented on %1$s" : "Você comentou em %1$s",
+ "You commented on {file}" : "Você comentou em {file}",
+ "%1$s commented on %2$s" : "%1$s comentou em %2$s",
+ "{author} commented on {file}" : "{author} comentou em {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentários</strong> aos ficheiros",
+ "Files" : "Ficheiros",
+ "Files app plugin to add comments to files" : "Plug-in da aplicação de ficheiros para adicionar comentários aos ficheiros",
"Edit comment" : "Editar comentário",
- "[Deleted user]" : "[utilizador apagado]",
- "No other comments available" : "Nenhum outro comentário disponível",
- "More comments..." : "Mais comentários...",
- "Save" : "Guardar",
- "Allowed characters {count} of {max}" : "{count} de {max} caracteres restantes",
- "{count} unread comments" : "{count} comentários não lidos",
- "Comment" : "Comentário"
+ "Delete comment" : "Eliminar comentário",
+ "Cancel edit" : "Cancelar edição",
+ "New comment" : "Novo comentário",
+ "Write a comment …" : "Escreva um comentário...",
+ "Post comment" : "Publicar comentário",
+ "No comments yet, start the conversation!" : "Ainda sem comentários, inicie uma conversação!",
+ "No more messages" : "Sem mais mensagens",
+ "Retry" : "Repetir",
+ "_1 new comment_::_{unread} new comments_" : ["1 novo comentário","{unread} novos comentários","{unread} novos comentários"],
+ "Comment" : "Comentário",
+ "Comment deleted" : "Comentário eliminado"
},
-"nplurals=2; plural=(n != 1);");
+"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/comments/l10n/pt_PT.json b/apps/comments/l10n/pt_PT.json
index f5fc1d7070b..5f681b1ae42 100644
--- a/apps/comments/l10n/pt_PT.json
+++ b/apps/comments/l10n/pt_PT.json
@@ -1,21 +1,25 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Comentários</strong> para ficheiros",
- "You commented" : "Comentou",
- "%1$s commented" : "%1$s comentou",
- "You commented on %2$s" : "Comentou %2$s",
- "%1$s commented on %2$s" : "%1$s comentou %2$s",
"Comments" : "Comentários",
- "Type in a new comment..." : "Escreva um novo comentário...",
- "Delete comment" : "Apagar comentário",
- "Post" : "Enviar",
- "Cancel" : "Cancelar",
+ "You commented" : "Comentou",
+ "{author} commented" : "{author} comentou",
+ "You commented on %1$s" : "Você comentou em %1$s",
+ "You commented on {file}" : "Você comentou em {file}",
+ "%1$s commented on %2$s" : "%1$s comentou em %2$s",
+ "{author} commented on {file}" : "{author} comentou em {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentários</strong> aos ficheiros",
+ "Files" : "Ficheiros",
+ "Files app plugin to add comments to files" : "Plug-in da aplicação de ficheiros para adicionar comentários aos ficheiros",
"Edit comment" : "Editar comentário",
- "[Deleted user]" : "[utilizador apagado]",
- "No other comments available" : "Nenhum outro comentário disponível",
- "More comments..." : "Mais comentários...",
- "Save" : "Guardar",
- "Allowed characters {count} of {max}" : "{count} de {max} caracteres restantes",
- "{count} unread comments" : "{count} comentários não lidos",
- "Comment" : "Comentário"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
+ "Delete comment" : "Eliminar comentário",
+ "Cancel edit" : "Cancelar edição",
+ "New comment" : "Novo comentário",
+ "Write a comment …" : "Escreva um comentário...",
+ "Post comment" : "Publicar comentário",
+ "No comments yet, start the conversation!" : "Ainda sem comentários, inicie uma conversação!",
+ "No more messages" : "Sem mais mensagens",
+ "Retry" : "Repetir",
+ "_1 new comment_::_{unread} new comments_" : ["1 novo comentário","{unread} novos comentários","{unread} novos comentários"],
+ "Comment" : "Comentário",
+ "Comment deleted" : "Comentário eliminado"
+},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/ro.js b/apps/comments/l10n/ro.js
index 71a0fa68531..d9ee2da0dcc 100644
--- a/apps/comments/l10n/ro.js
+++ b/apps/comments/l10n/ro.js
@@ -1,7 +1,32 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "Anulează",
- "Save" : "Salvează"
+ "Comments" : "Comentarii",
+ "You commented" : "Ai comentat",
+ "{author} commented" : " {author} a comentat",
+ "You commented on %1$s" : "Ai comentat la %1$s",
+ "You commented on {file}" : "Ai comentat la {file}",
+ "%1$s commented on %2$s" : "%1$s a comentat la %2$s",
+ "{author} commented on {file}" : " {author} a comentat la {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarii</strong> la fișiere",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} te-a menționat într-un comentariu la fișierul \"{file}\"",
+ "Files app plugin to add comments to files" : "Plugin pentru aplicația de fișiere pentru adăugarea de comentarii",
+ "Edit comment" : "Editează comentariul",
+ "Delete comment" : "Șterge comentariul",
+ "Cancel edit" : "Anulați editarea",
+ "Post comment" : "Postează comentariu",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pentru mențiuni, : pentru emoji, / pentru smart picker",
+ "Could not reload comments" : "Nu se pot reîncărca comentariile",
+ "Failed to mark comments as read" : "Eroare la marcarea comentariilor ca citite",
+ "Unable to load the comments list" : "Lista de comentarii nu poate fi încărcată",
+ "No comments yet, start the conversation!" : "Nici un comentariu încă, începe conversația!",
+ "No more messages" : "Nu mai sunt mesaje",
+ "Retry" : "Reîncearcă",
+ "_1 new comment_::_{unread} new comments_" : ["1 nou comentariu","{unread} noi comentarii","{unread} comentarii noi"],
+ "Comment" : "Comentariu",
+ "An error occurred while trying to edit the comment" : "A apărut o eroare la încercarea de a edita comentariul",
+ "Comment deleted" : "Comentariul a fost șters",
+ "An error occurred while trying to delete the comment" : "A apărut o eroare la încercarea de a șterge comentariul",
+ "An error occurred while trying to create the comment" : "A apărut o eroare la încercarea de a crea comentariul"
},
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));");
diff --git a/apps/comments/l10n/ro.json b/apps/comments/l10n/ro.json
index dfd0b01cfff..f8db4ddc882 100644
--- a/apps/comments/l10n/ro.json
+++ b/apps/comments/l10n/ro.json
@@ -1,5 +1,30 @@
{ "translations": {
- "Cancel" : "Anulează",
- "Save" : "Salvează"
+ "Comments" : "Comentarii",
+ "You commented" : "Ai comentat",
+ "{author} commented" : " {author} a comentat",
+ "You commented on %1$s" : "Ai comentat la %1$s",
+ "You commented on {file}" : "Ai comentat la {file}",
+ "%1$s commented on %2$s" : "%1$s a comentat la %2$s",
+ "{author} commented on {file}" : " {author} a comentat la {file}",
+ "<strong>Comments</strong> for files" : "<strong>Comentarii</strong> la fișiere",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} te-a menționat într-un comentariu la fișierul \"{file}\"",
+ "Files app plugin to add comments to files" : "Plugin pentru aplicația de fișiere pentru adăugarea de comentarii",
+ "Edit comment" : "Editează comentariul",
+ "Delete comment" : "Șterge comentariul",
+ "Cancel edit" : "Anulați editarea",
+ "Post comment" : "Postează comentariu",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pentru mențiuni, : pentru emoji, / pentru smart picker",
+ "Could not reload comments" : "Nu se pot reîncărca comentariile",
+ "Failed to mark comments as read" : "Eroare la marcarea comentariilor ca citite",
+ "Unable to load the comments list" : "Lista de comentarii nu poate fi încărcată",
+ "No comments yet, start the conversation!" : "Nici un comentariu încă, începe conversația!",
+ "No more messages" : "Nu mai sunt mesaje",
+ "Retry" : "Reîncearcă",
+ "_1 new comment_::_{unread} new comments_" : ["1 nou comentariu","{unread} noi comentarii","{unread} comentarii noi"],
+ "Comment" : "Comentariu",
+ "An error occurred while trying to edit the comment" : "A apărut o eroare la încercarea de a edita comentariul",
+ "Comment deleted" : "Comentariul a fost șters",
+ "An error occurred while trying to delete the comment" : "A apărut o eroare la încercarea de a șterge comentariul",
+ "An error occurred while trying to create the comment" : "A apărut o eroare la încercarea de a crea comentariul"
},"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"
} \ No newline at end of file
diff --git a/apps/comments/l10n/ru.js b/apps/comments/l10n/ru.js
index 755ca9e5d58..c6dc089a1d4 100644
--- a/apps/comments/l10n/ru.js
+++ b/apps/comments/l10n/ru.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
+ "Comments" : "Комментарии",
+ "You commented" : "Вы прокомментировали",
+ "{author} commented" : "{author} прокомментировал",
+ "You commented on %1$s" : "Вы прокомментировали %1$s",
+ "You commented on {file}" : "Вы прокомментировали «{file}»",
+ "%1$s commented on %2$s" : "%1$s прокомментировано на %2$s",
+ "{author} commented on {file}" : "{author} прокомментировал {file}",
"<strong>Comments</strong> for files" : "<strong>Комментарии</strong> к файлам",
- "You commented" : "Вы откомментировали",
- "%1$s commented" : "%1$s откомментировано",
- "You commented on %2$s" : "Вы откомментировали в %2$s",
- "%1$s commented on %2$s" : "%1$s откомментировано на %2$s",
- "Comments" : "Коментарии",
- "Type in a new comment..." : "Запишите новый комментарий...",
- "Delete comment" : "Удалить комментарий",
- "Post" : "Запись",
- "Cancel" : "Отмена",
+ "Files" : "Файлы",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Вы были упомянуты в комментарии к «{file}» пользователем, учётная запись которого была удалена.",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} упомянул(а) вас в комментарии к «{file}»",
+ "Files app plugin to add comments to files" : "Модуль приложения «Файлы», позволяющий комментировать файлы",
"Edit comment" : "Редактировать комментарий",
- "[Deleted user]" : "[Удалённый пользователь]",
- "No other comments available" : "Нет других комментариев",
- "More comments..." : "Ещё комментарии...",
- "Save" : "Сохранить",
- "Allowed characters {count} of {max}" : "Допустимых символов {count} из {max}",
- "{count} unread comments" : "{count} непрочитанных комментариев",
- "Comment" : "Коментарий"
+ "Delete comment" : "Удалить комментарий",
+ "Cancel edit" : "Отменить правку",
+ "New comment" : "Новый комментарий",
+ "Write a comment …" : "Напишите комментарий…",
+ "Post comment" : "Опубликовать комментарий",
+ "@ for mentions, : for emoji, / for smart picker" : "@ для упоминаний, : для эмодзи, / для интеллектуального выбора",
+ "Could not reload comments" : "Не удалось перезагрузить комментарии",
+ "Failed to mark comments as read" : "Не удалось пометить комментарии как прочитанные",
+ "Unable to load the comments list" : "Невозможно загрузить список комментариев",
+ "No comments yet, start the conversation!" : "Комментарии отсутствуют, начните обсуждение!",
+ "No more messages" : "Сообщений нет",
+ "Retry" : "Повторить",
+ "_1 new comment_::_{unread} new comments_" : ["1 новый комментарий","{unread} новых комментариев","{unread} новых комментариев","{unread} новых комментариев"],
+ "Comment" : "Комментарий",
+ "An error occurred while trying to edit the comment" : "Попытка редактирования комментария завершилась ошибкой",
+ "Comment deleted" : "Комментарий удалён",
+ "An error occurred while trying to delete the comment" : "Попытка удаления комментария завершилась ошибкой",
+ "An error occurred while trying to create the comment" : "Попытка создания комментария завершилась ошибкой"
},
"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);");
diff --git a/apps/comments/l10n/ru.json b/apps/comments/l10n/ru.json
index 7c5d8aa10cc..30a7ba82f37 100644
--- a/apps/comments/l10n/ru.json
+++ b/apps/comments/l10n/ru.json
@@ -1,21 +1,34 @@
{ "translations": {
+ "Comments" : "Комментарии",
+ "You commented" : "Вы прокомментировали",
+ "{author} commented" : "{author} прокомментировал",
+ "You commented on %1$s" : "Вы прокомментировали %1$s",
+ "You commented on {file}" : "Вы прокомментировали «{file}»",
+ "%1$s commented on %2$s" : "%1$s прокомментировано на %2$s",
+ "{author} commented on {file}" : "{author} прокомментировал {file}",
"<strong>Comments</strong> for files" : "<strong>Комментарии</strong> к файлам",
- "You commented" : "Вы откомментировали",
- "%1$s commented" : "%1$s откомментировано",
- "You commented on %2$s" : "Вы откомментировали в %2$s",
- "%1$s commented on %2$s" : "%1$s откомментировано на %2$s",
- "Comments" : "Коментарии",
- "Type in a new comment..." : "Запишите новый комментарий...",
- "Delete comment" : "Удалить комментарий",
- "Post" : "Запись",
- "Cancel" : "Отмена",
+ "Files" : "Файлы",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Вы были упомянуты в комментарии к «{file}» пользователем, учётная запись которого была удалена.",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} упомянул(а) вас в комментарии к «{file}»",
+ "Files app plugin to add comments to files" : "Модуль приложения «Файлы», позволяющий комментировать файлы",
"Edit comment" : "Редактировать комментарий",
- "[Deleted user]" : "[Удалённый пользователь]",
- "No other comments available" : "Нет других комментариев",
- "More comments..." : "Ещё комментарии...",
- "Save" : "Сохранить",
- "Allowed characters {count} of {max}" : "Допустимых символов {count} из {max}",
- "{count} unread comments" : "{count} непрочитанных комментариев",
- "Comment" : "Коментарий"
+ "Delete comment" : "Удалить комментарий",
+ "Cancel edit" : "Отменить правку",
+ "New comment" : "Новый комментарий",
+ "Write a comment …" : "Напишите комментарий…",
+ "Post comment" : "Опубликовать комментарий",
+ "@ for mentions, : for emoji, / for smart picker" : "@ для упоминаний, : для эмодзи, / для интеллектуального выбора",
+ "Could not reload comments" : "Не удалось перезагрузить комментарии",
+ "Failed to mark comments as read" : "Не удалось пометить комментарии как прочитанные",
+ "Unable to load the comments list" : "Невозможно загрузить список комментариев",
+ "No comments yet, start the conversation!" : "Комментарии отсутствуют, начните обсуждение!",
+ "No more messages" : "Сообщений нет",
+ "Retry" : "Повторить",
+ "_1 new comment_::_{unread} new comments_" : ["1 новый комментарий","{unread} новых комментариев","{unread} новых комментариев","{unread} новых комментариев"],
+ "Comment" : "Комментарий",
+ "An error occurred while trying to edit the comment" : "Попытка редактирования комментария завершилась ошибкой",
+ "Comment deleted" : "Комментарий удалён",
+ "An error occurred while trying to delete the comment" : "Попытка удаления комментария завершилась ошибкой",
+ "An error occurred while trying to create the comment" : "Попытка создания комментария завершилась ошибкой"
},"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/sc.js b/apps/comments/l10n/sc.js
new file mode 100644
index 00000000000..1980bde60d4
--- /dev/null
+++ b/apps/comments/l10n/sc.js
@@ -0,0 +1,31 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Cummentos",
+ "You commented" : "As cummentadu",
+ "{author} commented" : "{author} at cummentadu",
+ "You commented on %1$s" : "As cummentadu in %1$s",
+ "You commented on {file}" : "As cummentadu {file}",
+ "%1$s commented on %2$s" : "%1$s at cummentadu %2$s",
+ "{author} commented on {file}" : "{author} at cummentadu {file}",
+ "<strong>Comments</strong> for files" : "<strong>Cummentos</strong> pro archìvios",
+ "Files" : "Archìvios",
+ "Files app plugin to add comments to files" : "Estensione de s'aplicatzione archìvios pro agiùnghere cummentos a archìvios",
+ "Edit comment" : "Modìfica cummentu",
+ "Delete comment" : "Cantzella cummentu",
+ "Cancel edit" : "Annulla modìfica",
+ "New comment" : "Cummentu nou",
+ "Post comment" : "Pùblica cummentu",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pro mèntovos, : pro emojis, / pro su seletzionadore inteligente",
+ "Unable to load the comments list" : "Non faghet a carrigare sa lista de cummentos",
+ "No comments yet, start the conversation!" : "Ancora perunu cummentu, cumintza sa cunversatzione!",
+ "No more messages" : "Perunu àteru messàgiu",
+ "Retry" : "Torra a proare",
+ "_1 new comment_::_{unread} new comments_" : ["1 cummentu nou","{unread} cummentos noos"],
+ "Comment" : "Cummenta",
+ "An error occurred while trying to edit the comment" : "Ddoe at àpidu un'errore proende a modificare su cummentu",
+ "Comment deleted" : "Cummentu cantzelladu",
+ "An error occurred while trying to delete the comment" : "B'at àpidu un'errore proende a cantzellare su cummentu",
+ "An error occurred while trying to create the comment" : "B'at àpidu un'errore proende a creare su cummentu"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/sc.json b/apps/comments/l10n/sc.json
new file mode 100644
index 00000000000..1c7987c118d
--- /dev/null
+++ b/apps/comments/l10n/sc.json
@@ -0,0 +1,29 @@
+{ "translations": {
+ "Comments" : "Cummentos",
+ "You commented" : "As cummentadu",
+ "{author} commented" : "{author} at cummentadu",
+ "You commented on %1$s" : "As cummentadu in %1$s",
+ "You commented on {file}" : "As cummentadu {file}",
+ "%1$s commented on %2$s" : "%1$s at cummentadu %2$s",
+ "{author} commented on {file}" : "{author} at cummentadu {file}",
+ "<strong>Comments</strong> for files" : "<strong>Cummentos</strong> pro archìvios",
+ "Files" : "Archìvios",
+ "Files app plugin to add comments to files" : "Estensione de s'aplicatzione archìvios pro agiùnghere cummentos a archìvios",
+ "Edit comment" : "Modìfica cummentu",
+ "Delete comment" : "Cantzella cummentu",
+ "Cancel edit" : "Annulla modìfica",
+ "New comment" : "Cummentu nou",
+ "Post comment" : "Pùblica cummentu",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pro mèntovos, : pro emojis, / pro su seletzionadore inteligente",
+ "Unable to load the comments list" : "Non faghet a carrigare sa lista de cummentos",
+ "No comments yet, start the conversation!" : "Ancora perunu cummentu, cumintza sa cunversatzione!",
+ "No more messages" : "Perunu àteru messàgiu",
+ "Retry" : "Torra a proare",
+ "_1 new comment_::_{unread} new comments_" : ["1 cummentu nou","{unread} cummentos noos"],
+ "Comment" : "Cummenta",
+ "An error occurred while trying to edit the comment" : "Ddoe at àpidu un'errore proende a modificare su cummentu",
+ "Comment deleted" : "Cummentu cantzelladu",
+ "An error occurred while trying to delete the comment" : "B'at àpidu un'errore proende a cantzellare su cummentu",
+ "An error occurred while trying to create the comment" : "B'at àpidu un'errore proende a creare su cummentu"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/si_LK.js b/apps/comments/l10n/si_LK.js
deleted file mode 100644
index 9badedaef20..00000000000
--- a/apps/comments/l10n/si_LK.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "එපා",
- "Save" : "සුරකින්න"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/si_LK.json b/apps/comments/l10n/si_LK.json
deleted file mode 100644
index e5ce448e641..00000000000
--- a/apps/comments/l10n/si_LK.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "එපා",
- "Save" : "සුරකින්න"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/sk.js b/apps/comments/l10n/sk.js
new file mode 100644
index 00000000000..380b8c88fb5
--- /dev/null
+++ b/apps/comments/l10n/sk.js
@@ -0,0 +1,36 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Komentáre",
+ "You commented" : "Komentovali ste",
+ "{author} commented" : "{author} komentoval",
+ "You commented on %1$s" : "Komentovali ste %1$s",
+ "You commented on {file}" : "Komentovali ste {file}",
+ "%1$s commented on %2$s" : "%1$s komentoval %2$s",
+ "{author} commented on {file}" : "{author} komentoval {file}",
+ "<strong>Comments</strong> for files" : "<strong>Komentáre</strong> pre súbory",
+ "Files" : "Súbory",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Boli ste spomenutý v \"{file}\", v komentári užívateľom ktorý bol už vymazaný",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} vás spomenul v komentári k “{file}”",
+ "Files app plugin to add comments to files" : "Zásuvný modul aplikácie súborov, ktorý umožňuje súborom pridávať komentáre",
+ "Edit comment" : "Upraviť komentár",
+ "Delete comment" : "Zmazať komentár",
+ "Cancel edit" : "Zrušiť upravovanie",
+ "New comment" : "Nový komentár",
+ "Write a comment …" : "Napísať komentár ...",
+ "Post comment" : "Odoslať komentár",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pre spomienky, : pre emotikony, / pre inteligentný výber",
+ "Could not reload comments" : "Nepodarilo sa obnoviť komentáre",
+ "Failed to mark comments as read" : "Nepodarilo sa označiť komentáre ako prečítané.",
+ "Unable to load the comments list" : "Nie je možné načítať zoznam komentárov",
+ "No comments yet, start the conversation!" : "Žiadne komentáre, začnite konverzáciu!",
+ "No more messages" : "Žiadne ďaĺšie správy",
+ "Retry" : "Skúsiť znova",
+ "_1 new comment_::_{unread} new comments_" : ["1 nový komentár","{unread} nové komentáre","{unread} nových komentárov","{unread} nových komentárov"],
+ "Comment" : "Komentár",
+ "An error occurred while trying to edit the comment" : "Vyskytla sa chyba pri editovaní komentára",
+ "Comment deleted" : "Komentár bol odstránený",
+ "An error occurred while trying to delete the comment" : "Vyskytla sa chyba pri mazaní komentára",
+ "An error occurred while trying to create the comment" : "Vyskytla sa chyba pri vytváraní komentára"
+},
+"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);");
diff --git a/apps/comments/l10n/sk.json b/apps/comments/l10n/sk.json
new file mode 100644
index 00000000000..e617085d50a
--- /dev/null
+++ b/apps/comments/l10n/sk.json
@@ -0,0 +1,34 @@
+{ "translations": {
+ "Comments" : "Komentáre",
+ "You commented" : "Komentovali ste",
+ "{author} commented" : "{author} komentoval",
+ "You commented on %1$s" : "Komentovali ste %1$s",
+ "You commented on {file}" : "Komentovali ste {file}",
+ "%1$s commented on %2$s" : "%1$s komentoval %2$s",
+ "{author} commented on {file}" : "{author} komentoval {file}",
+ "<strong>Comments</strong> for files" : "<strong>Komentáre</strong> pre súbory",
+ "Files" : "Súbory",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Boli ste spomenutý v \"{file}\", v komentári užívateľom ktorý bol už vymazaný",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} vás spomenul v komentári k “{file}”",
+ "Files app plugin to add comments to files" : "Zásuvný modul aplikácie súborov, ktorý umožňuje súborom pridávať komentáre",
+ "Edit comment" : "Upraviť komentár",
+ "Delete comment" : "Zmazať komentár",
+ "Cancel edit" : "Zrušiť upravovanie",
+ "New comment" : "Nový komentár",
+ "Write a comment …" : "Napísať komentár ...",
+ "Post comment" : "Odoslať komentár",
+ "@ for mentions, : for emoji, / for smart picker" : "@ pre spomienky, : pre emotikony, / pre inteligentný výber",
+ "Could not reload comments" : "Nepodarilo sa obnoviť komentáre",
+ "Failed to mark comments as read" : "Nepodarilo sa označiť komentáre ako prečítané.",
+ "Unable to load the comments list" : "Nie je možné načítať zoznam komentárov",
+ "No comments yet, start the conversation!" : "Žiadne komentáre, začnite konverzáciu!",
+ "No more messages" : "Žiadne ďaĺšie správy",
+ "Retry" : "Skúsiť znova",
+ "_1 new comment_::_{unread} new comments_" : ["1 nový komentár","{unread} nové komentáre","{unread} nových komentárov","{unread} nových komentárov"],
+ "Comment" : "Komentár",
+ "An error occurred while trying to edit the comment" : "Vyskytla sa chyba pri editovaní komentára",
+ "Comment deleted" : "Komentár bol odstránený",
+ "An error occurred while trying to delete the comment" : "Vyskytla sa chyba pri mazaní komentára",
+ "An error occurred while trying to create the comment" : "Vyskytla sa chyba pri vytváraní komentára"
+},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/sk_SK.js b/apps/comments/l10n/sk_SK.js
deleted file mode 100644
index 808e0bff4d4..00000000000
--- a/apps/comments/l10n/sk_SK.js
+++ /dev/null
@@ -1,8 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Zrušiť",
- "Save" : "Uložiť",
- "Comment" : "Komentár"
-},
-"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;");
diff --git a/apps/comments/l10n/sk_SK.json b/apps/comments/l10n/sk_SK.json
deleted file mode 100644
index 649d040de7a..00000000000
--- a/apps/comments/l10n/sk_SK.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{ "translations": {
- "Cancel" : "Zrušiť",
- "Save" : "Uložiť",
- "Comment" : "Komentár"
-},"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/sl.js b/apps/comments/l10n/sl.js
index 79d8fc8e977..5731163c19f 100644
--- a/apps/comments/l10n/sl.js
+++ b/apps/comments/l10n/sl.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Opombe</strong> datotek",
- "You commented" : "Vaša opomba",
- "%1$s commented" : "%1$s opomb",
- "You commented on %2$s" : "Napisali ste opombo na %2$s",
- "%1$s commented on %2$s" : "%1$s opomb ob %2$s",
"Comments" : "Opombe",
- "Type in a new comment..." : "Vpis nove opombe ...",
- "Delete comment" : "Izbriši opombo",
- "Post" : "Objavi",
- "Cancel" : "Prekliči",
+ "You commented" : "Napišete opombo",
+ "{author} commented" : "{author} vpiše opombo",
+ "You commented on %1$s" : "Napišete opombo za %1$s",
+ "You commented on {file}" : "Napišete opombo na {file}",
+ "%1$s commented on %2$s" : "%1$s napiše opombo na %2$s",
+ "{author} commented on {file}" : "{author} napiše opombo na {file}",
+ "<strong>Comments</strong> for files" : "Vpisane so <strong>opombe</strong> k datotekam",
+ "Files" : "Datoteke",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Uporabnik, ki je sicer že izbrisan, vas omenja v opombi k datoteki »{file}«.",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} vas omeni v opombi k datoteki »{file}«",
+ "Files app plugin to add comments to files" : "Vstavek programa Datoteke za dodajanje opomb k datotekam",
"Edit comment" : "Uredi opombo",
- "[Deleted user]" : "[Izbrisan uporabnik]",
- "No other comments available" : "Ni drugih opomb",
- "More comments..." : "Več opomb ...",
- "Save" : "Shrani",
- "Allowed characters {count} of {max}" : "Dovoljeni znaki: {count} od {max}",
- "{count} unread comments" : "{count} neprebranih opomb",
- "Comment" : "Opomba"
+ "Delete comment" : "Izbriši opombo",
+ "Cancel edit" : "Prekliči urejanje",
+ "New comment" : "Nova opomba",
+ "Write a comment …" : "Dopišite opombo ...",
+ "Post comment" : "Objavi opombo",
+ "@ for mentions, : for emoji, / for smart picker" : "@ za omenjanje osebe, : za izris izraznih ikon, / za pametni izbirnik",
+ "Could not reload comments" : "Opomb ni mogoče posodobiti",
+ "Failed to mark comments as read" : "Označevanje opomb kot prebranih je spodletelo",
+ "Unable to load the comments list" : "Ni mogoče naložiti seznama opomb",
+ "No comments yet, start the conversation!" : "Ni še odzivov, bodite prvi!",
+ "No more messages" : "Ni drugih sporočil",
+ "Retry" : "Poskusi znova",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} nova opomba","{unread} novi opombi","{unread} nove opombe","{unread} novih opomb"],
+ "Comment" : "Opomba",
+ "An error occurred while trying to edit the comment" : "Prišlo je do napake med poskusom urejanja opombe",
+ "Comment deleted" : "Opomba je izbrisana",
+ "An error occurred while trying to delete the comment" : "Prišlo je do napake med brisanjem opombe",
+ "An error occurred while trying to create the comment" : "Prišlo je do napake med ustvarjanjem opombe"
},
"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);");
diff --git a/apps/comments/l10n/sl.json b/apps/comments/l10n/sl.json
index 1e71acbec39..0ee0fcad23f 100644
--- a/apps/comments/l10n/sl.json
+++ b/apps/comments/l10n/sl.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Opombe</strong> datotek",
- "You commented" : "Vaša opomba",
- "%1$s commented" : "%1$s opomb",
- "You commented on %2$s" : "Napisali ste opombo na %2$s",
- "%1$s commented on %2$s" : "%1$s opomb ob %2$s",
"Comments" : "Opombe",
- "Type in a new comment..." : "Vpis nove opombe ...",
- "Delete comment" : "Izbriši opombo",
- "Post" : "Objavi",
- "Cancel" : "Prekliči",
+ "You commented" : "Napišete opombo",
+ "{author} commented" : "{author} vpiše opombo",
+ "You commented on %1$s" : "Napišete opombo za %1$s",
+ "You commented on {file}" : "Napišete opombo na {file}",
+ "%1$s commented on %2$s" : "%1$s napiše opombo na %2$s",
+ "{author} commented on {file}" : "{author} napiše opombo na {file}",
+ "<strong>Comments</strong> for files" : "Vpisane so <strong>opombe</strong> k datotekam",
+ "Files" : "Datoteke",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Uporabnik, ki je sicer že izbrisan, vas omenja v opombi k datoteki »{file}«.",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} vas omeni v opombi k datoteki »{file}«",
+ "Files app plugin to add comments to files" : "Vstavek programa Datoteke za dodajanje opomb k datotekam",
"Edit comment" : "Uredi opombo",
- "[Deleted user]" : "[Izbrisan uporabnik]",
- "No other comments available" : "Ni drugih opomb",
- "More comments..." : "Več opomb ...",
- "Save" : "Shrani",
- "Allowed characters {count} of {max}" : "Dovoljeni znaki: {count} od {max}",
- "{count} unread comments" : "{count} neprebranih opomb",
- "Comment" : "Opomba"
+ "Delete comment" : "Izbriši opombo",
+ "Cancel edit" : "Prekliči urejanje",
+ "New comment" : "Nova opomba",
+ "Write a comment …" : "Dopišite opombo ...",
+ "Post comment" : "Objavi opombo",
+ "@ for mentions, : for emoji, / for smart picker" : "@ za omenjanje osebe, : za izris izraznih ikon, / za pametni izbirnik",
+ "Could not reload comments" : "Opomb ni mogoče posodobiti",
+ "Failed to mark comments as read" : "Označevanje opomb kot prebranih je spodletelo",
+ "Unable to load the comments list" : "Ni mogoče naložiti seznama opomb",
+ "No comments yet, start the conversation!" : "Ni še odzivov, bodite prvi!",
+ "No more messages" : "Ni drugih sporočil",
+ "Retry" : "Poskusi znova",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} nova opomba","{unread} novi opombi","{unread} nove opombe","{unread} novih opomb"],
+ "Comment" : "Opomba",
+ "An error occurred while trying to edit the comment" : "Prišlo je do napake med poskusom urejanja opombe",
+ "Comment deleted" : "Opomba je izbrisana",
+ "An error occurred while trying to delete the comment" : "Prišlo je do napake med brisanjem opombe",
+ "An error occurred while trying to create the comment" : "Prišlo je do napake med ustvarjanjem opombe"
},"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/sq.js b/apps/comments/l10n/sq.js
deleted file mode 100644
index fdb47e2425a..00000000000
--- a/apps/comments/l10n/sq.js
+++ /dev/null
@@ -1,23 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "<strong>Comments</strong> for files" : "<strong>Komente</strong> për kartela",
- "You commented" : "Komentuat",
- "%1$s commented" : "%1$s komentoi",
- "You commented on %2$s" : "Komentuat te %2$s",
- "%1$s commented on %2$s" : "%1$s komentoi te %2$s",
- "Comments" : "Komente",
- "Type in a new comment..." : "Shtypni një koment të ri…",
- "Delete comment" : "Fshije komentin",
- "Post" : "Postoje",
- "Cancel" : "Anuloje",
- "Edit comment" : "Përpunoni komentin",
- "[Deleted user]" : "[Përdorues i fshirë]",
- "No other comments available" : "S’ka komente të tjera",
- "More comments..." : "Më tepër komente…",
- "Save" : "Ruaje",
- "Allowed characters {count} of {max}" : "Shenja të lejuara {count} nga {max}",
- "{count} unread comments" : "{count} komente të palexuar",
- "Comment" : "Koment"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/sq.json b/apps/comments/l10n/sq.json
deleted file mode 100644
index deaeceac8ce..00000000000
--- a/apps/comments/l10n/sq.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Komente</strong> për kartela",
- "You commented" : "Komentuat",
- "%1$s commented" : "%1$s komentoi",
- "You commented on %2$s" : "Komentuat te %2$s",
- "%1$s commented on %2$s" : "%1$s komentoi te %2$s",
- "Comments" : "Komente",
- "Type in a new comment..." : "Shtypni një koment të ri…",
- "Delete comment" : "Fshije komentin",
- "Post" : "Postoje",
- "Cancel" : "Anuloje",
- "Edit comment" : "Përpunoni komentin",
- "[Deleted user]" : "[Përdorues i fshirë]",
- "No other comments available" : "S’ka komente të tjera",
- "More comments..." : "Më tepër komente…",
- "Save" : "Ruaje",
- "Allowed characters {count} of {max}" : "Shenja të lejuara {count} nga {max}",
- "{count} unread comments" : "{count} komente të palexuar",
- "Comment" : "Koment"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/sr.js b/apps/comments/l10n/sr.js
index aae126ef40f..95c34a5368f 100644
--- a/apps/comments/l10n/sr.js
+++ b/apps/comments/l10n/sr.js
@@ -1,21 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Коментари</strong> фајлова",
- "%1$s commented" : "%1$s коментариса",
- "%1$s commented on %2$s" : "%1$s коментариса на %2$s",
"Comments" : "Коментари",
- "Type in a new comment..." : "Укуцајте нови коментар...",
+ "You commented" : "Искоментарисали сте",
+ "{author} commented" : "{author} коментарисао",
+ "You commented on %1$s" : "Коментарисали сте на %1$s",
+ "You commented on {file}" : "Коментаристали сте на {file}",
+ "%1$s commented on %2$s" : "%1$s коментарисао на %2$s",
+ "{author} commented on {file}" : "{author} коментарисао на {file}",
+ "<strong>Comments</strong> for files" : "<strong>Коментари</strong> на фајлове",
+ "Files" : "Фајлови",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Поменути сте за „{file}”, у коментару налога који је касније обрисан",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} вас је поменуо у коментару за „{file}",
+ "Files app plugin to add comments to files" : "Додатак апликацији за фајлове да додајете коментаре на фајлове",
+ "Edit comment" : "Измени коментар",
"Delete comment" : "Обриши коментар",
- "Post" : "Објави",
- "Cancel" : "Откажи",
- "Edit comment" : "Уреди коментар",
- "[Deleted user]" : "[Обрисан корисник]",
- "No other comments available" : "Нема других коментара",
- "More comments..." : "Још коментара...",
- "Save" : "Сачувај",
- "Allowed characters {count} of {max}" : "Дозвољених {count} знакова од {max}",
- "{count} unread comments" : "{count} непрочитаних коментара",
- "Comment" : "Коментар"
+ "Cancel edit" : "Поништи измену",
+ "New comment" : "Нови коментар",
+ "Write a comment …" : "Напишите коментар…",
+ "Post comment" : "Објави коментар",
+ "@ for mentions, : for emoji, / for smart picker" : "@ за помињања, : за емођи, / за паметни бирач",
+ "Could not reload comments" : "Коментари не могу поново да се учитају",
+ "Failed to mark comments as read" : "Није успело означавање коментара као прочитаних",
+ "Unable to load the comments list" : "Не могуи да учитам списак коментара",
+ "No comments yet, start the conversation!" : "Још нема коментара. Започните дискусију!",
+ "No more messages" : "Нема више порука",
+ "Retry" : "Покушај поново",
+ "_1 new comment_::_{unread} new comments_" : ["1 нови коментар","{unread} нова коментара","{unread} нова коментара"],
+ "Comment" : "Коментар",
+ "An error occurred while trying to edit the comment" : "Грешка приликом покушаја мењања коментара",
+ "Comment deleted" : "Коментар обрисан",
+ "An error occurred while trying to delete the comment" : "Грешка приликом покушаја брисања коментара",
+ "An error occurred while trying to create the comment" : "Грешка приликом покушаја креирања коментара"
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/apps/comments/l10n/sr.json b/apps/comments/l10n/sr.json
index 12cdb29deb5..80120b1efd6 100644
--- a/apps/comments/l10n/sr.json
+++ b/apps/comments/l10n/sr.json
@@ -1,19 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Коментари</strong> фајлова",
- "%1$s commented" : "%1$s коментариса",
- "%1$s commented on %2$s" : "%1$s коментариса на %2$s",
"Comments" : "Коментари",
- "Type in a new comment..." : "Укуцајте нови коментар...",
+ "You commented" : "Искоментарисали сте",
+ "{author} commented" : "{author} коментарисао",
+ "You commented on %1$s" : "Коментарисали сте на %1$s",
+ "You commented on {file}" : "Коментаристали сте на {file}",
+ "%1$s commented on %2$s" : "%1$s коментарисао на %2$s",
+ "{author} commented on {file}" : "{author} коментарисао на {file}",
+ "<strong>Comments</strong> for files" : "<strong>Коментари</strong> на фајлове",
+ "Files" : "Фајлови",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Поменути сте за „{file}”, у коментару налога који је касније обрисан",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} вас је поменуо у коментару за „{file}",
+ "Files app plugin to add comments to files" : "Додатак апликацији за фајлове да додајете коментаре на фајлове",
+ "Edit comment" : "Измени коментар",
"Delete comment" : "Обриши коментар",
- "Post" : "Објави",
- "Cancel" : "Откажи",
- "Edit comment" : "Уреди коментар",
- "[Deleted user]" : "[Обрисан корисник]",
- "No other comments available" : "Нема других коментара",
- "More comments..." : "Још коментара...",
- "Save" : "Сачувај",
- "Allowed characters {count} of {max}" : "Дозвољених {count} знакова од {max}",
- "{count} unread comments" : "{count} непрочитаних коментара",
- "Comment" : "Коментар"
+ "Cancel edit" : "Поништи измену",
+ "New comment" : "Нови коментар",
+ "Write a comment …" : "Напишите коментар…",
+ "Post comment" : "Објави коментар",
+ "@ for mentions, : for emoji, / for smart picker" : "@ за помињања, : за емођи, / за паметни бирач",
+ "Could not reload comments" : "Коментари не могу поново да се учитају",
+ "Failed to mark comments as read" : "Није успело означавање коментара као прочитаних",
+ "Unable to load the comments list" : "Не могуи да учитам списак коментара",
+ "No comments yet, start the conversation!" : "Још нема коментара. Започните дискусију!",
+ "No more messages" : "Нема више порука",
+ "Retry" : "Покушај поново",
+ "_1 new comment_::_{unread} new comments_" : ["1 нови коментар","{unread} нова коментара","{unread} нова коментара"],
+ "Comment" : "Коментар",
+ "An error occurred while trying to edit the comment" : "Грешка приликом покушаја мењања коментара",
+ "Comment deleted" : "Коментар обрисан",
+ "An error occurred while trying to delete the comment" : "Грешка приликом покушаја брисања коментара",
+ "An error occurred while trying to create the comment" : "Грешка приликом покушаја креирања коментара"
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/sr@latin.js b/apps/comments/l10n/sr@latin.js
deleted file mode 100644
index c2185e95e92..00000000000
--- a/apps/comments/l10n/sr@latin.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "Odustani",
- "Save" : "Sačuvaj"
-},
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/apps/comments/l10n/sr@latin.json b/apps/comments/l10n/sr@latin.json
deleted file mode 100644
index f61bed4853a..00000000000
--- a/apps/comments/l10n/sr@latin.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "Odustani",
- "Save" : "Sačuvaj"
-},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/sv.js b/apps/comments/l10n/sv.js
index 6c3b17555bc..c96b8c94ee8 100644
--- a/apps/comments/l10n/sv.js
+++ b/apps/comments/l10n/sv.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> till filer",
+ "Comments" : "Kommentarer",
"You commented" : "Du kommenterade",
- "%1$s commented" : "%1$s har kommenterat",
- "You commented on %2$s" : "Du kommenterade %2$s",
+ "{author} commented" : "{author} kommenterade",
+ "You commented on %1$s" : "Du kommenterade på %1$s",
+ "You commented on {file}" : "Du kommenterade på {file}",
"%1$s commented on %2$s" : "%1$s kommenterade på %2$s",
- "Comments" : "Kommentarer",
- "Type in a new comment..." : "Skriv en ny kommentar",
- "Delete comment" : "Radera kommentar",
- "Post" : "Skicka",
- "Cancel" : "Avbryt",
+ "{author} commented on {file}" : "{author} kommenterade på {file}",
+ "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> för filer",
+ "Files" : "Filer",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Du har nämnts i \"{file}\", i en kommentar av en användare som sedan har blivit borttagen",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} nämnde dig i kommentar för \"{file}\"",
+ "Files app plugin to add comments to files" : "Filer-appinsticksmodul för att lägga till kommentarer till filer",
"Edit comment" : "Redigera kommentar",
- "[Deleted user]" : "[Raderad användare]",
- "No other comments available" : "Inga andra kommentarer tillgängliga",
- "More comments..." : "Fler kommentarter,,,",
- "Save" : "Spara",
- "Allowed characters {count} of {max}" : "Tillåtet antal tecken {count} av {max}",
- "{count} unread comments" : "{count} olästa kommentarer",
- "Comment" : "Kommentar"
+ "Delete comment" : "Ta bort kommentar",
+ "Cancel edit" : "Avbryt redigering",
+ "New comment" : "Ny kommentar",
+ "Write a comment …" : "Skriv en kommentar ...",
+ "Post comment" : "Publicera kommentar",
+ "@ for mentions, : for emoji, / for smart picker" : "@ för omnämnanden, : för emoji, / för smart picker",
+ "Could not reload comments" : "Kunde inte ladda om kommentarer",
+ "Failed to mark comments as read" : "Kunde inte markera kommentarer som lästa",
+ "Unable to load the comments list" : "Kunde inte ladda kommentarlistan",
+ "No comments yet, start the conversation!" : "Inga kommentarer ännu.",
+ "No more messages" : "Inga fler meddelanden",
+ "Retry" : "Försök igen",
+ "_1 new comment_::_{unread} new comments_" : ["1 ny kommentar","{unread} nya kommentarer"],
+ "Comment" : "Kommentar",
+ "An error occurred while trying to edit the comment" : "Ett fel uppstod vid redigering av kommentaren",
+ "Comment deleted" : "Kommentar borttagen",
+ "An error occurred while trying to delete the comment" : "Ett fel uppstod vid borttagning av kommentaren",
+ "An error occurred while trying to create the comment" : "Ett fel uppstod vid skapande av kommentaren"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/sv.json b/apps/comments/l10n/sv.json
index 6b2e9b7b71d..90d10190185 100644
--- a/apps/comments/l10n/sv.json
+++ b/apps/comments/l10n/sv.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> till filer",
+ "Comments" : "Kommentarer",
"You commented" : "Du kommenterade",
- "%1$s commented" : "%1$s har kommenterat",
- "You commented on %2$s" : "Du kommenterade %2$s",
+ "{author} commented" : "{author} kommenterade",
+ "You commented on %1$s" : "Du kommenterade på %1$s",
+ "You commented on {file}" : "Du kommenterade på {file}",
"%1$s commented on %2$s" : "%1$s kommenterade på %2$s",
- "Comments" : "Kommentarer",
- "Type in a new comment..." : "Skriv en ny kommentar",
- "Delete comment" : "Radera kommentar",
- "Post" : "Skicka",
- "Cancel" : "Avbryt",
+ "{author} commented on {file}" : "{author} kommenterade på {file}",
+ "<strong>Comments</strong> for files" : "<strong>Kommentarer</strong> för filer",
+ "Files" : "Filer",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Du har nämnts i \"{file}\", i en kommentar av en användare som sedan har blivit borttagen",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} nämnde dig i kommentar för \"{file}\"",
+ "Files app plugin to add comments to files" : "Filer-appinsticksmodul för att lägga till kommentarer till filer",
"Edit comment" : "Redigera kommentar",
- "[Deleted user]" : "[Raderad användare]",
- "No other comments available" : "Inga andra kommentarer tillgängliga",
- "More comments..." : "Fler kommentarter,,,",
- "Save" : "Spara",
- "Allowed characters {count} of {max}" : "Tillåtet antal tecken {count} av {max}",
- "{count} unread comments" : "{count} olästa kommentarer",
- "Comment" : "Kommentar"
+ "Delete comment" : "Ta bort kommentar",
+ "Cancel edit" : "Avbryt redigering",
+ "New comment" : "Ny kommentar",
+ "Write a comment …" : "Skriv en kommentar ...",
+ "Post comment" : "Publicera kommentar",
+ "@ for mentions, : for emoji, / for smart picker" : "@ för omnämnanden, : för emoji, / för smart picker",
+ "Could not reload comments" : "Kunde inte ladda om kommentarer",
+ "Failed to mark comments as read" : "Kunde inte markera kommentarer som lästa",
+ "Unable to load the comments list" : "Kunde inte ladda kommentarlistan",
+ "No comments yet, start the conversation!" : "Inga kommentarer ännu.",
+ "No more messages" : "Inga fler meddelanden",
+ "Retry" : "Försök igen",
+ "_1 new comment_::_{unread} new comments_" : ["1 ny kommentar","{unread} nya kommentarer"],
+ "Comment" : "Kommentar",
+ "An error occurred while trying to edit the comment" : "Ett fel uppstod vid redigering av kommentaren",
+ "Comment deleted" : "Kommentar borttagen",
+ "An error occurred while trying to delete the comment" : "Ett fel uppstod vid borttagning av kommentaren",
+ "An error occurred while trying to create the comment" : "Ett fel uppstod vid skapande av kommentaren"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/sw.js b/apps/comments/l10n/sw.js
new file mode 100644
index 00000000000..dbe931a3406
--- /dev/null
+++ b/apps/comments/l10n/sw.js
@@ -0,0 +1,36 @@
+OC.L10N.register(
+ "comments",
+ {
+ "Comments" : "Maoni",
+ "You commented" : "Ulitoa maoni",
+ "{author} commented" : "{author} alitoa maoni",
+ "You commented on %1$s" : "Ulitoa maoni katika %1$s",
+ "You commented on {file}" : "Ulitoa maoni katika {file}",
+ "%1$s commented on %2$s" : "%1$salitoa maoni katika %2$s",
+ "{author} commented on {file}" : "{author}alitoa maoni katika {file}",
+ "<strong>Comments</strong> for files" : "<strong>maoni</strong>kwa faili",
+ "Files" : "Mafaili",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Ulitajwa kwenye \"{file}\", kwenye maoni ya akaunti ambayo imefutwa",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user}amekutaja katika maoni kwenye\"{file}\"",
+ "Files app plugin to add comments to files" : "Programu-jalizi ya Faili ili kuongeza maoni kwenye faili ",
+ "Edit comment" : "Hariri maoni",
+ "Delete comment" : "Futa maoni",
+ "Cancel edit" : "Sistisha uhariri",
+ "New comment" : "Maoni mapya",
+ "Write a comment …" : "Andika maoni...",
+ "Post comment" : "Tuma maoni",
+ "@ for mentions, : for emoji, / for smart picker" : "@ kwa mitajo, : kwa emoji, / kwa kichagua smart",
+ "Could not reload comments" : "Haikuweza kupakia maoni",
+ "Failed to mark comments as read" : "imeshindwa kuweka alama kwenye maoni kama yamesomwa",
+ "Unable to load the comments list" : "Haiwezi kupakia orodha ya maoni",
+ "No comments yet, start the conversation!" : "Bado hakuna maoni, anza mazungumzo",
+ "No more messages" : "Hakuna jumbe zaidi",
+ "Retry" : "Jaribu tene",
+ "_1 new comment_::_{unread} new comments_" : ["1 new comment","{unread}maoni mapya "],
+ "Comment" : "Maoni",
+ "An error occurred while trying to edit the comment" : "Hitilafu ilitokea wakati wa kujaribu kuhariri maoni",
+ "Comment deleted" : "Maoni yamefutwa",
+ "An error occurred while trying to delete the comment" : "Hitilafu ilitokea wakati wa kujaribu kufuta maoni",
+ "An error occurred while trying to create the comment" : "Hitilafu ilitokea wakati wa kujaribu kuunda maoni"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/sw.json b/apps/comments/l10n/sw.json
new file mode 100644
index 00000000000..86dff80baf2
--- /dev/null
+++ b/apps/comments/l10n/sw.json
@@ -0,0 +1,34 @@
+{ "translations": {
+ "Comments" : "Maoni",
+ "You commented" : "Ulitoa maoni",
+ "{author} commented" : "{author} alitoa maoni",
+ "You commented on %1$s" : "Ulitoa maoni katika %1$s",
+ "You commented on {file}" : "Ulitoa maoni katika {file}",
+ "%1$s commented on %2$s" : "%1$salitoa maoni katika %2$s",
+ "{author} commented on {file}" : "{author}alitoa maoni katika {file}",
+ "<strong>Comments</strong> for files" : "<strong>maoni</strong>kwa faili",
+ "Files" : "Mafaili",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Ulitajwa kwenye \"{file}\", kwenye maoni ya akaunti ambayo imefutwa",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user}amekutaja katika maoni kwenye\"{file}\"",
+ "Files app plugin to add comments to files" : "Programu-jalizi ya Faili ili kuongeza maoni kwenye faili ",
+ "Edit comment" : "Hariri maoni",
+ "Delete comment" : "Futa maoni",
+ "Cancel edit" : "Sistisha uhariri",
+ "New comment" : "Maoni mapya",
+ "Write a comment …" : "Andika maoni...",
+ "Post comment" : "Tuma maoni",
+ "@ for mentions, : for emoji, / for smart picker" : "@ kwa mitajo, : kwa emoji, / kwa kichagua smart",
+ "Could not reload comments" : "Haikuweza kupakia maoni",
+ "Failed to mark comments as read" : "imeshindwa kuweka alama kwenye maoni kama yamesomwa",
+ "Unable to load the comments list" : "Haiwezi kupakia orodha ya maoni",
+ "No comments yet, start the conversation!" : "Bado hakuna maoni, anza mazungumzo",
+ "No more messages" : "Hakuna jumbe zaidi",
+ "Retry" : "Jaribu tene",
+ "_1 new comment_::_{unread} new comments_" : ["1 new comment","{unread}maoni mapya "],
+ "Comment" : "Maoni",
+ "An error occurred while trying to edit the comment" : "Hitilafu ilitokea wakati wa kujaribu kuhariri maoni",
+ "Comment deleted" : "Maoni yamefutwa",
+ "An error occurred while trying to delete the comment" : "Hitilafu ilitokea wakati wa kujaribu kufuta maoni",
+ "An error occurred while trying to create the comment" : "Hitilafu ilitokea wakati wa kujaribu kuunda maoni"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/comments/l10n/ta_LK.js b/apps/comments/l10n/ta_LK.js
deleted file mode 100644
index 8d16f1e90b6..00000000000
--- a/apps/comments/l10n/ta_LK.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "இரத்து செய்க",
- "Save" : "சேமிக்க "
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/ta_LK.json b/apps/comments/l10n/ta_LK.json
deleted file mode 100644
index b1a589161a6..00000000000
--- a/apps/comments/l10n/ta_LK.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "இரத்து செய்க",
- "Save" : "சேமிக்க "
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/te.js b/apps/comments/l10n/te.js
deleted file mode 100644
index ac519b5e833..00000000000
--- a/apps/comments/l10n/te.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "రద్దుచేయి",
- "Save" : "భద్రపరచు"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/te.json b/apps/comments/l10n/te.json
deleted file mode 100644
index 3184274b231..00000000000
--- a/apps/comments/l10n/te.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "రద్దుచేయి",
- "Save" : "భద్రపరచు"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/th_TH.js b/apps/comments/l10n/th_TH.js
deleted file mode 100644
index ba0e9aa812c..00000000000
--- a/apps/comments/l10n/th_TH.js
+++ /dev/null
@@ -1,17 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "<strong>Comments</strong> for files" : "<strong>แสดงความคิดเห็น</strong> สำหรับไฟล์",
- "%1$s commented" : "%1$s ได้ถูกแสดงความคิดเห็น",
- "%1$s commented on %2$s" : "%1$s ได้ถูกแสดงความคิดเห็นบน %2$s",
- "Comments" : "ความคิดเห็น",
- "Type in a new comment..." : "พิมพ์ความคิดเห็นใหม่ ...",
- "Delete comment" : "ลบความคิดเห็น",
- "Post" : "โพสต์",
- "Cancel" : "ยกเลิก",
- "Edit comment" : "แก้ไขความคิดเห็น",
- "[Deleted user]" : "[ผู้ใช้ถูกลบไปแล้ว]",
- "Save" : "บันทึก",
- "Comment" : "แสดงความคิดเห็น"
-},
-"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/th_TH.json b/apps/comments/l10n/th_TH.json
deleted file mode 100644
index 02ce39195c7..00000000000
--- a/apps/comments/l10n/th_TH.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>แสดงความคิดเห็น</strong> สำหรับไฟล์",
- "%1$s commented" : "%1$s ได้ถูกแสดงความคิดเห็น",
- "%1$s commented on %2$s" : "%1$s ได้ถูกแสดงความคิดเห็นบน %2$s",
- "Comments" : "ความคิดเห็น",
- "Type in a new comment..." : "พิมพ์ความคิดเห็นใหม่ ...",
- "Delete comment" : "ลบความคิดเห็น",
- "Post" : "โพสต์",
- "Cancel" : "ยกเลิก",
- "Edit comment" : "แก้ไขความคิดเห็น",
- "[Deleted user]" : "[ผู้ใช้ถูกลบไปแล้ว]",
- "Save" : "บันทึก",
- "Comment" : "แสดงความคิดเห็น"
-},"pluralForm" :"nplurals=1; plural=0;"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/tr.js b/apps/comments/l10n/tr.js
index ff5bbca4081..c8294d0ec30 100644
--- a/apps/comments/l10n/tr.js
+++ b/apps/comments/l10n/tr.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "Dosyalar için <strong>yorumlar</strong>",
+ "Comments" : "Yorumlar",
"You commented" : "Yorum yaptınız",
- "%1$s commented" : "%1$s yorumlanmış",
- "You commented on %2$s" : "%2$s için yorum yaptınız",
+ "{author} commented" : "{author} yorum yaptı",
+ "You commented on %1$s" : "%1$s hakkında yorum yaptınız",
+ "You commented on {file}" : "{file} hakkında yorum yaptınız",
"%1$s commented on %2$s" : "%1$s, %2$s için yorum yaptı",
- "Comments" : "Yorumlar",
- "Type in a new comment..." : "Yeni bir yorum yazın...",
- "Delete comment" : "Yorumu sil",
- "Post" : "Gönder",
- "Cancel" : "İptal",
+ "{author} commented on {file}" : "{author}, {file} hakkında yorum yaptı",
+ "<strong>Comments</strong> for files" : "Dosyalar için <strong>yorum</strong> yapıldığında",
+ "Files" : "Dosyalar",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "\"{file}\" hakkında bir yorumda silinmiş bir hesap tarafından anıldınız",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user}, \"{file}\" hakkındaki bir yorumda sizi andı",
+ "Files app plugin to add comments to files" : "Dosyalara notlar eklenmesini sağlayan Dosyalar uygulaması eklentisi",
"Edit comment" : "Yorumu düzenle",
- "[Deleted user]" : "[Silinmiş kullanıcı]",
- "No other comments available" : "Mevcut başka yorum yok",
- "More comments..." : "Daha fazla yorum...",
- "Save" : "Kaydet",
- "Allowed characters {count} of {max}" : "İzin verilen karakterler {count}/{max}",
- "{count} unread comments" : "{count} okunmamış yorum",
- "Comment" : "Yorum"
+ "Delete comment" : "Yorumu sil",
+ "Cancel edit" : "Düzenlemeyi iptal et",
+ "New comment" : "Yorum ekle",
+ "Write a comment …" : "Bir yorum yazın…",
+ "Post comment" : "Yorum gönder",
+ "@ for mentions, : for emoji, / for smart picker" : "Anmalar için @, emojiler için :, akıllı seçici için /",
+ "Could not reload comments" : "Yorumlar yeniden yüklenemedi",
+ "Failed to mark comments as read" : "Yorumlar okunmuş olarak işaretlenemedi",
+ "Unable to load the comments list" : "Yorum listesi yüklenemedi",
+ "No comments yet, start the conversation!" : "Henüz bir yorum yapılmamış! Bir görüşme başlatın!",
+ "No more messages" : "Başka ileti yok",
+ "Retry" : "Yeniden dene",
+ "_1 new comment_::_{unread} new comments_" : ["1 yeni yorum","{unread} yeni yorum"],
+ "Comment" : "Yorum",
+ "An error occurred while trying to edit the comment" : "Yorum düzenlenmeye çalışılırken bir sorun çıktı",
+ "Comment deleted" : "Yorum silindi",
+ "An error occurred while trying to delete the comment" : "Yorum silinmeye çalışılırken bir sorun çıktı",
+ "An error occurred while trying to create the comment" : "Yorum eklenmeye çalışılırken bir sorun çıktı"
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/comments/l10n/tr.json b/apps/comments/l10n/tr.json
index 724670c53ae..4664a265367 100644
--- a/apps/comments/l10n/tr.json
+++ b/apps/comments/l10n/tr.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "Dosyalar için <strong>yorumlar</strong>",
+ "Comments" : "Yorumlar",
"You commented" : "Yorum yaptınız",
- "%1$s commented" : "%1$s yorumlanmış",
- "You commented on %2$s" : "%2$s için yorum yaptınız",
+ "{author} commented" : "{author} yorum yaptı",
+ "You commented on %1$s" : "%1$s hakkında yorum yaptınız",
+ "You commented on {file}" : "{file} hakkında yorum yaptınız",
"%1$s commented on %2$s" : "%1$s, %2$s için yorum yaptı",
- "Comments" : "Yorumlar",
- "Type in a new comment..." : "Yeni bir yorum yazın...",
- "Delete comment" : "Yorumu sil",
- "Post" : "Gönder",
- "Cancel" : "İptal",
+ "{author} commented on {file}" : "{author}, {file} hakkında yorum yaptı",
+ "<strong>Comments</strong> for files" : "Dosyalar için <strong>yorum</strong> yapıldığında",
+ "Files" : "Dosyalar",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "\"{file}\" hakkında bir yorumda silinmiş bir hesap tarafından anıldınız",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user}, \"{file}\" hakkındaki bir yorumda sizi andı",
+ "Files app plugin to add comments to files" : "Dosyalara notlar eklenmesini sağlayan Dosyalar uygulaması eklentisi",
"Edit comment" : "Yorumu düzenle",
- "[Deleted user]" : "[Silinmiş kullanıcı]",
- "No other comments available" : "Mevcut başka yorum yok",
- "More comments..." : "Daha fazla yorum...",
- "Save" : "Kaydet",
- "Allowed characters {count} of {max}" : "İzin verilen karakterler {count}/{max}",
- "{count} unread comments" : "{count} okunmamış yorum",
- "Comment" : "Yorum"
+ "Delete comment" : "Yorumu sil",
+ "Cancel edit" : "Düzenlemeyi iptal et",
+ "New comment" : "Yorum ekle",
+ "Write a comment …" : "Bir yorum yazın…",
+ "Post comment" : "Yorum gönder",
+ "@ for mentions, : for emoji, / for smart picker" : "Anmalar için @, emojiler için :, akıllı seçici için /",
+ "Could not reload comments" : "Yorumlar yeniden yüklenemedi",
+ "Failed to mark comments as read" : "Yorumlar okunmuş olarak işaretlenemedi",
+ "Unable to load the comments list" : "Yorum listesi yüklenemedi",
+ "No comments yet, start the conversation!" : "Henüz bir yorum yapılmamış! Bir görüşme başlatın!",
+ "No more messages" : "Başka ileti yok",
+ "Retry" : "Yeniden dene",
+ "_1 new comment_::_{unread} new comments_" : ["1 yeni yorum","{unread} yeni yorum"],
+ "Comment" : "Yorum",
+ "An error occurred while trying to edit the comment" : "Yorum düzenlenmeye çalışılırken bir sorun çıktı",
+ "Comment deleted" : "Yorum silindi",
+ "An error occurred while trying to delete the comment" : "Yorum silinmeye çalışılırken bir sorun çıktı",
+ "An error occurred while trying to create the comment" : "Yorum eklenmeye çalışılırken bir sorun çıktı"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/ug.js b/apps/comments/l10n/ug.js
index 589911eeb21..dc45071aa69 100644
--- a/apps/comments/l10n/ug.js
+++ b/apps/comments/l10n/ug.js
@@ -1,7 +1,35 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "ۋاز كەچ",
- "Save" : "ساقلا"
+ "Comments" : "باھا",
+ "You commented" : "باھا بەردىڭىز",
+ "{author} commented" : "{author} باھا بەردى",
+ "You commented on %1$s" : "سىز%1 $ s غا باھا بەردىڭىز",
+ "You commented on {file}" : "سىز {file} گە باھا بەردىڭىز",
+ "%1$s commented on %2$s" : "%1 $ s%2 $ s غا باھا بەردى",
+ "{author} commented on {file}" : "{author} بولسا {file} گە باھا بەردى",
+ "<strong>Comments</strong> for files" : "ھۆججەتلەر ئۈچۈن <strong> باھا </ strong>",
+ "Files" : "ھۆججەتلەر",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "سىز ئۆچۈرۈلگەن ھېساباتنىڭ ئىزاھاتىدا سىز «{file}» دە تىلغا ئېلىندى",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} سىزنى \"{file}\" دىكى باھادا تىلغا ئالدى",
+ "Files app plugin to add comments to files" : "ھۆججەتلەرگە باھا قوشۇش ئۈچۈن ھۆججەت قىستۇرمىسى",
+ "Edit comment" : "باھا تەھرىرلەش",
+ "Delete comment" : "باھانى ئۆچۈرۈڭ",
+ "Cancel edit" : "تەھرىرلەشنى ئەمەلدىن قالدۇرۇڭ",
+ "New comment" : "يېڭى باھا",
+ "Write a comment …" : "باھا يېزىڭ…",
+ "Post comment" : "ئىنكاس يېزىڭ",
+ "@ for mentions, : for emoji, / for smart picker" : "@ تىلغا ئېلىش ئۈچۈن ،: emoji ئۈچۈن ، / ئەقلىي ئىقتىدارلىق تاللىغۇچ ئۈچۈن",
+ "Could not reload comments" : "ئىنكاسلارنى قايتا يۈكلىيەلمىدى",
+ "Failed to mark comments as read" : "ئىنكاسلارنى ئوقۇشقا بەلگە قويمىدى",
+ "Unable to load the comments list" : "باھا تىزىملىكىنى يۈكلىيەلمىدى",
+ "No comments yet, start the conversation!" : "تېخى باھا يوق ، سۆھبەتنى باشلاڭ!",
+ "No more messages" : "باشقا ئۇچۇر يوق",
+ "Retry" : "قايتا سىناڭ",
+ "Comment" : "باھا",
+ "An error occurred while trying to edit the comment" : "باھانى تەھرىرلىمەكچى بولغاندا خاتالىق كۆرۈلدى",
+ "Comment deleted" : "باھا ئۆچۈرۈلدى",
+ "An error occurred while trying to delete the comment" : "باھانى ئۆچۈرمەكچى بولغاندا خاتالىق كۆرۈلدى",
+ "An error occurred while trying to create the comment" : "باھا قۇرماقچى بولغاندا خاتالىق كۆرۈلدى"
},
-"nplurals=1; plural=0;");
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/ug.json b/apps/comments/l10n/ug.json
index 627eb112502..a7669c2131c 100644
--- a/apps/comments/l10n/ug.json
+++ b/apps/comments/l10n/ug.json
@@ -1,5 +1,33 @@
{ "translations": {
- "Cancel" : "ۋاز كەچ",
- "Save" : "ساقلا"
-},"pluralForm" :"nplurals=1; plural=0;"
+ "Comments" : "باھا",
+ "You commented" : "باھا بەردىڭىز",
+ "{author} commented" : "{author} باھا بەردى",
+ "You commented on %1$s" : "سىز%1 $ s غا باھا بەردىڭىز",
+ "You commented on {file}" : "سىز {file} گە باھا بەردىڭىز",
+ "%1$s commented on %2$s" : "%1 $ s%2 $ s غا باھا بەردى",
+ "{author} commented on {file}" : "{author} بولسا {file} گە باھا بەردى",
+ "<strong>Comments</strong> for files" : "ھۆججەتلەر ئۈچۈن <strong> باھا </ strong>",
+ "Files" : "ھۆججەتلەر",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "سىز ئۆچۈرۈلگەن ھېساباتنىڭ ئىزاھاتىدا سىز «{file}» دە تىلغا ئېلىندى",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} سىزنى \"{file}\" دىكى باھادا تىلغا ئالدى",
+ "Files app plugin to add comments to files" : "ھۆججەتلەرگە باھا قوشۇش ئۈچۈن ھۆججەت قىستۇرمىسى",
+ "Edit comment" : "باھا تەھرىرلەش",
+ "Delete comment" : "باھانى ئۆچۈرۈڭ",
+ "Cancel edit" : "تەھرىرلەشنى ئەمەلدىن قالدۇرۇڭ",
+ "New comment" : "يېڭى باھا",
+ "Write a comment …" : "باھا يېزىڭ…",
+ "Post comment" : "ئىنكاس يېزىڭ",
+ "@ for mentions, : for emoji, / for smart picker" : "@ تىلغا ئېلىش ئۈچۈن ،: emoji ئۈچۈن ، / ئەقلىي ئىقتىدارلىق تاللىغۇچ ئۈچۈن",
+ "Could not reload comments" : "ئىنكاسلارنى قايتا يۈكلىيەلمىدى",
+ "Failed to mark comments as read" : "ئىنكاسلارنى ئوقۇشقا بەلگە قويمىدى",
+ "Unable to load the comments list" : "باھا تىزىملىكىنى يۈكلىيەلمىدى",
+ "No comments yet, start the conversation!" : "تېخى باھا يوق ، سۆھبەتنى باشلاڭ!",
+ "No more messages" : "باشقا ئۇچۇر يوق",
+ "Retry" : "قايتا سىناڭ",
+ "Comment" : "باھا",
+ "An error occurred while trying to edit the comment" : "باھانى تەھرىرلىمەكچى بولغاندا خاتالىق كۆرۈلدى",
+ "Comment deleted" : "باھا ئۆچۈرۈلدى",
+ "An error occurred while trying to delete the comment" : "باھانى ئۆچۈرمەكچى بولغاندا خاتالىق كۆرۈلدى",
+ "An error occurred while trying to create the comment" : "باھا قۇرماقچى بولغاندا خاتالىق كۆرۈلدى"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/uk.js b/apps/comments/l10n/uk.js
index a7e1cbad958..03b1fea5b85 100644
--- a/apps/comments/l10n/uk.js
+++ b/apps/comments/l10n/uk.js
@@ -1,21 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>Коментарі</strong> до файлів",
- "%1$s commented" : "%1$s прокоментовано",
- "%1$s commented on %2$s" : "%1$s прокоментовано у %2$s",
"Comments" : "Коментарі",
- "Type in a new comment..." : "Введіть новий коментар...",
- "Delete comment" : "Видалити коментар",
- "Post" : "Відправити",
- "Cancel" : "Скасувати",
+ "You commented" : "Ви прокоментували",
+ "{author} commented" : "{author} прокоментував(-ла)",
+ "You commented on %1$s" : "Ви прокоментували на %1$s",
+ "You commented on {file}" : "Ви прокоментували {file}",
+ "%1$s commented on %2$s" : "%1$s прокоментовано у %2$s",
+ "{author} commented on {file}" : "{author} прокоментував(-ла) {file}",
+ "<strong>Comments</strong> for files" : "З'явилися <strong>коментарі</strong> до файлів",
+ "Files" : "Файли",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Вас згадали у \"{file}\" в коментарі, який було додано користувачем, якого було вилучено",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} згадав вас у коментарі до \"{file}\"",
+ "Files app plugin to add comments to files" : "Плаґін до застосунку и\"Файли\" для додавання коментарів до файлів",
"Edit comment" : "Редагувати коментар",
- "[Deleted user]" : "[Видалений користувач]",
- "No other comments available" : "Інші коментарі не доступні",
- "More comments..." : "Більше коментарів...",
- "Save" : "Зберегти",
- "Allowed characters {count} of {max}" : "Доступно символів {count} з {max}",
- "{count} unread comments" : "{count} непрочитаних коментарів",
- "Comment" : "Коментар"
+ "Delete comment" : "Вилучити коментар",
+ "Cancel edit" : "Скасувати редагування",
+ "New comment" : "Новий коментар",
+ "Write a comment …" : "Додати коментар ...",
+ "Post comment" : "Опублікувати коментар",
+ "@ for mentions, : for emoji, / for smart picker" : "@ згадати, : емоційки, / асистент вибору",
+ "Could not reload comments" : "Не вдалося перезавантажити коментарі",
+ "Failed to mark comments as read" : "Не вдалося позначити коментарі прочитаними",
+ "Unable to load the comments list" : "Не вдалося завантажити список коментарів",
+ "No comments yet, start the conversation!" : "Тут можна додати коментарі",
+ "No more messages" : "Більше жодних повідомлень",
+ "Retry" : "Ще раз",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} новий коментар","{unread} нових коментарів","{unread} нових коментарів","{unread} нових коментарів"],
+ "Comment" : "Коментар",
+ "An error occurred while trying to edit the comment" : "Під час редагування коментаря сталася помилка",
+ "Comment deleted" : "Коментар вилучено",
+ "An error occurred while trying to delete the comment" : "Під час спроби вилучити коментар сталася помилка",
+ "An error occurred while trying to create the comment" : "Під час створення коментаря сталася помилка"
},
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
+"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);");
diff --git a/apps/comments/l10n/uk.json b/apps/comments/l10n/uk.json
index ff3f3b7dc64..7802b6d4f15 100644
--- a/apps/comments/l10n/uk.json
+++ b/apps/comments/l10n/uk.json
@@ -1,19 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>Коментарі</strong> до файлів",
- "%1$s commented" : "%1$s прокоментовано",
- "%1$s commented on %2$s" : "%1$s прокоментовано у %2$s",
"Comments" : "Коментарі",
- "Type in a new comment..." : "Введіть новий коментар...",
- "Delete comment" : "Видалити коментар",
- "Post" : "Відправити",
- "Cancel" : "Скасувати",
+ "You commented" : "Ви прокоментували",
+ "{author} commented" : "{author} прокоментував(-ла)",
+ "You commented on %1$s" : "Ви прокоментували на %1$s",
+ "You commented on {file}" : "Ви прокоментували {file}",
+ "%1$s commented on %2$s" : "%1$s прокоментовано у %2$s",
+ "{author} commented on {file}" : "{author} прокоментував(-ла) {file}",
+ "<strong>Comments</strong> for files" : "З'явилися <strong>коментарі</strong> до файлів",
+ "Files" : "Файли",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Вас згадали у \"{file}\" в коментарі, який було додано користувачем, якого було вилучено",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} згадав вас у коментарі до \"{file}\"",
+ "Files app plugin to add comments to files" : "Плаґін до застосунку и\"Файли\" для додавання коментарів до файлів",
"Edit comment" : "Редагувати коментар",
- "[Deleted user]" : "[Видалений користувач]",
- "No other comments available" : "Інші коментарі не доступні",
- "More comments..." : "Більше коментарів...",
- "Save" : "Зберегти",
- "Allowed characters {count} of {max}" : "Доступно символів {count} з {max}",
- "{count} unread comments" : "{count} непрочитаних коментарів",
- "Comment" : "Коментар"
-},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
+ "Delete comment" : "Вилучити коментар",
+ "Cancel edit" : "Скасувати редагування",
+ "New comment" : "Новий коментар",
+ "Write a comment …" : "Додати коментар ...",
+ "Post comment" : "Опублікувати коментар",
+ "@ for mentions, : for emoji, / for smart picker" : "@ згадати, : емоційки, / асистент вибору",
+ "Could not reload comments" : "Не вдалося перезавантажити коментарі",
+ "Failed to mark comments as read" : "Не вдалося позначити коментарі прочитаними",
+ "Unable to load the comments list" : "Не вдалося завантажити список коментарів",
+ "No comments yet, start the conversation!" : "Тут можна додати коментарі",
+ "No more messages" : "Більше жодних повідомлень",
+ "Retry" : "Ще раз",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} новий коментар","{unread} нових коментарів","{unread} нових коментарів","{unread} нових коментарів"],
+ "Comment" : "Коментар",
+ "An error occurred while trying to edit the comment" : "Під час редагування коментаря сталася помилка",
+ "Comment deleted" : "Коментар вилучено",
+ "An error occurred while trying to delete the comment" : "Під час спроби вилучити коментар сталася помилка",
+ "An error occurred while trying to create the comment" : "Під час створення коментаря сталася помилка"
+},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"
} \ No newline at end of file
diff --git a/apps/comments/l10n/ur_PK.js b/apps/comments/l10n/ur_PK.js
deleted file mode 100644
index 2808425d15a..00000000000
--- a/apps/comments/l10n/ur_PK.js
+++ /dev/null
@@ -1,7 +0,0 @@
-OC.L10N.register(
- "comments",
- {
- "Cancel" : "منسوخ کریں",
- "Save" : "حفظ"
-},
-"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/ur_PK.json b/apps/comments/l10n/ur_PK.json
deleted file mode 100644
index 83df86652d2..00000000000
--- a/apps/comments/l10n/ur_PK.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{ "translations": {
- "Cancel" : "منسوخ کریں",
- "Save" : "حفظ"
-},"pluralForm" :"nplurals=2; plural=(n != 1);"
-} \ No newline at end of file
diff --git a/apps/comments/l10n/vi.js b/apps/comments/l10n/vi.js
index b21b2905116..7ee551e6efb 100644
--- a/apps/comments/l10n/vi.js
+++ b/apps/comments/l10n/vi.js
@@ -1,7 +1,31 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "Hủy",
- "Save" : "Lưu"
+ "Comments" : "Bình luận",
+ "You commented" : "Bạn đã bình luận",
+ "{author} commented" : "{author} đã bình luận",
+ "You commented on %1$s" : "Bạn đã bình luận về %1$s",
+ "You commented on {file}" : "Bạn đã bình luận đối với tệp tin {file}",
+ "%1$s commented on %2$s" : "%1$s đã bình luận về%2$s",
+ "{author} commented on {file}" : "{author} đã bình luận về tệp tin {file}",
+ "<strong>Comments</strong> for files" : "<strong>bình luận</strong> đối với các tệp tin",
+ "Files" : "Tệp tin",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} đã nhắc tới bạn trong một bình luận trên \"{file}\"",
+ "Files app plugin to add comments to files" : "Plugin ứng dụng Tệp để thêm bình luận vào tệp",
+ "Edit comment" : "Sửa bình luận",
+ "Delete comment" : "Xóa bình luận",
+ "Cancel edit" : "Hủy chỉnh sửa",
+ "Post comment" : "Đăng bình luận",
+ "Failed to mark comments as read" : "Không thể đánh dấu bình luận là đã đọc",
+ "Unable to load the comments list" : "Không thể tải danh sách bình luận",
+ "No comments yet, start the conversation!" : "Không có bình luận nào, bắt đầu cuộc hội thoại!",
+ "No more messages" : "Không có thêm tin nhắn",
+ "Retry" : "Thử lại",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} bình luận mới"],
+ "Comment" : "Bình luận",
+ "An error occurred while trying to edit the comment" : "Đã xảy ra lỗi khi cố gắng chỉnh sửa bình luận",
+ "Comment deleted" : "Đã xóa bình luận",
+ "An error occurred while trying to delete the comment" : "Đã xảy ra lỗi khi cố gắng xóa bình luận",
+ "An error occurred while trying to create the comment" : "Đã xảy ra lỗi khi cố gắng tạo bình luận"
},
"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/vi.json b/apps/comments/l10n/vi.json
index 71ecdab9df5..a014378b887 100644
--- a/apps/comments/l10n/vi.json
+++ b/apps/comments/l10n/vi.json
@@ -1,5 +1,29 @@
{ "translations": {
- "Cancel" : "Hủy",
- "Save" : "Lưu"
+ "Comments" : "Bình luận",
+ "You commented" : "Bạn đã bình luận",
+ "{author} commented" : "{author} đã bình luận",
+ "You commented on %1$s" : "Bạn đã bình luận về %1$s",
+ "You commented on {file}" : "Bạn đã bình luận đối với tệp tin {file}",
+ "%1$s commented on %2$s" : "%1$s đã bình luận về%2$s",
+ "{author} commented on {file}" : "{author} đã bình luận về tệp tin {file}",
+ "<strong>Comments</strong> for files" : "<strong>bình luận</strong> đối với các tệp tin",
+ "Files" : "Tệp tin",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} đã nhắc tới bạn trong một bình luận trên \"{file}\"",
+ "Files app plugin to add comments to files" : "Plugin ứng dụng Tệp để thêm bình luận vào tệp",
+ "Edit comment" : "Sửa bình luận",
+ "Delete comment" : "Xóa bình luận",
+ "Cancel edit" : "Hủy chỉnh sửa",
+ "Post comment" : "Đăng bình luận",
+ "Failed to mark comments as read" : "Không thể đánh dấu bình luận là đã đọc",
+ "Unable to load the comments list" : "Không thể tải danh sách bình luận",
+ "No comments yet, start the conversation!" : "Không có bình luận nào, bắt đầu cuộc hội thoại!",
+ "No more messages" : "Không có thêm tin nhắn",
+ "Retry" : "Thử lại",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} bình luận mới"],
+ "Comment" : "Bình luận",
+ "An error occurred while trying to edit the comment" : "Đã xảy ra lỗi khi cố gắng chỉnh sửa bình luận",
+ "Comment deleted" : "Đã xóa bình luận",
+ "An error occurred while trying to delete the comment" : "Đã xảy ra lỗi khi cố gắng xóa bình luận",
+ "An error occurred while trying to create the comment" : "Đã xảy ra lỗi khi cố gắng tạo bình luận"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/zh_CN.js b/apps/comments/l10n/zh_CN.js
index edfd32a9926..1b29a108500 100644
--- a/apps/comments/l10n/zh_CN.js
+++ b/apps/comments/l10n/zh_CN.js
@@ -1,21 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "<strong>评论文件</strong>",
- "%1$s commented" : "%1$s 已评论",
- "%1$s commented on %2$s" : "%1$s 评论了 %2$s",
"Comments" : "评论",
- "Type in a new comment..." : "添加新评论...",
- "Delete comment" : "删除评论",
- "Post" : "发布",
- "Cancel" : "取消",
+ "You commented" : "你的评论",
+ "{author} commented" : "{author} 评论了",
+ "You commented on %1$s" : "你在 %1$s 的评论",
+ "You commented on {file}" : "你对 {file} 的评论",
+ "%1$s commented on %2$s" : "%1$s 评论了 %2$s",
+ "{author} commented on {file}" : "{author} 对 {file} 的评论",
+ "<strong>Comments</strong> for files" : "文件的<strong>评论</strong>",
+ "Files" : "文件",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "你在文件 “{file}” 内被一个已删除的账号评论提及",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} 在 “{file}” 的评论中提到了你",
+ "Files app plugin to add comments to files" : "文件应用插件可向文件添加评论",
"Edit comment" : "编辑评论",
- "[Deleted user]" : "[Deleted user]",
- "No other comments available" : "没有其他评论",
- "More comments..." : "更多评论...",
- "Save" : "保存",
- "Allowed characters {count} of {max}" : "当前字数: {count},最大允许:{max}",
- "{count} unread comments" : "{count} 条未读评论",
- "Comment" : "评论"
+ "Delete comment" : "删除评论",
+ "Cancel edit" : "取消编辑",
+ "New comment" : "新评论",
+ "Write a comment …" : "发表评论 ...",
+ "Post comment" : "发表评论",
+ "@ for mentions, : for emoji, / for smart picker" : "使用“@”提及,“:”输入表情符号,“/”唤起智能选择",
+ "Could not reload comments" : "无法重载评论",
+ "Failed to mark comments as read" : "无法将评论标记为已读",
+ "Unable to load the comments list" : "无法加载评论列表",
+ "No comments yet, start the conversation!" : "还没有评论,开始对话吧!",
+ "No more messages" : "没有更多消息",
+ "Retry" : "重试",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} 条新评论"],
+ "Comment" : "评论",
+ "An error occurred while trying to edit the comment" : "编辑评论时出错",
+ "Comment deleted" : "评论已删除",
+ "An error occurred while trying to delete the comment" : "删除评论时出错",
+ "An error occurred while trying to create the comment" : "创建评论时出错"
},
"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/zh_CN.json b/apps/comments/l10n/zh_CN.json
index 0eaefb409b1..a6d668e613c 100644
--- a/apps/comments/l10n/zh_CN.json
+++ b/apps/comments/l10n/zh_CN.json
@@ -1,19 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "<strong>评论文件</strong>",
- "%1$s commented" : "%1$s 已评论",
- "%1$s commented on %2$s" : "%1$s 评论了 %2$s",
"Comments" : "评论",
- "Type in a new comment..." : "添加新评论...",
- "Delete comment" : "删除评论",
- "Post" : "发布",
- "Cancel" : "取消",
+ "You commented" : "你的评论",
+ "{author} commented" : "{author} 评论了",
+ "You commented on %1$s" : "你在 %1$s 的评论",
+ "You commented on {file}" : "你对 {file} 的评论",
+ "%1$s commented on %2$s" : "%1$s 评论了 %2$s",
+ "{author} commented on {file}" : "{author} 对 {file} 的评论",
+ "<strong>Comments</strong> for files" : "文件的<strong>评论</strong>",
+ "Files" : "文件",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "你在文件 “{file}” 内被一个已删除的账号评论提及",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} 在 “{file}” 的评论中提到了你",
+ "Files app plugin to add comments to files" : "文件应用插件可向文件添加评论",
"Edit comment" : "编辑评论",
- "[Deleted user]" : "[Deleted user]",
- "No other comments available" : "没有其他评论",
- "More comments..." : "更多评论...",
- "Save" : "保存",
- "Allowed characters {count} of {max}" : "当前字数: {count},最大允许:{max}",
- "{count} unread comments" : "{count} 条未读评论",
- "Comment" : "评论"
+ "Delete comment" : "删除评论",
+ "Cancel edit" : "取消编辑",
+ "New comment" : "新评论",
+ "Write a comment …" : "发表评论 ...",
+ "Post comment" : "发表评论",
+ "@ for mentions, : for emoji, / for smart picker" : "使用“@”提及,“:”输入表情符号,“/”唤起智能选择",
+ "Could not reload comments" : "无法重载评论",
+ "Failed to mark comments as read" : "无法将评论标记为已读",
+ "Unable to load the comments list" : "无法加载评论列表",
+ "No comments yet, start the conversation!" : "还没有评论,开始对话吧!",
+ "No more messages" : "没有更多消息",
+ "Retry" : "重试",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} 条新评论"],
+ "Comment" : "评论",
+ "An error occurred while trying to edit the comment" : "编辑评论时出错",
+ "Comment deleted" : "评论已删除",
+ "An error occurred while trying to delete the comment" : "删除评论时出错",
+ "An error occurred while trying to create the comment" : "创建评论时出错"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/zh_HK.js b/apps/comments/l10n/zh_HK.js
index 65cddd342ca..ed0661f0655 100644
--- a/apps/comments/l10n/zh_HK.js
+++ b/apps/comments/l10n/zh_HK.js
@@ -1,7 +1,36 @@
OC.L10N.register(
"comments",
{
- "Cancel" : "取消",
- "Save" : "儲存"
+ "Comments" : "留言",
+ "You commented" : "您已留言",
+ "{author} commented" : "{author} 已留言",
+ "You commented on %1$s" : "你對 %1$s 留了言",
+ "You commented on {file}" : "你對 {file} 留了言",
+ "%1$s commented on %2$s" : "%1$s 對 %2$s 留了言",
+ "{author} commented on {file}" : "{author} 對 {file} 留了言",
+ "<strong>Comments</strong> for files" : "檔案的<strong>留言</strong>",
+ "Files" : "檔案",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "一個已被刪除的帳戶在 “{file}” 的留言中提到你",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} 在 “{file}” 的留言中提到你",
+ "Files app plugin to add comments to files" : "檔案插件程式插件,用於為檔案增加註釋",
+ "Edit comment" : "編輯留言",
+ "Delete comment" : "刪除留言",
+ "Cancel edit" : "取消編輯",
+ "New comment" : "新評論",
+ "Write a comment …" : "發表評論 ...",
+ "Post comment" : "張貼留言",
+ "@ for mentions, : for emoji, / for smart picker" : "“@” 表示提及,“:” 表示表情符號,“/” 表示智慧型選擇器",
+ "Could not reload comments" : "無法重新加載評論",
+ "Failed to mark comments as read" : "無法將評論標記為已讀",
+ "Unable to load the comments list" : "無法載入留言清單",
+ "No comments yet, start the conversation!" : "尚無留言,開始討論吧!",
+ "No more messages" : "沒有更多訊息",
+ "Retry" : "重試",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} 個新留言"],
+ "Comment" : "留言",
+ "An error occurred while trying to edit the comment" : "嘗試編輯此留言時錯誤",
+ "Comment deleted" : "意見刪除",
+ "An error occurred while trying to delete the comment" : "嘗試刪除此留言時錯誤",
+ "An error occurred while trying to create the comment" : "嘗試建立此留言時錯誤"
},
"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/zh_HK.json b/apps/comments/l10n/zh_HK.json
index 4da0032a014..ea90a3983ea 100644
--- a/apps/comments/l10n/zh_HK.json
+++ b/apps/comments/l10n/zh_HK.json
@@ -1,5 +1,34 @@
{ "translations": {
- "Cancel" : "取消",
- "Save" : "儲存"
+ "Comments" : "留言",
+ "You commented" : "您已留言",
+ "{author} commented" : "{author} 已留言",
+ "You commented on %1$s" : "你對 %1$s 留了言",
+ "You commented on {file}" : "你對 {file} 留了言",
+ "%1$s commented on %2$s" : "%1$s 對 %2$s 留了言",
+ "{author} commented on {file}" : "{author} 對 {file} 留了言",
+ "<strong>Comments</strong> for files" : "檔案的<strong>留言</strong>",
+ "Files" : "檔案",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "一個已被刪除的帳戶在 “{file}” 的留言中提到你",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} 在 “{file}” 的留言中提到你",
+ "Files app plugin to add comments to files" : "檔案插件程式插件,用於為檔案增加註釋",
+ "Edit comment" : "編輯留言",
+ "Delete comment" : "刪除留言",
+ "Cancel edit" : "取消編輯",
+ "New comment" : "新評論",
+ "Write a comment …" : "發表評論 ...",
+ "Post comment" : "張貼留言",
+ "@ for mentions, : for emoji, / for smart picker" : "“@” 表示提及,“:” 表示表情符號,“/” 表示智慧型選擇器",
+ "Could not reload comments" : "無法重新加載評論",
+ "Failed to mark comments as read" : "無法將評論標記為已讀",
+ "Unable to load the comments list" : "無法載入留言清單",
+ "No comments yet, start the conversation!" : "尚無留言,開始討論吧!",
+ "No more messages" : "沒有更多訊息",
+ "Retry" : "重試",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} 個新留言"],
+ "Comment" : "留言",
+ "An error occurred while trying to edit the comment" : "嘗試編輯此留言時錯誤",
+ "Comment deleted" : "意見刪除",
+ "An error occurred while trying to delete the comment" : "嘗試刪除此留言時錯誤",
+ "An error occurred while trying to create the comment" : "嘗試建立此留言時錯誤"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/comments/l10n/zh_TW.js b/apps/comments/l10n/zh_TW.js
index 41c0dd4b0f2..42e06d4e4dd 100644
--- a/apps/comments/l10n/zh_TW.js
+++ b/apps/comments/l10n/zh_TW.js
@@ -1,23 +1,36 @@
OC.L10N.register(
"comments",
{
- "<strong>Comments</strong> for files" : "檔案的<strong>留言</strong>",
- "You commented" : "您留言",
- "%1$s commented" : "%1$s 留言",
- "You commented on %2$s" : "您對 %2$s 留言",
- "%1$s commented on %2$s" : "%1$s 對 %2$s 留言",
"Comments" : "留言",
- "Type in a new comment..." : "輸入新留言…",
- "Delete comment" : "刪除留言",
- "Post" : "送出",
- "Cancel" : "取消",
+ "You commented" : "您已留言",
+ "{author} commented" : "{author} 已留言",
+ "You commented on %1$s" : "您已對 %1$s 留言",
+ "You commented on {file}" : "您已對 {file} 留言",
+ "%1$s commented on %2$s" : "%1$s 已對 %2$s 留言",
+ "{author} commented on {file}" : "{author} 已對 {file} 留言",
+ "<strong>Comments</strong> for files" : "檔案的<strong>留言</strong>",
+ "Files" : "檔案",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "一個已刪除的帳號在「{file}」的留言中提及您。",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} 在「{file}」的留言中提到您",
+ "Files app plugin to add comments to files" : "用於對檔案加入留言的檔案應用程式插入式元件",
"Edit comment" : "編輯留言",
- "[Deleted user]" : "[已刪除的使用者]",
- "No other comments available" : "沒有其他留言",
- "More comments..." : "更多留言…",
- "Save" : "儲存",
- "Allowed characters {count} of {max}" : "已輸入 {count} / 長度限制 {max}",
- "{count} unread comments" : "{count} 則未讀留言",
- "Comment" : "留言"
+ "Delete comment" : "刪除留言",
+ "Cancel edit" : "取消編輯",
+ "New comment" : "新留言",
+ "Write a comment …" : "編寫留言……",
+ "Post comment" : "張貼留言",
+ "@ for mentions, : for emoji, / for smart picker" : "@ 表示提及,: 表示表情符號,/ 表示智慧型選取",
+ "Could not reload comments" : "無法重新載入留言",
+ "Failed to mark comments as read" : "無法將留言標記為已讀",
+ "Unable to load the comments list" : "無法載入留言列表",
+ "No comments yet, start the conversation!" : "尚無留言,開始討論!",
+ "No more messages" : "沒有其他訊息",
+ "Retry" : "重試",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} 則新留言"],
+ "Comment" : "留言",
+ "An error occurred while trying to edit the comment" : "嘗試編輯留言時發生錯誤",
+ "Comment deleted" : "留言已刪除",
+ "An error occurred while trying to delete the comment" : "嘗試刪除留言時發生錯誤",
+ "An error occurred while trying to create the comment" : "嘗試建立留言時發生錯誤"
},
"nplurals=1; plural=0;");
diff --git a/apps/comments/l10n/zh_TW.json b/apps/comments/l10n/zh_TW.json
index 7fe1b0fb1fa..309eaba81b0 100644
--- a/apps/comments/l10n/zh_TW.json
+++ b/apps/comments/l10n/zh_TW.json
@@ -1,21 +1,34 @@
{ "translations": {
- "<strong>Comments</strong> for files" : "檔案的<strong>留言</strong>",
- "You commented" : "您留言",
- "%1$s commented" : "%1$s 留言",
- "You commented on %2$s" : "您對 %2$s 留言",
- "%1$s commented on %2$s" : "%1$s 對 %2$s 留言",
"Comments" : "留言",
- "Type in a new comment..." : "輸入新留言…",
- "Delete comment" : "刪除留言",
- "Post" : "送出",
- "Cancel" : "取消",
+ "You commented" : "您已留言",
+ "{author} commented" : "{author} 已留言",
+ "You commented on %1$s" : "您已對 %1$s 留言",
+ "You commented on {file}" : "您已對 {file} 留言",
+ "%1$s commented on %2$s" : "%1$s 已對 %2$s 留言",
+ "{author} commented on {file}" : "{author} 已對 {file} 留言",
+ "<strong>Comments</strong> for files" : "檔案的<strong>留言</strong>",
+ "Files" : "檔案",
+ "You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "一個已刪除的帳號在「{file}」的留言中提及您。",
+ "{user} mentioned you in a comment on \"{file}\"" : "{user} 在「{file}」的留言中提到您",
+ "Files app plugin to add comments to files" : "用於對檔案加入留言的檔案應用程式插入式元件",
"Edit comment" : "編輯留言",
- "[Deleted user]" : "[已刪除的使用者]",
- "No other comments available" : "沒有其他留言",
- "More comments..." : "更多留言…",
- "Save" : "儲存",
- "Allowed characters {count} of {max}" : "已輸入 {count} / 長度限制 {max}",
- "{count} unread comments" : "{count} 則未讀留言",
- "Comment" : "留言"
+ "Delete comment" : "刪除留言",
+ "Cancel edit" : "取消編輯",
+ "New comment" : "新留言",
+ "Write a comment …" : "編寫留言……",
+ "Post comment" : "張貼留言",
+ "@ for mentions, : for emoji, / for smart picker" : "@ 表示提及,: 表示表情符號,/ 表示智慧型選取",
+ "Could not reload comments" : "無法重新載入留言",
+ "Failed to mark comments as read" : "無法將留言標記為已讀",
+ "Unable to load the comments list" : "無法載入留言列表",
+ "No comments yet, start the conversation!" : "尚無留言,開始討論!",
+ "No more messages" : "沒有其他訊息",
+ "Retry" : "重試",
+ "_1 new comment_::_{unread} new comments_" : ["{unread} 則新留言"],
+ "Comment" : "留言",
+ "An error occurred while trying to edit the comment" : "嘗試編輯留言時發生錯誤",
+ "Comment deleted" : "留言已刪除",
+ "An error occurred while trying to delete the comment" : "嘗試刪除留言時發生錯誤",
+ "An error occurred while trying to create the comment" : "嘗試建立留言時發生錯誤"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/comments/lib/Activity/Filter.php b/apps/comments/lib/Activity/Filter.php
new file mode 100644
index 00000000000..8dcafd872d7
--- /dev/null
+++ b/apps/comments/lib/Activity/Filter.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Activity;
+
+use OCP\Activity\IFilter;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+
+class Filter implements IFilter {
+ public function __construct(
+ protected IL10N $l,
+ protected IURLGenerator $url,
+ ) {
+ }
+
+ public function getIdentifier(): string {
+ return 'comments';
+ }
+
+ public function getName(): string {
+ return $this->l->t('Comments');
+ }
+
+ public function getPriority(): int {
+ return 40;
+ }
+
+ public function getIcon(): string {
+ return $this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/comment.svg'));
+ }
+
+ /**
+ * @param string[] $types
+ * @return string[] An array of allowed apps from which activities should be displayed
+ */
+ public function filterTypes(array $types): array {
+ return $types;
+ }
+
+ /**
+ * @return string[] An array of allowed apps from which activities should be displayed
+ */
+ public function allowedApps(): array {
+ return ['comments'];
+ }
+}
diff --git a/apps/comments/lib/Activity/Listener.php b/apps/comments/lib/Activity/Listener.php
new file mode 100644
index 00000000000..45064f4a6be
--- /dev/null
+++ b/apps/comments/lib/Activity/Listener.php
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Comments\Activity;
+
+use OCP\Activity\IManager;
+use OCP\App\IAppManager;
+use OCP\Comments\CommentsEvent;
+use OCP\Files\Config\IMountProviderCollection;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+use OCP\IUser;
+use OCP\IUserSession;
+use OCP\Share\IShareHelper;
+
+class Listener {
+ public function __construct(
+ protected IManager $activityManager,
+ protected IUserSession $session,
+ protected IAppManager $appManager,
+ protected IMountProviderCollection $mountCollection,
+ protected IRootFolder $rootFolder,
+ protected IShareHelper $shareHelper,
+ ) {
+ }
+
+ public function commentEvent(CommentsEvent $event): void {
+ if ($event->getComment()->getObjectType() !== 'files'
+ || $event->getEvent() !== CommentsEvent::EVENT_ADD
+ || !$this->appManager->isEnabledForAnyone('activity')) {
+ // Comment not for file, not adding a comment or no activity-app enabled (save the energy)
+ return;
+ }
+
+ // Get all mount point owners
+ $cache = $this->mountCollection->getMountCache();
+ $mounts = $cache->getMountsForFileId((int)$event->getComment()->getObjectId());
+ if (empty($mounts)) {
+ return;
+ }
+
+ $users = [];
+ foreach ($mounts as $mount) {
+ $owner = $mount->getUser()->getUID();
+ $ownerFolder = $this->rootFolder->getUserFolder($owner);
+ $nodes = $ownerFolder->getById((int)$event->getComment()->getObjectId());
+ if (!empty($nodes)) {
+ /** @var Node $node */
+ $node = array_shift($nodes);
+ $al = $this->shareHelper->getPathsForAccessList($node);
+ $users += $al['users'];
+ }
+ }
+
+ $actor = $this->session->getUser();
+ if ($actor instanceof IUser) {
+ $actor = $actor->getUID();
+ } else {
+ $actor = '';
+ }
+
+ $activity = $this->activityManager->generateEvent();
+ $activity->setApp('comments')
+ ->setType('comments')
+ ->setAuthor($actor)
+ ->setObject($event->getComment()->getObjectType(), (int)$event->getComment()->getObjectId())
+ ->setMessage('add_comment_message', [
+ 'commentId' => $event->getComment()->getId(),
+ ]);
+
+ foreach ($users as $user => $path) {
+ // numerical user ids end up as integers from array keys, but string
+ // is required
+ $activity->setAffectedUser((string)$user);
+
+ $activity->setSubject('add_comment_subject', [
+ 'actor' => $actor,
+ 'fileId' => (int)$event->getComment()->getObjectId(),
+ 'filePath' => trim($path, '/'),
+ ]);
+ $this->activityManager->publish($activity);
+ }
+ }
+}
diff --git a/apps/comments/lib/Activity/Provider.php b/apps/comments/lib/Activity/Provider.php
new file mode 100644
index 00000000000..ee53357efdb
--- /dev/null
+++ b/apps/comments/lib/Activity/Provider.php
@@ -0,0 +1,198 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Activity;
+
+use OCP\Activity\Exceptions\UnknownActivityException;
+use OCP\Activity\IEvent;
+use OCP\Activity\IManager;
+use OCP\Activity\IProvider;
+use OCP\Comments\ICommentsManager;
+use OCP\Comments\NotFoundException;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+use OCP\IUserManager;
+use OCP\L10N\IFactory;
+
+class Provider implements IProvider {
+ protected ?IL10N $l = null;
+
+ public function __construct(
+ protected IFactory $languageFactory,
+ protected IURLGenerator $url,
+ protected ICommentsManager $commentsManager,
+ protected IUserManager $userManager,
+ protected IManager $activityManager,
+ ) {
+ }
+
+ /**
+ * @param string $language
+ * @param IEvent $event
+ * @param IEvent|null $previousEvent
+ * @return IEvent
+ * @throws UnknownActivityException
+ * @since 11.0.0
+ */
+ public function parse($language, IEvent $event, ?IEvent $previousEvent = null): IEvent {
+ if ($event->getApp() !== 'comments') {
+ throw new UnknownActivityException();
+ }
+
+ $this->l = $this->languageFactory->get('comments', $language);
+
+ if ($event->getSubject() === 'add_comment_subject') {
+ $this->parseMessage($event);
+ if ($this->activityManager->getRequirePNG()) {
+ $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/comment.png')));
+ } else {
+ $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/comment.svg')));
+ }
+
+ if ($this->activityManager->isFormattingFilteredObject()) {
+ try {
+ return $this->parseShortVersion($event);
+ } catch (UnknownActivityException) {
+ // Ignore and simply use the long version...
+ }
+ }
+
+ return $this->parseLongVersion($event);
+ }
+ throw new UnknownActivityException();
+
+ }
+
+ /**
+ * @throws UnknownActivityException
+ */
+ protected function parseShortVersion(IEvent $event): IEvent {
+ $subjectParameters = $this->getSubjectParameters($event);
+
+ if ($event->getSubject() === 'add_comment_subject') {
+ if ($subjectParameters['actor'] === $this->activityManager->getCurrentUserId()) {
+ $event->setRichSubject($this->l->t('You commented'), []);
+ } else {
+ $author = $this->generateUserParameter($subjectParameters['actor']);
+ $event->setRichSubject($this->l->t('{author} commented'), [
+ 'author' => $author,
+ ]);
+ }
+ } else {
+ throw new UnknownActivityException();
+ }
+
+ return $event;
+ }
+
+ /**
+ * @throws UnknownActivityException
+ */
+ protected function parseLongVersion(IEvent $event): IEvent {
+ $subjectParameters = $this->getSubjectParameters($event);
+
+ if ($event->getSubject() === 'add_comment_subject') {
+ if ($subjectParameters['actor'] === $this->activityManager->getCurrentUserId()) {
+ $event->setParsedSubject($this->l->t('You commented on %1$s', [
+ $subjectParameters['filePath'],
+ ]))
+ ->setRichSubject($this->l->t('You commented on {file}'), [
+ 'file' => $this->generateFileParameter($subjectParameters['fileId'], $subjectParameters['filePath']),
+ ]);
+ } else {
+ $author = $this->generateUserParameter($subjectParameters['actor']);
+ $event->setParsedSubject($this->l->t('%1$s commented on %2$s', [
+ $author['name'],
+ $subjectParameters['filePath'],
+ ]))
+ ->setRichSubject($this->l->t('{author} commented on {file}'), [
+ 'author' => $author,
+ 'file' => $this->generateFileParameter($subjectParameters['fileId'], $subjectParameters['filePath']),
+ ]);
+ }
+ } else {
+ throw new UnknownActivityException();
+ }
+
+ return $event;
+ }
+
+ protected function getSubjectParameters(IEvent $event): array {
+ $subjectParameters = $event->getSubjectParameters();
+ if (isset($subjectParameters['fileId'])) {
+ return $subjectParameters;
+ }
+
+ // Fix subjects from 12.0.3 and older
+ //
+ // Do NOT Remove unless necessary
+ // Removing this will break parsing of activities that were created on
+ // Nextcloud 12, so we should keep this as long as it's acceptable.
+ // Otherwise if people upgrade over multiple releases in a short period,
+ // they will get the dead entries in their stream.
+ return [
+ 'actor' => $subjectParameters[0],
+ 'fileId' => $event->getObjectId(),
+ 'filePath' => trim($subjectParameters[1], '/'),
+ ];
+ }
+
+ protected function parseMessage(IEvent $event): void {
+ $messageParameters = $event->getMessageParameters();
+ if (empty($messageParameters)) {
+ // Email
+ return;
+ }
+
+ $commentId = $messageParameters['commentId'] ?? $messageParameters[0];
+
+ try {
+ $comment = $this->commentsManager->get((string)$commentId);
+ $message = $comment->getMessage();
+
+ $mentionCount = 1;
+ $mentions = [];
+ foreach ($comment->getMentions() as $mention) {
+ if ($mention['type'] !== 'user') {
+ continue;
+ }
+
+ $message = str_replace('@"' . $mention['id'] . '"', '{mention' . $mentionCount . '}', $message);
+ if (!str_contains($mention['id'], ' ') && !str_starts_with($mention['id'], 'guest/')) {
+ $message = str_replace('@' . $mention['id'], '{mention' . $mentionCount . '}', $message);
+ }
+
+ $mentions['mention' . $mentionCount] = $this->generateUserParameter($mention['id']);
+ $mentionCount++;
+ }
+
+ $event->setParsedMessage($comment->getMessage())
+ ->setRichMessage($message, $mentions);
+ } catch (NotFoundException $e) {
+ }
+ }
+
+ /**
+ * @return array<string, string>
+ */
+ protected function generateFileParameter(int $id, string $path): array {
+ return [
+ 'type' => 'file',
+ 'id' => (string)$id,
+ 'name' => basename($path),
+ 'path' => $path,
+ 'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $id]),
+ ];
+ }
+
+ protected function generateUserParameter(string $uid): array {
+ return [
+ 'type' => 'user',
+ 'id' => $uid,
+ 'name' => $this->userManager->getDisplayName($uid) ?? $uid,
+ ];
+ }
+}
diff --git a/apps/comments/lib/Activity/Setting.php b/apps/comments/lib/Activity/Setting.php
new file mode 100644
index 00000000000..7fbf4001b20
--- /dev/null
+++ b/apps/comments/lib/Activity/Setting.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Activity;
+
+use OCP\Activity\ActivitySettings;
+use OCP\IL10N;
+
+class Setting extends ActivitySettings {
+ public function __construct(
+ protected IL10N $l,
+ ) {
+ }
+
+ public function getIdentifier(): string {
+ return 'comments';
+ }
+
+ public function getName(): string {
+ return $this->l->t('<strong>Comments</strong> for files');
+ }
+
+ public function getGroupIdentifier() {
+ return 'files';
+ }
+
+ public function getGroupName() {
+ return $this->l->t('Files');
+ }
+
+ public function getPriority(): int {
+ return 50;
+ }
+
+ public function canChangeStream(): bool {
+ return true;
+ }
+
+ public function isDefaultEnabledStream(): bool {
+ return true;
+ }
+
+ public function canChangeMail(): bool {
+ return true;
+ }
+
+ public function isDefaultEnabledMail(): bool {
+ return false;
+ }
+}
diff --git a/apps/comments/lib/AppInfo/Application.php b/apps/comments/lib/AppInfo/Application.php
new file mode 100644
index 00000000000..db4a2ce614c
--- /dev/null
+++ b/apps/comments/lib/AppInfo/Application.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\AppInfo;
+
+use OCA\Comments\Capabilities;
+use OCA\Comments\Listener\CommentsEntityEventListener;
+use OCA\Comments\Listener\CommentsEventListener;
+use OCA\Comments\Listener\LoadAdditionalScripts;
+use OCA\Comments\Listener\LoadSidebarScripts;
+use OCA\Comments\MaxAutoCompleteResultsInitialState;
+use OCA\Comments\Notification\Notifier;
+use OCA\Comments\Search\CommentsSearchProvider;
+use OCA\Files\Event\LoadAdditionalScriptsEvent;
+use OCA\Files\Event\LoadSidebar;
+use OCP\AppFramework\App;
+use OCP\AppFramework\Bootstrap\IBootContext;
+use OCP\AppFramework\Bootstrap\IBootstrap;
+use OCP\AppFramework\Bootstrap\IRegistrationContext;
+use OCP\Comments\CommentsEntityEvent;
+use OCP\Comments\CommentsEvent;
+
+class Application extends App implements IBootstrap {
+ public const APP_ID = 'comments';
+
+ public function __construct(array $urlParams = []) {
+ parent::__construct(self::APP_ID, $urlParams);
+ }
+
+ public function register(IRegistrationContext $context): void {
+ $context->registerCapability(Capabilities::class);
+
+ $context->registerEventListener(
+ LoadAdditionalScriptsEvent::class,
+ LoadAdditionalScripts::class
+ );
+ $context->registerEventListener(
+ LoadSidebar::class,
+ LoadSidebarScripts::class
+ );
+ $context->registerEventListener(
+ CommentsEntityEvent::class,
+ CommentsEntityEventListener::class
+ );
+ $context->registerEventListener(
+ CommentsEvent::class,
+ CommentsEventListener::class,
+ );
+
+ $context->registerSearchProvider(CommentsSearchProvider::class);
+
+ $context->registerInitialStateProvider(MaxAutoCompleteResultsInitialState::class);
+
+ $context->registerNotifierService(Notifier::class);
+ }
+
+ public function boot(IBootContext $context): void {
+ }
+}
diff --git a/apps/comments/lib/Capabilities.php b/apps/comments/lib/Capabilities.php
new file mode 100644
index 00000000000..2057803d867
--- /dev/null
+++ b/apps/comments/lib/Capabilities.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments;
+
+use OCP\Capabilities\ICapability;
+
+class Capabilities implements ICapability {
+ /**
+ * @return array{files: array{comments: bool}}
+ */
+ public function getCapabilities(): array {
+ return [
+ 'files' => [
+ 'comments' => true,
+ ]
+ ];
+ }
+}
diff --git a/apps/comments/lib/Collaboration/CommentersSorter.php b/apps/comments/lib/Collaboration/CommentersSorter.php
new file mode 100644
index 00000000000..baa27155573
--- /dev/null
+++ b/apps/comments/lib/Collaboration/CommentersSorter.php
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Collaboration;
+
+use OCP\Collaboration\AutoComplete\ISorter;
+use OCP\Comments\ICommentsManager;
+
+class CommentersSorter implements ISorter {
+ public function __construct(
+ private ICommentsManager $commentsManager,
+ ) {
+ }
+
+ public function getId(): string {
+ return 'commenters';
+ }
+
+ /**
+ * Sorts people who commented on the given item atop (descelating) of the
+ * others
+ *
+ * @param array &$sortArray
+ * @param array $context
+ */
+ public function sort(array &$sortArray, array $context): void {
+ $commenters = $this->retrieveCommentsInformation($context['itemType'], $context['itemId']);
+ if (count($commenters) === 0) {
+ return;
+ }
+
+ foreach ($sortArray as $type => &$byType) {
+ if (!isset($commenters[$type])) {
+ continue;
+ }
+
+ // at least on PHP 5.6 usort turned out to be not stable. So we add
+ // the current index to the value and compare it on a draw
+ $i = 0;
+ $workArray = array_map(function ($element) use (&$i) {
+ return [$i++, $element];
+ }, $byType);
+
+ usort($workArray, function ($a, $b) use ($commenters, $type) {
+ $r = $this->compare($a[1], $b[1], $commenters[$type]);
+ if ($r === 0) {
+ $r = $a[0] - $b[0];
+ }
+ return $r;
+ });
+
+ // and remove the index values again
+ $byType = array_column($workArray, 1);
+ }
+ }
+
+ /**
+ * @return array<string, array<string, int>>
+ */
+ protected function retrieveCommentsInformation(string $type, string $id): array {
+ $comments = $this->commentsManager->getForObject($type, $id);
+ if (count($comments) === 0) {
+ return [];
+ }
+
+ $actors = [];
+ foreach ($comments as $comment) {
+ if (!isset($actors[$comment->getActorType()])) {
+ $actors[$comment->getActorType()] = [];
+ }
+ if (!isset($actors[$comment->getActorType()][$comment->getActorId()])) {
+ $actors[$comment->getActorType()][$comment->getActorId()] = 1;
+ } else {
+ $actors[$comment->getActorType()][$comment->getActorId()]++;
+ }
+ }
+ return $actors;
+ }
+
+ protected function compare(array $a, array $b, array $commenters): int {
+ $a = $a['value']['shareWith'];
+ $b = $b['value']['shareWith'];
+
+ $valueA = $commenters[$a] ?? 0;
+ $valueB = $commenters[$b] ?? 0;
+
+ return $valueB - $valueA;
+ }
+}
diff --git a/apps/comments/lib/Controller/NotificationsController.php b/apps/comments/lib/Controller/NotificationsController.php
new file mode 100644
index 00000000000..0937b6929b8
--- /dev/null
+++ b/apps/comments/lib/Controller/NotificationsController.php
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Controller;
+
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
+use OCP\AppFramework\Http\Attribute\OpenAPI;
+use OCP\AppFramework\Http\Attribute\PublicPage;
+use OCP\AppFramework\Http\NotFoundResponse;
+use OCP\AppFramework\Http\RedirectResponse;
+use OCP\Comments\IComment;
+use OCP\Comments\ICommentsManager;
+use OCP\Files\IRootFolder;
+use OCP\IRequest;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\IUserSession;
+use OCP\Notification\IManager;
+
+/**
+ * @package OCA\Comments\Controller
+ */
+#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
+class NotificationsController extends Controller {
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ protected ICommentsManager $commentsManager,
+ protected IRootFolder $rootFolder,
+ protected IURLGenerator $urlGenerator,
+ protected IManager $notificationManager,
+ protected IUserSession $userSession,
+ ) {
+ parent::__construct($appName, $request);
+ }
+
+ /**
+ * View a notification
+ *
+ * @param string $id ID of the notification
+ *
+ * @return RedirectResponse<Http::STATUS_SEE_OTHER, array{}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
+ *
+ * 303: Redirected to notification
+ * 404: Notification not found
+ */
+ #[PublicPage]
+ #[NoCSRFRequired]
+ public function view(string $id): RedirectResponse|NotFoundResponse {
+ $currentUser = $this->userSession->getUser();
+ if (!$currentUser instanceof IUser) {
+ return new RedirectResponse(
+ $this->urlGenerator->linkToRoute('core.login.showLoginForm', [
+ 'redirect_url' => $this->urlGenerator->linkToRoute(
+ 'comments.Notifications.view',
+ ['id' => $id]
+ ),
+ ])
+ );
+ }
+
+ try {
+ $comment = $this->commentsManager->get($id);
+ if ($comment->getObjectType() !== 'files') {
+ return new NotFoundResponse();
+ }
+ $userFolder = $this->rootFolder->getUserFolder($currentUser->getUID());
+ $files = $userFolder->getById((int)$comment->getObjectId());
+
+ $this->markProcessed($comment, $currentUser);
+
+ if (empty($files)) {
+ return new NotFoundResponse();
+ }
+
+ $url = $this->urlGenerator->linkToRouteAbsolute(
+ 'files.viewcontroller.showFile',
+ [ 'fileid' => $comment->getObjectId() ]
+ );
+
+ return new RedirectResponse($url);
+ } catch (\Exception $e) {
+ return new NotFoundResponse();
+ }
+ }
+
+ /**
+ * Marks the notification about a comment as processed
+ */
+ protected function markProcessed(IComment $comment, IUser $currentUser): void {
+ $notification = $this->notificationManager->createNotification();
+ $notification->setApp('comments')
+ ->setObject('comment', $comment->getId())
+ ->setSubject('mention')
+ ->setUser($currentUser->getUID());
+ $this->notificationManager->markProcessed($notification);
+ }
+}
diff --git a/apps/comments/lib/Listener/CommentsEntityEventListener.php b/apps/comments/lib/Listener/CommentsEntityEventListener.php
new file mode 100644
index 00000000000..5aeeb3c63ea
--- /dev/null
+++ b/apps/comments/lib/Listener/CommentsEntityEventListener.php
@@ -0,0 +1,35 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Listener;
+
+use OCP\Comments\CommentsEntityEvent;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Files\IRootFolder;
+
+/** @template-implements IEventListener<CommentsEntityEvent> */
+class CommentsEntityEventListener implements IEventListener {
+ public function __construct(
+ private IRootFolder $rootFolder,
+ private ?string $userId = null,
+ ) {
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof CommentsEntityEvent)) {
+ // Unrelated
+ return;
+ }
+
+ $event->addEntityCollection('files', function ($name): bool {
+ $nodes = $this->rootFolder->getUserFolder($this->userId)->getById((int)$name);
+ return !empty($nodes);
+ });
+ }
+}
diff --git a/apps/comments/lib/Listener/CommentsEventListener.php b/apps/comments/lib/Listener/CommentsEventListener.php
new file mode 100644
index 00000000000..a1e44995162
--- /dev/null
+++ b/apps/comments/lib/Listener/CommentsEventListener.php
@@ -0,0 +1,63 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+
+namespace OCA\Comments\Listener;
+
+use OCA\Comments\Activity\Listener as ActivityListener;
+use OCA\Comments\Notification\Listener as NotificationListener;
+use OCP\Comments\CommentsEvent;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+
+/** @template-implements IEventListener<CommentsEvent|Event> */
+class CommentsEventListener implements IEventListener {
+ public function __construct(
+ private ActivityListener $activityListener,
+ private NotificationListener $notificationListener,
+ ) {
+ }
+
+ public function handle(Event $event): void {
+ if (!$event instanceof CommentsEvent) {
+ return;
+ }
+
+ if ($event->getComment()->getObjectType() !== 'files') {
+ // this is a 'files'-specific Handler
+ return;
+ }
+
+ $eventType = $event->getEvent();
+ if ($eventType === CommentsEvent::EVENT_ADD
+ ) {
+ $this->notificationHandler($event);
+ $this->activityHandler($event);
+ return;
+ }
+
+ $applicableEvents = [
+ CommentsEvent::EVENT_PRE_UPDATE,
+ CommentsEvent::EVENT_UPDATE,
+ CommentsEvent::EVENT_DELETE,
+ ];
+ if (in_array($eventType, $applicableEvents)) {
+ $this->notificationHandler($event);
+ return;
+ }
+ }
+
+ private function activityHandler(CommentsEvent $event): void {
+ $this->activityListener->commentEvent($event);
+ }
+
+ private function notificationHandler(CommentsEvent $event): void {
+ $this->notificationListener->evaluate($event);
+ }
+}
diff --git a/apps/comments/lib/Listener/LoadAdditionalScripts.php b/apps/comments/lib/Listener/LoadAdditionalScripts.php
new file mode 100644
index 00000000000..81e1bfe5310
--- /dev/null
+++ b/apps/comments/lib/Listener/LoadAdditionalScripts.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Listener;
+
+use OCA\Comments\AppInfo\Application;
+use OCA\Files\Event\LoadAdditionalScriptsEvent;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Util;
+
+/** @template-implements IEventListener<LoadAdditionalScriptsEvent> */
+class LoadAdditionalScripts implements IEventListener {
+ public function handle(Event $event): void {
+ if (!($event instanceof LoadAdditionalScriptsEvent)) {
+ return;
+ }
+
+ // Adding init script for file list inline actions
+ Util::addInitScript(Application::APP_ID, 'init');
+ }
+}
diff --git a/apps/comments/lib/Listener/LoadSidebarScripts.php b/apps/comments/lib/Listener/LoadSidebarScripts.php
new file mode 100644
index 00000000000..906fe40fed2
--- /dev/null
+++ b/apps/comments/lib/Listener/LoadSidebarScripts.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Listener;
+
+use OCA\Comments\AppInfo\Application;
+use OCA\Files\Event\LoadSidebar;
+use OCP\App\IAppManager;
+use OCP\AppFramework\Services\IInitialState;
+use OCP\Comments\ICommentsManager;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Util;
+
+/** @template-implements IEventListener<LoadSidebar> */
+class LoadSidebarScripts implements IEventListener {
+ public function __construct(
+ private ICommentsManager $commentsManager,
+ private IInitialState $initialState,
+ private IAppManager $appManager,
+ ) {
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof LoadSidebar)) {
+ return;
+ }
+
+ $this->commentsManager->load();
+
+ $this->initialState->provideInitialState('activityEnabled', $this->appManager->isEnabledForUser('activity'));
+ // Add comments sidebar tab script
+ Util::addScript(Application::APP_ID, 'comments-tab', 'files');
+ }
+}
diff --git a/apps/comments/lib/MaxAutoCompleteResultsInitialState.php b/apps/comments/lib/MaxAutoCompleteResultsInitialState.php
new file mode 100644
index 00000000000..b4c8f8719db
--- /dev/null
+++ b/apps/comments/lib/MaxAutoCompleteResultsInitialState.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments;
+
+use OCP\AppFramework\Services\InitialStateProvider;
+use OCP\IConfig;
+
+class MaxAutoCompleteResultsInitialState extends InitialStateProvider {
+ public function __construct(
+ private IConfig $config,
+ ) {
+ }
+
+ public function getKey(): string {
+ return 'maxAutoCompleteResults';
+ }
+
+ public function getData(): int {
+ return (int)$this->config->getAppValue('comments', 'maxAutoCompleteResults', '10');
+ }
+}
diff --git a/apps/comments/lib/Notification/Listener.php b/apps/comments/lib/Notification/Listener.php
new file mode 100644
index 00000000000..43922f85e59
--- /dev/null
+++ b/apps/comments/lib/Notification/Listener.php
@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Comments\Notification;
+
+use OCP\Comments\CommentsEvent;
+use OCP\Comments\IComment;
+use OCP\IUserManager;
+use OCP\Notification\IManager;
+use OCP\Notification\INotification;
+
+class Listener {
+ public function __construct(
+ protected IManager $notificationManager,
+ protected IUserManager $userManager,
+ ) {
+ }
+
+ public function evaluate(CommentsEvent $event): void {
+ $comment = $event->getComment();
+
+ $mentions = $this->extractMentions($comment->getMentions());
+ if (empty($mentions)) {
+ // no one to notify
+ return;
+ }
+
+ $notification = $this->instantiateNotification($comment);
+
+ foreach ($mentions as $uid) {
+ if (($comment->getActorType() === 'users' && $uid === $comment->getActorId())
+ || !$this->userManager->userExists($uid)
+ ) {
+ // do not notify unknown users or yourself
+ continue;
+ }
+
+ $notification->setUser($uid);
+ if ($event->getEvent() === CommentsEvent::EVENT_DELETE
+ || $event->getEvent() === CommentsEvent::EVENT_PRE_UPDATE) {
+ $this->notificationManager->markProcessed($notification);
+ } else {
+ $this->notificationManager->notify($notification);
+ }
+ }
+ }
+
+ /**
+ * Creates a notification instance and fills it with comment data
+ */
+ public function instantiateNotification(IComment $comment): INotification {
+ $notification = $this->notificationManager->createNotification();
+ $notification
+ ->setApp('comments')
+ ->setObject('comment', $comment->getId())
+ ->setSubject('mention', [ $comment->getObjectType(), $comment->getObjectId() ])
+ ->setDateTime($comment->getCreationDateTime());
+
+ return $notification;
+ }
+
+ /**
+ * Flattens the mention array returned from comments to a list of user ids.
+ *
+ * @param array $mentions
+ * @return list<string> containing the mentions, e.g. ['alice', 'bob']
+ */
+ public function extractMentions(array $mentions): array {
+ if (empty($mentions)) {
+ return [];
+ }
+ $uids = [];
+ foreach ($mentions as $mention) {
+ if ($mention['type'] === 'user') {
+ $uids[] = $mention['id'];
+ }
+ }
+ return $uids;
+ }
+}
diff --git a/apps/comments/lib/Notification/Notifier.php b/apps/comments/lib/Notification/Notifier.php
new file mode 100644
index 00000000000..62562bf42aa
--- /dev/null
+++ b/apps/comments/lib/Notification/Notifier.php
@@ -0,0 +1,177 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Comments\Notification;
+
+use OCP\Comments\IComment;
+use OCP\Comments\ICommentsManager;
+use OCP\Comments\NotFoundException;
+use OCP\Files\IRootFolder;
+use OCP\IURLGenerator;
+use OCP\IUserManager;
+use OCP\L10N\IFactory;
+use OCP\Notification\AlreadyProcessedException;
+use OCP\Notification\INotification;
+use OCP\Notification\INotifier;
+use OCP\Notification\UnknownNotificationException;
+
+class Notifier implements INotifier {
+ public function __construct(
+ protected IFactory $l10nFactory,
+ protected IRootFolder $rootFolder,
+ protected ICommentsManager $commentsManager,
+ protected IURLGenerator $url,
+ protected IUserManager $userManager,
+ ) {
+ }
+
+ /**
+ * Identifier of the notifier, only use [a-z0-9_]
+ *
+ * @return string
+ * @since 17.0.0
+ */
+ public function getID(): string {
+ return 'comments';
+ }
+
+ /**
+ * Human readable name describing the notifier
+ *
+ * @return string
+ * @since 17.0.0
+ */
+ public function getName(): string {
+ return $this->l10nFactory->get('comments')->t('Comments');
+ }
+
+ /**
+ * @param INotification $notification
+ * @param string $languageCode The code of the language that should be used to prepare the notification
+ * @return INotification
+ * @throws UnknownNotificationException When the notification was not prepared by a notifier
+ * @throws AlreadyProcessedException When the notification is not needed anymore and should be deleted
+ * @since 9.0.0
+ */
+ public function prepare(INotification $notification, string $languageCode): INotification {
+ if ($notification->getApp() !== 'comments') {
+ throw new UnknownNotificationException();
+ }
+ try {
+ $comment = $this->commentsManager->get($notification->getObjectId());
+ } catch (NotFoundException $e) {
+ // needs to be converted to InvalidArgumentException, otherwise none Notifications will be shown at all
+ throw new UnknownNotificationException('Comment not found', 0, $e);
+ }
+ $l = $this->l10nFactory->get('comments', $languageCode);
+ $displayName = $comment->getActorId();
+ $isDeletedActor = $comment->getActorType() === ICommentsManager::DELETED_USER;
+ if ($comment->getActorType() === 'users') {
+ $commenter = $this->userManager->getDisplayName($comment->getActorId());
+ if ($commenter !== null) {
+ $displayName = $commenter;
+ }
+ }
+
+ switch ($notification->getSubject()) {
+ case 'mention':
+ $parameters = $notification->getSubjectParameters();
+ if ($parameters[0] !== 'files') {
+ throw new UnknownNotificationException('Unsupported comment object');
+ }
+ $userFolder = $this->rootFolder->getUserFolder($notification->getUser());
+ $nodes = $userFolder->getById((int)$parameters[1]);
+ if (empty($nodes)) {
+ throw new AlreadyProcessedException();
+ }
+ $node = $nodes[0];
+
+ $path = rtrim($node->getPath(), '/');
+ if (str_starts_with($path, '/' . $notification->getUser() . '/files/')) {
+ // Remove /user/files/...
+ $fullPath = $path;
+ [,,, $path] = explode('/', $fullPath, 4);
+ }
+ $subjectParameters = [
+ 'file' => [
+ 'type' => 'file',
+ 'id' => $comment->getObjectId(),
+ 'name' => $node->getName(),
+ 'path' => $path,
+ 'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $comment->getObjectId()]),
+ ],
+ ];
+
+ if ($isDeletedActor) {
+ $subject = $l->t('You were mentioned on "{file}", in a comment by an account that has since been deleted');
+ } else {
+ $subject = $l->t('{user} mentioned you in a comment on "{file}"');
+ $subjectParameters['user'] = [
+ 'type' => 'user',
+ 'id' => $comment->getActorId(),
+ 'name' => $displayName,
+ ];
+ }
+ [$message, $messageParameters] = $this->commentToRichMessage($comment);
+ $notification->setRichSubject($subject, $subjectParameters)
+ ->setRichMessage($message, $messageParameters)
+ ->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/comment.svg')))
+ ->setLink($this->url->linkToRouteAbsolute(
+ 'comments.Notifications.view',
+ ['id' => $comment->getId()])
+ );
+
+ return $notification;
+ break;
+
+ default:
+ throw new UnknownNotificationException('Invalid subject');
+ }
+ }
+
+ public function commentToRichMessage(IComment $comment): array {
+ $message = $comment->getMessage();
+ $messageParameters = [];
+ $mentionTypeCount = [];
+ $mentions = $comment->getMentions();
+ foreach ($mentions as $mention) {
+ if ($mention['type'] === 'user') {
+ $userDisplayName = $this->userManager->getDisplayName($mention['id']);
+ if ($userDisplayName === null) {
+ continue;
+ }
+ }
+ if (!array_key_exists($mention['type'], $mentionTypeCount)) {
+ $mentionTypeCount[$mention['type']] = 0;
+ }
+ $mentionTypeCount[$mention['type']]++;
+ // To keep a limited character set in parameter IDs ([a-zA-Z0-9-])
+ // the mention parameter ID does not include the mention ID (which
+ // could contain characters like '@' for user IDs) but a one-based
+ // index of the mentions of that type.
+ $mentionParameterId = 'mention-' . $mention['type'] . $mentionTypeCount[$mention['type']];
+ $message = str_replace('@"' . $mention['id'] . '"', '{' . $mentionParameterId . '}', $message);
+ if (!str_contains($mention['id'], ' ') && !str_starts_with($mention['id'], 'guest/')) {
+ $message = str_replace('@' . $mention['id'], '{' . $mentionParameterId . '}', $message);
+ }
+
+ try {
+ $displayName = $this->commentsManager->resolveDisplayName($mention['type'], $mention['id']);
+ } catch (\OutOfBoundsException $e) {
+ // There is no registered display name resolver for the mention
+ // type, so the client decides what to display.
+ $displayName = '';
+ }
+ $messageParameters[$mentionParameterId] = [
+ 'type' => $mention['type'],
+ 'id' => $mention['id'],
+ 'name' => $displayName
+ ];
+ }
+ return [$message, $messageParameters];
+ }
+}
diff --git a/apps/comments/lib/Search/CommentsSearchProvider.php b/apps/comments/lib/Search/CommentsSearchProvider.php
new file mode 100644
index 00000000000..87a658cab1c
--- /dev/null
+++ b/apps/comments/lib/Search/CommentsSearchProvider.php
@@ -0,0 +1,71 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Search;
+
+use OCP\IL10N;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\Search\IProvider;
+use OCP\Search\ISearchQuery;
+use OCP\Search\SearchResult;
+use OCP\Search\SearchResultEntry;
+use function array_map;
+use function pathinfo;
+
+class CommentsSearchProvider implements IProvider {
+ public function __construct(
+ private IUserManager $userManager,
+ private IL10N $l10n,
+ private IURLGenerator $urlGenerator,
+ private LegacyProvider $legacyProvider,
+ ) {
+ }
+
+ public function getId(): string {
+ return 'comments';
+ }
+
+ public function getName(): string {
+ return $this->l10n->t('Comments');
+ }
+
+ public function getOrder(string $route, array $routeParameters): int {
+ if ($route === 'files.View.index') {
+ // Files first
+ return 0;
+ }
+ return 10;
+ }
+
+ public function search(IUser $user, ISearchQuery $query): SearchResult {
+ return SearchResult::complete(
+ $this->l10n->t('Comments'),
+ array_map(function (Result $result) {
+ $path = $result->path;
+ $pathInfo = pathinfo($path);
+ $isUser = $this->userManager->userExists($result->authorId);
+ $avatarUrl = $isUser
+ ? $this->urlGenerator->linkToRouteAbsolute('core.avatar.getAvatar', ['userId' => $result->authorId, 'size' => 42])
+ : $this->urlGenerator->linkToRouteAbsolute('core.GuestAvatar.getAvatar', ['guestName' => $result->authorId, 'size' => 42]);
+ return new SearchResultEntry(
+ $avatarUrl,
+ $result->name,
+ $path,
+ $this->urlGenerator->linkToRouteAbsolute('files.view.index', [
+ 'dir' => $pathInfo['dirname'],
+ 'scrollto' => $pathInfo['basename'],
+ ]),
+ '',
+ true
+ );
+ }, $this->legacyProvider->search($query->getTerm()))
+ );
+ }
+}
diff --git a/apps/comments/lib/Search/LegacyProvider.php b/apps/comments/lib/Search/LegacyProvider.php
new file mode 100644
index 00000000000..a269c418d06
--- /dev/null
+++ b/apps/comments/lib/Search/LegacyProvider.php
@@ -0,0 +1,97 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Search;
+
+use OCP\Comments\IComment;
+use OCP\Comments\ICommentsManager;
+use OCP\Files\Folder;
+use OCP\Files\Node;
+use OCP\Files\NotFoundException;
+use OCP\IUser;
+use OCP\IUserSession;
+use OCP\Search\Provider;
+use OCP\Server;
+use function count;
+
+class LegacyProvider extends Provider {
+ /**
+ * Search for $query
+ *
+ * @param string $query
+ * @return array An array of OCP\Search\Result's
+ * @since 7.0.0
+ */
+ public function search($query): array {
+ $cm = Server::get(ICommentsManager::class);
+ $us = Server::get(IUserSession::class);
+
+ $user = $us->getUser();
+ if (!$user instanceof IUser) {
+ return [];
+ }
+ $uf = \OC::$server->getUserFolder($user->getUID());
+
+ if ($uf === null) {
+ return [];
+ }
+
+ $result = [];
+ $numComments = 50;
+ $offset = 0;
+
+ while (count($result) < $numComments) {
+ /** @var IComment[] $comments */
+ $comments = $cm->search($query, 'files', '', 'comment', $offset, $numComments);
+
+ foreach ($comments as $comment) {
+ if ($comment->getActorType() !== 'users') {
+ continue;
+ }
+
+ $displayName = $cm->resolveDisplayName('user', $comment->getActorId());
+
+ try {
+ $file = $this->getFileForComment($uf, $comment);
+ $result[] = new Result($query,
+ $comment,
+ $displayName,
+ $file->getPath()
+ );
+ } catch (NotFoundException $e) {
+ continue;
+ }
+ }
+
+ if (count($comments) < $numComments) {
+ // Didn't find more comments when we tried to get, so there are no more comments.
+ return $result;
+ }
+
+ $offset += $numComments;
+ $numComments = 50 - count($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param Folder $userFolder
+ * @param IComment $comment
+ * @return Node
+ * @throws NotFoundException
+ */
+ protected function getFileForComment(Folder $userFolder, IComment $comment): Node {
+ $nodes = $userFolder->getById((int)$comment->getObjectId());
+ if (empty($nodes)) {
+ throw new NotFoundException('File not found');
+ }
+
+ return array_shift($nodes);
+ }
+}
diff --git a/apps/comments/lib/Search/Result.php b/apps/comments/lib/Search/Result.php
new file mode 100644
index 00000000000..7478c110d63
--- /dev/null
+++ b/apps/comments/lib/Search/Result.php
@@ -0,0 +1,105 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Search;
+
+use OCP\Comments\IComment;
+use OCP\Files\NotFoundException;
+use OCP\Search\Result as BaseResult;
+
+/**
+ * @deprecated 20.0.0
+ */
+class Result extends BaseResult {
+ /**
+ * @deprecated 20.0.0
+ */
+ public $type = 'comment';
+ /**
+ * @deprecated 20.0.0
+ */
+ public $comment;
+ /**
+ * @deprecated 20.0.0
+ */
+ public $authorId;
+ /**
+ * @deprecated 20.0.0
+ */
+ public $path;
+ /**
+ * @deprecated 20.0.0
+ */
+ public $fileName;
+
+ /**
+ * @throws NotFoundException
+ * @deprecated 20.0.0
+ */
+ public function __construct(
+ string $search,
+ IComment $comment,
+ /**
+ * @deprecated 20.0.0
+ */
+ public string $authorName,
+ string $path,
+ ) {
+ parent::__construct(
+ $comment->getId(),
+ $comment->getMessage()
+ /* @todo , [link to file] */
+ );
+
+ $this->comment = $this->getRelevantMessagePart($comment->getMessage(), $search);
+ $this->authorId = $comment->getActorId();
+ $this->fileName = basename($path);
+ $this->path = $this->getVisiblePath($path);
+ }
+
+ /**
+ * @throws NotFoundException
+ */
+ protected function getVisiblePath(string $path): string {
+ $segments = explode('/', trim($path, '/'), 3);
+
+ if (!isset($segments[2])) {
+ throw new NotFoundException('Path not inside visible section');
+ }
+
+ return $segments[2];
+ }
+
+ /**
+ * @throws NotFoundException
+ */
+ protected function getRelevantMessagePart(string $message, string $search): string {
+ $start = mb_stripos($message, $search);
+ if ($start === false) {
+ throw new NotFoundException('Comment section not found');
+ }
+
+ $end = $start + mb_strlen($search);
+
+ if ($start <= 25) {
+ $start = 0;
+ $prefix = '';
+ } else {
+ $start -= 25;
+ $prefix = '…';
+ }
+
+ if ((mb_strlen($message) - $end) <= 25) {
+ $end = mb_strlen($message);
+ $suffix = '';
+ } else {
+ $end += 25;
+ $suffix = '…';
+ }
+
+ return $prefix . mb_substr($message, $start, $end - $start) . $suffix;
+ }
+}
diff --git a/apps/comments/openapi.json b/apps/comments/openapi.json
new file mode 100644
index 00000000000..cadc64da052
--- /dev/null
+++ b/apps/comments/openapi.json
@@ -0,0 +1,46 @@
+{
+ "openapi": "3.0.3",
+ "info": {
+ "title": "comments",
+ "version": "0.0.1",
+ "description": "Files app plugin to add comments to files",
+ "license": {
+ "name": "agpl"
+ }
+ },
+ "components": {
+ "securitySchemes": {
+ "basic_auth": {
+ "type": "http",
+ "scheme": "basic"
+ },
+ "bearer_auth": {
+ "type": "http",
+ "scheme": "bearer"
+ }
+ },
+ "schemas": {
+ "Capabilities": {
+ "type": "object",
+ "required": [
+ "files"
+ ],
+ "properties": {
+ "files": {
+ "type": "object",
+ "required": [
+ "comments"
+ ],
+ "properties": {
+ "comments": {
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "paths": {},
+ "tags": []
+}
diff --git a/apps/comments/openapi.json.license b/apps/comments/openapi.json.license
new file mode 100644
index 00000000000..83559daa9dc
--- /dev/null
+++ b/apps/comments/openapi.json.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later \ No newline at end of file
diff --git a/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts b/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts
new file mode 100644
index 00000000000..e8020f1f029
--- /dev/null
+++ b/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts
@@ -0,0 +1,179 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+import { File, Permission, View, FileAction } from '@nextcloud/files'
+import { describe, expect, test, vi } from 'vitest'
+
+import { action } from './inlineUnreadCommentsAction'
+import logger from '../logger'
+
+const view = {
+ id: 'files',
+ name: 'Files',
+} as View
+
+describe('Inline unread comments action display name tests', () => {
+ test('Default values', () => {
+ const file = new File({
+ id: 1,
+ source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
+ owner: 'admin',
+ mime: 'text/plain',
+ permissions: Permission.ALL,
+ attributes: {
+ 'comments-unread': 1,
+ },
+ })
+
+ expect(action).toBeInstanceOf(FileAction)
+ expect(action.id).toBe('comments-unread')
+ expect(action.displayName([file], view)).toBe('')
+ expect(action.title!([file], view)).toBe('1 new comment')
+ expect(action.iconSvgInline([], view)).toMatch(/<svg.+<\/svg>/)
+ expect(action.enabled!([file], view)).toBe(true)
+ expect(action.inline!(file, view)).toBe(true)
+ expect(action.default).toBeUndefined()
+ expect(action.order).toBe(-140)
+ })
+
+ test('Display name when file has two new comments', () => {
+ const file = new File({
+ id: 1,
+ source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
+ owner: 'admin',
+ mime: 'text/plain',
+ permissions: Permission.ALL,
+ attributes: {
+ 'comments-unread': 2,
+ },
+ })
+
+ expect(action.displayName([file], view)).toBe('')
+ expect(action.title!([file], view)).toBe('2 new comments')
+ })
+})
+
+describe('Inline unread comments action enabled tests', () => {
+ test('Action is disabled when comments-unread attribute is missing', () => {
+ const file = new File({
+ id: 1,
+ source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
+ owner: 'admin',
+ mime: 'text/plain',
+ permissions: Permission.ALL,
+ attributes: { },
+ })
+
+ expect(action.enabled!([file], view)).toBe(false)
+ })
+
+ test('Action is disabled when file does not have unread comments', () => {
+ const file = new File({
+ id: 1,
+ source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
+ owner: 'admin',
+ mime: 'text/plain',
+ permissions: Permission.ALL,
+ attributes: {
+ 'comments-unread': 0,
+ },
+ })
+
+ expect(action.enabled!([file], view)).toBe(false)
+ })
+
+ test('Action is enabled when file has a single unread comment', () => {
+ const file = new File({
+ id: 1,
+ source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
+ owner: 'admin',
+ mime: 'text/plain',
+ permissions: Permission.ALL,
+ attributes: {
+ 'comments-unread': 1,
+ },
+ })
+
+ expect(action.enabled!([file], view)).toBe(true)
+ })
+
+ test('Action is enabled when file has a two unread comments', () => {
+ const file = new File({
+ id: 1,
+ source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
+ owner: 'admin',
+ mime: 'text/plain',
+ permissions: Permission.ALL,
+ attributes: {
+ 'comments-unread': 2,
+ },
+ })
+
+ expect(action.enabled!([file], view)).toBe(true)
+ })
+})
+
+describe('Inline unread comments action execute tests', () => {
+ test('Action opens sidebar', async () => {
+ const openMock = vi.fn()
+ const setActiveTabMock = vi.fn()
+ window.OCA = {
+ Files: {
+ Sidebar: {
+ open: openMock,
+ setActiveTab: setActiveTabMock,
+ },
+ },
+ }
+
+ const file = new File({
+ id: 1,
+ source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
+ owner: 'admin',
+ mime: 'text/plain',
+ permissions: Permission.ALL,
+ attributes: {
+ 'comments-unread': 1,
+ },
+ })
+
+ const result = await action.exec!(file, view, '/')
+
+ expect(result).toBe(null)
+ expect(setActiveTabMock).toBeCalledWith('comments')
+ expect(openMock).toBeCalledWith('/foobar.txt')
+ })
+
+ test('Action handles sidebar open failure', async () => {
+ const openMock = vi.fn(() => { throw new Error('Mock error') })
+ const setActiveTabMock = vi.fn()
+ window.OCA = {
+ Files: {
+ Sidebar: {
+ open: openMock,
+ setActiveTab: setActiveTabMock,
+ },
+ },
+ }
+ vi.spyOn(logger, 'error').mockImplementation(() => vi.fn())
+
+ const file = new File({
+ id: 1,
+ source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
+ owner: 'admin',
+ mime: 'text/plain',
+ permissions: Permission.ALL,
+ attributes: {
+ 'comments-unread': 1,
+ },
+ })
+
+ const result = await action.exec!(file, view, '/')
+
+ expect(result).toBe(false)
+ expect(setActiveTabMock).toBeCalledWith('comments')
+ expect(openMock).toBeCalledWith('/foobar.txt')
+ expect(logger.error).toBeCalledTimes(1)
+ })
+})
diff --git a/apps/comments/src/actions/inlineUnreadCommentsAction.ts b/apps/comments/src/actions/inlineUnreadCommentsAction.ts
new file mode 100644
index 00000000000..0afd93d7606
--- /dev/null
+++ b/apps/comments/src/actions/inlineUnreadCommentsAction.ts
@@ -0,0 +1,46 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+import { FileAction, Node } from '@nextcloud/files'
+import { translate as t, translatePlural as n } from '@nextcloud/l10n'
+import CommentProcessingSvg from '@mdi/svg/svg/comment-processing.svg?raw'
+
+import logger from '../logger'
+
+export const action = new FileAction({
+ id: 'comments-unread',
+
+ title(nodes: Node[]) {
+ const unread = nodes[0].attributes['comments-unread'] as number
+ if (unread >= 0) {
+ return n('comments', '1 new comment', '{unread} new comments', unread, { unread })
+ }
+ return t('comments', 'Comment')
+ },
+
+ // Empty string when rendered inline
+ displayName: () => '',
+
+ iconSvgInline: () => CommentProcessingSvg,
+
+ enabled(nodes: Node[]) {
+ const unread = nodes[0].attributes['comments-unread'] as number|undefined
+ return typeof unread === 'number' && unread > 0
+ },
+
+ async exec(node: Node) {
+ try {
+ window.OCA.Files.Sidebar.setActiveTab('comments')
+ await window.OCA.Files.Sidebar.open(node.path)
+ return null
+ } catch (error) {
+ logger.error('Error while opening sidebar', { error })
+ return false
+ }
+ },
+
+ inline: () => true,
+
+ order: -140,
+})
diff --git a/apps/comments/src/comments-activity-tab.ts b/apps/comments/src/comments-activity-tab.ts
new file mode 100644
index 00000000000..77f6c9bca04
--- /dev/null
+++ b/apps/comments/src/comments-activity-tab.ts
@@ -0,0 +1,78 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+import moment from '@nextcloud/moment'
+import Vue, { type ComponentPublicInstance } from 'vue'
+import logger from './logger.js'
+import { getComments } from './services/GetComments.js'
+
+import { PiniaVuePlugin, createPinia } from 'pinia'
+
+Vue.use(PiniaVuePlugin)
+
+let ActivityTabPluginView
+let ActivityTabPluginInstance
+
+/**
+ * Register the comments plugins for the Activity sidebar
+ */
+export function registerCommentsPlugins() {
+ window.OCA.Activity.registerSidebarAction({
+ mount: async (el, { fileInfo, reload }) => {
+ const pinia = createPinia()
+
+ if (!ActivityTabPluginView) {
+ const { default: ActivityCommentAction } = await import('./views/ActivityCommentAction.vue')
+ // @ts-expect-error Types are broken for Vue2
+ ActivityTabPluginView = Vue.extend(ActivityCommentAction)
+ }
+ ActivityTabPluginInstance = new ActivityTabPluginView({
+ el,
+ pinia,
+ propsData: {
+ reloadCallback: reload,
+ resourceId: fileInfo.id,
+ },
+ })
+ logger.info('Comments plugin mounted in Activity sidebar action', { fileInfo })
+ },
+ unmount: () => {
+ // destroy previous instance if available
+ if (ActivityTabPluginInstance) {
+ ActivityTabPluginInstance.$destroy()
+ }
+ },
+ })
+
+ window.OCA.Activity.registerSidebarEntries(async ({ fileInfo, limit, offset }) => {
+ const { data: comments } = await getComments({ resourceType: 'files', resourceId: fileInfo.id }, { limit, offset })
+ logger.debug('Loaded comments', { fileInfo, comments })
+ const { default: CommentView } = await import('./views/ActivityCommentEntry.vue')
+ // @ts-expect-error Types are broken for Vue2
+ const CommentsViewObject = Vue.extend(CommentView)
+
+ return comments.map((comment) => ({
+ _CommentsViewInstance: undefined as ComponentPublicInstance | undefined,
+
+ timestamp: moment(comment.props?.creationDateTime).toDate().getTime(),
+
+ mount(element: HTMLElement, { reload }) {
+ this._CommentsViewInstance = new CommentsViewObject({
+ el: element,
+ propsData: {
+ comment,
+ resourceId: fileInfo.id,
+ reloadCallback: reload,
+ },
+ })
+ },
+ unmount() {
+ this._CommentsViewInstance?.$destroy()
+ },
+ }))
+ })
+
+ window.OCA.Activity.registerSidebarFilter((activity) => activity.type !== 'comments')
+ logger.info('Comments plugin registered for Activity sidebar action')
+}
diff --git a/apps/comments/src/comments-app.js b/apps/comments/src/comments-app.js
new file mode 100644
index 00000000000..a91a4bb37bb
--- /dev/null
+++ b/apps/comments/src/comments-app.js
@@ -0,0 +1,15 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import CommentsInstance from './services/CommentsInstance.js'
+
+// Init Comments
+if (window.OCA && !window.OCA.Comments) {
+ Object.assign(window.OCA, { Comments: {} })
+}
+
+// Init Comments App view
+Object.assign(window.OCA.Comments, { View: CommentsInstance })
+console.debug('OCA.Comments.View initialized')
diff --git a/apps/comments/src/comments-tab.js b/apps/comments/src/comments-tab.js
new file mode 100644
index 00000000000..d3ebe3e9596
--- /dev/null
+++ b/apps/comments/src/comments-tab.js
@@ -0,0 +1,60 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+// eslint-disable-next-line n/no-missing-import, import/no-unresolved
+import MessageReplyText from '@mdi/svg/svg/message-reply-text.svg?raw'
+import { getCSPNonce } from '@nextcloud/auth'
+import { loadState } from '@nextcloud/initial-state'
+import { registerCommentsPlugins } from './comments-activity-tab.ts'
+
+// @ts-expect-error __webpack_nonce__ is injected by webpack
+__webpack_nonce__ = getCSPNonce()
+
+if (loadState('comments', 'activityEnabled', false) && OCA?.Activity?.registerSidebarAction !== undefined) {
+ // Do not mount own tab but mount into activity
+ window.addEventListener('DOMContentLoaded', function() {
+ registerCommentsPlugins()
+ })
+} else {
+ // Init Comments tab component
+ let TabInstance = null
+ const commentTab = new OCA.Files.Sidebar.Tab({
+ id: 'comments',
+ name: t('comments', 'Comments'),
+ iconSvg: MessageReplyText,
+
+ async mount(el, fileInfo, context) {
+ if (TabInstance) {
+ TabInstance.$destroy()
+ }
+ TabInstance = new OCA.Comments.View('files', {
+ // Better integration with vue parent component
+ parent: context,
+ propsData: {
+ resourceId: fileInfo.id,
+ },
+ })
+ // Only mount after we have all the info we need
+ await TabInstance.update(fileInfo.id)
+ TabInstance.$mount(el)
+ },
+ update(fileInfo) {
+ TabInstance.update(fileInfo.id)
+ },
+ destroy() {
+ TabInstance.$destroy()
+ TabInstance = null
+ },
+ scrollBottomReached() {
+ TabInstance.onScrollBottomReached()
+ },
+ })
+
+ window.addEventListener('DOMContentLoaded', function() {
+ if (OCA.Files && OCA.Files.Sidebar) {
+ OCA.Files.Sidebar.registerTab(commentTab)
+ }
+ })
+}
diff --git a/apps/comments/src/components/Comment.vue b/apps/comments/src/components/Comment.vue
new file mode 100644
index 00000000000..80f035530fb
--- /dev/null
+++ b/apps/comments/src/components/Comment.vue
@@ -0,0 +1,384 @@
+<!--
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+<template>
+ <component :is="tag"
+ v-show="!deleted && !isLimbo"
+ :class="{'comment--loading': loading}"
+ class="comment">
+ <!-- Comment header toolbar -->
+ <div class="comment__side">
+ <!-- Author -->
+ <NcAvatar class="comment__avatar"
+ :display-name="actorDisplayName"
+ :user="actorId"
+ :size="32" />
+ </div>
+ <div class="comment__body">
+ <div class="comment__header">
+ <span class="comment__author">{{ actorDisplayName }}</span>
+
+ <!-- Comment actions,
+ show if we have a message id and current user is author -->
+ <NcActions v-if="isOwnComment && id && !loading" class="comment__actions">
+ <template v-if="!editing">
+ <NcActionButton close-after-click
+ @click="onEdit">
+ <template #icon>
+ <IconPencilOutline :size="20" />
+ </template>
+ {{ t('comments', 'Edit comment') }}
+ </NcActionButton>
+ <NcActionSeparator />
+ <NcActionButton close-after-click
+ @click="onDeleteWithUndo">
+ <template #icon>
+ <IconTrashCanOutline :size="20" />
+ </template>
+ {{ t('comments', 'Delete comment') }}
+ </NcActionButton>
+ </template>
+
+ <NcActionButton v-else @click="onEditCancel">
+ <template #icon>
+ <IconClose :size="20" />
+ </template>
+ {{ t('comments', 'Cancel edit') }}
+ </NcActionButton>
+ </NcActions>
+
+ <!-- Show loading if we're editing or deleting, not on new ones -->
+ <div v-if="id && loading" class="comment_loading icon-loading-small" />
+
+ <!-- Relative time to the comment creation -->
+ <NcDateTime v-else-if="creationDateTime"
+ class="comment__timestamp"
+ :timestamp="timestamp"
+ :ignore-seconds="true" />
+ </div>
+
+ <!-- Message editor -->
+ <form v-if="editor || editing" class="comment__editor" @submit.prevent>
+ <div class="comment__editor-group">
+ <NcRichContenteditable ref="editor"
+ :auto-complete="autoComplete"
+ :contenteditable="!loading"
+ :label="editor ? t('comments', 'New comment') : t('comments', 'Edit comment')"
+ :placeholder="t('comments', 'Write a comment …')"
+ :value="localMessage"
+ :user-data="userData"
+ aria-describedby="tab-comments__editor-description"
+ @update:value="updateLocalMessage"
+ @submit="onSubmit" />
+ <div class="comment__submit">
+ <NcButton type="tertiary-no-background"
+ native-type="submit"
+ :aria-label="t('comments', 'Post comment')"
+ :disabled="isEmptyMessage"
+ @click="onSubmit">
+ <template #icon>
+ <NcLoadingIcon v-if="loading" />
+ <IconArrowRight v-else :size="20" />
+ </template>
+ </NcButton>
+ </div>
+ </div>
+ <div id="tab-comments__editor-description" class="comment__editor-description">
+ {{ t('comments', '@ for mentions, : for emoji, / for smart picker') }}
+ </div>
+ </form>
+
+ <!-- Message content -->
+ <NcRichText v-else
+ class="comment__message"
+ :class="{'comment__message--expanded': expanded}"
+ :text="richContent.message"
+ :arguments="richContent.mentions"
+ @click="onExpand" />
+ </div>
+ </component>
+</template>
+
+<script>
+import { getCurrentUser } from '@nextcloud/auth'
+import { translate as t } from '@nextcloud/l10n'
+
+import NcActionButton from '@nextcloud/vue/components/NcActionButton'
+import NcActions from '@nextcloud/vue/components/NcActions'
+import NcActionSeparator from '@nextcloud/vue/components/NcActionSeparator'
+import NcAvatar from '@nextcloud/vue/components/NcAvatar'
+import NcButton from '@nextcloud/vue/components/NcButton'
+import NcDateTime from '@nextcloud/vue/components/NcDateTime'
+import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
+import NcUserBubble from '@nextcloud/vue/components/NcUserBubble'
+
+import IconArrowRight from 'vue-material-design-icons/ArrowRight.vue'
+import IconClose from 'vue-material-design-icons/Close.vue'
+import IconTrashCanOutline from 'vue-material-design-icons/TrashCanOutline.vue'
+import IconPencilOutline from 'vue-material-design-icons/PencilOutline.vue'
+
+import CommentMixin from '../mixins/CommentMixin.js'
+import { mapStores } from 'pinia'
+import { useDeletedCommentLimbo } from '../store/deletedCommentLimbo.js'
+
+// Dynamic loading
+const NcRichContenteditable = () => import('@nextcloud/vue/components/NcRichContenteditable')
+const NcRichText = () => import('@nextcloud/vue/components/NcRichText')
+
+export default {
+ name: 'Comment',
+
+ components: {
+ IconArrowRight,
+ IconClose,
+ IconTrashCanOutline,
+ IconPencilOutline,
+ NcActionButton,
+ NcActions,
+ NcActionSeparator,
+ NcAvatar,
+ NcButton,
+ NcDateTime,
+ NcLoadingIcon,
+ NcRichContenteditable,
+ NcRichText,
+ },
+ mixins: [CommentMixin],
+
+ inheritAttrs: false,
+
+ props: {
+ actorDisplayName: {
+ type: String,
+ required: true,
+ },
+ actorId: {
+ type: String,
+ required: true,
+ },
+ creationDateTime: {
+ type: String,
+ default: null,
+ },
+
+ /**
+ * Force the editor display
+ */
+ editor: {
+ type: Boolean,
+ default: false,
+ },
+
+ /**
+ * Provide the autocompletion data
+ */
+ autoComplete: {
+ type: Function,
+ required: true,
+ },
+ userData: {
+ type: Object,
+ default: () => ({}),
+ },
+
+ tag: {
+ type: String,
+ default: 'div',
+ },
+ },
+
+ data() {
+ return {
+ expanded: false,
+ // Only change data locally and update the original
+ // parent data when the request is sent and resolved
+ localMessage: '',
+ submitted: false,
+ }
+ },
+
+ computed: {
+ ...mapStores(useDeletedCommentLimbo),
+
+ /**
+ * Is the current user the author of this comment
+ *
+ * @return {boolean}
+ */
+ isOwnComment() {
+ return getCurrentUser().uid === this.actorId
+ },
+
+ richContent() {
+ const mentions = {}
+ let message = this.localMessage
+
+ Object.keys(this.userData).forEach((user, index) => {
+ const key = `mention-${index}`
+ const regex = new RegExp(`@${user}|@"${user}"`, 'g')
+ message = message.replace(regex, `{${key}}`)
+ mentions[key] = {
+ component: NcUserBubble,
+ props: {
+ user,
+ displayName: this.userData[user].label,
+ primary: this.userData[user].primary,
+ },
+ }
+ })
+
+ return { mentions, message }
+ },
+
+ isEmptyMessage() {
+ return !this.localMessage || this.localMessage.trim() === ''
+ },
+
+ /**
+ * Timestamp of the creation time (in ms UNIX time)
+ */
+ timestamp() {
+ return Date.parse(this.creationDateTime)
+ },
+
+ isLimbo() {
+ return this.deletedCommentLimboStore.checkForId(this.id)
+ },
+ },
+
+ watch: {
+ // If the data change, update the local value
+ message(message) {
+ this.updateLocalMessage(message)
+ },
+ },
+
+ beforeMount() {
+ // Init localMessage
+ this.updateLocalMessage(this.message)
+ },
+
+ methods: {
+ t,
+
+ /**
+ * Update local Message on outer change
+ *
+ * @param {string} message the message to set
+ */
+ updateLocalMessage(message) {
+ this.localMessage = message.toString()
+ this.submitted = false
+ },
+
+ /**
+ * Dispatch message between edit and create
+ */
+ onSubmit() {
+ // Do not submit if message is empty
+ if (this.localMessage.trim() === '') {
+ return
+ }
+
+ if (this.editor) {
+ this.onNewComment(this.localMessage.trim())
+ this.$nextTick(() => {
+ // Focus the editor again
+ this.$refs.editor.$el.focus()
+ })
+ return
+ }
+ this.onEditComment(this.localMessage.trim())
+ },
+
+ onExpand() {
+ this.expanded = true
+ },
+ },
+
+}
+</script>
+
+<style lang="scss" scoped>
+@use "sass:math";
+
+$comment-padding: 10px;
+
+.comment {
+ display: flex;
+ gap: 8px;
+ padding: 5px $comment-padding;
+
+ &__side {
+ display: flex;
+ align-items: flex-start;
+ padding-top: 6px;
+ }
+
+ &__body {
+ display: flex;
+ flex-grow: 1;
+ flex-direction: column;
+ }
+
+ &__header {
+ display: flex;
+ align-items: center;
+ min-height: 44px;
+ }
+
+ &__actions {
+ margin-inline-start: $comment-padding !important;
+ }
+
+ &__author {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ color: var(--color-text-maxcontrast);
+ }
+
+ &_loading,
+ &__timestamp {
+ margin-inline-start: auto;
+ text-align: end;
+ white-space: nowrap;
+ color: var(--color-text-maxcontrast);
+ }
+
+ &__editor-group {
+ position: relative;
+ }
+
+ &__editor-description {
+ color: var(--color-text-maxcontrast);
+ padding-block: var(--default-grid-baseline);
+ }
+
+ &__submit {
+ position: absolute !important;
+ bottom: 5px;
+ inset-inline-end: 0;
+ }
+
+ &__message {
+ white-space: pre-wrap;
+ word-break: normal;
+ max-height: 70px;
+ overflow: hidden;
+ margin-top: -6px;
+ &--expanded {
+ max-height: none;
+ overflow: visible;
+ }
+ }
+}
+
+.rich-contenteditable__input {
+ min-height: 44px;
+ margin: 0;
+ padding: $comment-padding;
+}
+
+</style>
diff --git a/apps/comments/src/init.ts b/apps/comments/src/init.ts
new file mode 100644
index 00000000000..675274b1b40
--- /dev/null
+++ b/apps/comments/src/init.ts
@@ -0,0 +1,8 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+import { registerFileAction } from '@nextcloud/files'
+import { action } from './actions/inlineUnreadCommentsAction'
+
+registerFileAction(action)
diff --git a/apps/comments/src/logger.js b/apps/comments/src/logger.js
new file mode 100644
index 00000000000..a51bc6d750b
--- /dev/null
+++ b/apps/comments/src/logger.js
@@ -0,0 +1,11 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { getLoggerBuilder } from '@nextcloud/logger'
+
+export default getLoggerBuilder()
+ .setApp('comments')
+ .detectUser()
+ .build()
diff --git a/apps/comments/src/mixins/CommentMixin.js b/apps/comments/src/mixins/CommentMixin.js
new file mode 100644
index 00000000000..722ad3444ce
--- /dev/null
+++ b/apps/comments/src/mixins/CommentMixin.js
@@ -0,0 +1,115 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { showError, showUndo, TOAST_UNDO_TIMEOUT } from '@nextcloud/dialogs'
+import NewComment from '../services/NewComment.js'
+import DeleteComment from '../services/DeleteComment.js'
+import EditComment from '../services/EditComment.js'
+import { mapStores } from 'pinia'
+import { useDeletedCommentLimbo } from '../store/deletedCommentLimbo.js'
+import logger from '../logger.js'
+
+export default {
+ props: {
+ id: {
+ type: Number,
+ default: null,
+ },
+ message: {
+ type: String,
+ default: '',
+ },
+ resourceId: {
+ type: [String, Number],
+ required: true,
+ },
+ resourceType: {
+ type: String,
+ default: 'files',
+ },
+ },
+
+ data() {
+ return {
+ deleted: false,
+ editing: false,
+ loading: false,
+ }
+ },
+
+ computed: {
+ ...mapStores(useDeletedCommentLimbo),
+ },
+
+ methods: {
+ // EDITION
+ onEdit() {
+ this.editing = true
+ },
+ onEditCancel() {
+ this.editing = false
+ // Restore original value
+ this.updateLocalMessage(this.message)
+ },
+ async onEditComment(message) {
+ this.loading = true
+ try {
+ await EditComment(this.resourceType, this.resourceId, this.id, message)
+ logger.debug('Comment edited', { resourceType: this.resourceType, resourceId: this.resourceId, id: this.id, message })
+ this.$emit('update:message', message)
+ this.editing = false
+ } catch (error) {
+ showError(t('comments', 'An error occurred while trying to edit the comment'))
+ console.error(error)
+ } finally {
+ this.loading = false
+ }
+ },
+
+ // DELETION
+ onDeleteWithUndo() {
+ this.$emit('delete')
+ this.deleted = true
+ this.deletedCommentLimboStore.addId(this.id)
+ const timeOutDelete = setTimeout(this.onDelete, TOAST_UNDO_TIMEOUT)
+ showUndo(t('comments', 'Comment deleted'), () => {
+ clearTimeout(timeOutDelete)
+ this.deleted = false
+ this.deletedCommentLimboStore.removeId(this.id)
+ })
+ },
+ async onDelete() {
+ try {
+ await DeleteComment(this.resourceType, this.resourceId, this.id)
+ logger.debug('Comment deleted', { resourceType: this.resourceType, resourceId: this.resourceId, id: this.id })
+ this.$emit('delete', this.id)
+ } catch (error) {
+ showError(t('comments', 'An error occurred while trying to delete the comment'))
+ console.error(error)
+ this.deleted = false
+ this.deletedCommentLimboStore.removeId(this.id)
+ }
+ },
+
+ // CREATION
+ async onNewComment(message) {
+ this.loading = true
+ try {
+ const newComment = await NewComment(this.resourceType, this.resourceId, message)
+ logger.debug('New comment posted', { resourceType: this.resourceType, resourceId: this.resourceId, newComment })
+ this.$emit('new', newComment)
+
+ // Clear old content
+ this.$emit('update:message', '')
+ this.localMessage = ''
+ } catch (error) {
+ showError(t('comments', 'An error occurred while trying to create the comment'))
+ console.error(error)
+ } finally {
+ this.loading = false
+ }
+ },
+ },
+}
diff --git a/apps/comments/src/mixins/CommentView.ts b/apps/comments/src/mixins/CommentView.ts
new file mode 100644
index 00000000000..c6cb3aa9ee0
--- /dev/null
+++ b/apps/comments/src/mixins/CommentView.ts
@@ -0,0 +1,76 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+import axios from '@nextcloud/axios'
+import { getCurrentUser } from '@nextcloud/auth'
+import { loadState } from '@nextcloud/initial-state'
+import { generateOcsUrl } from '@nextcloud/router'
+import { defineComponent } from 'vue'
+
+export default defineComponent({
+ props: {
+ resourceId: {
+ type: Number,
+ required: true,
+ },
+ resourceType: {
+ type: String,
+ default: 'files',
+ },
+ },
+ data() {
+ return {
+ editorData: {
+ actorDisplayName: getCurrentUser()!.displayName as string,
+ actorId: getCurrentUser()!.uid as string,
+ key: 'editor',
+ },
+ userData: {},
+ }
+ },
+ methods: {
+ /**
+ * Autocomplete @mentions
+ *
+ * @param {string} search the query
+ * @param {Function} callback the callback to process the results with
+ */
+ async autoComplete(search, callback) {
+ const { data } = await axios.get(generateOcsUrl('core/autocomplete/get'), {
+ params: {
+ search,
+ itemType: 'files',
+ itemId: this.resourceId,
+ sorter: 'commenters|share-recipients',
+ limit: loadState('comments', 'maxAutoCompleteResults'),
+ },
+ })
+ // Save user data so it can be used by the editor to replace mentions
+ data.ocs.data.forEach(user => { this.userData[user.id] = user })
+ return callback(Object.values(this.userData))
+ },
+
+ /**
+ * Make sure we have all mentions as Array of objects
+ *
+ * @param mentions the mentions list
+ */
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ genMentionsData(mentions: any[]): Record<string, object> {
+ Object.values(mentions)
+ .flat()
+ .forEach(mention => {
+ this.userData[mention.mentionId] = {
+ // TODO: support groups
+ icon: 'icon-user',
+ id: mention.mentionId,
+ label: mention.mentionDisplayName,
+ source: 'users',
+ primary: getCurrentUser()?.uid === mention.mentionId,
+ }
+ })
+ return this.userData
+ },
+ },
+})
diff --git a/apps/comments/src/services/CommentsInstance.js b/apps/comments/src/services/CommentsInstance.js
new file mode 100644
index 00000000000..cc45d0cbea7
--- /dev/null
+++ b/apps/comments/src/services/CommentsInstance.js
@@ -0,0 +1,55 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { getCSPNonce } from '@nextcloud/auth'
+import { t, n } from '@nextcloud/l10n'
+import { PiniaVuePlugin, createPinia } from 'pinia'
+import Vue from 'vue'
+import CommentsApp from '../views/Comments.vue'
+import logger from '../logger.js'
+
+Vue.use(PiniaVuePlugin)
+// eslint-disable-next-line camelcase
+__webpack_nonce__ = getCSPNonce()
+
+// Add translates functions
+Vue.mixin({
+ data() {
+ return {
+ logger,
+ }
+ },
+ methods: {
+ t,
+ n,
+ },
+})
+
+export default class CommentInstance {
+
+ /**
+ * Initialize a new Comments instance for the desired type
+ *
+ * @param {string} resourceType the comments endpoint type
+ * @param {object} options the vue options (propsData, parent, el...)
+ */
+ constructor(resourceType = 'files', options = {}) {
+ const pinia = createPinia()
+
+ // Merge options and set `resourceType` property
+ options = {
+ ...options,
+ propsData: {
+ ...(options.propsData ?? {}),
+ resourceType,
+ },
+ pinia,
+ }
+ // Init Comments component
+ const View = Vue.extend(CommentsApp)
+ return new View(options)
+ }
+
+}
diff --git a/apps/comments/src/services/DavClient.js b/apps/comments/src/services/DavClient.js
new file mode 100644
index 00000000000..3e9a529283f
--- /dev/null
+++ b/apps/comments/src/services/DavClient.js
@@ -0,0 +1,27 @@
+/**
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { createClient } from 'webdav'
+import { getRootPath } from '../utils/davUtils.js'
+import { getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
+
+// init webdav client
+const client = createClient(getRootPath())
+
+// set CSRF token header
+const setHeaders = (token) => {
+ client.setHeaders({
+ // Add this so the server knows it is an request from the browser
+ 'X-Requested-With': 'XMLHttpRequest',
+ // Inject user auth
+ requesttoken: token ?? '',
+ })
+}
+
+// refresh headers when request token changes
+onRequestTokenUpdate(setHeaders)
+setHeaders(getRequestToken())
+
+export default client
diff --git a/apps/comments/src/services/DeleteComment.js b/apps/comments/src/services/DeleteComment.js
new file mode 100644
index 00000000000..1ed63d7836a
--- /dev/null
+++ b/apps/comments/src/services/DeleteComment.js
@@ -0,0 +1,20 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import client from './DavClient.js'
+
+/**
+ * Delete a comment
+ *
+ * @param {string} resourceType the resource type
+ * @param {number} resourceId the resource ID
+ * @param {number} commentId the comment iD
+ */
+export default async function(resourceType, resourceId, commentId) {
+ const commentPath = ['', resourceType, resourceId, commentId].join('/')
+
+ // Fetch newly created comment data
+ await client.deleteFile(commentPath)
+}
diff --git a/apps/comments/src/services/EditComment.js b/apps/comments/src/services/EditComment.js
new file mode 100644
index 00000000000..4ec33415a72
--- /dev/null
+++ b/apps/comments/src/services/EditComment.js
@@ -0,0 +1,32 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import client from './DavClient.js'
+
+/**
+ * Edit an existing comment
+ *
+ * @param {string} resourceType the resource type
+ * @param {number} resourceId the resource ID
+ * @param {number} commentId the comment iD
+ * @param {string} message the message content
+ */
+export default async function(resourceType, resourceId, commentId, message) {
+ const commentPath = ['', resourceType, resourceId, commentId].join('/')
+
+ return await client.customRequest(commentPath, Object.assign({
+ method: 'PROPPATCH',
+ data: `<?xml version="1.0"?>
+ <d:propertyupdate
+ xmlns:d="DAV:"
+ xmlns:oc="http://owncloud.org/ns">
+ <d:set>
+ <d:prop>
+ <oc:message>${message}</oc:message>
+ </d:prop>
+ </d:set>
+ </d:propertyupdate>`,
+ }))
+}
diff --git a/apps/comments/src/services/GetComments.ts b/apps/comments/src/services/GetComments.ts
new file mode 100644
index 00000000000..c42aa21d6cb
--- /dev/null
+++ b/apps/comments/src/services/GetComments.ts
@@ -0,0 +1,67 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { parseXML, type DAVResult, type FileStat, type ResponseDataDetailed } from 'webdav'
+
+// https://github.com/perry-mitchell/webdav-client/issues/339
+import { processResponsePayload } from 'webdav/dist/node/response.js'
+import { prepareFileFromProps } from 'webdav/dist/node/tools/dav.js'
+import client from './DavClient.js'
+
+export const DEFAULT_LIMIT = 20
+
+/**
+ * Retrieve the comments list
+ *
+ * @param {object} data destructuring object
+ * @param {string} data.resourceType the resource type
+ * @param {number} data.resourceId the resource ID
+ * @param {object} [options] optional options for axios
+ * @param {number} [options.offset] the pagination offset
+ * @param {number} [options.limit] the pagination limit, defaults to 20
+ * @param {Date} [options.datetime] optional date to query
+ * @return {{data: object[]}} the comments list
+ */
+export const getComments = async function({ resourceType, resourceId }, options: { offset: number, limit?: number, datetime?: Date }) {
+ const resourcePath = ['', resourceType, resourceId].join('/')
+ const datetime = options.datetime ? `<oc:datetime>${options.datetime.toISOString()}</oc:datetime>` : ''
+ const response = await client.customRequest(resourcePath, Object.assign({
+ method: 'REPORT',
+ data: `<?xml version="1.0"?>
+ <oc:filter-comments
+ xmlns:d="DAV:"
+ xmlns:oc="http://owncloud.org/ns"
+ xmlns:nc="http://nextcloud.org/ns"
+ xmlns:ocs="http://open-collaboration-services.org/ns">
+ <oc:limit>${options.limit ?? DEFAULT_LIMIT}</oc:limit>
+ <oc:offset>${options.offset || 0}</oc:offset>
+ ${datetime}
+ </oc:filter-comments>`,
+ }, options))
+
+ const responseData = await response.text()
+ const result = await parseXML(responseData)
+ const stat = getDirectoryFiles(result, true)
+ return processResponsePayload(response, stat, true) as ResponseDataDetailed<FileStat[]>
+}
+
+// https://github.com/perry-mitchell/webdav-client/blob/8d9694613c978ce7404e26a401c39a41f125f87f/source/operations/directoryContents.ts
+const getDirectoryFiles = function(
+ result: DAVResult,
+ isDetailed = false,
+): Array<FileStat> {
+ // Extract the response items (directory contents)
+ const {
+ multistatus: { response: responseItems },
+ } = result
+
+ // Map all items to a consistent output structure (results)
+ return responseItems.map(item => {
+ // Each item should contain a stat object
+ const props = item.propstat!.prop!
+
+ return prepareFileFromProps(props, props.id!.toString(), isDetailed)
+ })
+}
diff --git a/apps/comments/src/services/NewComment.js b/apps/comments/src/services/NewComment.js
new file mode 100644
index 00000000000..663b4d72e02
--- /dev/null
+++ b/apps/comments/src/services/NewComment.js
@@ -0,0 +1,50 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { getCurrentUser } from '@nextcloud/auth'
+import { getRootPath } from '../utils/davUtils.js'
+import { decodeHtmlEntities } from '../utils/decodeHtmlEntities.js'
+import axios from '@nextcloud/axios'
+import client from './DavClient.js'
+
+/**
+ * Retrieve the comments list
+ *
+ * @param {string} resourceType the resource type
+ * @param {number} resourceId the resource ID
+ * @param {string} message the message
+ * @return {object} the new comment
+ */
+export default async function(resourceType, resourceId, message) {
+ const resourcePath = ['', resourceType, resourceId].join('/')
+
+ const response = await axios.post(getRootPath() + resourcePath, {
+ actorDisplayName: getCurrentUser().displayName,
+ actorId: getCurrentUser().uid,
+ actorType: 'users',
+ creationDateTime: (new Date()).toUTCString(),
+ message,
+ objectType: resourceType,
+ verb: 'comment',
+ })
+
+ // Retrieve comment id from resource location
+ const commentId = parseInt(response.headers['content-location'].split('/').pop())
+ const commentPath = resourcePath + '/' + commentId
+
+ // Fetch newly created comment data
+ const comment = await client.stat(commentPath, {
+ details: true,
+ })
+
+ const props = comment.data.props
+ // Decode twice to handle potentially double-encoded entities
+ // FIXME Remove this once https://github.com/nextcloud/server/issues/29306
+ // is resolved
+ props.actorDisplayName = decodeHtmlEntities(props.actorDisplayName, 2)
+ props.message = decodeHtmlEntities(props.message, 2)
+
+ return comment.data
+}
diff --git a/apps/comments/src/services/ReadComments.ts b/apps/comments/src/services/ReadComments.ts
new file mode 100644
index 00000000000..73682e21d95
--- /dev/null
+++ b/apps/comments/src/services/ReadComments.ts
@@ -0,0 +1,38 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import client from './DavClient.js'
+
+import type { Response } from 'webdav'
+
+/**
+ * Mark comments older than the date timestamp as read
+ *
+ * @param resourceType the resource type
+ * @param resourceId the resource ID
+ * @param date the date object
+ */
+export const markCommentsAsRead = (
+ resourceType: string,
+ resourceId: number,
+ date: Date,
+): Promise<Response> => {
+ const resourcePath = ['', resourceType, resourceId].join('/')
+ const readMarker = date.toUTCString()
+
+ return client.customRequest(resourcePath, {
+ method: 'PROPPATCH',
+ data: `<?xml version="1.0"?>
+ <d:propertyupdate
+ xmlns:d="DAV:"
+ xmlns:oc="http://owncloud.org/ns">
+ <d:set>
+ <d:prop>
+ <oc:readMarker>${readMarker}</oc:readMarker>
+ </d:prop>
+ </d:set>
+ </d:propertyupdate>`,
+ })
+}
diff --git a/apps/comments/src/store/deletedCommentLimbo.js b/apps/comments/src/store/deletedCommentLimbo.js
new file mode 100644
index 00000000000..3e511addebb
--- /dev/null
+++ b/apps/comments/src/store/deletedCommentLimbo.js
@@ -0,0 +1,28 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { defineStore } from 'pinia'
+
+export const useDeletedCommentLimbo = defineStore('deletedCommentLimbo', {
+ state: () => ({
+ idsInLimbo: [],
+ }),
+ actions: {
+ addId(id) {
+ this.idsInLimbo.push(id)
+ },
+
+ removeId(id) {
+ const index = this.idsInLimbo.indexOf(id)
+ if (index > -1) {
+ this.idsInLimbo.splice(index, 1)
+ }
+ },
+
+ checkForId(id) {
+ this.idsInLimbo.includes(id)
+ },
+ },
+})
diff --git a/apps/comments/src/utils/cancelableRequest.js b/apps/comments/src/utils/cancelableRequest.js
new file mode 100644
index 00000000000..c2d380c80f9
--- /dev/null
+++ b/apps/comments/src/utils/cancelableRequest.js
@@ -0,0 +1,36 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+/**
+ * Creates a cancelable axios 'request object'.
+ *
+ * @param {Function} request the axios promise request
+ * @return {object}
+ */
+const cancelableRequest = function(request) {
+ const controller = new AbortController()
+ const signal = controller.signal
+
+ /**
+ * Execute the request
+ *
+ * @param {string} url the url to send the request to
+ * @param {object} [options] optional config for the request
+ */
+ const fetch = async function(url, options) {
+ const response = await request(
+ url,
+ Object.assign({ signal }, options),
+ )
+ return response
+ }
+
+ return {
+ request: fetch,
+ abort: () => controller.abort(),
+ }
+}
+
+export default cancelableRequest
diff --git a/apps/comments/src/utils/davUtils.js b/apps/comments/src/utils/davUtils.js
new file mode 100644
index 00000000000..33efc8e7d10
--- /dev/null
+++ b/apps/comments/src/utils/davUtils.js
@@ -0,0 +1,12 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { generateRemoteUrl } from '@nextcloud/router'
+
+const getRootPath = function() {
+ return generateRemoteUrl('dav/comments')
+}
+
+export { getRootPath }
diff --git a/apps/comments/src/utils/decodeHtmlEntities.js b/apps/comments/src/utils/decodeHtmlEntities.js
new file mode 100644
index 00000000000..4c492954256
--- /dev/null
+++ b/apps/comments/src/utils/decodeHtmlEntities.js
@@ -0,0 +1,17 @@
+/**
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+/**
+ * @param {any} value -
+ * @param {any} passes -
+ */
+export function decodeHtmlEntities(value, passes = 1) {
+ const parser = new DOMParser()
+ let decoded = value
+ for (let i = 0; i < passes; i++) {
+ decoded = parser.parseFromString(decoded, 'text/html').documentElement.textContent
+ }
+ return decoded
+}
diff --git a/apps/comments/src/views/ActivityCommentAction.vue b/apps/comments/src/views/ActivityCommentAction.vue
new file mode 100644
index 00000000000..f9a9a97796f
--- /dev/null
+++ b/apps/comments/src/views/ActivityCommentAction.vue
@@ -0,0 +1,54 @@
+<!--
+ - SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+
+<template>
+ <Comment v-bind="editorData"
+ :auto-complete="autoComplete"
+ :resource-type="resourceType"
+ :editor="true"
+ :user-data="userData"
+ :resource-id="resourceId"
+ class="comments-action"
+ @new="onNewComment" />
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue'
+import Comment from '../components/Comment.vue'
+import CommentView from '../mixins/CommentView.js'
+import logger from '../logger'
+import { showError } from '@nextcloud/dialogs'
+import { translate as t } from '@nextcloud/l10n'
+
+export default defineComponent({
+ components: {
+ Comment,
+ },
+ mixins: [CommentView],
+ props: {
+ reloadCallback: {
+ type: Function,
+ required: true,
+ },
+ },
+ methods: {
+ onNewComment() {
+ try {
+ // just force reload
+ this.reloadCallback()
+ } catch (e) {
+ showError(t('comments', 'Could not reload comments'))
+ logger.debug(e)
+ }
+ },
+ },
+})
+</script>
+
+<style scoped>
+.comments-action {
+ padding: 0;
+}
+</style>
diff --git a/apps/comments/src/views/ActivityCommentEntry.vue b/apps/comments/src/views/ActivityCommentEntry.vue
new file mode 100644
index 00000000000..bbfe530b2e3
--- /dev/null
+++ b/apps/comments/src/views/ActivityCommentEntry.vue
@@ -0,0 +1,71 @@
+<!--
+ - SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+
+<template>
+ <Comment ref="comment"
+ tag="li"
+ v-bind="comment.props"
+ :auto-complete="autoComplete"
+ :resource-type="resourceType"
+ :message="commentMessage"
+ :resource-id="resourceId"
+ :user-data="genMentionsData(comment.props.mentions)"
+ class="comments-activity"
+ @delete="reloadCallback()" />
+</template>
+
+<script lang="ts">
+import type { PropType } from 'vue'
+import { translate as t } from '@nextcloud/l10n'
+
+import Comment from '../components/Comment.vue'
+import CommentView from '../mixins/CommentView'
+
+export default {
+ name: 'ActivityCommentEntry',
+
+ components: {
+ Comment,
+ },
+
+ mixins: [CommentView],
+ props: {
+ comment: {
+ type: Object,
+ required: true,
+ },
+ reloadCallback: {
+ type: Function as PropType<() => void>,
+ required: true,
+ },
+ },
+
+ data() {
+ return {
+ commentMessage: '',
+ }
+ },
+
+ watch: {
+ comment() {
+ this.commentMessage = this.comment.props.message
+ },
+ },
+
+ mounted() {
+ this.commentMessage = this.comment.props.message
+ },
+
+ methods: {
+ t,
+ },
+}
+</script>
+
+<style scoped>
+.comments-activity {
+ padding: 0;
+}
+</style>
diff --git a/apps/comments/src/views/Comments.vue b/apps/comments/src/views/Comments.vue
new file mode 100644
index 00000000000..657af888a12
--- /dev/null
+++ b/apps/comments/src/views/Comments.vue
@@ -0,0 +1,279 @@
+<!--
+ - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+
+<template>
+ <div v-element-visibility="onVisibilityChange"
+ class="comments"
+ :class="{ 'icon-loading': isFirstLoading }">
+ <!-- Editor -->
+ <Comment v-bind="editorData"
+ :auto-complete="autoComplete"
+ :resource-type="resourceType"
+ :editor="true"
+ :user-data="userData"
+ :resource-id="currentResourceId"
+ class="comments__writer"
+ @new="onNewComment" />
+
+ <template v-if="!isFirstLoading">
+ <NcEmptyContent v-if="!hasComments && done"
+ class="comments__empty"
+ :name="t('comments', 'No comments yet, start the conversation!')">
+ <template #icon>
+ <IconMessageReplyTextOutline />
+ </template>
+ </NcEmptyContent>
+ <ul v-else>
+ <!-- Comments -->
+ <Comment v-for="comment in comments"
+ :key="comment.props.id"
+ tag="li"
+ v-bind="comment.props"
+ :auto-complete="autoComplete"
+ :resource-type="resourceType"
+ :message.sync="comment.props.message"
+ :resource-id="currentResourceId"
+ :user-data="genMentionsData(comment.props.mentions)"
+ class="comments__list"
+ @delete="onDelete" />
+ </ul>
+
+ <!-- Loading more message -->
+ <div v-if="loading && !isFirstLoading" class="comments__info icon-loading" />
+
+ <div v-else-if="hasComments && done" class="comments__info">
+ {{ t('comments', 'No more messages') }}
+ </div>
+
+ <!-- Error message -->
+ <template v-else-if="error">
+ <NcEmptyContent class="comments__error" :name="error">
+ <template #icon>
+ <IconAlertCircleOutline />
+ </template>
+ </NcEmptyContent>
+ <NcButton class="comments__retry" @click="getComments">
+ <template #icon>
+ <IconRefresh />
+ </template>
+ {{ t('comments', 'Retry') }}
+ </NcButton>
+ </template>
+ </template>
+ </div>
+</template>
+
+<script>
+import { showError } from '@nextcloud/dialogs'
+import { translate as t } from '@nextcloud/l10n'
+import { vElementVisibility as elementVisibility } from '@vueuse/components'
+
+import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
+import NcButton from '@nextcloud/vue/components/NcButton'
+import IconRefresh from 'vue-material-design-icons/Refresh.vue'
+import IconMessageReplyTextOutline from 'vue-material-design-icons/MessageReplyTextOutline.vue'
+import IconAlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'
+
+import Comment from '../components/Comment.vue'
+import CommentView from '../mixins/CommentView'
+import cancelableRequest from '../utils/cancelableRequest.js'
+import { getComments, DEFAULT_LIMIT } from '../services/GetComments.ts'
+import { markCommentsAsRead } from '../services/ReadComments.ts'
+
+export default {
+ name: 'Comments',
+
+ components: {
+ Comment,
+ NcEmptyContent,
+ NcButton,
+ IconRefresh,
+ IconMessageReplyTextOutline,
+ IconAlertCircleOutline,
+ },
+
+ directives: {
+ elementVisibility,
+ },
+
+ mixins: [CommentView],
+
+ data() {
+ return {
+ error: '',
+ loading: false,
+ done: false,
+
+ currentResourceId: this.resourceId,
+ offset: 0,
+ comments: [],
+
+ cancelRequest: () => {},
+
+ Comment,
+ userData: {},
+ }
+ },
+
+ computed: {
+ hasComments() {
+ return this.comments.length > 0
+ },
+ isFirstLoading() {
+ return this.loading && this.offset === 0
+ },
+ },
+
+ watch: {
+ resourceId() {
+ this.currentResourceId = this.resourceId
+ },
+ },
+
+ methods: {
+ t,
+
+ async onVisibilityChange(isVisible) {
+ if (isVisible) {
+ try {
+ await markCommentsAsRead(this.resourceType, this.currentResourceId, new Date())
+ } catch (e) {
+ showError(e.message || t('comments', 'Failed to mark comments as read'))
+ }
+ }
+ },
+
+ /**
+ * Update current resourceId and fetch new data
+ *
+ * @param {number} resourceId the current resourceId (fileId...)
+ */
+ async update(resourceId) {
+ this.currentResourceId = resourceId
+ this.resetState()
+ this.getComments()
+ },
+
+ /**
+ * Ran when the bottom of the tab is reached
+ */
+ onScrollBottomReached() {
+ /**
+ * Do not fetch more if we:
+ * - are showing an error
+ * - already fetched everything
+ * - are currently loading
+ */
+ if (this.error || this.done || this.loading) {
+ return
+ }
+ this.getComments()
+ },
+
+ /**
+ * Get the existing shares infos
+ */
+ async getComments() {
+ // Cancel any ongoing request
+ this.cancelRequest('cancel')
+
+ try {
+ this.loading = true
+ this.error = ''
+
+ // Init cancellable request
+ const { request, abort } = cancelableRequest(getComments)
+ this.cancelRequest = abort
+
+ // Fetch comments
+ const { data: comments } = await request({
+ resourceType: this.resourceType,
+ resourceId: this.currentResourceId,
+ }, { offset: this.offset }) || { data: [] }
+
+ this.logger.debug(`Processed ${comments.length} comments`, { comments })
+
+ // We received less than the requested amount,
+ // we're done fetching comments
+ if (comments.length < DEFAULT_LIMIT) {
+ this.done = true
+ }
+
+ // Insert results
+ this.comments.push(...comments)
+
+ // Increase offset for next fetch
+ this.offset += DEFAULT_LIMIT
+ } catch (error) {
+ if (error.message === 'cancel') {
+ return
+ }
+ this.error = t('comments', 'Unable to load the comments list')
+ console.error('Error loading the comments list', error)
+ } finally {
+ this.loading = false
+ }
+ },
+
+ /**
+ * Add newly created comment to the list
+ *
+ * @param {object} comment the new comment
+ */
+ onNewComment(comment) {
+ this.comments.unshift(comment)
+ },
+
+ /**
+ * Remove deleted comment from the list
+ *
+ * @param {number} id the deleted comment
+ */
+ onDelete(id) {
+ const index = this.comments.findIndex(comment => comment.props.id === id)
+ if (index > -1) {
+ this.comments.splice(index, 1)
+ } else {
+ console.error('Could not find the deleted comment in the list', id)
+ }
+ },
+
+ /**
+ * Reset the current view to its default state
+ */
+ resetState() {
+ this.error = ''
+ this.loading = false
+ this.done = false
+ this.offset = 0
+ this.comments = []
+ },
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+.comments {
+ min-height: 100%;
+ display: flex;
+ flex-direction: column;
+
+ &__empty,
+ &__error {
+ flex: 1 0;
+ }
+
+ &__retry {
+ margin: 0 auto;
+ }
+
+ &__info {
+ height: 60px;
+ color: var(--color-text-maxcontrast);
+ text-align: center;
+ line-height: 60px;
+ }
+}
+</style>
diff --git a/apps/comments/tests/Unit/Activity/ListenerTest.php b/apps/comments/tests/Unit/Activity/ListenerTest.php
new file mode 100644
index 00000000000..675a28a16b1
--- /dev/null
+++ b/apps/comments/tests/Unit/Activity/ListenerTest.php
@@ -0,0 +1,159 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Tests\Unit\Activity;
+
+use OCA\Comments\Activity\Listener;
+use OCP\Activity\IEvent;
+use OCP\Activity\IManager;
+use OCP\App\IAppManager;
+use OCP\Comments\CommentsEvent;
+use OCP\Comments\IComment;
+use OCP\Files\Config\ICachedMountFileInfo;
+use OCP\Files\Config\IMountProviderCollection;
+use OCP\Files\Config\IUserMountCache;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+use OCP\IUser;
+use OCP\IUserSession;
+use OCP\Share\IShareHelper;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class ListenerTest extends TestCase {
+ protected IManager&MockObject $activityManager;
+ protected IUserSession&MockObject $session;
+ protected IAppManager&MockObject $appManager;
+ protected IMountProviderCollection&MockObject $mountProviderCollection;
+ protected IRootFolder&MockObject $rootFolder;
+ protected IShareHelper&MockObject $shareHelper;
+ protected Listener $listener;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->activityManager = $this->createMock(IManager::class);
+ $this->session = $this->createMock(IUserSession::class);
+ $this->appManager = $this->createMock(IAppManager::class);
+ $this->mountProviderCollection = $this->createMock(IMountProviderCollection::class);
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+ $this->shareHelper = $this->createMock(IShareHelper::class);
+
+ $this->listener = new Listener(
+ $this->activityManager,
+ $this->session,
+ $this->appManager,
+ $this->mountProviderCollection,
+ $this->rootFolder,
+ $this->shareHelper
+ );
+ }
+
+ public function testCommentEvent(): void {
+ $this->appManager->expects($this->any())
+ ->method('isEnabledForAnyone')
+ ->with('activity')
+ ->willReturn(true);
+
+ $comment = $this->createMock(IComment::class);
+ $comment->expects($this->any())
+ ->method('getObjectType')
+ ->willReturn('files');
+
+ /** @var CommentsEvent|MockObject $event */
+ $event = $this->createMock(CommentsEvent::class);
+ $event->expects($this->any())
+ ->method('getComment')
+ ->willReturn($comment);
+ $event->expects($this->any())
+ ->method('getEvent')
+ ->willReturn(CommentsEvent::EVENT_ADD);
+
+ /** @var IUser|MockObject $ownerUser */
+ $ownerUser = $this->createMock(IUser::class);
+ $ownerUser->expects($this->any())
+ ->method('getUID')
+ ->willReturn('937393');
+
+ /** @var MockObject $mount */
+ $mount = $this->createMock(ICachedMountFileInfo::class);
+ $mount->expects($this->any())
+ ->method('getUser')
+ ->willReturn($ownerUser); // perhaps not the right user, but does not matter in this scenario
+
+ $mounts = [ $mount, $mount ]; // to make sure duplicates are dealt with
+
+ $userMountCache = $this->createMock(IUserMountCache::class);
+ $userMountCache->expects($this->any())
+ ->method('getMountsForFileId')
+ ->willReturn($mounts);
+
+ $this->mountProviderCollection->expects($this->any())
+ ->method('getMountCache')
+ ->willReturn($userMountCache);
+
+ $node = $this->createMock(Node::class);
+ $nodes = [ $node ];
+
+ $ownerFolder = $this->createMock(Folder::class);
+ $ownerFolder->expects($this->any())
+ ->method('getById')
+ ->willReturn($nodes);
+
+ $this->rootFolder->expects($this->any())
+ ->method('getUserFolder')
+ ->willReturn($ownerFolder);
+
+ $al = [ 'users' => [
+ '873304' => 'i/got/it/here',
+ '254342' => 'there/i/have/it',
+ 'sandra' => 'and/here/i/placed/it'
+ ]];
+ $this->shareHelper->expects($this->any())
+ ->method('getPathsForAccessList')
+ ->willReturn($al);
+
+ $this->session->expects($this->any())
+ ->method('getUser')
+ ->willReturn($ownerUser);
+
+ /** @var MockObject $activity */
+ $activity = $this->createMock(IEvent::class);
+ $activity->expects($this->exactly(count($al['users'])))
+ ->method('setAffectedUser');
+ $activity->expects($this->once())
+ ->method('setApp')
+ ->with('comments')
+ ->willReturnSelf();
+ $activity->expects($this->once())
+ ->method('setType')
+ ->with('comments')
+ ->willReturnSelf();
+ $activity->expects($this->once())
+ ->method('setAuthor')
+ ->with($ownerUser->getUID())
+ ->willReturnSelf();
+ $activity->expects($this->once())
+ ->method('setObject')
+ ->with('files', $this->anything())
+ ->willReturnSelf();
+ $activity->expects($this->once())
+ ->method('setMessage')
+ ->with('add_comment_message', $this->anything())
+ ->willReturnSelf();
+
+ $this->activityManager->expects($this->once())
+ ->method('generateEvent')
+ ->willReturn($activity);
+ $this->activityManager->expects($this->exactly(count($al['users'])))
+ ->method('publish');
+
+ $this->listener->commentEvent($event);
+ }
+}
diff --git a/apps/comments/tests/Unit/AppInfo/ApplicationTest.php b/apps/comments/tests/Unit/AppInfo/ApplicationTest.php
new file mode 100644
index 00000000000..119db5333b5
--- /dev/null
+++ b/apps/comments/tests/Unit/AppInfo/ApplicationTest.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Comments\Tests\Unit\AppInfo;
+
+use OCA\Comments\Activity\Filter;
+use OCA\Comments\Activity\Listener;
+use OCA\Comments\Activity\Provider;
+use OCA\Comments\Activity\Setting;
+use OCA\Comments\AppInfo\Application;
+use OCA\Comments\Controller\NotificationsController;
+use OCA\Comments\Notification\Notifier;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use OCP\Server;
+use Test\TestCase;
+
+/**
+ * Class ApplicationTest
+ *
+ * @group DB
+ *
+ * @package OCA\Comments\Tests\Unit\AppInfo
+ */
+class ApplicationTest extends TestCase {
+ protected function setUp(): void {
+ parent::setUp();
+ Server::get(IUserManager::class)->createUser('dummy', '456');
+ Server::get(IUserSession::class)->setUser(Server::get(IUserManager::class)->get('dummy'));
+ }
+
+ protected function tearDown(): void {
+ Server::get(IUserManager::class)->get('dummy')->delete();
+ parent::tearDown();
+ }
+
+ public function test(): void {
+ $app = new Application();
+ $c = $app->getContainer();
+
+ $services = [
+ NotificationsController::class,
+ Filter::class,
+ Listener::class,
+ Provider::class,
+ Setting::class,
+ \OCA\Comments\Notification\Listener::class,
+ Notifier::class,
+ ];
+
+ foreach ($services as $service) {
+ $s = $c->get($service);
+ $this->assertInstanceOf($service, $s);
+ }
+ }
+}
diff --git a/apps/comments/tests/Unit/Collaboration/CommentersSorterTest.php b/apps/comments/tests/Unit/Collaboration/CommentersSorterTest.php
new file mode 100644
index 00000000000..4d3392a562d
--- /dev/null
+++ b/apps/comments/tests/Unit/Collaboration/CommentersSorterTest.php
@@ -0,0 +1,136 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Tests\Unit\Collaboration;
+
+use OCA\Comments\Collaboration\CommentersSorter;
+use OCP\Comments\IComment;
+use OCP\Comments\ICommentsManager;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class CommentersSorterTest extends TestCase {
+ protected ICommentsManager&MockObject $commentsManager;
+ protected CommentersSorter $sorter;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->commentsManager = $this->createMock(ICommentsManager::class);
+
+ $this->sorter = new CommentersSorter($this->commentsManager);
+ }
+
+ /**
+ * @param $data
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('sortDataProvider')]
+ public function testSort($data): void {
+ $commentMocks = [];
+ foreach ($data['actors'] as $actorType => $actors) {
+ foreach ($actors as $actorId => $noOfComments) {
+ for ($i = 0;$i < $noOfComments;$i++) {
+ $mock = $this->createMock(IComment::class);
+ $mock->expects($this->atLeastOnce())
+ ->method('getActorType')
+ ->willReturn($actorType);
+ $mock->expects($this->atLeastOnce())
+ ->method('getActorId')
+ ->willReturn($actorId);
+ $commentMocks[] = $mock;
+ }
+ }
+ }
+
+ $this->commentsManager->expects($this->once())
+ ->method('getForObject')
+ ->willReturn($commentMocks);
+
+ $workArray = $data['input'];
+ $this->sorter->sort($workArray, ['itemType' => 'files', 'itemId' => '24']);
+
+ $this->assertEquals($data['expected'], $workArray);
+ }
+
+ public static function sortDataProvider(): array {
+ return [[
+ [
+ #1 – sort properly and otherwise keep existing order
+ 'actors' => ['users' => ['celia' => 3, 'darius' => 7, 'faruk' => 5, 'gail' => 5], 'bots' => ['r2-d2' => 8]],
+ 'input' => [
+ 'users' => [
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ['value' => ['shareWith' => 'celia']],
+ ['value' => ['shareWith' => 'darius']],
+ ['value' => ['shareWith' => 'elena']],
+ ['value' => ['shareWith' => 'faruk']],
+ ['value' => ['shareWith' => 'gail']],
+ ],
+ 'bots' => [
+ ['value' => ['shareWith' => 'c-3po']],
+ ['value' => ['shareWith' => 'r2-d2']],
+ ]
+ ],
+ 'expected' => [
+ 'users' => [
+ ['value' => ['shareWith' => 'darius']],
+ ['value' => ['shareWith' => 'faruk']],
+ ['value' => ['shareWith' => 'gail']],
+ ['value' => ['shareWith' => 'celia']],
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ['value' => ['shareWith' => 'elena']],
+ ],
+ 'bots' => [
+ ['value' => ['shareWith' => 'r2-d2']],
+ ['value' => ['shareWith' => 'c-3po']],
+ ]
+ ],
+ ],
+ [
+ #2 – no commentors, input equals output
+ 'actors' => [],
+ 'input' => [
+ 'users' => [
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ['value' => ['shareWith' => 'celia']],
+ ['value' => ['shareWith' => 'darius']],
+ ['value' => ['shareWith' => 'elena']],
+ ['value' => ['shareWith' => 'faruk']],
+ ['value' => ['shareWith' => 'gail']],
+ ],
+ 'bots' => [
+ ['value' => ['shareWith' => 'c-3po']],
+ ['value' => ['shareWith' => 'r2-d2']],
+ ]
+ ],
+ 'expected' => [
+ 'users' => [
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ['value' => ['shareWith' => 'celia']],
+ ['value' => ['shareWith' => 'darius']],
+ ['value' => ['shareWith' => 'elena']],
+ ['value' => ['shareWith' => 'faruk']],
+ ['value' => ['shareWith' => 'gail']],
+ ],
+ 'bots' => [
+ ['value' => ['shareWith' => 'c-3po']],
+ ['value' => ['shareWith' => 'r2-d2']],
+ ]
+ ],
+ ],
+ [
+ #3 – no nothing
+ 'actors' => [],
+ 'input' => [],
+ 'expected' => [],
+ ],
+ ]];
+ }
+}
diff --git a/apps/comments/tests/Unit/Controller/NotificationsTest.php b/apps/comments/tests/Unit/Controller/NotificationsTest.php
new file mode 100644
index 00000000000..04490ca63e8
--- /dev/null
+++ b/apps/comments/tests/Unit/Controller/NotificationsTest.php
@@ -0,0 +1,214 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Comments\Tests\Unit\Controller;
+
+use OCA\Comments\Controller\NotificationsController;
+use OCP\AppFramework\Http\NotFoundResponse;
+use OCP\AppFramework\Http\RedirectResponse;
+use OCP\Comments\IComment;
+use OCP\Comments\ICommentsManager;
+use OCP\Comments\NotFoundException;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+use OCP\IRequest;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\IUserSession;
+use OCP\Notification\IManager;
+use OCP\Notification\INotification;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class NotificationsTest extends TestCase {
+ protected ICommentsManager&MockObject $commentsManager;
+ protected IRootFolder&MockObject $rootFolder;
+ protected IUserSession&MockObject $session;
+ protected IManager&MockObject $notificationManager;
+ protected IURLGenerator&MockObject $urlGenerator;
+ protected NotificationsController $notificationsController;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->commentsManager = $this->createMock(ICommentsManager::class);
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+ $this->session = $this->createMock(IUserSession::class);
+ $this->notificationManager = $this->createMock(IManager::class);
+ $this->urlGenerator = $this->createMock(IURLGenerator::class);
+
+ $this->notificationsController = new NotificationsController(
+ 'comments',
+ $this->createMock(IRequest::class),
+ $this->commentsManager,
+ $this->rootFolder,
+ $this->urlGenerator,
+ $this->notificationManager,
+ $this->session
+ );
+ }
+
+ public function testViewGuestRedirect(): void {
+ $this->commentsManager->expects($this->never())
+ ->method('get');
+
+ $this->rootFolder->expects($this->never())
+ ->method('getUserFolder');
+
+ $this->session->expects($this->once())
+ ->method('getUser')
+ ->willReturn(null);
+
+ $this->notificationManager->expects($this->never())
+ ->method('createNotification');
+ $this->notificationManager->expects($this->never())
+ ->method('markProcessed');
+
+ $this->urlGenerator->expects($this->exactly(2))
+ ->method('linkToRoute')
+ ->willReturnMap([
+ ['comments.Notifications.view', ['id' => '42'], 'link-to-comment'],
+ ['core.login.showLoginForm', ['redirect_url' => 'link-to-comment'], 'link-to-login'],
+ ]);
+
+ /** @var RedirectResponse $response */
+ $response = $this->notificationsController->view('42');
+ $this->assertInstanceOf(RedirectResponse::class, $response);
+ $this->assertSame('link-to-login', $response->getRedirectURL());
+ }
+
+ public function testViewSuccess(): void {
+ $comment = $this->createMock(IComment::class);
+ $comment->expects($this->any())
+ ->method('getObjectType')
+ ->willReturn('files');
+ $comment->expects($this->any())
+ ->method('getId')
+ ->willReturn('1234');
+
+ $this->commentsManager->expects($this->any())
+ ->method('get')
+ ->with('42')
+ ->willReturn($comment);
+
+ $file = $this->createMock(Node::class);
+ $folder = $this->createMock(Folder::class);
+ $user = $this->createMock(IUser::class);
+
+ $this->rootFolder->expects($this->once())
+ ->method('getUserFolder')
+ ->willReturn($folder);
+
+ $folder->expects($this->once())
+ ->method('getById')
+ ->willReturn([$file]);
+
+ $this->session->expects($this->once())
+ ->method('getUser')
+ ->willReturn($user);
+
+ $user->expects($this->any())
+ ->method('getUID')
+ ->willReturn('user');
+
+ $notification = $this->createMock(INotification::class);
+ $notification->expects($this->any())
+ ->method($this->anything())
+ ->willReturn($notification);
+
+ $this->notificationManager->expects($this->once())
+ ->method('createNotification')
+ ->willReturn($notification);
+ $this->notificationManager->expects($this->once())
+ ->method('markProcessed')
+ ->with($notification);
+
+ $response = $this->notificationsController->view('42');
+ $this->assertInstanceOf(RedirectResponse::class, $response);
+ }
+
+ public function testViewInvalidComment(): void {
+ $this->commentsManager->expects($this->any())
+ ->method('get')
+ ->with('42')
+ ->willThrowException(new NotFoundException());
+
+ $this->rootFolder->expects($this->never())
+ ->method('getUserFolder');
+
+ $user = $this->createMock(IUser::class);
+
+ $this->session->expects($this->once())
+ ->method('getUser')
+ ->willReturn($user);
+
+ $user->expects($this->any())
+ ->method('getUID')
+ ->willReturn('user');
+
+ $this->notificationManager->expects($this->never())
+ ->method('createNotification');
+ $this->notificationManager->expects($this->never())
+ ->method('markProcessed');
+
+ $response = $this->notificationsController->view('42');
+ $this->assertInstanceOf(NotFoundResponse::class, $response);
+ }
+
+ public function testViewNoFile(): void {
+ $comment = $this->createMock(IComment::class);
+ $comment->expects($this->any())
+ ->method('getObjectType')
+ ->willReturn('files');
+ $comment->expects($this->any())
+ ->method('getId')
+ ->willReturn('1234');
+
+ $this->commentsManager->expects($this->any())
+ ->method('get')
+ ->with('42')
+ ->willReturn($comment);
+
+ $folder = $this->createMock(Folder::class);
+
+ $this->rootFolder->expects($this->once())
+ ->method('getUserFolder')
+ ->willReturn($folder);
+
+ $folder->expects($this->once())
+ ->method('getById')
+ ->willReturn([]);
+
+ $user = $this->createMock(IUser::class);
+
+ $this->session->expects($this->once())
+ ->method('getUser')
+ ->willReturn($user);
+
+ $user->expects($this->any())
+ ->method('getUID')
+ ->willReturn('user');
+
+ $notification = $this->createMock(INotification::class);
+ $notification->expects($this->any())
+ ->method($this->anything())
+ ->willReturn($notification);
+
+ $this->notificationManager->expects($this->once())
+ ->method('createNotification')
+ ->willReturn($notification);
+ $this->notificationManager->expects($this->once())
+ ->method('markProcessed')
+ ->with($notification);
+
+ $response = $this->notificationsController->view('42');
+ $this->assertInstanceOf(NotFoundResponse::class, $response);
+ }
+}
diff --git a/apps/comments/tests/Unit/EventHandlerTest.php b/apps/comments/tests/Unit/EventHandlerTest.php
new file mode 100644
index 00000000000..9d26f828d70
--- /dev/null
+++ b/apps/comments/tests/Unit/EventHandlerTest.php
@@ -0,0 +1,87 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Tests\Unit\Notification;
+
+use OCA\Comments\Activity\Listener as ActivityListener;
+use OCA\Comments\Listener\CommentsEventListener;
+use OCA\Comments\Notification\Listener as NotificationListener;
+use OCP\Comments\CommentsEvent;
+use OCP\Comments\IComment;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class EventHandlerTest extends TestCase {
+ protected ActivityListener&MockObject $activityListener;
+ protected NotificationListener&MockObject $notificationListener;
+ protected CommentsEventListener $eventHandler;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->activityListener = $this->createMock(ActivityListener::class);
+ $this->notificationListener = $this->createMock(NotificationListener::class);
+
+ $this->eventHandler = new CommentsEventListener($this->activityListener, $this->notificationListener);
+ }
+
+ public function testNotFiles(): void {
+ /** @var IComment|MockObject $comment */
+ $comment = $this->createMock(IComment::class);
+ $comment->expects($this->once())
+ ->method('getObjectType')
+ ->willReturn('smiles');
+
+ /** @var CommentsEvent|MockObject $event */
+ $event = $this->createMock(CommentsEvent::class);
+ $event->expects($this->once())
+ ->method('getComment')
+ ->willReturn($comment);
+ $event->expects($this->never())
+ ->method('getEvent');
+
+ $this->eventHandler->handle($event);
+ }
+
+ public static function handledProvider(): array {
+ return [
+ [CommentsEvent::EVENT_DELETE],
+ [CommentsEvent::EVENT_UPDATE],
+ [CommentsEvent::EVENT_PRE_UPDATE],
+ [CommentsEvent::EVENT_ADD]
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('handledProvider')]
+ public function testHandled(string $eventType): void {
+ /** @var IComment|MockObject $comment */
+ $comment = $this->createMock(IComment::class);
+ $comment->expects($this->once())
+ ->method('getObjectType')
+ ->willReturn('files');
+
+ /** @var CommentsEvent|MockObject $event */
+ $event = $this->createMock(CommentsEvent::class);
+ $event->expects($this->atLeastOnce())
+ ->method('getComment')
+ ->willReturn($comment);
+ $event->expects($this->atLeastOnce())
+ ->method('getEvent')
+ ->willReturn($eventType);
+
+ $this->notificationListener->expects($this->once())
+ ->method('evaluate')
+ ->with($event);
+
+ $this->activityListener->expects($this->any())
+ ->method('commentEvent')
+ ->with($event);
+
+ $this->eventHandler->handle($event);
+ }
+}
diff --git a/apps/comments/tests/Unit/Notification/ListenerTest.php b/apps/comments/tests/Unit/Notification/ListenerTest.php
new file mode 100644
index 00000000000..356a26f23cd
--- /dev/null
+++ b/apps/comments/tests/Unit/Notification/ListenerTest.php
@@ -0,0 +1,195 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Comments\Tests\Unit\Notification;
+
+use OCA\Comments\Notification\Listener;
+use OCP\Comments\CommentsEvent;
+use OCP\Comments\IComment;
+use OCP\IURLGenerator;
+use OCP\IUserManager;
+use OCP\Notification\IManager;
+use OCP\Notification\INotification;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class ListenerTest extends TestCase {
+ protected IManager&MockObject $notificationManager;
+ protected IUserManager&MockObject $userManager;
+ protected IURLGenerator&MockObject $urlGenerator;
+ protected Listener $listener;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->notificationManager = $this->createMock(IManager::class);
+ $this->userManager = $this->createMock(IUserManager::class);
+
+ $this->listener = new Listener(
+ $this->notificationManager,
+ $this->userManager
+ );
+ }
+
+ public static function eventProvider(): array {
+ return [
+ [CommentsEvent::EVENT_ADD, 'notify'],
+ [CommentsEvent::EVENT_UPDATE, 'notify'],
+ [CommentsEvent::EVENT_PRE_UPDATE, 'markProcessed'],
+ [CommentsEvent::EVENT_DELETE, 'markProcessed']
+ ];
+ }
+
+ /**
+ * @param string $eventType
+ * @param string $notificationMethod
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('eventProvider')]
+ public function testEvaluate($eventType, $notificationMethod): void {
+ /** @var IComment|MockObject $comment */
+ $comment = $this->createMock(IComment::class);
+ $comment->expects($this->any())
+ ->method('getObjectType')
+ ->willReturn('files');
+ $comment->expects($this->any())
+ ->method('getCreationDateTime')
+ ->willReturn(new \DateTime());
+ $comment->expects($this->once())
+ ->method('getMentions')
+ ->willReturn([
+ [ 'type' => 'user', 'id' => 'foobar'],
+ [ 'type' => 'user', 'id' => 'barfoo'],
+ [ 'type' => 'user', 'id' => 'foo@bar.com'],
+ [ 'type' => 'user', 'id' => 'bar@foo.org@foobar.io'],
+ [ 'type' => 'user', 'id' => '23452-4333-54353-2342'],
+ [ 'type' => 'user', 'id' => 'yolo'],
+ ]);
+ $comment->expects($this->atLeastOnce())
+ ->method('getId')
+ ->willReturn('1234');
+
+ /** @var CommentsEvent|MockObject $event */
+ $event = $this->createMock(CommentsEvent::class);
+ $event->expects($this->once())
+ ->method('getComment')
+ ->willReturn($comment);
+ $event->expects(($this->any()))
+ ->method(('getEvent'))
+ ->willReturn($eventType);
+
+ /** @var INotification|MockObject $notification */
+ $notification = $this->createMock(INotification::class);
+ $notification->expects($this->any())
+ ->method($this->anything())
+ ->willReturn($notification);
+ $notification->expects($this->exactly(6))
+ ->method('setUser');
+
+ $this->notificationManager->expects($this->once())
+ ->method('createNotification')
+ ->willReturn($notification);
+ $this->notificationManager->expects($this->exactly(6))
+ ->method($notificationMethod)
+ ->with($this->isInstanceOf('\OCP\Notification\INotification'));
+
+ $this->userManager->expects($this->exactly(6))
+ ->method('userExists')
+ ->willReturnMap([
+ ['foobar', true],
+ ['barfoo', true],
+ ['foo@bar.com', true],
+ ['bar@foo.org@foobar.io', true],
+ ['23452-4333-54353-2342', true],
+ ['yolo', true]
+ ]);
+
+ $this->listener->evaluate($event);
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('eventProvider')]
+ public function testEvaluateNoMentions(string $eventType): void {
+ /** @var IComment|MockObject $comment */
+ $comment = $this->createMock(IComment::class);
+ $comment->expects($this->any())
+ ->method('getObjectType')
+ ->willReturn('files');
+ $comment->expects($this->any())
+ ->method('getCreationDateTime')
+ ->willReturn(new \DateTime());
+ $comment->expects($this->once())
+ ->method('getMentions')
+ ->willReturn([]);
+
+ /** @var CommentsEvent|MockObject $event */
+ $event = $this->createMock(CommentsEvent::class);
+ $event->expects($this->once())
+ ->method('getComment')
+ ->willReturn($comment);
+ $event->expects(($this->any()))
+ ->method(('getEvent'))
+ ->willReturn($eventType);
+
+ $this->notificationManager->expects($this->never())
+ ->method('createNotification');
+ $this->notificationManager->expects($this->never())
+ ->method('notify');
+ $this->notificationManager->expects($this->never())
+ ->method('markProcessed');
+
+ $this->userManager->expects($this->never())
+ ->method('userExists');
+
+ $this->listener->evaluate($event);
+ }
+
+ public function testEvaluateUserDoesNotExist(): void {
+ /** @var IComment|MockObject $comment */
+ $comment = $this->createMock(IComment::class);
+ $comment->expects($this->any())
+ ->method('getObjectType')
+ ->willReturn('files');
+ $comment->expects($this->any())
+ ->method('getCreationDateTime')
+ ->willReturn(new \DateTime());
+ $comment->expects($this->once())
+ ->method('getMentions')
+ ->willReturn([[ 'type' => 'user', 'id' => 'foobar']]);
+ $comment->expects($this->atLeastOnce())
+ ->method('getId')
+ ->willReturn('1234');
+
+ /** @var CommentsEvent|MockObject $event */
+ $event = $this->createMock(CommentsEvent::class);
+ $event->expects($this->once())
+ ->method('getComment')
+ ->willReturn($comment);
+ $event->expects(($this->any()))
+ ->method(('getEvent'))
+ ->willReturn(CommentsEvent::EVENT_ADD);
+
+ /** @var INotification|MockObject $notification */
+ $notification = $this->createMock(INotification::class);
+ $notification->expects($this->any())
+ ->method($this->anything())
+ ->willReturn($notification);
+ $notification->expects($this->never())
+ ->method('setUser');
+
+ $this->notificationManager->expects($this->once())
+ ->method('createNotification')
+ ->willReturn($notification);
+ $this->notificationManager->expects($this->never())
+ ->method('notify');
+
+ $this->userManager->expects($this->once())
+ ->method('userExists')
+ ->with('foobar')
+ ->willReturn(false);
+
+ $this->listener->evaluate($event);
+ }
+}
diff --git a/apps/comments/tests/Unit/Notification/NotifierTest.php b/apps/comments/tests/Unit/Notification/NotifierTest.php
new file mode 100644
index 00000000000..37cad0b43df
--- /dev/null
+++ b/apps/comments/tests/Unit/Notification/NotifierTest.php
@@ -0,0 +1,554 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Comments\Tests\Unit\Notification;
+
+use OCA\Comments\Notification\Notifier;
+use OCP\Comments\IComment;
+use OCP\Comments\ICommentsManager;
+use OCP\Comments\NotFoundException;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+use OCP\IUserManager;
+use OCP\L10N\IFactory;
+use OCP\Notification\AlreadyProcessedException;
+use OCP\Notification\INotification;
+use OCP\Notification\UnknownNotificationException;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class NotifierTest extends TestCase {
+ protected IFactory&MockObject $l10nFactory;
+ protected IL10N&MockObject $l;
+ protected IRootFolder&MockObject $folder;
+ protected ICommentsManager&MockObject $commentsManager;
+ protected IURLGenerator&MockObject $url;
+ protected IUserManager&MockObject $userManager;
+ protected INotification&MockObject $notification;
+ protected IComment&MockObject $comment;
+ protected Notifier $notifier;
+ protected string $lc = 'tlh_KX';
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->l10nFactory = $this->createMock(IFactory::class);
+ $this->folder = $this->createMock(IRootFolder::class);
+ $this->commentsManager = $this->createMock(ICommentsManager::class);
+ $this->url = $this->createMock(IURLGenerator::class);
+ $this->userManager = $this->createMock(IUserManager::class);
+
+ $this->notifier = new Notifier(
+ $this->l10nFactory,
+ $this->folder,
+ $this->commentsManager,
+ $this->url,
+ $this->userManager
+ );
+
+ $this->l = $this->createMock(IL10N::class);
+ $this->l->expects($this->any())
+ ->method('t')
+ ->willReturnCallback(function ($text, $parameters = []) {
+ return vsprintf($text, $parameters);
+ });
+
+ $this->notification = $this->createMock(INotification::class);
+ $this->comment = $this->createMock(IComment::class);
+ }
+
+ public function testPrepareSuccess(): void {
+ $fileName = 'Gre\'thor.odp';
+ $displayName = 'Huraga';
+
+ /** @var Node&MockObject $node */
+ $node = $this->createMock(Node::class);
+ $node
+ ->expects($this->atLeastOnce())
+ ->method('getName')
+ ->willReturn($fileName);
+ $node
+ ->expects($this->atLeastOnce())
+ ->method('getPath')
+ ->willReturn('/you/files/' . $fileName);
+
+ $userFolder = $this->createMock(Folder::class);
+ $this->folder->expects($this->once())
+ ->method('getUserFolder')
+ ->with('you')
+ ->willReturn($userFolder);
+ $userFolder->expects($this->once())
+ ->method('getById')
+ ->with('678')
+ ->willReturn([$node]);
+
+ $this->notification->expects($this->exactly(2))
+ ->method('getUser')
+ ->willReturn('you');
+ $this->notification
+ ->expects($this->once())
+ ->method('getApp')
+ ->willReturn('comments');
+ $this->notification
+ ->expects($this->once())
+ ->method('getSubject')
+ ->willReturn('mention');
+ $this->notification
+ ->expects($this->once())
+ ->method('getSubjectParameters')
+ ->willReturn(['files', '678']);
+ $this->notification
+ ->expects($this->never())
+ ->method('setParsedSubject');
+ $this->notification
+ ->expects($this->once())
+ ->method('setRichSubject')
+ ->with('{user} mentioned you in a comment on "{file}"', $this->anything())
+ ->willReturnSelf();
+ $this->notification
+ ->expects($this->once())
+ ->method('setRichMessage')
+ ->with('Hi {mention-user1}!', ['mention-user1' => ['type' => 'user', 'id' => 'you', 'name' => 'Your name']])
+ ->willReturnSelf();
+ $this->notification
+ ->expects($this->never())
+ ->method('setParsedMessage');
+ $this->notification
+ ->expects($this->once())
+ ->method('setIcon')
+ ->with('absolute-image-path')
+ ->willReturnSelf();
+
+ $this->url->expects($this->once())
+ ->method('imagePath')
+ ->with('core', 'actions/comment.svg')
+ ->willReturn('image-path');
+ $this->url->expects($this->once())
+ ->method('getAbsoluteURL')
+ ->with('image-path')
+ ->willReturn('absolute-image-path');
+
+ $this->l10nFactory
+ ->expects($this->once())
+ ->method('get')
+ ->willReturn($this->l);
+
+ $this->comment
+ ->expects($this->any())
+ ->method('getActorId')
+ ->willReturn('huraga');
+ $this->comment
+ ->expects($this->any())
+ ->method('getActorType')
+ ->willReturn('users');
+ $this->comment
+ ->expects($this->any())
+ ->method('getMessage')
+ ->willReturn('Hi @you!');
+ $this->comment
+ ->expects($this->any())
+ ->method('getMentions')
+ ->willReturn([['type' => 'user', 'id' => 'you']]);
+ $this->comment->expects($this->atLeastOnce())
+ ->method('getId')
+ ->willReturn('1234');
+
+ $this->commentsManager
+ ->expects($this->once())
+ ->method('get')
+ ->willReturn($this->comment);
+ $this->commentsManager
+ ->expects($this->once())
+ ->method('resolveDisplayName')
+ ->with('user', 'you')
+ ->willReturn('Your name');
+
+ $this->userManager
+ ->expects($this->exactly(2))
+ ->method('getDisplayName')
+ ->willReturnMap([
+ ['huraga', $displayName],
+ ['you', 'You'],
+ ]);
+
+ $this->notifier->prepare($this->notification, $this->lc);
+ }
+
+ public function testPrepareSuccessDeletedUser(): void {
+ $fileName = 'Gre\'thor.odp';
+
+ /** @var Node|MockObject $node */
+ $node = $this->createMock(Node::class);
+ $node
+ ->expects($this->atLeastOnce())
+ ->method('getName')
+ ->willReturn($fileName);
+ $node
+ ->expects($this->atLeastOnce())
+ ->method('getPath')
+ ->willReturn('/you/files/' . $fileName);
+
+ $userFolder = $this->createMock(Folder::class);
+ $this->folder->expects($this->once())
+ ->method('getUserFolder')
+ ->with('you')
+ ->willReturn($userFolder);
+ $userFolder->expects($this->once())
+ ->method('getById')
+ ->with('678')
+ ->willReturn([$node]);
+
+ $this->notification->expects($this->exactly(2))
+ ->method('getUser')
+ ->willReturn('you');
+ $this->notification
+ ->expects($this->once())
+ ->method('getApp')
+ ->willReturn('comments');
+ $this->notification
+ ->expects($this->once())
+ ->method('getSubject')
+ ->willReturn('mention');
+ $this->notification
+ ->expects($this->once())
+ ->method('getSubjectParameters')
+ ->willReturn(['files', '678']);
+ $this->notification
+ ->expects($this->never())
+ ->method('setParsedSubject');
+ $this->notification
+ ->expects($this->once())
+ ->method('setRichSubject')
+ ->with('You were mentioned on "{file}", in a comment by an account that has since been deleted', $this->anything())
+ ->willReturnSelf();
+ $this->notification
+ ->expects($this->once())
+ ->method('setRichMessage')
+ ->with('Hi {mention-user1}!', ['mention-user1' => ['type' => 'user', 'id' => 'you', 'name' => 'Your name']])
+ ->willReturnSelf();
+ $this->notification
+ ->expects($this->never())
+ ->method('setParsedMessage');
+ $this->notification
+ ->expects($this->once())
+ ->method('setIcon')
+ ->with('absolute-image-path')
+ ->willReturnSelf();
+
+ $this->url->expects($this->once())
+ ->method('imagePath')
+ ->with('core', 'actions/comment.svg')
+ ->willReturn('image-path');
+ $this->url->expects($this->once())
+ ->method('getAbsoluteURL')
+ ->with('image-path')
+ ->willReturn('absolute-image-path');
+
+ $this->l10nFactory
+ ->expects($this->once())
+ ->method('get')
+ ->willReturn($this->l);
+
+ $this->comment
+ ->expects($this->any())
+ ->method('getActorId')
+ ->willReturn('huraga');
+ $this->comment
+ ->expects($this->any())
+ ->method('getActorType')
+ ->willReturn(ICommentsManager::DELETED_USER);
+ $this->comment
+ ->expects($this->any())
+ ->method('getMessage')
+ ->willReturn('Hi @you!');
+ $this->comment
+ ->expects($this->any())
+ ->method('getMentions')
+ ->willReturn([['type' => 'user', 'id' => 'you']]);
+
+ $this->commentsManager
+ ->expects($this->once())
+ ->method('get')
+ ->willReturn($this->comment);
+ $this->commentsManager
+ ->expects($this->once())
+ ->method('resolveDisplayName')
+ ->with('user', 'you')
+ ->willReturn('Your name');
+
+ $this->userManager
+ ->expects($this->once())
+ ->method('getDisplayName')
+ ->willReturnMap([
+ ['huraga', null],
+ ['you', 'You'],
+ ]);
+
+ $this->notifier->prepare($this->notification, $this->lc);
+ }
+
+
+ public function testPrepareDifferentApp(): void {
+ $this->expectException(UnknownNotificationException::class);
+
+ $this->folder
+ ->expects($this->never())
+ ->method('getById');
+
+ $this->notification
+ ->expects($this->once())
+ ->method('getApp')
+ ->willReturn('constructions');
+ $this->notification
+ ->expects($this->never())
+ ->method('getSubject');
+ $this->notification
+ ->expects($this->never())
+ ->method('getSubjectParameters');
+ $this->notification
+ ->expects($this->never())
+ ->method('setParsedSubject');
+
+ $this->l10nFactory
+ ->expects($this->never())
+ ->method('get');
+
+ $this->commentsManager
+ ->expects($this->never())
+ ->method('get');
+
+ $this->userManager
+ ->expects($this->never())
+ ->method('getDisplayName');
+
+ $this->notifier->prepare($this->notification, $this->lc);
+ }
+
+
+ public function testPrepareNotFound(): void {
+ $this->expectException(UnknownNotificationException::class);
+
+ $this->folder
+ ->expects($this->never())
+ ->method('getById');
+
+ $this->notification
+ ->expects($this->once())
+ ->method('getApp')
+ ->willReturn('comments');
+ $this->notification
+ ->expects($this->never())
+ ->method('getSubject');
+ $this->notification
+ ->expects($this->never())
+ ->method('getSubjectParameters');
+ $this->notification
+ ->expects($this->never())
+ ->method('setParsedSubject');
+
+ $this->l10nFactory
+ ->expects($this->never())
+ ->method('get');
+
+ $this->commentsManager
+ ->expects($this->once())
+ ->method('get')
+ ->willThrowException(new NotFoundException());
+
+ $this->userManager
+ ->expects($this->never())
+ ->method('getDisplayName');
+
+ $this->notifier->prepare($this->notification, $this->lc);
+ }
+
+
+ public function testPrepareDifferentSubject(): void {
+ $this->expectException(UnknownNotificationException::class);
+
+ $displayName = 'Huraga';
+
+ $this->folder
+ ->expects($this->never())
+ ->method('getById');
+
+ $this->notification
+ ->expects($this->once())
+ ->method('getApp')
+ ->willReturn('comments');
+ $this->notification
+ ->expects($this->once())
+ ->method('getSubject')
+ ->willReturn('unlike');
+ $this->notification
+ ->expects($this->never())
+ ->method('getSubjectParameters');
+ $this->notification
+ ->expects($this->never())
+ ->method('setParsedSubject');
+
+ $this->l
+ ->expects($this->never())
+ ->method('t');
+
+ $this->l10nFactory
+ ->expects($this->once())
+ ->method('get')
+ ->willReturn($this->l);
+
+ $this->comment
+ ->expects($this->any())
+ ->method('getActorId')
+ ->willReturn('huraga');
+ $this->comment
+ ->expects($this->any())
+ ->method('getActorType')
+ ->willReturn('users');
+
+ $this->commentsManager
+ ->expects($this->once())
+ ->method('get')
+ ->willReturn($this->comment);
+
+ $this->userManager
+ ->expects($this->once())
+ ->method('getDisplayName')
+ ->with('huraga')
+ ->willReturn($displayName);
+
+ $this->notifier->prepare($this->notification, $this->lc);
+ }
+
+
+ public function testPrepareNotFiles(): void {
+ $this->expectException(UnknownNotificationException::class);
+
+ $displayName = 'Huraga';
+
+ $this->folder
+ ->expects($this->never())
+ ->method('getById');
+
+ $this->notification
+ ->expects($this->once())
+ ->method('getApp')
+ ->willReturn('comments');
+ $this->notification
+ ->expects($this->once())
+ ->method('getSubject')
+ ->willReturn('mention');
+ $this->notification
+ ->expects($this->once())
+ ->method('getSubjectParameters')
+ ->willReturn(['ships', '678']);
+ $this->notification
+ ->expects($this->never())
+ ->method('setParsedSubject');
+
+ $this->l
+ ->expects($this->never())
+ ->method('t');
+
+ $this->l10nFactory
+ ->expects($this->once())
+ ->method('get')
+ ->willReturn($this->l);
+
+ $this->comment
+ ->expects($this->any())
+ ->method('getActorId')
+ ->willReturn('huraga');
+ $this->comment
+ ->expects($this->any())
+ ->method('getActorType')
+ ->willReturn('users');
+
+ $this->commentsManager
+ ->expects($this->once())
+ ->method('get')
+ ->willReturn($this->comment);
+
+ $this->userManager
+ ->expects($this->once())
+ ->method('getDisplayName')
+ ->with('huraga')
+ ->willReturn($displayName);
+
+ $this->notifier->prepare($this->notification, $this->lc);
+ }
+
+
+ public function testPrepareUnresolvableFileID(): void {
+ $this->expectException(AlreadyProcessedException::class);
+
+ $displayName = 'Huraga';
+
+ $userFolder = $this->createMock(Folder::class);
+ $this->folder->expects($this->once())
+ ->method('getUserFolder')
+ ->with('you')
+ ->willReturn($userFolder);
+ $userFolder->expects($this->once())
+ ->method('getById')
+ ->with('678')
+ ->willReturn([]);
+
+ $this->notification->expects($this->once())
+ ->method('getUser')
+ ->willReturn('you');
+ $this->notification
+ ->expects($this->once())
+ ->method('getApp')
+ ->willReturn('comments');
+ $this->notification
+ ->expects($this->once())
+ ->method('getSubject')
+ ->willReturn('mention');
+ $this->notification
+ ->expects($this->once())
+ ->method('getSubjectParameters')
+ ->willReturn(['files', '678']);
+ $this->notification
+ ->expects($this->never())
+ ->method('setParsedSubject');
+
+ $this->l
+ ->expects($this->never())
+ ->method('t');
+
+ $this->l10nFactory
+ ->expects($this->once())
+ ->method('get')
+ ->willReturn($this->l);
+
+ $this->comment
+ ->expects($this->any())
+ ->method('getActorId')
+ ->willReturn('huraga');
+ $this->comment
+ ->expects($this->any())
+ ->method('getActorType')
+ ->willReturn('users');
+
+ $this->commentsManager
+ ->expects($this->once())
+ ->method('get')
+ ->willReturn($this->comment);
+
+ $this->userManager
+ ->expects($this->once())
+ ->method('getDisplayName')
+ ->with('huraga')
+ ->willReturn($displayName);
+
+ $this->notifier->prepare($this->notification, $this->lc);
+ }
+}
diff --git a/apps/comments/tests/js/commentscollectionSpec.js b/apps/comments/tests/js/commentscollectionSpec.js
deleted file mode 100644
index 2f41a272f67..00000000000
--- a/apps/comments/tests/js/commentscollectionSpec.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License comment 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-describe('OCA.Comments.CommentCollection', function() {
- var CommentCollection = OCA.Comments.CommentCollection;
- var collection, syncStub;
- var comment1, comment2, comment3;
-
- beforeEach(function() {
- syncStub = sinon.stub(CommentCollection.prototype, 'sync');
- collection = new CommentCollection();
- collection.setObjectId(5);
-
- comment1 = {
- id: 1,
- actorType: 'users',
- actorId: 'user1',
- actorDisplayName: 'User One',
- objectType: 'files',
- objectId: 5,
- message: 'First',
- creationDateTime: Date.UTC(2016, 1, 3, 10, 5, 0)
- };
- comment2 = {
- id: 2,
- actorType: 'users',
- actorId: 'user2',
- actorDisplayName: 'User Two',
- objectType: 'files',
- objectId: 5,
- message: 'Second\nNewline',
- creationDateTime: Date.UTC(2016, 1, 3, 10, 0, 0)
- };
- comment3 = {
- id: 3,
- actorType: 'users',
- actorId: 'user3',
- actorDisplayName: 'User Three',
- objectType: 'files',
- objectId: 5,
- message: 'Third',
- creationDateTime: Date.UTC(2016, 1, 3, 5, 0, 0)
- };
- });
- afterEach(function() {
- syncStub.restore();
- });
-
- it('fetches the next page', function() {
- collection._limit = 2;
- collection.fetchNext();
-
- expect(syncStub.calledOnce).toEqual(true);
- expect(syncStub.lastCall.args[0]).toEqual('REPORT');
- var options = syncStub.lastCall.args[2];
- expect(options.remove).toEqual(false);
-
- var parser = new DOMParser();
- var doc = parser.parseFromString(options.data, "application/xml");
- expect(doc.getElementsByTagNameNS('http://owncloud.org/ns', 'limit')[0].textContent).toEqual('3');
- expect(doc.getElementsByTagNameNS('http://owncloud.org/ns', 'offset')[0].textContent).toEqual('0');
-
- syncStub.yieldTo('success', [comment1, comment2, comment3]);
-
- expect(collection.length).toEqual(2);
- expect(collection.hasMoreResults()).toEqual(true);
-
- collection.fetchNext();
-
- expect(syncStub.calledTwice).toEqual(true);
- options = syncStub.lastCall.args[2];
- doc = parser.parseFromString(options.data, "application/xml");
- expect(doc.getElementsByTagNameNS('http://owncloud.org/ns', 'limit')[0].textContent).toEqual('3');
- expect(doc.getElementsByTagNameNS('http://owncloud.org/ns', 'offset')[0].textContent).toEqual('2');
-
- syncStub.yieldTo('success', [comment3]);
-
- expect(collection.length).toEqual(3);
- expect(collection.hasMoreResults()).toEqual(false);
-
- collection.fetchNext();
-
- // no further requests
- expect(syncStub.calledTwice).toEqual(true);
- });
- it('resets page counted when calling reset', function() {
- collection.fetchNext();
-
- syncStub.yieldTo('success', [comment1]);
-
- expect(collection.hasMoreResults()).toEqual(false);
-
- collection.reset();
-
- expect(collection.hasMoreResults()).toEqual(true);
- });
- describe('resetting read marker', function() {
- var updateStub;
- var clock;
-
- beforeEach(function() {
- updateStub = sinon.stub(OCA.Comments.CommentSummaryModel.prototype, 'save');
- clock = sinon.useFakeTimers(Date.UTC(2016, 1, 3, 10, 5, 9));
- });
- afterEach(function() {
- updateStub.restore();
- clock.restore();
- });
-
- it('resets read marker to the default date', function() {
- var successStub = sinon.stub();
- collection.updateReadMarker(null, {
- success: successStub
- });
-
- expect(updateStub.calledOnce).toEqual(true);
- expect(updateStub.lastCall.args[0]).toEqual({
- readMarker: new Date(Date.UTC(2016, 1, 3, 10, 5, 9)).toUTCString()
- });
-
- updateStub.yieldTo('success');
-
- expect(successStub.calledOnce).toEqual(true);
- });
- it('resets read marker to the given date', function() {
- var successStub = sinon.stub();
- collection.updateReadMarker(new Date(Date.UTC(2016, 1, 2, 3, 4, 5)), {
- success: successStub
- });
-
- expect(updateStub.calledOnce).toEqual(true);
- expect(updateStub.lastCall.args[0]).toEqual({
- readMarker: new Date(Date.UTC(2016, 1, 2, 3, 4, 5)).toUTCString()
- });
-
- updateStub.yieldTo('success');
-
- expect(successStub.calledOnce).toEqual(true);
- });
- });
-});
-
diff --git a/apps/comments/tests/js/commentstabviewSpec.js b/apps/comments/tests/js/commentstabviewSpec.js
deleted file mode 100644
index 70930da7520..00000000000
--- a/apps/comments/tests/js/commentstabviewSpec.js
+++ /dev/null
@@ -1,452 +0,0 @@
-/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2016 Vincent Petry <pvince81@owncloud.com>
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* comment 3 of the License, or any later comment.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-describe('OCA.Comments.CommentsTabView tests', function() {
- var view, fileInfoModel;
- var fetchStub;
- var testComments;
- var clock;
-
- /**
- * Creates a dummy message with the given length
- *
- * @param {int} len length
- * @return {string} message
- */
- function createMessageWithLength(len) {
- var bigMessage = '';
- for (var i = 0; i < len; i++) {
- bigMessage += 'a';
- }
- return bigMessage;
- }
-
- beforeEach(function() {
- clock = sinon.useFakeTimers(Date.UTC(2016, 1, 3, 10, 5, 9));
- fetchStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'fetchNext');
- view = new OCA.Comments.CommentsTabView();
- fileInfoModel = new OCA.Files.FileInfoModel({
- id: 5,
- name: 'One.txt',
- mimetype: 'text/plain',
- permissions: 31,
- path: '/subdir',
- size: 123456789,
- etag: 'abcdefg',
- mtime: Date.UTC(2016, 1, 0, 0, 0, 0)
- });
- view.render();
- var comment1 = new OCA.Comments.CommentModel({
- id: 1,
- actorType: 'users',
- actorId: 'user1',
- actorDisplayName: 'User One',
- objectType: 'files',
- objectId: 5,
- message: 'First',
- creationDateTime: new Date(Date.UTC(2016, 1, 3, 10, 5, 0)).toUTCString()
- });
- var comment2 = new OCA.Comments.CommentModel({
- id: 2,
- actorType: 'users',
- actorId: 'user2',
- actorDisplayName: 'User Two',
- objectType: 'files',
- objectId: 5,
- message: 'Second\nNewline',
- creationDateTime: new Date(Date.UTC(2016, 1, 3, 10, 0, 0)).toUTCString()
- });
-
- testComments = [comment1, comment2];
- });
- afterEach(function() {
- view.remove();
- view = undefined;
- fetchStub.restore();
- clock.restore();
- });
- describe('rendering', function() {
- it('reloads matching comments when setting file info model', function() {
- view.setFileInfo(fileInfoModel);
- expect(fetchStub.calledOnce).toEqual(true);
- });
-
- it('renders loading icon while fetching comments', function() {
- view.setFileInfo(fileInfoModel);
- view.collection.trigger('request');
-
- expect(view.$el.find('.loading').length).toEqual(1);
- expect(view.$el.find('.comments li').length).toEqual(0);
- });
-
- it('renders comments', function() {
- view.setFileInfo(fileInfoModel);
- view.collection.set(testComments);
-
- var $comments = view.$el.find('.comments>li');
- expect($comments.length).toEqual(2);
- var $item = $comments.eq(0);
- expect($item.find('.author').text()).toEqual('User One');
- expect($item.find('.date').text()).toEqual('seconds ago');
- expect($item.find('.message').text()).toEqual('First');
-
- $item = $comments.eq(1);
- expect($item.find('.author').text()).toEqual('User Two');
- expect($item.find('.date').text()).toEqual('5 minutes ago');
- expect($item.find('.message').html()).toEqual('Second<br>Newline');
- });
-
- it('renders comments from deleted user differently', function() {
- testComments[0].set('actorType', 'deleted_users', {silent: true});
- view.collection.set(testComments);
-
- var $item = view.$el.find('.comment[data-id=1]');
- expect($item.find('.author').text()).toEqual('[Deleted user]');
- expect($item.find('.avatar').attr('data-username')).not.toBeDefined();
- });
- });
- describe('more comments', function() {
- var hasMoreResultsStub;
-
- beforeEach(function() {
- view.collection.set(testComments);
- hasMoreResultsStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'hasMoreResults');
- });
- afterEach(function() {
- hasMoreResultsStub.restore();
- });
-
- it('shows "More comments" button when more comments are available', function() {
- hasMoreResultsStub.returns(true);
- view.collection.trigger('sync');
-
- expect(view.$el.find('.showMore').hasClass('hidden')).toEqual(false);
- });
- it('does not show "More comments" button when more comments are available', function() {
- hasMoreResultsStub.returns(false);
- view.collection.trigger('sync');
-
- expect(view.$el.find('.showMore').hasClass('hidden')).toEqual(true);
- });
- it('fetches and appends the next page when clicking the "More" button', function() {
- hasMoreResultsStub.returns(true);
-
- expect(fetchStub.notCalled).toEqual(true);
-
- view.$el.find('.showMore').click();
-
- expect(fetchStub.calledOnce).toEqual(true);
- });
- it('appends comment to the list when added to collection', function() {
- var comment3 = new OCA.Comments.CommentModel({
- id: 3,
- actorType: 'users',
- actorId: 'user3',
- actorDisplayName: 'User Three',
- objectType: 'files',
- objectId: 5,
- message: 'Third',
- creationDateTime: new Date(Date.UTC(2016, 1, 3, 5, 0, 0)).toUTCString()
- });
-
- view.collection.add(comment3);
-
- expect(view.$el.find('.comments>li').length).toEqual(3);
-
- var $item = view.$el.find('.comments>li').eq(2);
- expect($item.find('.author').text()).toEqual('User Three');
- expect($item.find('.date').text()).toEqual('5 hours ago');
- expect($item.find('.message').html()).toEqual('Third');
- });
- });
- describe('posting comments', function() {
- var createStub;
- var currentUserStub;
-
- beforeEach(function() {
- view.collection.set(testComments);
- createStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'create');
- currentUserStub = sinon.stub(OC, 'getCurrentUser');
- currentUserStub.returns({
- uid: 'testuser',
- displayName: 'Test User'
- });
- });
- afterEach(function() {
- createStub.restore();
- currentUserStub.restore();
- });
-
- it('creates a new comment when clicking post button', function() {
- view.$el.find('.message').val('New message');
- view.$el.find('form').submit();
-
- expect(createStub.calledOnce).toEqual(true);
- expect(createStub.lastCall.args[0]).toEqual({
- actorId: 'testuser',
- actorDisplayName: 'Test User',
- actorType: 'users',
- verb: 'comment',
- message: 'New message',
- creationDateTime: new Date(Date.UTC(2016, 1, 3, 10, 5, 9)).toUTCString()
- });
- });
- it('does not create a comment if the field is empty', function() {
- view.$el.find('.message').val(' ');
- view.$el.find('form').submit();
-
- expect(createStub.notCalled).toEqual(true);
- });
- it('does not create a comment if the field length is too large', function() {
- var bigMessage = '';
- for (var i = 0; i < view._commentMaxLength * 2; i++) {
- bigMessage += 'a';
- }
- view.$el.find('.message').val(bigMessage);
- view.$el.find('form').submit();
-
- expect(createStub.notCalled).toEqual(true);
- });
- describe('limit indicator', function() {
- var tooltipStub;
- var $message;
- var $submitButton;
-
- beforeEach(function() {
- tooltipStub = sinon.stub($.fn, 'tooltip');
- $message = view.$el.find('.message');
- $submitButton = view.$el.find('.submit');
- });
- afterEach(function() {
- tooltipStub.restore();
- });
-
- it('does not displays tooltip when limit is far away', function() {
- $message.val(createMessageWithLength(3));
- $message.trigger('change');
-
- expect(tooltipStub.calledWith('show')).toEqual(false);
- expect($submitButton.prop('disabled')).toEqual(false);
- expect($message.hasClass('error')).toEqual(false);
- });
- it('displays tooltip when limit is almost reached', function() {
- $message.val(createMessageWithLength(view._commentMaxLength - 2));
- $message.trigger('change');
-
- expect(tooltipStub.calledWith('show')).toEqual(true);
- expect($submitButton.prop('disabled')).toEqual(false);
- expect($message.hasClass('error')).toEqual(false);
- });
- it('displays tooltip and disabled button when limit is exceeded', function() {
- $message.val(createMessageWithLength(view._commentMaxLength + 2));
- $message.trigger('change');
-
- expect(tooltipStub.calledWith('show')).toEqual(true);
- expect($submitButton.prop('disabled')).toEqual(true);
- expect($message.hasClass('error')).toEqual(true);
- });
- });
- });
- describe('editing comments', function() {
- var saveStub;
- var currentUserStub;
-
- beforeEach(function() {
- saveStub = sinon.stub(OCA.Comments.CommentModel.prototype, 'save');
- currentUserStub = sinon.stub(OC, 'getCurrentUser');
- currentUserStub.returns({
- uid: 'testuser',
- displayName: 'Test User'
- });
- view.collection.add({
- id: 1,
- actorId: 'testuser',
- actorDisplayName: 'Test User',
- actorType: 'users',
- verb: 'comment',
- message: 'New message',
- creationDateTime: new Date(Date.UTC(2016, 1, 3, 10, 5, 9)).toUTCString()
- });
- view.collection.add({
- id: 2,
- actorId: 'anotheruser',
- actorDisplayName: 'Another User',
- actorType: 'users',
- verb: 'comment',
- message: 'New message from another user',
- creationDateTime: new Date(Date.UTC(2016, 1, 3, 10, 5, 9)).toUTCString()
- });
- });
- afterEach(function() {
- saveStub.restore();
- currentUserStub.restore();
- });
-
- it('shows edit link for owner comments', function() {
- var $comment = view.$el.find('.comment[data-id=1]');
- expect($comment.length).toEqual(1);
- expect($comment.find('.action.edit').length).toEqual(1);
- });
-
- it('does not show edit link for other user\'s comments', function() {
- var $comment = view.$el.find('.comment[data-id=2]');
- expect($comment.length).toEqual(1);
- expect($comment.find('.action.edit').length).toEqual(0);
- });
-
- it('shows edit form when clicking edit', function() {
- var $comment = view.$el.find('.comment[data-id=1]');
- $comment.find('.action.edit').click();
-
- expect($comment.hasClass('hidden')).toEqual(true);
- var $formRow = view.$el.find('.newCommentRow.comment[data-id=1]');
- expect($formRow.length).toEqual(1);
- });
-
- it('saves message and updates comment item when clicking save', function() {
- var $comment = view.$el.find('.comment[data-id=1]');
- $comment.find('.action.edit').click();
-
- var $formRow = view.$el.find('.newCommentRow.comment[data-id=1]');
- expect($formRow.length).toEqual(1);
-
- $formRow.find('textarea').val('modified\nmessage');
- $formRow.find('form').submit();
-
- expect(saveStub.calledOnce).toEqual(true);
- expect(saveStub.lastCall.args[0]).toEqual({
- message: 'modified\nmessage'
- });
-
- var model = view.collection.get(1);
- // simulate the fact that save sets the attribute
- model.set('message', 'modified\nmessage');
- saveStub.yieldTo('success', model);
-
- // original comment element is visible again
- expect($comment.hasClass('hidden')).toEqual(false);
- // and its message was updated
- expect($comment.find('.message').html()).toEqual('modified<br>message');
-
- // form row is gone
- $formRow = view.$el.find('.newCommentRow.comment[data-id=1]');
- expect($formRow.length).toEqual(0);
- });
-
- it('restores original comment when cancelling', function() {
- var $comment = view.$el.find('.comment[data-id=1]');
- $comment.find('.action.edit').click();
-
- var $formRow = view.$el.find('.newCommentRow.comment[data-id=1]');
- expect($formRow.length).toEqual(1);
-
- $formRow.find('textarea').val('modified\nmessage');
- $formRow.find('.cancel').click();
-
- expect(saveStub.notCalled).toEqual(true);
-
- // original comment element is visible again
- expect($comment.hasClass('hidden')).toEqual(false);
- // and its message was not updated
- expect($comment.find('.message').html()).toEqual('New message');
-
- // form row is gone
- $formRow = view.$el.find('.newCommentRow.comment[data-id=1]');
- expect($formRow.length).toEqual(0);
- });
-
- it('destroys model when clicking delete', function() {
- var destroyStub = sinon.stub(OCA.Comments.CommentModel.prototype, 'destroy');
- var $comment = view.$el.find('.comment[data-id=1]');
- $comment.find('.action.edit').click();
-
- var $formRow = view.$el.find('.newCommentRow.comment[data-id=1]');
- expect($formRow.length).toEqual(1);
-
- $formRow.find('.delete').click();
-
- expect(destroyStub.calledOnce).toEqual(true);
- expect(destroyStub.thisValues[0].id).toEqual(1);
-
- destroyStub.yieldTo('success');
-
- // original comment element is gone
- $comment = view.$el.find('.comment[data-id=1]');
- expect($comment.length).toEqual(0);
-
- // form row is gone
- $formRow = view.$el.find('.newCommentRow.comment[data-id=1]');
- expect($formRow.length).toEqual(0);
-
- destroyStub.restore();
- });
- it('does not submit comment if the field is empty', function() {
- var $comment = view.$el.find('.comment[data-id=1]');
- $comment.find('.action.edit').click();
- $comment.find('.message').val(' ');
- $comment.find('form').submit();
-
- expect(saveStub.notCalled).toEqual(true);
- });
- it('does not submit comment if the field length is too large', function() {
- var $comment = view.$el.find('.comment[data-id=1]');
- $comment.find('.action.edit').click();
- $comment.find('.message').val(createMessageWithLength(view._commentMaxLength * 2));
- $comment.find('form').submit();
-
- expect(saveStub.notCalled).toEqual(true);
- });
- });
- describe('read marker', function() {
- var updateMarkerStub;
-
- beforeEach(function() {
- updateMarkerStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'updateReadMarker');
- });
- afterEach(function() {
- updateMarkerStub.restore();
- });
-
- it('resets the read marker after REPORT', function() {
- testComments[0].set('isUnread', true, {silent: true});
- testComments[1].set('isUnread', true, {silent: true});
- view.collection.set(testComments);
- view.collection.trigger('sync', 'REPORT');
-
- expect(updateMarkerStub.calledOnce).toEqual(true);
- expect(updateMarkerStub.lastCall.args[0]).toBeFalsy();
- });
- it('does not reset the read marker if there was no unread comments', function() {
- view.collection.set(testComments);
- view.collection.trigger('sync', 'REPORT');
-
- expect(updateMarkerStub.notCalled).toEqual(true);
- });
- it('does not reset the read marker when posting comments', function() {
- testComments[0].set('isUnread', true, {silent: true});
- testComments[1].set('isUnread', true, {silent: true});
- view.collection.set(testComments);
- view.collection.trigger('sync', 'POST');
-
- expect(updateMarkerStub.notCalled).toEqual(true);
- });
- });
-});
diff --git a/apps/comments/tests/js/filespluginSpec.js b/apps/comments/tests/js/filespluginSpec.js
deleted file mode 100644
index 78becc5af09..00000000000
--- a/apps/comments/tests/js/filespluginSpec.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2016 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-describe('OCA.Comments.FilesPlugin tests', function() {
- var fileList;
- var testFiles;
-
- beforeEach(function() {
- var $content = $('<div id="content"></div>');
- $('#testArea').append($content);
- // dummy file list
- var $div = $(
- '<div>' +
- '<table id="filestable">' +
- '<thead></thead>' +
- '<tbody id="fileList"></tbody>' +
- '</table>' +
- '</div>');
- $('#content').append($div);
-
- fileList = new OCA.Files.FileList($div);
- OCA.Comments.FilesPlugin.attach(fileList);
-
- testFiles = [{
- id: 1,
- type: 'file',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc',
- shareOwner: 'User One',
- isShareMountPoint: false,
- commentsUnread: 3
- }];
- });
- afterEach(function() {
- fileList.destroy();
- fileList = null;
- });
-
- describe('Comment icon', function() {
- it('does not render icon when no unread comments available', function() {
- testFiles[0].commentsUnread = 0;
- fileList.setFiles(testFiles);
- var $tr = fileList.findFileEl('One.txt');
- expect($tr.find('.action-comment').length).toEqual(0);
- });
- it('renders comment icon and extra data', function() {
- var $action, $tr;
- fileList.setFiles(testFiles);
- $tr = fileList.findFileEl('One.txt');
- $action = $tr.find('.action-comment');
- expect($action.length).toEqual(1);
- expect($action.hasClass('permanent')).toEqual(true);
-
- expect($tr.attr('data-comments-unread')).toEqual('3');
- });
- it('clicking icon opens sidebar', function() {
- var sidebarStub = sinon.stub(fileList, 'showDetailsView');
- var $action, $tr;
- fileList.setFiles(testFiles);
- $tr = fileList.findFileEl('One.txt');
- $action = $tr.find('.action-comment');
- $action.click();
-
- expect(sidebarStub.calledOnce).toEqual(true);
- expect(sidebarStub.lastCall.args[0]).toEqual('One.txt');
- expect(sidebarStub.lastCall.args[1]).toEqual('commentsTabView');
- });
- });
- describe('elementToFile', function() {
- it('returns comment count', function() {
- fileList.setFiles(testFiles);
- var $tr = fileList.findFileEl('One.txt');
- var data = fileList.elementToFile($tr);
- expect(data.commentsUnread).toEqual(3);
- });
- it('does not set comment count when not set', function() {
- delete testFiles[0].commentsUnread;
- fileList.setFiles(testFiles);
- var $tr = fileList.findFileEl('One.txt');
- var data = fileList.elementToFile($tr);
- expect(data.commentsUnread).not.toBeDefined();
- });
- it('does not set comment count when zero', function() {
- testFiles[0].commentsUnread = 0;
- fileList.setFiles(testFiles);
- var $tr = fileList.findFileEl('One.txt');
- var data = fileList.elementToFile($tr);
- expect(data.commentsUnread).not.toBeDefined();
- });
- });
-});